Skip to content

fix(data_export): make collection export respect the active filter and sort - #953

Open
marianmoldovan wants to merge 1 commit into
mainfrom
fix/297-export-respects-filters
Open

fix(data_export): make collection export respect the active filter and sort#953
marianmoldovan wants to merge 1 commit into
mainfrom
fix/297-export-respects-filters

Conversation

@marianmoldovan

Copy link
Copy Markdown
Collaborator

Fixes #297 — open since 2022.

The gap

doDownload called dataSource.fetchCollection({ path, collection }) with no filter, orderBy or order, so exports always returned the whole collection regardless of what the user was looking at. The plumbing already existed: FetchCollectionProps accepts those, and this component already receives tableController (which exposes filterValues and sortBy) via CollectionActionsProps.

UX decision

One opt-out switch, default ON: "Only export results matching the current filter/sort".

  • Shown only when there is something to opt out of — a filter the user set themselves, or an active sort. Unfiltered collections see an unchanged dialog.
  • Silently changing 4-year-old behaviour could surprise anyone relying on a full export, hence the visible toggle rather than a silent switch.
  • Wording reuses the repo's existing "filter/sort" phrasing (clear_filter_sort, no_results_filter_sort) instead of inventing terminology, and covers the filter-only and sort-only cases with one string.
  • Placed with the other BooleanSwitchWithLabel switches, same component and props shape.

forceFilter

Checked first, and it matters: useDataSourceTableController already seeds filterValues from forceFilter and refuses user changes while it's set, so tableController.filterValues already contains it. Handling:

  • forceFilter is spread in unconditionally, after the controller's values, so it always wins — matching FiltersDialog.tsx.
  • Forced keys are excluded when deciding whether to show the switch, so a collection whose only filter is forced doesn't get a pointless toggle.
  • Net: toggling off gives forceFilter only; toggling on gives user filter + forceFilter.

searchString — deliberately not covered, and here's why

The Firestore delegate's fetchCollection destructures searchString, documents it in JSDoc, and then never passes it to buildQuery. Text search is implemented only in listenCollection via performTextSearch. Wiring it into the export would silently do nothing.

So a known remaining limitation: exporting while a text search is active still exports the unsearched set. That's a separate latent issue worth its own ticket (adjacent to #322/#571), not something to paper over here.

i18n

Every locale file is typed FireCMSTranslations (not partial), so the new key had to be added to all 8 core locales — and the label prop is covered by the repo's i18next/no-literal-string rule, so a bare literal wasn't an option. The guarantee was mutation-tested: deleting the key from pl.ts alone makes tsc fail with TS2741.

Verification

pnpm --filter @firecms/data_export build exits 0 (after rebuilding @firecms/core, whose checked-in dist on main is stale — a pre-existing condition, untouched here).

BasicExportAction.tsx needs no change: it receives already-materialised data and has no fetchCollection call.

Gap

The two extracted helpers (hasUserFilterOrSort, resolveExportFilterAndSort) are pure and trivially testable but module-private and uncovered. Jest is already configured in data_export, so a spec would be cheap — the helpers just need exporting. The dialog rendering and the actual filtered download are unverified at runtime.

🤖 Generated with Claude Code

…d sort

`doDownload` called `dataSource.fetchCollection` with only `path` and
`collection`, so exporting always dumped the whole collection regardless of the
filter or sort applied in the collection view. The filter and sort are now read
from the `tableController` that `CollectionActionsProps` already provides and
forwarded as `filter`, `orderBy` and `order`.

Default behaviour: the filtered and sorted set is exported. Because that
silently changes four-year-old behaviour, the export dialog gains an opt-out
switch ("Only export results matching the current filter/sort", default on).
It is only rendered when there is something to opt out of, i.e. a filter the
user applied themselves or an active sort, so the dialog is unchanged for
unfiltered collections.

`collection.forceFilter` is a data scoping constraint rather than a user
preference, so it is merged in unconditionally and takes precedence over the
table controller's filter values, matching the precedence FiltersDialog uses.
Since `useDataSourceTableController` already seeds `filterValues` from
`forceFilter` and refuses user changes while it is set, forced keys are
excluded when deciding whether to show the switch.

`searchString` is deliberately not forwarded: the Firestore delegate accepts it
in `FetchCollectionProps` but ignores it in `fetchCollection` (text search is
only implemented for `listenCollection`), so passing it would silently do
nothing.

Adds the `export_apply_filter_sort` key to `FireCMSTranslations` and all eight
locale files.

Fixes #297

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown

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 fixes collection exports in @firecms/data_export so that exported results can respect the currently active table filter and sort (addressing #297), with a default-on opt-out toggle in the export dialog. It also adds the necessary i18n key across all core locales.

Changes:

  • Pass filter, orderBy, and order into dataSource.fetchCollection during collection export, derived from tableController (and always applying forceFilter).
  • Add a default-on “Only export results matching the current filter/sort” toggle, shown only when a user-applied filter or any sort is active.
  • Add the new export_apply_filter_sort translation key to FireCMSTranslations and all core locale files.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated no comments.

Show a summary per file
File Description
packages/firecms_core/src/types/translations.ts Adds export_apply_filter_sort to the typed translations contract.
packages/firecms_core/src/locales/en.ts Adds English string for the new export toggle label.
packages/firecms_core/src/locales/de.ts Adds German string for the new export toggle label.
packages/firecms_core/src/locales/es.ts Adds Spanish string for the new export toggle label.
packages/firecms_core/src/locales/fr.ts Adds French string for the new export toggle label.
packages/firecms_core/src/locales/hi.ts Adds Hindi string for the new export toggle label.
packages/firecms_core/src/locales/it.ts Adds Italian string for the new export toggle label.
packages/firecms_core/src/locales/pl.ts Adds Polish string for the new export toggle label.
packages/firecms_core/src/locales/pt.ts Adds Portuguese string for the new export toggle label.
packages/data_export/src/export/ExportCollectionAction.tsx Implements filter/sort-aware export (plus forceFilter precedence) and adds the opt-out switch UI.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

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.

Export function to consider filter set

2 participants