From 6242d46e3cc9ee0f35325292ace50488a4bb15dc Mon Sep 17 00:00:00 2001 From: Caroline D <108160931+CarolineDenis@users.noreply.github.com> Date: Wed, 10 May 2023 10:31:56 -0400 Subject: [PATCH] Create CSV export with only selected query rows Fixes #2348 --- .../js_src/lib/components/QueryBuilder/Export.tsx | 2 ++ .../js_src/lib/components/QueryBuilder/Results.tsx | 8 +++++--- .../lib/components/QueryBuilder/ResultsWrapper.tsx | 10 ++++++++-- .../js_src/lib/components/QueryBuilder/Wrapped.tsx | 6 ++++++ 4 files changed, 21 insertions(+), 5 deletions(-) diff --git a/specifyweb/frontend/js_src/lib/components/QueryBuilder/Export.tsx b/specifyweb/frontend/js_src/lib/components/QueryBuilder/Export.tsx index 473469d0ab7..b97e80efb7e 100644 --- a/specifyweb/frontend/js_src/lib/components/QueryBuilder/Export.tsx +++ b/specifyweb/frontend/js_src/lib/components/QueryBuilder/Export.tsx @@ -23,6 +23,7 @@ export function QueryExportButtons({ queryResource, getQueryFieldRecords, recordSetId, + selectedRows, }: { readonly baseTableName: keyof Tables; readonly fields: RA; @@ -31,6 +32,7 @@ export function QueryExportButtons({ | (() => RA>) | undefined; readonly recordSetId: number | undefined; + readonly selectedRows: ReadonlySet; }): JSX.Element { const showConfirmation = (): boolean => fields.some(({ mappingPath }) => !mappingPathIsComplete(mappingPath)); diff --git a/specifyweb/frontend/js_src/lib/components/QueryBuilder/Results.tsx b/specifyweb/frontend/js_src/lib/components/QueryBuilder/Results.tsx index 4fa61b5e4d0..94bae95f279 100644 --- a/specifyweb/frontend/js_src/lib/components/QueryBuilder/Results.tsx +++ b/specifyweb/frontend/js_src/lib/components/QueryBuilder/Results.tsx @@ -68,6 +68,7 @@ type Props = { readonly createRecordSet: JSX.Element | undefined; readonly extraButtons: JSX.Element | undefined; readonly tableClassName?: string; + readonly selectedRows: GetSet>; }; export function QueryResults(props: Props): JSX.Element { @@ -86,6 +87,7 @@ export function QueryResults(props: Props): JSX.Element { createRecordSet, extraButtons, tableClassName = '', + selectedRows: [selectedRows, setSelectedRows], } = props; const visibleFieldSpecs = fieldSpecs.filter(({ isPhantom }) => !isPhantom); @@ -121,9 +123,9 @@ export function QueryResults(props: Props): JSX.Element { const [treeRanksLoaded = false] = useAsyncState(fetchTreeRanks, false); // Ids of selected records - const [selectedRows, setSelectedRows] = React.useState>( - new Set() - ); + // const [selectedRows, setSelectedRows] = React.useState>( + // new Set() + // ); const lastSelectedRow = React.useRef(undefined); // Unselect all rows when query is reRun React.useEffect(() => setSelectedRows(new Set()), [fieldSpecs]); diff --git a/specifyweb/frontend/js_src/lib/components/QueryBuilder/ResultsWrapper.tsx b/specifyweb/frontend/js_src/lib/components/QueryBuilder/ResultsWrapper.tsx index bf2a359af2e..f16e47c9eb9 100644 --- a/specifyweb/frontend/js_src/lib/components/QueryBuilder/ResultsWrapper.tsx +++ b/specifyweb/frontend/js_src/lib/components/QueryBuilder/ResultsWrapper.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { ajax } from '../../utils/ajax'; -import type { IR, RA } from '../../utils/types'; +import type { GetSet, IR, RA } from '../../utils/types'; import { keysToLowerCase, replaceItem } from '../../utils/utils'; import type { SpecifyResource } from '../DataModel/legacyTypes'; import type { SpecifyModel } from '../DataModel/specifyModel'; @@ -27,12 +27,14 @@ export function QueryResultsWrapper({ extraButtons, model, onSelected: handleSelected, + // selectedRows: [selectedRows, setSelectedRows], ...props }: ResultsProps & { readonly model: SpecifyModel; readonly createRecordSet: JSX.Element | undefined; readonly extraButtons: JSX.Element | undefined; readonly onSelected?: (selected: RA) => void; + readonly selectedRows: GetSet>; }): JSX.Element | null { const newProps = useQueryResultsWrapper(props); @@ -49,6 +51,7 @@ export function QueryResultsWrapper({ extraButtons={extraButtons} model={model} onSelected={handleSelected} + // selectedRows={[selectedRows, setSelectedRows]} /> @@ -69,6 +72,7 @@ type ResultsProps = { */ newFields: RA ) => void; + readonly selectedRows: GetSet>; }; type PartialProps = Omit< @@ -99,13 +103,14 @@ export function useQueryResultsWrapper({ recordSetId, forceCollection, onSortChange: handleSortChange, + selectedRows: [selectedRows, setSelectedRows], }: ResultsProps): PartialProps | undefined { /* * Need to store all props in a state so that query field edits do not affect * the query results until query is reRun */ const [props, setProps] = React.useState< - Omit | undefined + Omit | undefined >(undefined); const [totalCount, setTotalCount] = React.useState( @@ -217,5 +222,6 @@ export function useQueryResultsWrapper({ : { ...props, totalCount, + selectedRows: [selectedRows, setSelectedRows], }; } diff --git a/specifyweb/frontend/js_src/lib/components/QueryBuilder/Wrapped.tsx b/specifyweb/frontend/js_src/lib/components/QueryBuilder/Wrapped.tsx index d1a57ee2060..4481b1d5f6a 100644 --- a/specifyweb/frontend/js_src/lib/components/QueryBuilder/Wrapped.tsx +++ b/specifyweb/frontend/js_src/lib/components/QueryBuilder/Wrapped.tsx @@ -97,6 +97,10 @@ export function QueryBuilder({ const [query, setQuery] = useResource(queryResource); useErrorContext('query', query); + const [selectedRows, setSelectedRows] = React.useState>( + new Set() + ); + const model = getModelById(query.contextTableId); const buildInitialState = React.useCallback( () => @@ -536,6 +540,7 @@ export function QueryBuilder({ getQueryFieldRecords={getQueryFieldRecords} queryResource={queryResource} recordSetId={recordSet?.id} + selectedRows={selectedRows} /> ) } @@ -553,6 +558,7 @@ export function QueryBuilder({ }); runQuery('regular', fields); }} + selectedRows={[selectedRows, setSelectedRows]} /> )}