Skip to content

Dashboard UX re-design#2781

Merged
pylipp merged 32 commits into
masterfrom
dashboard-redesign
Jun 25, 2026
Merged

Dashboard UX re-design#2781
pylipp merged 32 commits into
masterfrom
dashboard-redesign

Conversation

@pylipp

@pylipp pylipp commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

https://trello.com/c/Hd8yfFuD

Filtering rework (shared-components/statviz)

Replaced the global Apollo Reactive Variable filter state with per-section local filter state, controlled by staged FilterPanel components (Apply action only commits filters).

Filter dimensions per section

  • ItemsAndBoxes (stock): product, product gender, product category, location, tags
  • MovedBoxes (movement): move date range, product, product gender, product category, tags
  • Demographics (beneficiaries): age (0–7, 8–15, 16–25, 26–40, 41–65, 66+), human gender, tags

Key changes

  • One initial DASHBOARD_FILTER_DATA_QUERY fetches the base's products, locations, and tags to populate filter options; categories are derived from products
  • Filter actions (and a boxes/items display toggle for stock and movement sections) are placed in the top-right of each section accordion header
  • Applied filters are synced with the URL using section-specific prefixes: s (stock), m (movement), b (beneficiaries). Parameters: d1/d2 for dates, p product, g gender, c category, t tags, a age — e.g. ?md1=2026-03-22&md2=2026-06-22&sp=1234&bt=9,10
  • Removed the filter wrap from Dashboard.tsx
  • *FilterContainer components no longer use reactive variables; all filter state is passed as props
  • Dropped useReactiveVar(*FilterValuesVar), *FilterValuesVar() writes, and useMultiSelectFilter calls from filter containers
  • New self-contained panel components: StockFilterPanel, MovementFilterPanel, DemographicsFilterPanel
  • filterByTags utility generalised to accept any { id: number }[]

@pylipp pylipp force-pushed the dashboard-redesign branch from 3a3f7ac to 40fc461 Compare June 18, 2026 16:24
@codecov

codecov Bot commented Jun 18, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 76.32%. Comparing base (504b344) to head (bbeb221).
⚠️ Report is 1 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #2781      +/-   ##
==========================================
- Coverage   77.11%   76.32%   -0.80%     
==========================================
  Files         326      326              
  Lines       23437    23441       +4     
  Branches     2354     2326      -28     
==========================================
- Hits        18074    17891     -183     
- Misses       5315     5502     +187     
  Partials       48       48              
