A CSV export honours the typed search, so the file matches the table on screen
With no facet filter and no selection, a table narrowed by typing exported every row in the source. The export now takes an optional search transform, and the data table passes the matcher it already uses for its visible rows. An explicit selection still outranks the search, and a caller that passes nothing is unchanged.
This commit is contained in:
parent
9d7d630fd6
commit
34573a27c9
2 changed files with 13 additions and 3 deletions
|
|
@ -74,6 +74,12 @@ export const EXPORT_FIELDS = [
|
|||
* It is applied to the COMMENT LINE ONLY — never to a data column (see buildCsv).
|
||||
*/
|
||||
export function useCsvExport({ rowStore, rows, selectionSet, filterSet, FACET_ACC, dataOpts = {}, labelFor = null,
|
||||
// ★ THE TYPED SEARCH NARROWS THE EXPORT TOO. Optional rows->rows transform, so a caller that does not
|
||||
// pass it behaves exactly as before. Without it the export ignored the search box completely: with no
|
||||
// facet filter and no selection, pickRows() fell through to EVERY row, so a reader who typed "Bhutan"
|
||||
// and saw 13 rows downloaded all 2,107. Not applied to an explicit selection — picking rows by hand
|
||||
// outranks a text filter, which is the documented priority model, and the reader can see what they picked.
|
||||
searchFilter = null,
|
||||
// What this export calls itself, and who to credit for the data. Defaults keep every existing
|
||||
// caller's file identical to the byte.
|
||||
exportLabel = 'Research Dashboard', sources = '',
|
||||
|
|
@ -160,6 +166,7 @@ export function useCsvExport({ rowStore, rows, selectionSet, filterSet, FACET_AC
|
|||
}
|
||||
|
||||
function pickRows() {
|
||||
const narrow = (list) => (typeof searchFilter === 'function' ? searchFilter(list) : list)
|
||||
if (selectionSet && selectionSet.size) {
|
||||
return [...selectionSet].map((s) => rowStore.value.get(s)).filter(Boolean)
|
||||
}
|
||||
|
|
@ -168,9 +175,9 @@ export function useCsvExport({ rowStore, rows, selectionSet, filterSet, FACET_AC
|
|||
// The bus's own predicate, handed in by the shell — the exporter must select the same rows
|
||||
// the reader is looking at, and a private copy of the rule is how an export starts
|
||||
// disagreeing with the screen it was taken from.
|
||||
return (rows.value || []).filter((r) => rowMatches(r, FACET_ACC))
|
||||
return narrow((rows.value || []).filter((r) => rowMatches(r, FACET_ACC)))
|
||||
}
|
||||
return rows.value || []
|
||||
return narrow(rows.value || [])
|
||||
}
|
||||
function scopeLabel() {
|
||||
if (selectionSet && selectionSet.size) return `selection (${selectionSet.size})`
|
||||
|
|
|
|||
|
|
@ -547,7 +547,10 @@ const rowCount = computed(() => filtered.value.length)
|
|||
// columns are untouched.
|
||||
const { labelFor: csvLabelFor } = useTreeLegendLabels(cfg, inject('dataStore', null), inject('searchSourceId', null))
|
||||
const csv = dash && bus
|
||||
? useCsvExport({ rowStore: dash.rowStore, rows: dash.rows, selectionSet: bus.selectionSet, filterSet: bus.filterSet, FACET_ACC: FACETS, dataOpts: cfg.data, labelFor: csvLabelFor })
|
||||
? useCsvExport({ rowStore: dash.rowStore, rows: dash.rows, selectionSet: bus.selectionSet, filterSet: bus.filterSet, FACET_ACC: FACETS, dataOpts: cfg.data, labelFor: csvLabelFor,
|
||||
// The table already narrows the screen with this exact matcher (see visibleRows); handing it to the
|
||||
// exporter is what makes the download agree with what the reader is looking at.
|
||||
searchFilter: (list) => filterRowsBySearch(list, matchSearch) })
|
||||
: null
|
||||
const exportToast = ref('')
|
||||
const exporting = ref(false)
|
||||
|
|
|
|||
Loading…
Reference in a new issue