[FEATURE] Member overview - data foundation, layout & density #547

Open
opened 2026-06-30 16:05:20 +02:00 by simon · 0 comments
Owner

Description

Splits the oversized #512 into shippable pieces. This issue delivers the data foundation + visual layout/density, and keeps the existing filter panel until the filter redesign (#548) lands — so it ships independently.

Why

  • The table forces constant horizontal scrolling: the address is split into four columns (Country/City/Street/House Number) and cells have generous padding.
  • The LiveView loads all members into memory and filters/sorts several dimensions in memory → no pagination, does not scale to thousands of members.

Scope — in

Data foundation (the backbone)

  • Push the remaining in-memory filters/sorts down to the DB (Ash). Already DB-level: full-text search, fee-type filter, group filter. To move:
    • Payment/cycle status → Ash aggregate/expression calculation, or a denormalized cycle_end column (cycle end is currently computed = cycle_start + interval). The one genuinely tricky item.
    • Boolean custom fields → JSONB predicate + add a GIN index on custom_field_values.value (none today).
    • Date custom fields → JSONB JOIN + range cast.
    • Group sort → Ash aggregate (group names/count).
  • Render rows with LiveView streams; keyset pagination + infinite scroll (phx-viewport-bottom), bridged via AshPhoenix.LiveView.assign_page_and_stream_result/2. (Flop is Ecto-only — not used.)

Layout & density

  • Composite address cell (display-layer only, no DB change): line 1 street + house no., line 2 postal code + city. Keep city / postal code findable via search (and/or as filter fields).
  • Density toggle (icon, tooltip): Compact default (~36–40px) / Comfortable (~48–52px), driven by one spacing token, persisted per account; interactive targets ≥24px in both.
  • Column manager repositioned next to the filters with consistent button design; visibility + All/None (buttons) + a curated default column set. Persistence preserved (URL → session → cookie → global). Column ordering stays in the Datafield settings (sortable table like the join form).
  • Search clear (×) icon — folds in #160.
  • Sticky header + pinned identifier column; truncation + ellipsis with hover/focus tooltip.

Accessibility (WCAG 2.2 AA)

  • Native <table> (not ARIA grid); sortable headers expose aria-sort (one active); non-color sort glyph.
  • Persistent polite live region for result count + loading; aria-busy during fetch.
  • Logical focus order, visible focus, target sizes ≥24px, reflow at 320px.

Scope — out (separate issues)

  • New filter paradigm (Add-Filter-Builder, chips) → #548.
  • Saved views → #549.
  • Address DB remodeling incl. Country → #550.
  • In-table column reorder / resize / user-pinning.