Flag Coverage Δ
backend 99.65% <ø> (ø)
frontend 69.95% <ø> (ø)
sharedComponents 24.25% <ø> (-44.47%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@pylipp pylipp force-pushed the dashboard-redesign branch from 40fc461 to dfd81d6 Compare June 19, 2026 13:10
@pylipp

pylipp commented Jun 22, 2026

Copy link
Copy Markdown
Contributor Author

@copilot I need a rework of the filtering implementation in shared-components/statviz.
The current implementation builds on a global filter state using Apollo Reactive Variables, and derives the active selection from the URL.
The goal for the new implementation: each of the three sections (ItemsAndBoxes, MovedBoxes, Demographics) in Dashboard.tsx has its own, local filter state (filters are NOT shared across sections). It is controlled by a FilterPanel which applies filters only when the user executes the Apply action (cf. ProductsTable).

  • ItemsAndBoxes has the filter dimensions

    • product
    • product gender
    • product category
    • location
    • tags
  • MovedBoxes has the filter dimensions

    • move date
    • product
    • product gender
    • product category
    • tags
  • Demographics has the filter dimensions

    • age (steps of 0-7, 8-15, 16-25, 26-40, 41-65, 66+)
    • human gender
    • tags
  • for determining the filter options, issue one initial request to fetch the base's products, locations, and tags

  • the resp. filter action are placed in the top right of the section

  • the applied filters are synced with the URL. Sections are indicated by prefix s/m/b (stock, movement, beneficiaries) indicated as following: d1/d2 for dates, p for product, g for gender, c for category, t for tags, a for age. Multiple values are separated by comma. Example: ?md1=2026-03-22&md2=2026-06-22&sp=1234&mc=4&bt=9,10&bg=3 filters for product 1234 in the stock section, movement date and category 4 in the movement section, and tags 9+10 and gender 3 in the beneficiaries section

  • data for the sections stock and movement can be shown by boxes or by items count. There should be a selection action next to the filter action in these sections. Switching for boxes to items or vice versa updates the display immediately

  • remove the filter wrap in Dashboard.tsx

  • make sure eslint (v9 compliant), prettier, type checking, and build pass

Implementation details

What changes:

  1. a new "staged" filter component: You'd extract the filter UI (currently spread across GenderProductFilter, TabbedTagFilter, etc.) into a self-contained panel component — analogous to ProductsFilter. This component holds stagedFilters locally and only calls back on "Apply"
  2. *FilterContainer lose global vars and gain local applied state
  3. what you can drop entirely:
    • useReactiveVar(*FilterValuesVar)
    • *FilterValuesVar() write in useEffect
    • useMultiSelectFilter for each filter dimension

…sync

Co-authored-by: pylipp <10617122+pylipp@users.noreply.github.com>

Copilot AI commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

@copilot I need a rework of the filtering implementation in shared-components/statviz.
The current implementation builds on a global filter state using Apollo Reactive Variables, ...

Done. Here's a summary of what was implemented:

New files:

  • utils/dashboardFilters.ts – types (IProductOption, ICategoryOption, ILocationOption, ITagOption, StockAppliedFilters, MovementAppliedFilters, DemographicsAppliedFilters), URL param constants, read/write URL helpers, and defaults
  • components/filter/StockFilterPanel.tsx – staged Drawer panel (product, gender, category, location, tags); Apply/Clear
  • components/filter/MovementFilterPanel.tsx – same for movement (date range, product, gender, category, tags)
  • components/filter/DemographicsFilterPanel.tsx – same for demographics (age ranges: 0-7, 8-15, 16-25, 26-40, 41-65, 66+; human gender; tags)

Updated sections (Dashboard.tsx / ItemsAndBoxes / MovedBoxes / Demographics):

  • Dashboard.tsx: removed filter wrap; issues one DASHBOARD_FILTER_DATA_QUERY (base → products/locations/tags) to populate filter options; passes derived options to sections; categories are deduped from products
  • Each section holds local applied filter state derived from URL params on mount; Apply writes back to URL via section-specific prefixes (s, m, b)
  • ItemsAndBoxes and MovedBoxes each have a boxes/items select next to the filter action; switching updates display immediately

URL scheme (as specified): ?sp=…&sg=…&sc=…&sl=…&st=… (stock), ?md1=…&md2=…&mp=…&mg=…&mc=…&mt=… (movement), ?ba=…&bg=…&bt=… (demographics). Multiple values comma-separated.

Filter containers (CreatedBoxesFilterContainer, MovedBoxesFilterContainer, DemographicFilterContainer): removed all useReactiveVar, *FilterValuesVar writes, and useMultiSelectFilter calls; now accept typed props only.

filterByTags.ts generalised to { id: number }[] to remove the ITagFilterValue dependency.

ESLint (v9), Prettier, TypeScript, all 6 tests, and build all pass.

…s to AccordionPanel

Co-authored-by: pylipp <10617122+pylipp@users.noreply.github.com>
Copilot AI changed the title Dashboard UX re-design refactor(statviz): split *FilterPanel into FilterPanel + *Filters, move controls into AccordionPanel Jun 22, 2026
Copilot AI changed the title refactor(statviz): split *FilterPanel into FilterPanel + *Filters, move controls into AccordionPanel feat(statviz): add StockOverviewRing chart + fix react-icons build Jun 22, 2026
Co-authored-by: pylipp <10617122+pylipp@users.noreply.github.com>
Copilot AI changed the title feat(statviz): add StockOverviewRing chart + fix react-icons build statviz: add StockOverviewRing pie chart with user-controlled grouping dimension Jun 23, 2026
Copilot AI changed the title statviz: add StockOverviewRing pie chart with user-controlled grouping dimension shared-front: replace StockDataFilter with StockOverviewRingFilterContainer Jun 23, 2026
Co-authored-by: pylipp <10617122+pylipp@users.noreply.github.com>
Copilot AI changed the title shared-front: replace StockDataFilter with StockOverviewRingFilterContainer shared-front: wire StockOverviewRingFilterContainer to URL-derived filters Jun 23, 2026
@pylipp pylipp changed the title shared-front: wire StockOverviewRingFilterContainer to URL-derived filters Dashboard UX re-design Jun 23, 2026
@pylipp pylipp requested a review from Copilot June 23, 2026 16:32

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR implements the “Dashboard UX re-design” filtering rework for Statviz: replacing the previous global reactive-variable filter state with per-dashboard-section, staged filter panels, and syncing the applied filter state via section-prefixed URL parameters.

Changes:

  • Introduces a shared URL (de)serialization layer for stock/movement/demographics filters (dashboardFilters.ts) and generalizes filterByTags.
  • Refactors dashboard sections (Stock, Movement, Beneficiaries) to use local staged filter drawers (Apply commits to URL) and to pass applied filter props down into data/filter containers.
  • Adds a new Stock Overview “ring” visualization and updates chart styling (PieChart inner radius/label geometry).

Reviewed changes

Copilot reviewed 28 out of 29 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
shared-front/src/App.tsx Switches public “shared-front” stock view to URL-derived applied filters and the new stock ring filter container.
shared-components/statviz/utils/filterByTags.ts Generalizes tag filtering utility input type to { id: number }[].
shared-components/statviz/utils/dashboardFilters.ts New central utilities/types for reading/writing section-prefixed filters to URL params.
shared-components/statviz/utils/analytics/constants.ts Removes an unused/retired graph type constant.
shared-components/statviz/dashboard/StockOverview.tsx Removes legacy StockOverview accordion section component.
shared-components/statviz/dashboard/MovedBoxes.tsx Refactors Movement section to staged filters + URL sync + boxes/items toggle.
shared-components/statviz/dashboard/ItemsAndBoxes.tsx Refactors Stock section to staged filters + URL sync + boxes/items toggle + new ring chart container.
shared-components/statviz/dashboard/Demographics.tsx Refactors Beneficiaries section to staged filters + URL sync.
shared-components/statviz/dashboard/Dashboard.tsx Adds single “filter option” query (products/locations/tags) and wires section components with option props.
shared-components/statviz/components/visualizations/stock/StockOverviewRingFilterContainer.tsx New filter container applying StockAppliedFilters to the stock overview ring visualization.
shared-components/statviz/components/visualizations/stock/StockOverviewRingDataContainer.tsx New data container fetching stock overview data for the ring chart.
shared-components/statviz/components/visualizations/stock/StockOverviewRing.tsx New ring (pie) visualization with grouping selector persisted via URL.
shared-components/statviz/components/visualizations/movedBoxes/MovedBoxesFilterContainer.tsx Drops reactive-var filters; filters moved box facts by applied filter props.
shared-components/statviz/components/visualizations/movedBoxes/MovedBoxesDataContainer.tsx Accepts applied filters + boxes/items and passes them into the filter container.
shared-components/statviz/components/visualizations/movedBoxes/MovedBoxes.test.tsx Updates moved-boxes data-container test to supply required new props.
shared-components/statviz/components/visualizations/demographic/DemographicFilterContainer.tsx Drops reactive-var filters; filters demographic facts by applied filter props (age/gender/tags).
shared-components/statviz/components/visualizations/demographic/DemographicDataContainer.tsx Accepts applied filters and passes them into the filter container.
shared-components/statviz/components/visualizations/createdBoxes/TopCreatedProducts.tsx Removes the “Top Created Products” visualization.
shared-components/statviz/components/visualizations/createdBoxes/CreatedBoxesFilterContainer.tsx Drops reactive-var filters; filters created-box facts by applied filter props and renders only the created-box chart.
shared-components/statviz/components/visualizations/createdBoxes/CreatedBoxesDataContainer.tsx Accepts applied filters + boxes/items and passes them into the filter container.
shared-components/statviz/components/visualizations/createdBoxes/CreatedBoxesCharts.tsx Removes the multi-chart wrapper previously combining created boxes + top products.
shared-components/statviz/components/nivo/PieChart.tsx Adjusts pie chart geometry for center labels and link label lengths.
shared-components/statviz/components/filter/StockFilters.tsx New staged Stock filter panel UI (gender/product/category/location/tags).
shared-components/statviz/components/filter/MovementFilters.tsx New staged Movement filter panel UI (date range + gender/product/category/tags).
shared-components/statviz/components/filter/FilterPanel.tsx New reusable drawer-based filter panel wrapper (icon button + drawer).
shared-components/statviz/components/filter/DemographicsFilters.tsx New staged demographics filter panel UI (age ranges + gender + tags).
package.json Moves react-icons dependency to the workspace root (used by shared-components FilterPanel).
front/package.json Removes react-icons dependency from the front app (now provided at root).
pnpm-lock.yaml Lockfile update reflecting dependency move.
Files not reviewed (1)
  • pnpm-lock.yaml: Generated file

Comment thread shared-components/statviz/components/filter/FilterPanel.tsx Outdated
Comment thread shared-components/statviz/dashboard/ItemsAndBoxes.tsx
Comment thread shared-components/statviz/dashboard/ItemsAndBoxes.tsx
Comment thread shared-components/statviz/dashboard/MovedBoxes.tsx
Comment thread shared-components/statviz/dashboard/MovedBoxes.tsx
Comment thread shared-components/statviz/dashboard/Demographics.tsx
Comment on lines +255 to +258
const defaults = defaultMovementFilters();
return {
dateFrom: searchParams.get(MOVEMENT_URL_PARAMS.dateFrom) ?? defaults.dateFrom,
dateTo: searchParams.get(MOVEMENT_URL_PARAMS.dateTo) ?? defaults.dateTo,
Comment on lines +65 to +74
const handleClear = useCallback(() => {
setStaged((prev) => ({
...prev,
products: [],
genders: [],
categories: [],
includedTags: [],
excludedTags: [],
}));
}, []);
@pylipp pylipp marked this pull request as ready for review June 25, 2026 16:30

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 45 out of 45 changed files in this pull request and generated 5 comments.

Comment on lines +88 to +93
<Select
size="md"
value={boxesOrItems}
onChange={handleBoxesOrItemsChange}
width="120px"
>
Comment on lines +81 to +86
<Select
size="md"
value={boxesOrItems}
onChange={handleBoxesOrItemsChange}
width="120px"
>
Comment on lines +218 to +223
export function readStockFiltersFromUrl(
searchParams: URLSearchParams,
allProducts: IProductOption[],
allCategories: ICategoryOption[],
allLocations: ILocationOption[],
allTags: ITagOption[],
Comment thread shared-front/src/App.tsx
Comment thread shared-front/src/App.tsx
@pylipp pylipp merged commit b230601 into master Jun 25, 2026
14 checks passed
@pylipp pylipp deleted the dashboard-redesign branch June 25, 2026 16:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants