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>
This commit is contained in:
290
.paul/phases/120-alert-component-unification/120-01-PLAN.md
Normal file
290
.paul/phases/120-alert-component-unification/120-01-PLAN.md
Normal file
@@ -0,0 +1,290 @@
|
||||
---
|
||||
phase: 120-alert-component-unification
|
||||
plan: 01
|
||||
type: execute
|
||||
wave: 1
|
||||
depends_on: []
|
||||
files_modified:
|
||||
- resources/scss/shared/_ui-components.scss
|
||||
- resources/views/components/alert.php
|
||||
- public/assets/js/modules/alert-dismiss.js
|
||||
- resources/views/layouts/app.php
|
||||
- resources/views/layouts/auth.php
|
||||
- resources/views/layouts/public.php
|
||||
- src/Core/Support/Flash.php
|
||||
- resources/views/settings/fakturownia.php
|
||||
- resources/views/settings/accounting-invoice-edit.php
|
||||
- resources/views/settings/smsplanet.php
|
||||
- resources/views/settings/hostedsms.php
|
||||
- resources/views/settings/accounting.php
|
||||
- resources/views/settings/accounting-receipt-edit.php
|
||||
- resources/views/settings/accounting-receipts.php
|
||||
- resources/views/settings/accounting-invoices.php
|
||||
- resources/views/accounting/invoice_form.php
|
||||
- resources/views/users/index.php
|
||||
- resources/views/statistics/orders.php
|
||||
- resources/views/settings/statuses.php
|
||||
- resources/views/settings/shoppro.php
|
||||
- resources/views/settings/printing.php
|
||||
- resources/views/settings/project-mappings.php
|
||||
- resources/views/settings/integrations.php
|
||||
- resources/views/settings/email-templates.php
|
||||
- resources/views/settings/inpost.php
|
||||
- resources/views/settings/email-templates-form.php
|
||||
- resources/views/settings/email-mailboxes.php
|
||||
- resources/views/settings/delivery-statuses.php
|
||||
- resources/views/settings/database.php
|
||||
- resources/views/settings/delivery-status-form.php
|
||||
- resources/views/settings/cron.php
|
||||
- resources/views/settings/company.php
|
||||
- resources/views/settings/apaczka.php
|
||||
- resources/views/settings/allegro.php
|
||||
- resources/views/orders/receipt-create.php
|
||||
- resources/views/orders/list.php
|
||||
- resources/views/automation/index.php
|
||||
- resources/views/automation/form.php
|
||||
- resources/views/auth/login.php
|
||||
autonomous: true
|
||||
delegation: off
|
||||
---
|
||||
|
||||
<objective>
|
||||
## Goal
|
||||
Ujednolicic alerty/flash messages w calej aplikacji: reusable komponent widoku, brakujacy wariant `--info`, ikony i dismiss button, centralny renderer flash w layoutach. Po teście połączenia w `/settings/integrations/fakturownia` alert "OK (HTTP 200)" pojawia sie jako wyraznie wystylizowany `alert--info` z ikona i mozliwoscia zamkniecia.
|
||||
|
||||
## Purpose
|
||||
Obecnie 34 widoki uzywaja inline `<div class="alert alert--TYPE">` z roznym wzorcem; brak `.alert--info` powoduje czarny tekst na bialym tle (bug widoczny w fakturownia.php). Brak centralnego renderowania flash zmusza kazdy controller+widok do recznego przekazywania zmiennych `$flashSave/$flashTest/$flashError`. Jedno zrodlo prawdy upraszcza UX i przyszle utrzymanie.
|
||||
|
||||
## Output
|
||||
- `resources/views/components/alert.php` (komponent z paramami `$type`, `$message`, `$dismissible`)
|
||||
- `resources/scss/shared/_ui-components.scss` z `.alert--info`, ikonami i stylami dismiss
|
||||
- `public/assets/js/modules/alert-dismiss.js` (vanilla JS, idempotent guard)
|
||||
- `src/Core/Support/Flash.php` rozszerzone o `push()` + `all()` z zachowaniem `set()/get()` (BC)
|
||||
- Centralny render flash w `layouts/app.php` (+ `auth.php`, `public.php`)
|
||||
- Migracja 34 widokow na komponent + zamiana `.flash--*` w login.php
|
||||
</objective>
|
||||
|
||||
<context>
|
||||
<clarifications>
|
||||
- **Zakres** — Jak szeroki zakres migracji widokow w tej fazie?
|
||||
→ Odpowiedz: Komponent + migracja wszystkich (34 widoki).
|
||||
- **Funkcje** — Jakie warianty i funkcje ma obslugiwac komponent alert?
|
||||
→ Odpowiedz: Wariant info (brakujacy), Ikona per typ (info/success/warning/danger), Przycisk dismiss (×). Auto-hide pominiete.
|
||||
- **Flash legacy** — Czy ujednolicic rowniez stary wzorzec `.flash--error` (login.php) z nowym `.alert--*`?
|
||||
→ Odpowiedz: Tak, zastapic `.flash--*` przez `.alert--*`.
|
||||
- **Flash render** — Czy wyswietlanie alertow z sesji (Flash::get) zrobic tez przez komponent (centralny render np. w layoucie)?
|
||||
→ Odpowiedz: Centralny renderer flash w layoucie app.php (i auth/public).
|
||||
</clarifications>
|
||||
|
||||
## Project Context
|
||||
@.paul/PROJECT.md
|
||||
@.paul/STATE.md
|
||||
@.paul/codebase/architecture.md
|
||||
|
||||
## Source Files
|
||||
@resources/scss/shared/_ui-components.scss
|
||||
@resources/views/settings/fakturownia.php
|
||||
@resources/views/layouts/app.php
|
||||
@resources/views/auth/login.php
|
||||
@src/Core/Support/Flash.php
|
||||
</context>
|
||||
|
||||
<acceptance_criteria>
|
||||
|
||||
## AC-1: Komponent alert + brakujacy wariant info
|
||||
```gherkin
|
||||
Given uzytkownik otwiera /settings/integrations/fakturownia i wykonuje udany test polaczenia
|
||||
When kontroler ustawia Flash::push('info', 'OK (HTTP 200)') i widok renderuje sie ponownie
|
||||
Then na gorze strony pokazuje sie alert z niebieskim tlem (#eff6ff), niebieska ramka, ikona "i" po lewej, tekstem "OK (HTTP 200)" w czytelnym kontraście oraz przyciskiem × po prawej; klikniecie × usuwa alert z DOM bez przeladowania
|
||||
```
|
||||
|
||||
## AC-2: Centralny renderer flash w layoutach
|
||||
```gherkin
|
||||
Given kontroler wywoluje Flash::push('success', 'Zapisano') albo legacy Flash::set('module.save', 'Zapisano')
|
||||
When renderowany jest widok dziedziczacy z layouts/app.php (lub auth.php / public.php)
|
||||
Then layout automatycznie wyswietla wszystkie zakolejkowane flash entries u gory glownego obszaru, bez koniecznosci ifow w widoku; po pobraniu Flash::all() kolejne zadanie nie pokazuje juz tych wpisow
|
||||
```
|
||||
|
||||
## AC-3: Migracja widokow i flash--error
|
||||
```gherkin
|
||||
Given kazdy z 34 widokow wymienionych w files_modified
|
||||
When przegladam ich kod
|
||||
Then zaden nie zawiera inline `<div class="alert alert--...">` z zmiennymi flash (zamiast tego uzywa komponentu lub renderowanie jest delegowane do layoutu); login.php nie zawiera klasy `.flash--error` (zostala zastapiona alert--danger przez komponent); wizualnie alerty na fakturownia/hostedsms/smsplanet/login wygladaja identycznie i spojnie
|
||||
```
|
||||
|
||||
</acceptance_criteria>
|
||||
|
||||
<tasks>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 1: Komponent alert + SCSS info/ikony/dismiss + JS</name>
|
||||
<files>
|
||||
resources/scss/shared/_ui-components.scss,
|
||||
resources/views/components/alert.php,
|
||||
public/assets/js/modules/alert-dismiss.js,
|
||||
resources/views/layouts/app.php,
|
||||
resources/views/layouts/auth.php,
|
||||
resources/views/layouts/public.php
|
||||
</files>
|
||||
<action>
|
||||
1) SCSS — w `_ui-components.scss` po istniejacych `.alert--success/warning/danger` dodac:
|
||||
- `.alert` — display: flex; gap: 10px; align-items: flex-start; (zachowac padding/border-radius/border/font-size/min-height)
|
||||
- `.alert__icon` — flex: 0 0 18px; line-height: 1; svg width/height 18px; color: inherit
|
||||
- `.alert__body` — flex: 1; line-height: 1.4
|
||||
- `.alert__dismiss` — margin-left: auto; background: none; border: 0; cursor: pointer; padding: 2px 6px; color: inherit; opacity: 0.6; &:hover { opacity: 1 }
|
||||
- `.alert--info` — border-color: #bfdbfe; background: #eff6ff; color: #1e3a8a
|
||||
- Subtelnie wzmocnic kontrast tla istniejacych wariantow tylko jezeli wymaga to drobnej zmiany (np. zostawic jak jest dla --success/warning/danger).
|
||||
2) `resources/views/components/alert.php` — komponent renderujacy 1 alert. Params (przez extract):
|
||||
- `$type` (string, default 'info') — jeden z: info|success|warning|danger
|
||||
- `$message` (string) — escapowany przez `$e()`; alternatywnie `$messageHtml` (trusted HTML, opcjonalnie)
|
||||
- `$dismissible` (bool, default true)
|
||||
- Markup: `<div class="alert alert--{type}" role="alert" data-alert>` + `<span class="alert__icon" aria-hidden="true">{svgIconForType}</span>` + `<div class="alert__body">{message}</div>` + dismiss button (jezeli `$dismissible`).
|
||||
- Mapping typ → svg inline (info: i in circle; success: check; warning: triangle !; danger: x in circle). Trzymac SVG inline jako private map array `$ICONS` zdefiniowany w komponencie.
|
||||
- Walidacja: gdy `$type` nie z whitelist → fallback `info`.
|
||||
3) `public/assets/js/modules/alert-dismiss.js` — vanilla JS:
|
||||
- Idempotent guard: `if (window.__alertDismissBound) return; window.__alertDismissBound = true;`
|
||||
- `document.addEventListener('click', (e) => { const btn = e.target.closest('[data-alert-dismiss]'); if (!btn) return; const alert = btn.closest('[data-alert]'); if (alert) alert.remove(); });`
|
||||
- Brak zewnetrznych zaleznosci, brak jQuery.
|
||||
4) Layouty (`app.php`, `auth.php`, `public.php`):
|
||||
- Dodac `<link rel="stylesheet" href="/assets/css/app.css?ver=...">` juz istnieje — pliki SCSS sa kompilowane recznie (poza zakresem), nie ruszamy build pipeline.
|
||||
- Dodac `<script src="/assets/js/modules/alert-dismiss.js?ver=...">` przed `</body>` (analogicznie do innych modulow).
|
||||
- Dodac centralny render flash entries: na poczatku glownego content area, ITERACJA po `App\Core\Support\Flash::all()` i wywolanie komponentu `alert.php` dla kazdego wpisu `{type, message}`. Wzor:
|
||||
```php
|
||||
<?php foreach (\App\Core\Support\Flash::all() as $entry): ?>
|
||||
<?php $type = (string) ($entry['type'] ?? 'info'); $message = (string) ($entry['message'] ?? ''); $dismissible = true; include __DIR__ . '/../components/alert.php'; ?>
|
||||
<?php endforeach; ?>
|
||||
```
|
||||
- W `app.php` umiescic blok zaraz po otwarciu `<main>` (lub odpowiednim content wrap, znalezc grep "app-shell__main" / "content").
|
||||
- W `auth.php` i `public.php` — analogicznie, u gory glownego obszaru.
|
||||
Avoid:
|
||||
- Nie dodawac jQuery / bundlerow.
|
||||
- Nie zmieniac wygladu istniejacych alertow --success/--warning/--danger (poza dodaniem __icon + dismiss).
|
||||
- SVG inline (nie eksternalizowac do osobnych plikow).
|
||||
</action>
|
||||
<verify>
|
||||
1) `grep -rn "alert--info" resources/scss/shared/_ui-components.scss` zwraca definicje.
|
||||
2) Plik `resources/views/components/alert.php` istnieje i zawiera `<div class="alert alert--<?= $type ?>"`.
|
||||
3) `grep -rn "Flash::all" resources/views/layouts/` zwraca 3 wystapienia (app/auth/public).
|
||||
4) Ladowanie strony /settings/integrations/fakturownia po tescie polaczenia pokazuje niebieski alert info z ikona i przyciskiem × (manualny smoke test po skompilowaniu SCSS).
|
||||
</verify>
|
||||
<done>AC-1, AC-2 spelnione w zakresie infrastruktury (komponent + central render + style + JS).</done>
|
||||
</task>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 2: Flash::push/all + BC dla Flash::set/get</name>
|
||||
<files>src/Core/Support/Flash.php</files>
|
||||
<action>
|
||||
Rozszerzyc `App\Core\Support\Flash` o kolejke typowanych wpisow przy zachowaniu wstecznej kompatybilnosci.
|
||||
1) Dodac sekcje kolejki w sesji: `$_SESSION['_flash_queue']` (lista `['type' => string, 'message' => string]`).
|
||||
2) Nowa metoda: `public static function push(string $type, string $message): void`
|
||||
- Whitelist `$type`: info/success/warning/danger; fallback 'info'.
|
||||
- Append do `$_SESSION['_flash_queue']`.
|
||||
3) Nowa metoda: `public static function all(): array`
|
||||
- Zwraca i CZYSCI kolejke (consume-once).
|
||||
- Dodatkowo: skanuje legacy `$_SESSION['_flash']` (klucz-string => wartosc-string) i konwertuje do typowanych entries:
|
||||
- klucz konczacy sie na `.error` lub zawierajacy `error` → type=danger
|
||||
- klucz konczacy sie na `.save` / `.success` / zawierajacy `success`/`saved`/`saved` → type=success
|
||||
- klucz zawierajacy `warning` → type=warning
|
||||
- reszta (`.test`, `.info`, etc.) → type=info
|
||||
- Po konsumpcji czysci `_flash` analogicznie do `get()`.
|
||||
- Zachowac kolejnosc: najpierw push-queue, potem legacy.
|
||||
4) `set()`/`get()` pozostaja bez zmian (BC) — nie czyscic ich z `all()` jezeli `get()` nie zostal jeszcze wywolany; tj. `all()` POBIERA wszystkie pozostale legacy entries (controllery zwykle juz pobraly konkretne klucze przed renderem, wiec layout konsumuje to co zostalo).
|
||||
5) Brak zmian sygnatury istniejacych metod, brak removed methods.
|
||||
</action>
|
||||
<verify>
|
||||
1) `grep -n "public static function push" src/Core/Support/Flash.php` → 1 match.
|
||||
2) `grep -n "public static function all" src/Core/Support/Flash.php` → 1 match.
|
||||
3) Recznie: w widoku `Flash::set('fakturownia.test', 'OK (HTTP 200)'); Flash::all()` zwraca `[['type'=>'info','message'=>'OK (HTTP 200)']]`.
|
||||
</verify>
|
||||
<done>AC-2 spelnione w warstwie logiki (sesja → typowane entries).</done>
|
||||
</task>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 3: Migracja 34 widokow + login flash--error</name>
|
||||
<files>
|
||||
resources/views/settings/fakturownia.php, resources/views/settings/accounting-invoice-edit.php,
|
||||
resources/views/settings/smsplanet.php, resources/views/settings/hostedsms.php,
|
||||
resources/views/settings/accounting.php, resources/views/settings/accounting-receipt-edit.php,
|
||||
resources/views/settings/accounting-receipts.php, resources/views/settings/accounting-invoices.php,
|
||||
resources/views/accounting/invoice_form.php, resources/views/users/index.php,
|
||||
resources/views/statistics/orders.php, resources/views/settings/statuses.php,
|
||||
resources/views/settings/shoppro.php, resources/views/settings/printing.php,
|
||||
resources/views/settings/project-mappings.php, resources/views/settings/integrations.php,
|
||||
resources/views/settings/email-templates.php, resources/views/settings/inpost.php,
|
||||
resources/views/settings/email-templates-form.php, resources/views/settings/email-mailboxes.php,
|
||||
resources/views/settings/delivery-statuses.php, resources/views/settings/database.php,
|
||||
resources/views/settings/delivery-status-form.php, resources/views/settings/cron.php,
|
||||
resources/views/settings/company.php, resources/views/settings/apaczka.php,
|
||||
resources/views/settings/allegro.php, resources/views/orders/receipt-create.php,
|
||||
resources/views/orders/list.php, resources/views/automation/index.php,
|
||||
resources/views/automation/form.php, resources/views/auth/login.php
|
||||
</files>
|
||||
<action>
|
||||
Strategia migracji per widok:
|
||||
1) Usunac inline bloki `<?php if ($flashXxx !== ''): ?><div class="alert alert--TYPE" role="...">...</div><?php endif; ?>`
|
||||
— flash wyswietlany jest teraz centralnie przez layout (Flash::all() → komponent).
|
||||
Kontrolery NIE wymagaja zmian w tej fazie (Flash::set zachowuje BC i jest konsumowany przez `Flash::all()` w layoucie).
|
||||
2) Dla alertow NIE-flashowych (np. statyczne komunikaty/stany w widoku, nie z sesji) — zamienic na include komponentu:
|
||||
```php
|
||||
<?php $type='info'; $message='...'; $dismissible=false; include dirname(__DIR__) . '/components/alert.php'; ?>
|
||||
```
|
||||
Sprawdzic kazdy widok — jezeli alert jest oparty na zmiennej $flashXxx (z sesji), usunac caly blok. Jezeli alert pokazuje stan biezacy (np. "Brak konfiguracji"), zostawic ale przepuscic przez komponent.
|
||||
3) `resources/views/auth/login.php` — zamienic `<div class="flash flash--error">...</div>` (lub podobny) na include komponentu `alert.php` z `$type='danger'`. Usunac wszystkie odwolania `.flash--error` w tym pliku. Login uzywa `layouts/auth.php` — flash messages tez przejda przez centralny render.
|
||||
4) Po migracji NIE usuwac SCSS `.flash--error` jeszcze (separate cleanup task w przyszlosci) — wystarczy ze nie jest uzywany w widokach.
|
||||
5) Smoke test recznie po kazdej grupie modulow (settings/, automation/, orders/, auth/) — sprawdzic w przegladarce ze flash success/error/info wyglada jak zaprojektowano.
|
||||
Avoid:
|
||||
- Nie dotykac kontrolerow (BC przez Flash::all() w layoucie).
|
||||
- Nie zmieniac semantyki: jezeli widok renderowal blad jako `alert--danger`, po migracji ma byc nadal danger.
|
||||
- Nie usuwac role="alert" / role="status" — komponent ma `role="alert"` na stale.
|
||||
</action>
|
||||
<verify>
|
||||
1) `grep -rn 'class="alert alert--' resources/views/` zwraca tylko `resources/views/components/alert.php` (komponent jest jedynym renderem).
|
||||
2) `grep -rn 'flash--error' resources/views/` zwraca 0 wynikow.
|
||||
3) `grep -rn '\$flashError\|\$flashSave\|\$flashTest' resources/views/` zwraca 0 wynikow lub tylko miejsca gdzie zmienna jest przekazywana z kontrolera ale nie renderowana (akceptowalne — kontroler i tak ja przekazuje, layout konsumuje przez Flash::all()).
|
||||
4) Smoke: /settings/integrations/fakturownia → test polaczenia → niebieski alert info z ikona i ×; klik × usuwa alert; reload strony nie pokazuje go ponownie.
|
||||
5) /auth/login z bledem logowania → czerwony alert danger z ikona.
|
||||
</verify>
|
||||
<done>AC-3 spelnione: 34 widoki + login zmigrowane, flash--error usuniety z widokow, wszystkie alerty wygladaja spojnie.</done>
|
||||
</task>
|
||||
|
||||
</tasks>
|
||||
|
||||
<boundaries>
|
||||
|
||||
## DO NOT CHANGE
|
||||
- `src/Modules/**/*Controller.php` — kontrolery dalej uzywaja `Flash::set('module.key', '...')` (BC).
|
||||
- `resources/modules/jquery-alerts/` — modul dialogow OrderProAlerts (osobny system, nie alerty stronowe).
|
||||
- `resources/scss/modules/_customer-risk-alert.scss` — inny komponent (banner ostrzezenia o kliencie).
|
||||
- Istniejace warianty `.alert--success`, `.alert--warning`, `.alert--danger` (zachowac kolory; mozna tylko dodac `__icon`/`__dismiss` strukture).
|
||||
|
||||
## SCOPE LIMITS
|
||||
- Brak migracji kontrolerow na `Flash::push()` w tej fazie (BC zapewnia layout przez `Flash::all()`).
|
||||
- Brak auto-hide (timer JS) — zdjete z zakresu w odpowiedzi clarifications.
|
||||
- Brak usuwania SCSS `.flash--error` z `_ui-components.scss` (deferred cleanup).
|
||||
- Brak nowych endpointow API ani migracji DB.
|
||||
- Build SCSS → CSS jest robiony recznie przez operatora poza tym planem; plan modyfikuje pliki .scss, ale `public/assets/css/app.css` zostanie zregenerowany osobno (operator/build pipeline).
|
||||
|
||||
</boundaries>
|
||||
|
||||
<verification>
|
||||
Before declaring plan complete:
|
||||
- [ ] `grep -rn 'class="alert alert--' resources/views/` → tylko `components/alert.php`
|
||||
- [ ] `grep -rn 'flash--error' resources/views/` → 0
|
||||
- [ ] `grep -rn 'Flash::all' resources/views/layouts/` → 3
|
||||
- [ ] Manual smoke: /settings/integrations/fakturownia po teste polaczenia → niebieski alert info z ikona + dismiss
|
||||
- [ ] Manual smoke: /auth/login z blednym haslem → czerwony alert danger z ikona
|
||||
- [ ] Manual smoke: zapis dowolnego ustawienia (np. fakturownia save) → zielony alert success
|
||||
- [ ] AC-1, AC-2, AC-3 wszystkie spelnione
|
||||
</verification>
|
||||
|
||||
<success_criteria>
|
||||
- Komponent `alert.php` jest jedynym renderem alertu w widokach.
|
||||
- `.alert--info` istnieje i ma czytelny kontrast.
|
||||
- Centralny renderer flash dziala w 3 layoutach (app/auth/public).
|
||||
- Flash::push/all dodane bez breakingu Flash::set/get.
|
||||
- 34 widoki + login zmigrowane, brak inline `<div class="alert alert--...">` z flash zmiennymi.
|
||||
</success_criteria>
|
||||
|
||||
<output>
|
||||
After completion, create `.paul/phases/120-alert-component-unification/120-01-SUMMARY.md`
|
||||
</output>
|
||||
193
.paul/phases/120-alert-component-unification/120-01-SUMMARY.md
Normal file
193
.paul/phases/120-alert-component-unification/120-01-SUMMARY.md
Normal file
@@ -0,0 +1,193 @@
|
||||
---
|
||||
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*
|
||||
Reference in New Issue
Block a user