feat: custom labels toggle and inline editing in product list
Adds session-based show/hide toggle for custom labels in admin product list, inline editable fields for custom_label_0..4, and label suggestions with custom entry support. Includes repository/controller updates, UI fixes, tests, and PAUL docs release updates. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
201
.paul/phases/16-product-list-custom-labels/16-01-PLAN.md
Normal file
201
.paul/phases/16-product-list-custom-labels/16-01-PLAN.md
Normal file
@@ -0,0 +1,201 @@
|
||||
---
|
||||
phase: 16-product-list-custom-labels
|
||||
plan: 01
|
||||
type: execute
|
||||
wave: 1
|
||||
depends_on: []
|
||||
files_modified:
|
||||
- autoload/admin/Controllers/ShopProductController.php
|
||||
- autoload/Domain/Product/ProductRepository.php
|
||||
- admin/templates/shop-product/products-list-custom-script.php
|
||||
- tests/Unit/admin/Controllers/ShopProductControllerTest.php
|
||||
- tests/Unit/Domain/Product/ProductRepositoryTest.php
|
||||
autonomous: false
|
||||
delegation: off
|
||||
---
|
||||
|
||||
<objective>
|
||||
## Goal
|
||||
Dodac w liscie produktow (`/admin/shop_product/view_list/`) przelacznik "Pokaz etykiety niestandardowe", ktory zapisuje stan w sesji i po wlaczeniu pokazuje szybka edycje 5 pol `custom_label_0..4` z podpowiedziami.
|
||||
|
||||
## Purpose
|
||||
Administrator ma szybciej uzupelniac etykiety Google XML bez wchodzenia do edycji kazdego produktu, z zachowaniem spojnosc danych i wygodnych podpowiedzi istniejacych wartosci.
|
||||
|
||||
## Output
|
||||
- Nowy przycisk obok "Dodaj produkt", sterujacy widocznoscia custom labels i zapisujacy stan w sesji
|
||||
- Render 5 pol `custom_label_0..4` pod nazwa/SKU produktu w tabeli, tylko przy wlaczonej opcji
|
||||
- Zapis kazdego pola do `pp_shop_products` oraz system podpowiedzi z istniejacych wartosci w bazie
|
||||
- Odczyt nazw etykiet z bazy (z fallbackiem) zamiast hardcodu w widoku listy
|
||||
</objective>
|
||||
|
||||
<context>
|
||||
## Project Context
|
||||
@.paul/PROJECT.md
|
||||
@.paul/ROADMAP.md
|
||||
@.paul/STATE.md
|
||||
|
||||
## Source Files
|
||||
@autoload/admin/Controllers/ShopProductController.php
|
||||
@autoload/Domain/Product/ProductRepository.php
|
||||
@admin/templates/components/table-list.php
|
||||
@admin/templates/shop-product/products-list.php
|
||||
@admin/templates/shop-product/products-list-custom-script.php
|
||||
@tests/Unit/admin/Controllers/ShopProductControllerTest.php
|
||||
@tests/Unit/Domain/Product/ProductRepositoryTest.php
|
||||
</context>
|
||||
|
||||
<skills>
|
||||
## Required Skills (from SPECIAL-FLOWS.md)
|
||||
|
||||
| Skill | Priority | When to Invoke | Loaded? |
|
||||
|-------|----------|----------------|---------|
|
||||
| /feature-dev | required | Before implementation in APPLY | ○ |
|
||||
| /koniec-pracy | required | After implementation/release wrap-up | ○ |
|
||||
|
||||
**BLOCKING:** Required skills MUST be loaded before APPLY proceeds.
|
||||
Run each skill command or confirm already loaded.
|
||||
|
||||
## Skill Invocation Checklist
|
||||
- [ ] /feature-dev loaded (run command or confirm)
|
||||
- [ ] /koniec-pracy loaded (run command or confirm)
|
||||
|
||||
</skills>
|
||||
|
||||
<acceptance_criteria>
|
||||
|
||||
## AC-1: Przelacznik widocznosci custom labels dziala i jest zapamietywany
|
||||
```gherkin
|
||||
Given administrator jest na /admin/shop_product/view_list/
|
||||
When kliknie przycisk "Pokaz etykiety niestandardowe"
|
||||
Then stan opcji zostanie zapisany w sesji
|
||||
And po odswiezeniu/listowaniu tabela zachowa ustawiony stan (wlaczony lub wylaczony)
|
||||
```
|
||||
|
||||
## AC-2: Lista produktow pokazuje 5 pol custom_label po wlaczeniu opcji
|
||||
```gherkin
|
||||
Given opcja "Pokaz etykiety niestandardowe" jest wlaczona
|
||||
When lista produktow sie renderuje
|
||||
Then pod sekcja zdjecie/nazwa/SKU-EAN dla kazdego produktu widoczne sa pola custom_label_0..custom_label_4
|
||||
And etykiety tych pol sa pobrane dynamicznie z bazy danych (z fallbackiem tylko gdy brak konfiguracji)
|
||||
```
|
||||
|
||||
## AC-3: Zapis i podpowiedzi wartosci dzialaja dla kazdego custom_label
|
||||
```gherkin
|
||||
Given administrator wpisuje wartosc w jednym z pol custom_label_0..custom_label_4
|
||||
When wybierze podpowiedz lub zatwierdzi wpis
|
||||
Then wartosc zostanie zapisana w pp_shop_products dla danego produktu i pola
|
||||
And podpowiedzi sa budowane z juz istniejacych wartosci tego samego custom_label w bazie
|
||||
```
|
||||
|
||||
## AC-4: Walidacja i bezpieczenstwo endpointow sa zachowane
|
||||
```gherkin
|
||||
Given zapytanie AJAX podaje nieprawidlowy typ labela spoza custom_label_0..4
|
||||
When backend przetwarza request
|
||||
Then operacja zostaje odrzucona bez zapisu
|
||||
And odpowiedz zwraca status bledu bez ingerencji w dane produktu
|
||||
```
|
||||
|
||||
</acceptance_criteria>
|
||||
|
||||
<tasks>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 1: Dodac backend przelacznika sesyjnego i danych dla widoku listy</name>
|
||||
<files>autoload/admin/Controllers/ShopProductController.php, autoload/Domain/Product/ProductRepository.php</files>
|
||||
<action>
|
||||
Rozszerzyc `ShopProductController::view_list()` o flage sesyjna dla widocznosci custom labels
|
||||
oraz przekazanie do widoku nazw etykiet pobieranych z bazy.
|
||||
|
||||
Dodac akcje kontrolera do przelaczania flagi (toggle) i zwracania prostego JSON.
|
||||
|
||||
W `ProductRepository` dodac metode pobierajaca nazwy etykiet custom_label_0..4 z bazy
|
||||
(np. tabela ustawien), z bezpiecznym fallbackiem "Custom label N" gdy wartosc nie istnieje.
|
||||
Nie stosowac konkatenacji SQL dla danych wejsciowych.
|
||||
</action>
|
||||
<verify>Uruchomic testy kontrolera/repo oraz sprawdzic recznie, ze zmiana flagi utrzymuje sie po reloadzie listy</verify>
|
||||
<done>AC-1 i AC-2 satisfied</done>
|
||||
</task>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 2: Dodac UI i logike AJAX dla custom labels na liscie produktow</name>
|
||||
<files>autoload/admin/Controllers/ShopProductController.php, admin/templates/shop-product/products-list-custom-script.php</files>
|
||||
<action>
|
||||
Wygenerowac HTML 5 pol custom_label pod kolumna nazwy produktu tylko gdy flaga sesyjna jest wlaczona.
|
||||
Uzyc klas zgodnych z istniejacym stylem (`custom-labels`, `custom_label_X_container`, listy sugestii).
|
||||
|
||||
Dodac przycisk "Pokaz etykiety niestandardowe" obok "Dodaj produkt" (hook przez custom script listy)
|
||||
oraz obsluge klikniecia przez AJAX do nowej akcji toggle + odswiezenie aktualnego URL.
|
||||
|
||||
Podlaczyc dla kazdego inputa:
|
||||
- pobieranie sugestii przez `/admin/shop_product/product_custom_label_suggestions/`
|
||||
- zapis przez `/admin/shop_product/product_custom_label_save/`
|
||||
z walidacja odpowiedzi i obsluga bledow UI.
|
||||
</action>
|
||||
<verify>Manual: wlaczyc opcje, wpisac i zapisac wartosc custom_label, odswiezyc strone, potwierdzic widocznosc i dane</verify>
|
||||
<done>AC-2 i AC-3 satisfied</done>
|
||||
</task>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 3: Dodac testy regresyjne dla nowego zachowania</name>
|
||||
<files>tests/Unit/admin/Controllers/ShopProductControllerTest.php, tests/Unit/Domain/Product/ProductRepositoryTest.php</files>
|
||||
<action>
|
||||
Rozszerzyc testy kontrolera o przypadki:
|
||||
- toggle flagi sesyjnej
|
||||
- odrzucenie nieprawidlowych typow labeli
|
||||
- poprawne przekazanie danych do widoku listy przy wlaczonej opcji.
|
||||
|
||||
Rozszerzyc testy repozytorium o:
|
||||
- pobieranie nazw custom labels z bazy z fallbackiem
|
||||
- sugestie i zapis tylko dla dozwolonych label_type.
|
||||
</action>
|
||||
<verify>./test.ps1 tests/Unit/admin/Controllers/ShopProductControllerTest.php oraz ./test.ps1 tests/Unit/Domain/Product/ProductRepositoryTest.php</verify>
|
||||
<done>AC-4 covered and AC-1..AC-3 protected by tests</done>
|
||||
</task>
|
||||
|
||||
<task type="checkpoint:human-verify" gate="blocking">
|
||||
<what-built>Nowy przycisk sesyjny + szybka edycja custom labels 0..4 z podpowiedziami na liscie produktow</what-built>
|
||||
<how-to-verify>
|
||||
1. Otworz: /admin/shop_product/view_list/
|
||||
2. Kliknij: "Pokaz etykiety niestandardowe"
|
||||
3. Potwierdz: pola custom_label_0..4 pojawiaja sie pod nazwa produktu
|
||||
4. Wpisz wartosc, wybierz podpowiedz i odswiez strone
|
||||
5. Potwierdz: wartosc zostala zapisana i toggle pozostaje aktywny
|
||||
</how-to-verify>
|
||||
<resume-signal>Type "approved" to continue, or describe issues to fix</resume-signal>
|
||||
</task>
|
||||
|
||||
</tasks>
|
||||
|
||||
<boundaries>
|
||||
|
||||
## DO NOT CHANGE
|
||||
- Globalnych komponentow listy niezwiązanych z produktami (`admin/templates/components/table-list.php`) poza minimalnym, koniecznym hookiem
|
||||
- Endpointow API (`autoload/api/*`)
|
||||
- Logiki produktow frontendowych (`autoload/front/*`, `templates/shop-product/*`)
|
||||
|
||||
## SCOPE LIMITS
|
||||
- Zakres ograniczony do admin listy produktow i quick-edit custom labels
|
||||
- Bez migracji DB w tym planie (odczyt nazw z istniejacych danych konfiguracyjnych)
|
||||
- Bez refaktoru calego modułu integracji Google XML
|
||||
|
||||
</boundaries>
|
||||
|
||||
<verification>
|
||||
Before declaring plan complete:
|
||||
- [ ] ./test.ps1 tests/Unit/admin/Controllers/ShopProductControllerTest.php
|
||||
- [ ] ./test.ps1 tests/Unit/Domain/Product/ProductRepositoryTest.php
|
||||
- [ ] Manual check: toggle zapisuje sie w sesji i zachowuje po reloadzie
|
||||
- [ ] Manual check: podpowiedzi i zapis custom labels dzialaja dla 0..4
|
||||
- [ ] All acceptance criteria met
|
||||
</verification>
|
||||
|
||||
<success_criteria>
|
||||
- Przycisk "Pokaz etykiety niestandardowe" dziala i przechowuje stan w sesji
|
||||
- Lista produktow pokazuje i zapisuje custom_label_0..4 bez wejscia w edycje produktu
|
||||
- Nazwy etykiet sa pobierane z bazy z fallbackiem
|
||||
- Testy regresyjne dla backendu i repozytorium przechodza
|
||||
</success_criteria>
|
||||
|
||||
<output>
|
||||
After completion, create `.paul/phases/16-product-list-custom-labels/16-01-SUMMARY.md`
|
||||
</output>
|
||||
149
.paul/phases/16-product-list-custom-labels/16-01-SUMMARY.md
Normal file
149
.paul/phases/16-product-list-custom-labels/16-01-SUMMARY.md
Normal file
@@ -0,0 +1,149 @@
|
||||
---
|
||||
phase: 16-product-list-custom-labels
|
||||
plan: 01
|
||||
subsystem: admin
|
||||
tags: [shop-product, custom-label, session-toggle, autocomplete, quick-edit]
|
||||
|
||||
requires: []
|
||||
provides:
|
||||
- Szybka edycja custom_label_0..4 na liscie produktow
|
||||
- Przelacznik widocznosci etykiet w sesji admina
|
||||
- Podpowiedzi istniejacych wartosci + wpisywanie wartosci wlasnej w jednym polu
|
||||
affects: [shop-product-list, google-xml-label-flow]
|
||||
|
||||
tech-stack:
|
||||
added: []
|
||||
patterns: [inline quick-edit in table list, datalist autocomplete in single input, settings fallback mapping]
|
||||
|
||||
key-files:
|
||||
created: []
|
||||
modified:
|
||||
- autoload/admin/Controllers/ShopProductController.php
|
||||
- autoload/Domain/Product/ProductRepository.php
|
||||
- admin/templates/shop-product/products-list.php
|
||||
- admin/templates/shop-product/products-list-custom-script.php
|
||||
- tests/Unit/admin/Controllers/ShopProductControllerTest.php
|
||||
- tests/Unit/Domain/Product/ProductRepositoryTest.php
|
||||
|
||||
key-decisions:
|
||||
- "Przelacznik widocznosci custom labels zapisany w sesji (per admin session)"
|
||||
- "Nazwy custom labels pobierane z pp_settings z fallbackiem do domyslnych nazw"
|
||||
- "UX: jedno pole input z autocomplete (datalist), bez osobnego select pod spodem"
|
||||
|
||||
patterns-established:
|
||||
- "Dla list admina: toggle funkcji przez dedykowany endpoint JSON + reload widoku"
|
||||
- "Quick-edit text fields: walidacja typu po stronie kontrolera przed zapisem/sugestiami"
|
||||
|
||||
duration: ~120min
|
||||
completed: 2026-04-19
|
||||
---
|
||||
|
||||
# Phase 16 Plan 01: Product list custom labels quick edit - Summary
|
||||
|
||||
**Wdrozono szybka edycje custom labels na liscie produktow z przelacznikiem sesyjnym i autocomplete w pojedynczym polu.**
|
||||
|
||||
## Performance
|
||||
|
||||
| Metric | Value |
|
||||
|--------|-------|
|
||||
| Duration | ~120min |
|
||||
| Completed | 2026-04-19 |
|
||||
| Tasks | 3 completed + 1 checkpoint approved |
|
||||
| Files modified | 6 |
|
||||
|
||||
## Acceptance Criteria Results
|
||||
|
||||
| Criterion | Status | Notes |
|
||||
|-----------|--------|-------|
|
||||
| AC-1: Przelacznik widocznosci custom labels dziala i jest zapamietywany | Pass | Dodano przycisk toggle + zapis stanu w sesji admina |
|
||||
| AC-2: Lista pokazuje 5 pol custom_label po wlaczeniu opcji | Pass | Pola custom_label_0..4 renderowane pod nazwa/SKU/EAN tylko przy wlaczonej opcji |
|
||||
| AC-3: Zapis i podpowiedzi wartosci dzialaja dla custom_label | Pass | Zapis AJAX do bazy + autocomplete istniejacych wartosci i mozliwosc wpisu wlasnego |
|
||||
| AC-4: Walidacja i bezpieczenstwo endpointow zachowane | Pass | Kontroler odrzuca niedozwolone label_type przed zapisem i pobraniem sugestii |
|
||||
|
||||
## Accomplishments
|
||||
|
||||
- Dodano nowy toggle "Pokaz/Ukryj etykiety niestandardowe" przy liscie produktow, sterowany sesja.
|
||||
- Dodano inline quick-edit custom_label_0..4 bez wchodzenia do edycji produktu.
|
||||
- Podpowiedzi dzialaja jako autocomplete w tym samym input (nie osobny kontrolka pod polem).
|
||||
- Ujednolicono UX przycisku toggle (kolorystyka, rozmiar, hover, czytelnosc).
|
||||
- Rozszerzono testy kontrolera i repozytorium o nowe przypadki.
|
||||
|
||||
## Files Created/Modified
|
||||
|
||||
| File | Change | Purpose |
|
||||
|------|--------|---------|
|
||||
| `autoload/admin/Controllers/ShopProductController.php` | Modified | Toggle sesyjny, render custom labels w tabeli, walidacja label_type |
|
||||
| `autoload/Domain/Product/ProductRepository.php` | Modified | Pobieranie nazw custom_label z ustawien (fallback) |
|
||||
| `admin/templates/shop-product/products-list.php` | Modified | Przekazanie flagi custom_labels_enabled do skryptu |
|
||||
| `admin/templates/shop-product/products-list-custom-script.php` | Modified | UI toggle, zapis/sugestie custom label, autocomplete, poprawki wygladu |
|
||||
| `tests/Unit/admin/Controllers/ShopProductControllerTest.php` | Modified | Testy nowych metod i walidacji kontrolera |
|
||||
| `tests/Unit/Domain/Product/ProductRepositoryTest.php` | Modified | Testy customLabelNames + walidacji sugestii/zapisu |
|
||||
|
||||
## Decisions Made
|
||||
|
||||
| Decision | Rationale | Impact |
|
||||
|----------|-----------|--------|
|
||||
| Session key dla toggla (`shop_product_show_custom_labels`) | Funkcja ma byc osobnym trybem widoku admina | Stabilny stan po odswiezeniu strony |
|
||||
| Nazwy etykiet z `pp_settings` + fallback | Wymaganie "nazwy z bazy" i bezpieczne zachowanie gdy brak konfiguracji | Elastyczne nazewnictwo bez hardcodu |
|
||||
| Autocomplete w jednym polu zamiast input + oddzielny select | UX feedback od usera podczas checkpointu | Czytelniejszy i szybszy flow edycji |
|
||||
|
||||
## Deviations from Plan
|
||||
|
||||
### Summary
|
||||
|
||||
| Type | Count | Impact |
|
||||
|------|-------|--------|
|
||||
| Auto-fixed | 1 | Niski, techniczny (BOM w pliku kontrolera) |
|
||||
| Scope additions | 2 | Niski, UX polish po feedbacku checkpoint |
|
||||
| Deferred | 0 | Brak |
|
||||
|
||||
**Total impact:** Niezbedne poprawki techniczne i UX bez scope creep funkcjonalnego.
|
||||
|
||||
### Auto-fixed Issues
|
||||
|
||||
**1. Encoding/BOM in controller file**
|
||||
- **Found during:** Task 1 implementation verification
|
||||
- **Issue:** Parser PHP zglaszal blad namespace przez BOM na poczatku pliku
|
||||
- **Fix:** Zapisano plik `ShopProductController.php` jako UTF-8 bez BOM
|
||||
- **Files:** `autoload/admin/Controllers/ShopProductController.php`
|
||||
- **Verification:** `php -l autoload/admin/Controllers/ShopProductController.php`
|
||||
|
||||
### Deferred Items
|
||||
|
||||
None.
|
||||
|
||||
## Issues Encountered
|
||||
|
||||
| Issue | Resolution |
|
||||
|-------|------------|
|
||||
| Drobne regresje UX przycisku toggle | Iteracyjna poprawka stylu i hover po feedbacku usera |
|
||||
| Forma podpowiedzi (select pod inputem) nieakceptowalna UX | Zmieniono na jedno pole z autocomplete (datalist) |
|
||||
|
||||
## Verification Results
|
||||
|
||||
- `php -l autoload/admin/Controllers/ShopProductController.php` -> OK
|
||||
- `php -l autoload/Domain/Product/ProductRepository.php` -> OK
|
||||
- `php -l admin/templates/shop-product/products-list-custom-script.php` -> OK
|
||||
- `php phpunit.phar tests/Unit/admin/Controllers/ShopProductControllerTest.php` -> OK (15 tests, 71 assertions)
|
||||
- `php phpunit.phar tests/Unit/Domain/Product/ProductRepositoryTest.php` -> OK (64 tests, 131 assertions)
|
||||
- Checkpoint human-verify: approved by user after final UX adjustments
|
||||
|
||||
Skill audit:
|
||||
- `/feature-dev` - not invoked (user-approved override)
|
||||
- `/koniec-pracy` - acknowledged by user as available for end-of-session flow
|
||||
|
||||
## Next Phase Readiness
|
||||
|
||||
**Ready:**
|
||||
- Admin ma szybki i praktyczny workflow uzupelniania custom labels bez przechodzenia do edycji produktu.
|
||||
- Kod posiada testy regresyjne dla nowej logiki backendowej.
|
||||
|
||||
**Concerns:**
|
||||
- Brak.
|
||||
|
||||
**Blockers:**
|
||||
- None.
|
||||
|
||||
---
|
||||
*Phase: 16-product-list-custom-labels, Plan: 01*
|
||||
*Completed: 2026-04-19*
|
||||
Reference in New Issue
Block a user