#107 — Einkaufsliste — nur belegte Kategorien anzeigen, passendere Icons #110

Closed
opened 2026-08-18 13:14:08 +02:00 by lena · 1 comment
lena commented 2026-08-18 13:14:08 +02:00 (Migrated from git.butzei.de)

Story: Einkaufsliste — nur belegte Kategorien anzeigen, passendere Icons

As a Nutzer der Einkaufsliste,
I want to in der normalen Ansicht und im Online-Warenkorb nur Kategorien sehen, in denen gerade aktive
Produkte stehen, und Icons, die zur jeweiligen Kategorie passen,
so that die Liste nicht von leeren Sektionen zugemüllt wird und ich Kategorien auf einen Blick optisch
erkenne.

Klärung vom 2026-08-08 (PO-Rückfrage beantwortet): "Beide Sichtweisen" = die normale Produkt-Ansicht und
die Online-Warenkorb-Ansicht (ShoppingCartCheckPanel).

Acceptance criteria:

  • In der normalen Produkt-Ansicht (ShoppingListPage.tsx) werden nur Kategorien gerendert, die
    mindestens ein aktives Produkt (IsOnList = true) enthalten — leere Kategorien (neu angelegt, oder
    nur inaktive/abgehakte Produkte) werden ausgeblendet, nicht gelöscht.
  • Im Online-Warenkorb (ShoppingCartCheckPanel) gilt dieselbe Regel.
  • Der Kategorie-Verwaltungsdialog (ShoppingCategoryManager, erreichbar über "Categories") zeigt
    weiterhin alle Kategorien, auch leere — er dient dem Verwalten/Anlegen/Löschen von Kategorien, nicht
    nur der Produktübersicht, und ist von dieser Story nicht betroffen.
  • Eine Kategorie, die durch Ausblenden aller ihrer Produkte leer wird, verschwindet automatisch aus
    beiden Ansichten, ohne dass die Kategorie selbst gelöscht wird (Story #106's Drag-and-Drop-Ziel bleibt
    über die Kategorie-Verwaltung weiterhin erreichbar).
  • Die 14 vordefinierten Kategorie-Icons (CreateShoppingListCommandHandler.DefaultSections) werden
    durchgesehen und durch Emojis ersetzt, die inhaltlich eindeutiger zur jeweiligen Kategorie passen (z. B.
    wo ein Icon aktuell mehrdeutig oder generisch wirkt). Konkrete Icon-Wahl liegt beim Frontend Engineer,
    solange sie inhaltlich nachvollziehbar zur Kategorie passt.

Out of scope for this story:

  • Automatisches Löschen dauerhaft leerer Kategorien.
  • Icon-Auswahl für nutzerdefinierte (nicht-vordefinierte) Kategorien — die haben ohnehin schon ein frei
    wählbares Icon-Feld.
# Story: Einkaufsliste — nur belegte Kategorien anzeigen, passendere Icons **As a** Nutzer der Einkaufsliste, **I want to** in der normalen Ansicht und im Online-Warenkorb nur Kategorien sehen, in denen gerade aktive Produkte stehen, und Icons, die zur jeweiligen Kategorie passen, **so that** die Liste nicht von leeren Sektionen zugemüllt wird und ich Kategorien auf einen Blick optisch erkenne. **Klärung vom 2026-08-08 (PO-Rückfrage beantwortet):** "Beide Sichtweisen" = die normale Produkt-Ansicht und die Online-Warenkorb-Ansicht (`ShoppingCartCheckPanel`). **Acceptance criteria:** - [ ] In der normalen Produkt-Ansicht (`ShoppingListPage.tsx`) werden nur Kategorien gerendert, die mindestens ein aktives Produkt (`IsOnList = true`) enthalten — leere Kategorien (neu angelegt, oder nur inaktive/abgehakte Produkte) werden ausgeblendet, nicht gelöscht. - [ ] Im Online-Warenkorb (`ShoppingCartCheckPanel`) gilt dieselbe Regel. - [ ] Der Kategorie-Verwaltungsdialog (`ShoppingCategoryManager`, erreichbar über "Categories") zeigt weiterhin **alle** Kategorien, auch leere — er dient dem Verwalten/Anlegen/Löschen von Kategorien, nicht nur der Produktübersicht, und ist von dieser Story nicht betroffen. - [ ] Eine Kategorie, die durch Ausblenden aller ihrer Produkte leer wird, verschwindet automatisch aus beiden Ansichten, ohne dass die Kategorie selbst gelöscht wird (Story `#106`'s Drag-and-Drop-Ziel bleibt über die Kategorie-Verwaltung weiterhin erreichbar). - [ ] Die 14 vordefinierten Kategorie-Icons (`CreateShoppingListCommandHandler.DefaultSections`) werden durchgesehen und durch Emojis ersetzt, die inhaltlich eindeutiger zur jeweiligen Kategorie passen (z. B. wo ein Icon aktuell mehrdeutig oder generisch wirkt). Konkrete Icon-Wahl liegt beim Frontend Engineer, solange sie inhaltlich nachvollziehbar zur Kategorie passt. **Out of scope for this story:** - Automatisches Löschen dauerhaft leerer Kategorien. - Icon-Auswahl für nutzerdefinierte (nicht-vordefinierte) Kategorien — die haben ohnehin schon ein frei wählbares Icon-Feld.
lena commented 2026-08-18 13:14:09 +02:00 (Migrated from git.butzei.de)

design (107_shopping_category_display_and_icons_design.md)

Design note: #107 — Einkaufsliste: nur belegte Kategorien anzeigen, passendere Icons

