Files
orderPRO/.paul/phases/120-alert-component-unification/120-01-SUMMARY.md
Jacek Pyziak 933dfcc67b feat(120): alert component unification
Phase 120 - Plan 01:
- Reusable PHP alert component (resources/views/components/alert.php)
  with inline SVG icon per type, optional dismiss button.
- Missing .alert--info SCSS variant added (#eff6ff/#bfdbfe/#1e3a8a) -
  fixes black-on-white alert after Fakturownia test connection.
- Flash::push(type, message) + Flash::all() with BC for set/get;
  legacy key heuristic (error/.save/warning -> typed entries).
- Central flash renderer in 3 layouts (app/auth/public) iterating
  Flash::all() through component (.alerts-stack wrap).
- Vanilla JS alert-dismiss.js with idempotent guard and delegated
  click handler on [data-alert-dismiss].
- 36 views migrated off inline <div class="alert alert--TYPE">;
  .flash--error/success removed from views (orders/show, shipments/prepare).
- SCSS rebuilt: public/assets/css/{app,login}.css.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 18:47:41 +02:00

194 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
phase: 120-alert-component-unification
plan: 01
subsystem: ui
tags: [alerts, flash, components, scss, php-view, accessibility, dismissable]
requires:
- phase: 113-fakturownia-foundation
provides: Flash usage pattern, fakturownia.php view (bug reporter)
- phase: 118-fakturownia-single-instance
provides: fakturownia.php single-form view that exposed missing .alert--info
provides:
- Reusable view component for alerts (`resources/views/components/alert.php`)
- .alert--info SCSS variant + flex layout with icon/body/dismiss
- Dismiss JS module (`alert-dismiss.js`) with delegated click handler
- Flash::push(type, message) + Flash::all() with legacy heuristic
- Central flash renderer in 3 layouts (app/auth/public)
- 36 views migrated off inline alert markup
affects: [future settings views, future Flash::push usage, login UX, any new admin views]
tech-stack:
added: []
patterns:
- Component include with extracted locals (`$type`, `$message`, `$dismissible`, `$messageHtml`)
- Central renderer in layout consuming queued + legacy flash entries
- Idempotent vanilla JS modules guarded via window flags
key-files:
created:
- resources/views/components/alert.php
- public/assets/js/modules/alert-dismiss.js
modified:
- resources/scss/shared/_ui-components.scss
- public/assets/css/app.css (rebuilt)
- public/assets/css/login.css (rebuilt)
- src/Core/Support/Flash.php
- resources/views/layouts/app.php
- resources/views/layouts/auth.php
- resources/views/layouts/public.php
key-decisions:
- "Component-based view include over template engine partial - no DI needed, BC z `extract` pattern"
- "Flash::set/get pozostawione BC; kontrolery NIE dotykane - migracja widokow wystarczyla"
- "Heurystyka klucza legacy (`.save`/`error`/`warning`) zamiast wymuszania Flash::push - migracja stopniowa"
- "messageHtml jako trusted opt-in dla wpisow z markup (uvaga: lista faktur/paragonow/debug pre)"
- "JS alerty w email-mailboxes.php pozostawione na klasach SCSS - markup komponentu poza zakresem"
patterns-established:
- "Alert markup: `<?php $type=...; $message=...; $dismissible=...; include dirname(__DIR__) . '/components/alert.php'; ?>`"
- "Trusted HTML w alert: ob_start() ... $messageHtml = ob_get_clean(); include ...; unset($messageHtml);"
- "Central layout flash render: foreach Flash::all() → include components/alert.php (wrap .alerts-stack)"
duration: ~50min
started: 2026-05-12T15:00:00Z
completed: 2026-05-12T15:40:00Z
---
# Phase 120 Plan 01: Alert Component Unification
**Reusable PHP alert component z `.alert--info` (brakujacy wariant), inline SVG ikona per typ, dismiss button + central Flash renderer w 3 layoutach; 36 widokow zmigrowanych.**
## Performance
| Metric | Value |
|--------|-------|
| Duration | ~50 minut |
| Started | 2026-05-12T15:00:00Z |
| Completed | 2026-05-12T15:40:00Z |
| Tasks | 3 z 3 ukonczone |
| Files modified | 42 (component + JS + SCSS + 3 layouty + Flash + 36 widokow + 2 CSS rebuilds) |
## Acceptance Criteria Results
| Criterion | Status | Notes |
|-----------|--------|-------|
| AC-1: Komponent alert + brakujacy wariant info | Pass | `.alert--info` (#eff6ff/#bfdbfe/#1e3a8a) w `app.css` zweryfikowany; ikona SVG + dismiss × renderowane przez `components/alert.php`. Test polaczenia fakturownia → niebieski alert z ikona "i" i ×. |
| AC-2: Centralny renderer flash w layoutach | Pass | `Flash::all()` w `app.php`, `auth.php`, `public.php` (3 hits w grep); typowana kolejka push + legacy fallback z heurystyka klucza. |
| AC-3: Migracja widokow + flash--error | Pass | `grep 'class="alert alert--' resources/views/` → tylko `components/alert.php`; `grep 'flash--' resources/views/` → 0. 36 widokow przeszlo `php -l`. |
## Accomplishments
- Component-based alert markup dostepny w jednym pliku — `resources/views/components/alert.php` z ikonami SVG inline per typ (info/success/warning/danger) i opcjonalnym dismiss.
- Brakujacy `.alert--info` (#eff6ff bg, #1e3a8a tekst, #bfdbfe border) — zwerfikowany w skompilowanym `public/assets/css/app.css` (63 560 B, rebuilt via `npx sass`).
- `Flash::push(type, message)` + `Flash::all()` z BC dla `Flash::set/get` — heurystyka klucza legacy mapuje `.save/.created/.deleted/.toggled/success` → success, `error/fail/danger` → danger, `warning` → warning, reszta → info.
- Central flash renderer w 3 layoutach (`app.php`, `auth.php`, `public.php`) — przyszle `Flash::push()` zadziala bez ifow w widokach.
- 36 widokow zmigrowanych off inline `<div class="alert alert--TYPE">` (34 z planu + odkryte `orders/show.php` i `shipments/prepare.php` ze starym wzorcem `.flash--error/success`).
- Vanilla JS dismiss z idempotent guardem + delegated click handlerem — brak duplikowanego bindowania.
## Task Commits
Brak atomowych commits per task — caly plan zostanie wyemitowany jako single commit w transition phase (zgodnie z konwencja projektu, faza 119/118 dziedzicza ten wzorzec).
| Task | Commit | Type | Description |
|------|--------|------|-------------|
| Task 1: Komponent + SCSS + JS + layouty | (transition) | feat | Alert component, SCSS info/icon/dismiss, JS, central layout render |
| Task 2: Flash push/all + BC | (transition) | feat | Flash::push/all + legacy heuristic |
| Task 3: Migracja 36 widokow | (transition) | refactor | Inline alert/flash markup → component include |
## Files Created/Modified
| File | Change | Purpose |
|------|--------|---------|
| `resources/views/components/alert.php` | Created | Reusable alert component z ikona/body/dismiss |
| `public/assets/js/modules/alert-dismiss.js` | Created | Vanilla JS dismiss z idempotent guardem |
| `resources/scss/shared/_ui-components.scss` | Modified | `.alert` flex + `__icon`/`__body`/`__dismiss`, `.alert--info`, `.alerts-stack` |
| `public/assets/css/app.css` | Rebuilt | Wygenerowany z SCSS (`npx sass --style=compressed`) |
| `public/assets/css/login.css` | Rebuilt | Wygenerowany z SCSS |
| `src/Core/Support/Flash.php` | Modified | `push()`, `all()`, `inferTypeFromKey()` (private); BC dla `set/get` |
| `resources/views/layouts/app.php` | Modified | Central flash render + `alert-dismiss.js` script tag |
| `resources/views/layouts/auth.php` | Modified | Central flash render + `alert-dismiss.js` script tag |
| `resources/views/layouts/public.php` | Modified | Central flash render + `alert-dismiss.js` script tag |
| `resources/views/settings/fakturownia.php` | Modified | Inline alerts → component (bug reporter) |
| `resources/views/settings/{hostedsms,smsplanet,inpost,apaczka,allegro,company,cron,database,delivery-statuses,delivery-status-form,email-mailboxes,email-templates,email-templates-form,integrations,printing,project-mappings,shoppro,statuses,accounting,accounting-receipts,accounting-receipt-edit,accounting-invoices,accounting-invoice-edit}.php` | Modified | Inline alerts → component (23 plikow) |
| `resources/views/orders/{list,show,receipt-create}.php` | Modified | Inline alerts + `.flash--*` → component (3 pliki) |
| `resources/views/shipments/prepare.php` | Modified | 4× `.flash--error` → component |
| `resources/views/accounting/invoice_form.php` | Modified | Inline alerts + warning HTML → component z `$messageHtml` |
| `resources/views/automation/{index,form}.php` | Modified | Inline alerts → component |
| `resources/views/users/index.php` | Modified | Inline alerts → component |
| `resources/views/statistics/orders.php` | Modified | Debug warning HTML → component z `$messageHtml` |
| `resources/views/auth/login.php` | Modified | `.alert--danger login-alert` → component (`flash--error` flow) |
| `.paul/codebase/architecture.md` | Modified | Sekcja "Phase 120 — Alert Component Unification" |
| `.paul/codebase/tech_changelog.md` | Modified | Wpis dla Phase 120 |
## Decisions Made
| Decision | Rationale | Impact |
|----------|-----------|--------|
| Component przez `include` z extracted locals zamiast template helper | Zero infrastruktury, BC z istniejacym wzorcem `<?php include ... ?>` w widokach | Latwa migracja, brak nowych zaleznosci |
| Kontrolery NIE zmieniane (BC `Flash::set/get`) | Plan boundary: DO NOT CHANGE controllers. Migracja widokow wystarcza, central renderer obsluguje przyszle `Flash::push()` | Zachowany dotychczasowy flow flash z pre-fetchem w kontrolerze |
| `messageHtml` jako trusted opt-in (4 widoki: invoice_form, receipt-create, printing, statistics/orders) | `<ul>`/`<pre>`/`<strong>` content wymaga HTML — alternatywa byloby budowanie list w kontrolerze co rozmywa odpowiedzialnosc | Component obsluguje zarowno simple text jak i markup wewnetrzny |
| Heurystyka klucza legacy w `Flash::all()` | Migracja kontrolerow odlozona; klucze `module.save/error/test` daja sygnal typu | Operator widzi poprawny kolor bez zmian w kontrolerach |
| `unset($messageHtml)` po kazdym uzyciu | PHP `include` widzi zmienne z scope kontekstu; bez unsetu kolejny `include` w tym samym widoku falszywie wykrywa `isset($messageHtml)` | Kazde wywolanie komponentu jest izolowane |
| CSS rebuild wykonany inline (Phase 120) | Plan boundary mowil "build poza zakresem"; uzytkownik poprosil explicit | `app.css` i `login.css` aktualne, `.alert--info` zweryfikowany w skompilowanym CSS |
## Deviations from Plan
### Summary
| Type | Count | Impact |
|------|-------|--------|
| Auto-fixed | 2 | Eliminacja `.flash--error` z 2 dodatkowych widokow (out-of-list) |
| Scope additions | 1 | CSS rebuild zrobiony inline na zyczenie uzytkownika |
| Deferred | 2 | Migracja JS alerts w email-mailboxes; usuniecie `.flash--*` z SCSS |
**Total impact:** Essential fixes, no scope creep. Plan AC-3 wymagal `flash--error` = 0 — dodatkowe 2 pliki musialy zostac zmigrowane.
### Auto-fixed Issues
**1. [Coverage] `orders/show.php` i `shipments/prepare.php` z `.flash--error/success`**
- **Found during:** Task 3 final verify (`grep 'flash--' resources/views/`)
- **Issue:** Plan files_modified wymienial 34 widoki + login.php, ale grep ujawnil dodatkowe 2 widoki uzywajace starego `.flash--*` wzorca (5 wystapien lacznie).
- **Fix:** Zmigrowane na komponent `alert.php` z `$type='danger'/'success'`.
- **Files:** `resources/views/orders/show.php`, `resources/views/shipments/prepare.php`.
- **Verification:** `grep 'flash--' resources/views/` → 0.
**2. [Build] CSS rebuild via `npx sass`**
- **Found during:** Po Task 3, na zyczenie uzytkownika ("Przebuduj css")
- **Issue:** Plan boundary mowil "build SCSS poza zakresem"; bez rebuildu `.alert--info` nie zadzialalby w przegladarce.
- **Fix:** `npx --yes sass --style=compressed --no-source-map resources/scss/{app,login}.scss public/assets/css/{app,login}.css`.
- **Files:** `public/assets/css/app.css` (63 560 B), `public/assets/css/login.css` (7 409 B).
- **Verification:** `grep 'alert--info' app.css``border-color:#bfdbfe;background:#eff6ff;color:#1e3a8a`.
### Deferred Items
- **ALERT-JS-MIGRATION-120**: `resources/views/settings/email-mailboxes.php` linie 398/400/406 — JS-generowane alerty AJAX testu SMTP (`resultDiv.className = 'mt-12 alert alert--success'`). Uzywaja unified `.alert` SCSS, ale nie maja markupu komponentu (brak ikony/dismiss). Migracja wymagalaby JS template helpera — out of scope (discovered w Task 3).
- **FLASH-SCSS-CLEANUP-120**: `.flash--error/success/warning` w `_ui-components.scss` (jezeli istnieja) — nieuzywane po Phase 120, ale plan boundary explicit zostawia. Usuniecie w przyszlej fazie cleanup.
## Issues Encountered
| Issue | Resolution |
|-------|------------|
| `$messageHtml` persiste po pierwszym include w widoku — kolejne include widzialy `isset($messageHtml)` jako true | `unset($messageHtml)` po kazdym wywolaniu komponentu z `$messageHtml` (4 widoki) |
| `npm run build:css` failed — `sass` not in PATH | Uzyto `npx --yes sass` — pobiera deklaracje z `devDependencies` package.json |
## Next Phase Readiness
**Ready:**
- Komponent alert dostepny dla wszystkich przyszlych widokow — wzorzec `<?php $type=...; $message=...; $dismissible=...; include dirname(__DIR__) . '/components/alert.php'; ?>`.
- `Flash::push($type, $message)` dostepny dla kontrolerow ktore chca dolaczyc typowane flash entries bez magic keys.
- Central renderer w layoutach — dowolny nowy `Flash::push()` (lub `Flash::set()`) automatycznie renderuje sie u gory strony.
- CSS aktualny — operator moze odpalic smoke testy bez dalszych krokow build.
**Concerns:**
- Kontrolery dalej mieszaja `Flash::set('module.key', '...')` z konwencja key-based — przy migracji ku `Flash::push()` heurystyka klucza staje sie redundantna. Mozna zmigrowac stopniowo w kolejnych fazach.
- JS alerty w email-mailboxes.php beda wygladaly nieco inaczej (bez ikony/dismiss) niz PHP-renderowane — nieuwage UX, ale spojnosc wizualna 95%.
**Blockers:** None.
---
*Phase: 120-alert-component-unification, Plan: 01*
*Completed: 2026-05-12*