Skip to content

✨ feat: add scoped refresh event with loading state to VirtualizedTable - #669

Merged
futjesus merged 3 commits into
mainfrom
feat/virtualized-table-refresh-event
Jul 27, 2026
Merged

✨ feat: add scoped refresh event with loading state to VirtualizedTable#669
futjesus merged 3 commits into
mainfrom
feat/virtualized-table-refresh-event

Conversation

@futjesus

Copy link
Copy Markdown
Member

Summary

Fixes two issues reported when using VirtualizedTable across micro-frontends:

  1. No loading state on manual refresh — with fetchData, background refetches only flip TanStack Query's isFetching, which nothing consumed, so a refresh button produced no visual feedback.
  2. Resetting one table's filters cleared every filter dropdown on the pageFilterEvent.RESET was dispatched globally with no scope.

Changes

New sendRefreshEvent(tableId?)

  • VirtualizedTable.Events.sendRefreshEvent(tableId?) refetches the table's internal query and shows the loading skeleton (and hides pagination) while in flight, same as the initial load.
  • With a tableId only the matching table refreshes; without arguments every mounted table refreshes (for refresh buttons living outside a table).
  • No-op on tables without fetchData. Handles overlapping refreshes, fetch failures (skeleton clears, rows kept) and unmount mid-refresh. Background/polling refetches still never flash the skeleton.

Scoped filter reset

  • resetEvent(scope?) now carries a scope; each <Filter> root gets a resetScope (auto-generated via useId, injectable by prop) and VirtualizedTable injects its tableId.
  • sendResetFiltersEvent('table-a') now only clears table A's search, provider state and dropdowns.
  • Unscoped resetEvent() keeps the previous reset-everything behavior (note: CustomEvent normalizes an undefined detail to null, hence the nullish guard).
  • ⚠️ Behavior change: a standalone Filter.ResetButton no longer clears dropdowns in other <Filter> roots — that was the leak being fixed.

Other

  • VirtualizedTable events split into per-scope folders (events/row, events/filters, events/refresh) with their own types and tests.
  • Filter's theme no longer defaults to 'civo'; when undefined it inherits from the ancestor's data-theme.
  • Replaced vite-tsconfig-paths with Vite 8's native resolve.tsconfigPaths in the Storybook config (removes the deprecation warning and the dependency).

Consumer usage

<Button onClick={() => { VirtualizedTable.Events.sendRefreshEvent(TABLE_ID); }}>Refresh</Button>

Requires the table to use fetchData; each mounted table needs a unique id.

Testing

  • New tests: manual refresh skeleton lifecycle (success/failure), broadcast refresh, scoped ignore, no-op without fetchData, scoped/unscoped resetEvent, ResetButton per-root scoping, and a two-table e2e for sendResetFiltersEvent.
  • New ManualRefresh Storybook story with an external refresh button.
  • npm run ci green: 502 tests, lint, types, prettier, build, Storybook build.

- Add sendRefreshEvent(tableId?) to VirtualizedTable.Events: refetches the
  internal query and shows the loading skeleton while in flight; without a
  tableId it refreshes every mounted table (no-op on tables without fetchData)
- Scope FilterEvent.RESET by a per-Filter resetScope (auto-generated via
  useId, injectable by prop) so resetting one table's filters no longer clears
  every filter dropdown on the page; unscoped resetEvent() keeps resetting all
- Split VirtualizedTable events into per-scope folders (row, filters, refresh)
  with their own types and tests
- Remove the 'civo' default theme on Filter so it inherits from the ancestor
  when undefined
@futjesus
futjesus force-pushed the feat/virtualized-table-refresh-event branch from 58b50e3 to 07c9187 Compare July 27, 2026 14:29
@futjesus
futjesus merged commit 17d9042 into main Jul 27, 2026
1 check passed
@futjesus
futjesus deleted the feat/virtualized-table-refresh-event branch July 27, 2026 14:39
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.

1 participant