Scope confirmed against the code

  • ShoppingListPage.tsx already computed productsByCategory from activeProducts (products with
    isOnList === true) but rendered orderedCategories (every category from the fetched list)
    unconditionally — an empty section still got a header + empty product list. Fix: filter
    orderedCategories down to categories with at least one bucket entry, computed after
    productsByCategory is built.
  • ShoppingCartCheckPanel (the "Online cart" panel) does not group by category at all — it's a
    flat name+checkbox list (confirmed in its own test: "name only, no quantity/comments"). It already
    only ever receives activeProducts as its products prop from ShoppingListPage, so there is no
    empty-category header it could show in the first place. The AC's "same rule applies" is therefore
    satisfied by the existing data flow — no code change needed there. Recorded here explicitly rather
    than silently skipped, since the story's own PO clarification named this component directly.
  • ShoppingCategoryManager (the "Categories" management dialog) fetches and shows all categories
    unfiltered already, exactly as the AC requires (it's for managing sections, not browsing products).
    No change needed.
  • A category that becomes empty by unchecking/moving its last active product disappears automatically
    from the section list on the next render, since the filter is computed live from products state —
    no separate "is this now empty" bookkeeping needed. The category row itself is untouched (still
    exists, still reachable via "Categories" for #106's drag-and-drop target), matching the AC.

Icon review (CreateShoppingListCommandHandler.DefaultSections)

Changed 4 of the 14 predefined section icons where the emoji read as one specific item rather than
the category as a whole, or clashed with a neighboring category's icon:

Section Before After Why
Obst & Gemüse Broccoli reads as "vegetables" only; apple is the more universal produce icon and doesn't exclude fruit.
Kühlregal Cheese reads as one specific product, not the whole refrigerated case (milk, yogurt, eggs, cold cuts). Milk carton is the standard "dairy/cold case" icon.
Drogerie & Haushalt Lotion bottle reads as cosmetics specifically; toilet paper is the more recognizable combined drugstore/household staple icon.
Glutenfreie Lebensmittel Herb leaf carries no gluten-free meaning and visually clashed with Bioladen's right below it. (crossed wheat) is the closest available emoji analog to the real-world gluten-free symbol.

The other 10 (Backwaren , Trockenwaren , Müsli & Nüsse , Aufstriche , Glas und Dosen ,
Getränke , Gewürze , Tiefkühl ❄️, Essig/Öl & Co , Bioladen ) already anchor clearly enough to
their category and were left unchanged.

This only affects sections seeded for shopping lists created from now on — same as the original
#90 seed, there's no backfill migration for already-existing lists' category rows. Consistent with
how this seed data has always been treated (a one-time creation-time default, not a synced source of
truth).

Out of scope (per story)

  • No automatic deletion of permanently-empty categories.
  • No icon picker changes for user-created categories (already free-text).
**design** (`107_shopping_category_display_and_icons_design.md`) # Design note: `#107` — Einkaufsliste: nur belegte Kategorien anzeigen, passendere Icons ## Scope confirmed against the code - `ShoppingListPage.tsx` already computed `productsByCategory` from `activeProducts` (products with `isOnList === true`) but rendered `orderedCategories` (every category from the fetched list) unconditionally — an empty section still got a header + empty product list. Fix: filter `orderedCategories` down to categories with at least one bucket entry, computed *after* `productsByCategory` is built. - `ShoppingCartCheckPanel` (the "Online cart" panel) does **not** group by category at all — it's a flat name+checkbox list (confirmed in its own test: "name only, no quantity/comments"). It already only ever receives `activeProducts` as its `products` prop from `ShoppingListPage`, so there is no empty-category header it could show in the first place. The AC's "same rule applies" is therefore satisfied by the existing data flow — no code change needed there. Recorded here explicitly rather than silently skipped, since the story's own PO clarification named this component directly. - `ShoppingCategoryManager` (the "Categories" management dialog) fetches and shows all categories unfiltered already, exactly as the AC requires (it's for managing sections, not browsing products). No change needed. - A category that becomes empty by unchecking/moving its last active product disappears automatically from the section list on the next render, since the filter is computed live from `products` state — no separate "is this now empty" bookkeeping needed. The category row itself is untouched (still exists, still reachable via "Categories" for `#106`'s drag-and-drop target), matching the AC. ## Icon review (`CreateShoppingListCommandHandler.DefaultSections`) Changed 4 of the 14 predefined section icons where the emoji read as one specific item rather than the category as a whole, or clashed with a neighboring category's icon: | Section | Before | After | Why | |---|---|---|---| | Obst & Gemüse | | | Broccoli reads as "vegetables" only; apple is the more universal produce icon and doesn't exclude fruit. | | Kühlregal | | | Cheese reads as one specific product, not the whole refrigerated case (milk, yogurt, eggs, cold cuts). Milk carton is the standard "dairy/cold case" icon. | | Drogerie & Haushalt | | | Lotion bottle reads as cosmetics specifically; toilet paper is the more recognizable combined drugstore/household staple icon. | | Glutenfreie Lebensmittel | | | Herb leaf carries no gluten-free meaning and visually clashed with Bioladen's right below it. (crossed wheat) is the closest available emoji analog to the real-world gluten-free symbol. | The other 10 (Backwaren , Trockenwaren , Müsli & Nüsse , Aufstriche , Glas und Dosen , Getränke , Gewürze , Tiefkühl ❄️, Essig/Öl & Co , Bioladen ) already anchor clearly enough to their category and were left unchanged. This only affects sections seeded for shopping lists **created from now on** — same as the original `#90` seed, there's no backfill migration for already-existing lists' category rows. Consistent with how this seed data has always been treated (a one-time creation-time default, not a synced source of truth). ## Out of scope (per story) - No automatic deletion of permanently-empty categories. - No icon picker changes for user-created categories (already free-text).
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
robert/todo#110
No description provided.