--- phase: 10-select2-global-search plan: 01 type: execute wave: 1 depends_on: [] files_modified: - libraries/adspro-select2-autoinit.js - templates/site/layout-logged.php - layout/style.scss - layout/style.css - templates/products/main_view.php - templates/campaign_terms/main_view.php autonomous: false delegation: off --- ## Goal Globalny auto-init Select2 dla wszystkich `` (campaign_terms). Dla statycznych selectów wystarcza `$(document).ready`. ## AC-1: Select "Grupa reklam" na /campaign_terms ma wyszukiwarkę ```gherkin Given użytkownik jest na /campaign_terms i wybrał klienta + kampanię (załadowane >4 grupy reklam) When kliknie w select "Grupa reklam" Then otwiera się dropdown Select2 z polem wyszukiwania And wpisanie fragmentu nazwy filtruje listę And wybór grupy działa identycznie jak wcześniej (load_search_terms / load_negative) ``` ## AC-2: Globalny auto-init pokrywa wszystkie selecty z >4 opcjami ```gherkin Given dowolna podstrona w layout-logged ma `` którego pierwsza opcja ma value="" When użytkownik wybrał wartość niepustą Then widoczny jest przycisk X (clear) When użytkownik kliknie X Then wartość selecta wraca do "" i wyzwalany jest `change` ``` ## AC-4: Styl spójny z dotychczasowym wyglądem /products ```gherkin Given Select2 jest aktywny na dowolnej stronie layout-logged Then wysokość selecta = 38px, border-radius 6px, kolor focusa #6690f4 And styl dropdown, search input, highlighted option = jak obecnie na /products And nie ma duplikacji CSS w `templates/products/main_view.php` (block `.products-page .select2-*` usunięty) ``` ## AC-5: Brak regresji indywidualnych Select2 ```gherkin Given dotychczasowe miejsca z ręcznym `$el.select2(...)` z własną konfiguracją (np. googleCategory z `data: cats`, placeholder, allowClear) When strona się ładuje Then nadal działają poprawnie (auto-init pomija już zainicjalizowane instancje przez sprawdzenie `$el.data('select2')`) And `init_products_scope_select_search()` jest usunięte (zastąpione auto-initem), `update_delete_ad_group_button_state()` oraz `.trigger('change.select2')` nadal działają ``` Task 1: Utworzyć moduł auto-init Select2 libraries/adspro-select2-autoinit.js Utworzyć nowy plik z modułem auto-init. Wymagania: 1. Sprawdza `typeof $.fn.select2 !== 'undefined'` przed działaniem. 2. Eksportuje `window.adsproSelect2Init($root)`: - `$root` opcjonalny (domyślnie `$(document.body)`) - Wyszukuje `select` w `$root` filtrując: * pomija `select[multiple]` z natywną logiką jeśli ma `data-adspro-select2="false"` (multiple jest OK domyślnie) * pomija `.no-select2` lub `[data-adspro-select2="false"]` * pomija jeśli `$el.data('select2')` już istnieje (już zainicjalizowane) * pomija jeśli select jest w `.select2-container` (wewnątrz Select2 wyświetlacza) * pomija jeśli rodzic ma klasę `.dataTables_length` (długość strony DataTables — krótka lista) * Inicjalizuje gdy: `select.options.length > 4` LUB ma atrybut `data-adspro-select2="true"` - Dla każdego pasującego selecta: * options.width = '100%' * options.allowClear = true jeśli pierwsza ` Plik istnieje, `node -c` lub `php -r "echo file_exists('libraries/adspro-select2-autoinit.js') ? 'OK' : 'FAIL';"` zwraca OK; w przeglądarce DevTools → `typeof window.adsproSelect2Init === 'function'`. AC-2, AC-3 częściowo (silnik gotowy) Task 2: Załadować auto-init w layout i uogólnić CSS Select2 templates/site/layout-logged.php, layout/style.scss, layout/style.css 1. W `templates/site/layout-logged.php` po linii `` (linia ~35) dodać: ```html ``` (Uwaga: w pliku są dwa źródła select2 — local i CDN. Auto-init dorzucamy raz, po obu.) 2. W `layout/style.scss` dodać nową sekcję `// === Select2 global overrides ===` z regułami zaadaptowanymi z `templates/products/main_view.php` linie 136-189. Selektory globalne (BEZ prefiksu `.products-page`): - `.select2-container` width 100% - `.select2-container--default .select2-selection--single` (height 38, border #e2e8f0, radius 6, bg #fff) - `.select2-selection__rendered` (line-height 36, padding 12/36, color #2d3748) - `.select2-selection__placeholder` (#6c757d) - `.select2-selection__arrow` (height 36, right 8) - `.select2-container--focus .select2-selection--single` (border #6690f4, shadow rgba(102,144,244,.1)) - `.select2-dropdown` (border #e2e8f0, radius 6) - `.select2-search--dropdown .select2-search__field` (border, radius, height 34, font 14) - `.select2-results__option` (font 14) - `.select2-container--default .select2-results__option--highlighted[aria-selected]` (bg #6690f4, color #fff) 3. Skompilować SCSS do `layout/style.css` (lub dopisać te same reguły bezpośrednio do `layout/style.css` jeśli SCSS nie jest auto-budowane w projekcie — sprawdzić nagłówek pliku style.css czy ma marker auto-generated). Jeżeli style.css jest commitowane ręcznie, dopisać identyczny blok CSS na końcu pliku style.css. Avoid: - Nie usuwać żadnych innych istniejących reguł z style.scss/style.css. - Nie zmieniać kolejności ładowania Select2 CSS (local + CDN — obecny stan zachować). Po odświeżeniu dowolnej strony layout-logged: w DevTools `$('.select2-container').length > 0` na stronach z natywnymi selectami z >4 opcjami; computed style selecta = height 38px. AC-2, AC-4 Task 3: Usunąć redundantne Select2 w products i podłączyć helper w campaign_terms templates/products/main_view.php, templates/campaign_terms/main_view.php **W `templates/products/main_view.php`:** 1. Usunąć blok CSS `.products-page .select2-*` (linie ~136-189) — zastąpiony przez globalne reguły z Task 2. 2. Usunąć funkcję `init_products_scope_select_search()` (linie ~610-631) ORAZ jej wywołanie w linii ~723. - Jeśli wywołanie jest częścią innego bloku, zostawić sąsiednie linie nietknięte; tylko skreślić wywołanie funkcji. 3. NIE ruszać `$googleCategory.select2({...})` w linii ~2414 (ma własny `data:`, `placeholder`, `allowClear` — auto-init go pominie bo będzie już zainicjalizowany przed/po; dodać przed tym wywołaniem klasę `no-select2` na `$googleCategory` LUB zostawić — auto-init nie nadpisuje istniejących instancji, więc bezpiecznie). 4. Zachować wszystkie `$x.trigger('change.select2')` (linie ~1112, 1133, 1159, 1178) — nadal aktualne. **W `templates/campaign_terms/main_view.php`:** 1. W funkcji `load_campaigns()` po linii `$campaign_select.val( restore_campaign_id );` (~1791) i ogólnie po wszystkich append() w success: dodać: ```js if ( typeof window.adsproSelect2Init === 'function' ) window.adsproSelect2Init( $campaign_select.parent() ); $campaign_select.trigger( 'change.select2' ); ``` 2. W funkcji `load_ad_groups()` po pętli `ad_groups.forEach` (po ~1738): analogicznie dla `$ad_group_select`. 3. Dla `#terms_client_id` (jeśli ma >4 opcji od razu po PHP render) auto-init z `$(document).ready` go pokryje — nie trzeba zmian; ale dla pewności dodać atrybut `data-adspro-select2="true"` w ``) — auto-init obsługuje je tak samo (Select2 ma natywne wsparcie), ale nie dodajemy zaawansowanych opcji typu tagi. - Brak nowych migracji DB, brak zmian w PHP poza ewentualnymi atrybutami HTML w templatach. Before declaring plan complete: - [ ] Plik `libraries/adspro-select2-autoinit.js` istnieje i jest podłączony w layout-logged.php - [ ] Globalne style Select2 w `layout/style.css` - [ ] Blok `.products-page .select2-*` usunięty z `templates/products/main_view.php` - [ ] Funkcja `init_products_scope_select_search()` i jej wywołanie usunięte - [ ] `data-adspro-select2="true"` na 3 selectach w `templates/campaign_terms/main_view.php` - [ ] `window.adsproSelect2Init(...)` wywoływane po load_campaigns/load_ad_groups w campaign_terms - [ ] Brak błędów JS w konsoli na /campaign_terms i /products - [ ] Checkpoint human-verify zaakceptowany - Wszystkie zadania ukończone - Wszystkie kryteria akceptacji spełnione - Brak regresji wizualnej/funkcjonalnej na /products - Wyszukiwarka działa na /campaign_terms → Grupa reklam (i na każdym innym selecie z >4 opcjami w layout-logged) After completion, create `.paul/phases/10-select2-global-search/10-01-SUMMARY.md`