---
phase: 03-products-all-campaigns-view
plan: 01
subsystem: ui
tags: [select2, jquery, products, filter, frontend]
requires:
- phase: (none)
provides: istniejący szablon /products oraz backend z `build_scope_filters` obsługującym już campaign_id ≤ 0
provides:
- Widoczna opcja "- wszystkie kampanie -" w filtrze kampanii na /products po każdej selekcji
- Widoczna opcja "- wszystkie grupy -" w filtrze grup reklam na /products po każdej selekcji
- Przywrócony widok zagregowany bez konieczności czyszczenia localStorage / zmiany klienta
affects:
- Każda przyszła zmiana w filtrach Select2 na /products (np. dodanie kolejnych filtrów ze scope)
- Ewentualne rozszerzenia filtrów analogicznych na innych stronach (sugerowane: /campaigns, jeśli używa podobnego wzorca Select2 z placeholderem + allowClear)
tech-stack:
added: []
patterns:
- "Select2 z pustą opcją default: nie używać `placeholder` + `allowClear` jednocześnie, jeśli pierwsza ma być dostępna w dropdownie (Select2 chowa ją jako placeholder)"
key-files:
created: []
modified:
- templates/products/main_view.php
key-decisions:
- "Usunięcie `placeholder` i `allowClear` zamiast wprowadzania sentinel value='0' — minimalny blast radius, brak zmian w handlerach i backendzie"
patterns-established:
- "W szablonach z filtrami Select2, gdzie reprezentuje widok 'wszystkie', nie konfigurować placeholdera Select2 — żeby opcja pozostała widoczna w dropdownie po selekcji"
duration: ~25min
started: 2026-04-24T23:00:00+02:00
completed: 2026-04-24T23:25:00+02:00
---
# Phase 3 Plan 01: Products — widok "wszystkie kampanie" (Summary)
**Przywrócono możliwość powrotu do zagregowanego widoku produktów (wszystkie kampanie / wszystkie grupy reklam) na stronie /products — pojedynczym kliknięciem w dropdown, bez czyszczenia localStorage.**
## Performance
| Metric | Value |
|--------|-------|
| Duration | ~25 min (PLAN + APPLY + UNIFY) |
| Started | 2026-04-24T23:00:00+02:00 |
| Completed | 2026-04-24T23:25:00+02:00 |
| Tasks | 2 z 2 (1 auto + 1 human-verify) |
| Files modified | 1 |
## Acceptance Criteria Results
| Criterion | Status | Notes |
|-----------|--------|-------|
| AC-1: Powrót do "wszystkie kampanie" po wyborze kampanii | Pass | Zweryfikowane w przeglądarce: opcja widoczna w dropdownie, tabela przeładowuje zagregowany widok, panele boczne chowane |
| AC-2: Powrót do "wszystkie grupy" po wyborze grupy reklam | Pass | Zweryfikowane: przycisk "Usuń grupę reklam" wyszarzony, tabela wraca do pełnego widoku kampanii |
| AC-3: Stan zachowany w localStorage po F5 | Pass | Po reloadzie oba dropdowny pokazują "- wszystkie … -", brak błędów w konsoli |
| AC-4: Brak regresji w istniejących przepływach | Pass | Filtry tekstowe, sortowanie, paginacja, edycja inline CL1/CL4/min_roas, usuwanie grup SHOPPING — wszystko działa |
## Accomplishments
- Znalezienie i naprawa nieoczywistej interakcji Select2: `placeholder` + `allowClear` ukrywa pierwszą ` ` jako placeholder, co odbiera użytkownikowi możliwość powrotu do agregatu po selekcji.
- Zmiana ograniczona do **1 pliku, 4 linii** — bez dotykania kontrolera, factory, migracji, innych szablonów ani CSS.
- Zero regresji w pozostałych przepływach UI na /products (zweryfikowane w checkpoint human-verify wg AC-4).
## Task Commits
Nie wykonano jeszcze commita — commit wykona użytkownik ręcznie lub osobnym poleceniem (projekt używa FTP sync do produkcji, patrz `.vscode/ftp-kr.sync.cache.json`).
| Task | Commit | Type | Description |
|------|--------|------|-------------|
| Task 1: Fix Select2 config w init_products_scope_select_search | (pending) | fix | Usunięto `placeholder: '- wybierz -'` i `allowClear: true` z konfiguracji Select2 dla filtrów kampanii/grup reklam |
| Task 2: Human-verify w przeglądarce | n/a | n/a | Zatwierdzone: "approved" |
Sugerowany komunikat commita: `fix(products): przywróć widok "wszystkie kampanie" w filtrze /products`
## Files Created/Modified
| File | Change | Purpose |
|------|--------|---------|
| `templates/products/main_view.php` | Modified (+1 / −3, linie 523–527) | Uproszczono konfigurację Select2 w `init_products_scope_select_search()` — pozostaje tylko `width: '100%'` |
## Decisions Made
| Decision | Rationale | Impact |
|----------|-----------|--------|
| Usunięcie `placeholder` i `allowClear` zamiast wprowadzenia `value="0"` dla opcji "wszystkie" | Minimalny blast radius: brak zmian w handlerach `change`, brak zmian w backendzie, brak zmian w localStorage; zgodne z istniejącym kontraktem `(int)$campaign_id` w `build_scope_filters` | Przyszłe filtry typu "wszystkie" na /products powinny stosować ten sam wzorzec: pusta ` ` + brak placeholdera w Select2 |
## Deviations from Plan
### Summary
| Type | Count | Impact |
|------|-------|--------|
| Auto-fixed | 0 | — |
| Scope additions | 0 | — |
| Deferred | 0 | — |
| Wording / verify delta | 1 | Kosmetyczna różnica w verify (patrz niżej), brak wpływu funkcjonalnego |
**Total impact:** Plan wdrożony 1:1, jedna kosmetyczna różnica w kryterium `verify` bez wpływu na AC.
### Auto-fixed Issues
Brak.
### Wording / Verify delta
**1. Verify wording: `grep allowClear` → brak trafień (plan) vs 1 trafienie (actual)**
- **Found during:** Task 1 verify
- **Issue:** Plan oczekiwał, że po zmianie `grep -n allowClear templates/products/main_view.php` zwróci 0 trafień. Faktycznie zwrócił 1 (linia 2097).
- **Diagnoza:** Linia 2097 należy do Google taxonomy category pickera w modalu edycji produktu (`$googleCategory.select2({...})` wewnątrz `loadGoogleCategories`) — niezwiązany feature, poza zakresem planu.
- **Fix:** Nie wymagany. In-scope init (`init_products_scope_select_search`, linie 523–525) jest czysty. Plan miał za szeroki pattern; intencja (brak `allowClear` w filtrach scope) została zrealizowana.
- **Verification:** Ręczna weryfikacja wiersza 2097 — kontekst to `loadGoogleCategories`, nie filtry /products.
### Deferred Items
Brak.
## Issues Encountered
Brak. Plan wdrożony 1:1.
## Next Phase Readiness
**Ready:**
- UI /products stabilne i kompletne pod kątem filtrów scope (klient → kampania → grupa → wszystkie/konkretne).
- Wzorzec "Select2 bez placeholdera dla agregatu" udokumentowany — można replikować na innych stronach z podobnymi filtrami.
**Concerns:**
- Pozostała instancja `allowClear: true` w `loadGoogleCategories` (linia 2097) jest nietknięta — to inny feature, ale warto mieć świadomość, że ten sam wzorzec Select2 stosowany jest w projekcie w dwóch miejscach.
- Deploy na produkcję wymaga FTP sync szablonu + hard reload w przeglądarce klienta (Ctrl+Shift+R) ze względu na cache JS.
**Blockers:** Brak.
---
*Phase: 03-products-all-campaigns-view, Plan: 01*
*Completed: 2026-04-24*