Acceptance criteria

  • At the default column set, the overview fits common desktop widths without horizontal scroll (address shown as one composite cell).
  • Density toggle switches Compact/Comfortable; the choice persists per account; interactive targets stay ≥24px in both.
  • The list paginates via keyset infinite scroll; filtering and sorting run in the DB; no full-table in-memory load on mount.
  • Every existing filter and sort yields identical results to before (regression-safe), now DB-backed.
  • Search has a clear (×) icon (#160); city and postal code remain findable via search.
  • Column manager sits next to the filters with consistent button styling (visibility + All/None + curated defaults); existing persistence semantics preserved.
  • Result count and loading are announced via a polite live region; sortable headers expose aria-sort; the table is keyboard-operable; WCAG 2.2 AA.
  • CI green; existing member-overview tests pass (extended where behavior changed, no redundant tests).

Dependencies

  • Foundation for #548. Independent of #550.

References

  • Analysis doc issue-512-member-overview-redesign.md — §6.4 (DB-pushdown feasibility), §6.5 (responsiveness/pagination), §10 (split), §11 (mockups).
  • Mockups: mockups/mockup-1-compact.png, mockups/mockup-2-comfortable.png, mockups/mockup-4-columns.png.
  • Folds in #160. Parent: #512.
## Description Splits the oversized #512 into shippable pieces. **This issue delivers the data foundation + visual layout/density**, and **keeps the existing filter panel** until the filter redesign (#548) lands — so it ships independently. ### Why - The table forces constant **horizontal scrolling**: the address is split into four columns (Country/City/Street/House Number) and cells have generous padding. - The LiveView **loads all members into memory** and filters/sorts several dimensions in memory → no pagination, does not scale to thousands of members. ## Scope — in **Data foundation (the backbone)** - Push the remaining in-memory filters/sorts down to the DB (Ash). Already DB-level: full-text search, fee-type filter, group filter. To move: - **Payment/cycle status** → Ash aggregate/expression calculation, or a denormalized `cycle_end` column (cycle end is currently computed = `cycle_start + interval`). *The one genuinely tricky item.* - **Boolean custom fields** → JSONB predicate + **add a GIN index** on `custom_field_values.value` (none today). - **Date custom fields** → JSONB JOIN + range cast. - **Group sort** → Ash aggregate (group names/count). - Render rows with **LiveView streams**; **keyset pagination** + **infinite scroll** (`phx-viewport-bottom`), bridged via `AshPhoenix.LiveView.assign_page_and_stream_result/2`. (Flop is Ecto-only — not used.) **Layout & density** - **Composite address cell** (display-layer only, no DB change): line 1 `street + house no.`, line 2 `postal code + city`. Keep **city / postal code findable** via search (and/or as filter fields). - **Density toggle** (icon, tooltip): Compact default (~36–40px) / Comfortable (~48–52px), driven by one spacing token, **persisted per account**; interactive targets ≥24px in both. - **Column manager** repositioned next to the filters with consistent button design; visibility + **All/None** (buttons) + a **curated default column set**. Persistence preserved (URL → session → cookie → global). Column **ordering stays in the Datafield settings** (sortable table like the join form). - **Search clear (×)** icon — folds in **#160**. - Sticky header + pinned identifier column; truncation + ellipsis with hover/**focus** tooltip. **Accessibility (WCAG 2.2 AA)** - Native `<table>` (not ARIA grid); sortable headers expose `aria-sort` (one active); non-color sort glyph. - Persistent polite **live region** for result count + loading; `aria-busy` during fetch. - Logical focus order, visible focus, target sizes ≥24px, reflow at 320px. ## Scope — out (separate issues) - New filter paradigm (Add-Filter-Builder, chips) → **#548**. - Saved views → **#549**. - Address DB remodeling incl. Country → **#550**. - In-table column reorder / resize / user-pinning. ## Acceptance criteria - [ ] At the default column set, the overview fits common desktop widths **without horizontal scroll** (address shown as one composite cell). - [ ] **Density toggle** switches Compact/Comfortable; the choice **persists per account**; interactive targets stay ≥24px in both. - [ ] The list **paginates via keyset infinite scroll**; filtering and sorting run **in the DB**; no full-table in-memory load on mount. - [ ] Every existing filter and sort yields **identical results** to before (regression-safe), now DB-backed. - [ ] Search has a **clear (×)** icon (#160); **city and postal code remain findable** via search. - [ ] Column manager sits **next to the filters** with consistent button styling (visibility + All/None + curated defaults); existing persistence semantics preserved. - [ ] Result count and loading are **announced via a polite live region**; sortable headers expose `aria-sort`; the table is keyboard-operable; **WCAG 2.2 AA**. - [ ] CI green; existing member-overview tests pass (extended where behavior changed, no redundant tests). ## Dependencies - **Foundation for #548.** Independent of #550. ## References - Analysis doc `issue-512-member-overview-redesign.md` — §6.4 (DB-pushdown feasibility), §6.5 (responsiveness/pagination), §10 (split), §11 (mockups). - Mockups: `mockups/mockup-1-compact.png`, `mockups/mockup-2-comfortable.png`, `mockups/mockup-4-columns.png`. - Folds in #160. Parent: #512.
simon changed title from [FEATURE] Member overview — data foundation, layout & density (redesign part 1) to [FEATURE] Member overview - data foundation, layout & density (redesign part 1) 2026-06-30 16:05:36 +02:00
simon changed title from [FEATURE] Member overview - data foundation, layout & density (redesign part 1) to [FEATURE] Member overview - data foundation, layout & density 2026-06-30 16:14:10 +02:00
simon added the
enhancement
L
UX Improvement
labels 2026-06-30 16:20:16 +02:00
simon added this to the Sprint 17: Juni 2026 project 2026-06-30 16:20:23 +02:00
simon added this to the Minor UI and Feature Polishing | TI I milestone 2026-06-30 16:20:32 +02:00
simon self-assigned this 2026-06-30 16:20:38 +02:00
Sign in to join this conversation.
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: local-it/mitgliederverwaltung#547
No description provided.