From cb3162f084848b1402ad2fb2c450f5842fa9c674 Mon Sep 17 00:00:00 2001 From: Darin Kelkhoff Date: Tue, 16 Apr 2024 20:39:33 -0500 Subject: [PATCH] CE-1115 Add sort indication to report setup; make recordQuery, when being used for report setup, not write local storage; --- .../query/BasicAndAdvancedQueryControls.tsx | 30 +++++++++---- .../widgets/misc/ReportSetupWidget.tsx | 10 ++++- src/qqq/pages/records/query/RecordQuery.tsx | 43 ++++++++++++++++--- 3 files changed, 65 insertions(+), 18 deletions(-) diff --git a/src/qqq/components/query/BasicAndAdvancedQueryControls.tsx b/src/qqq/components/query/BasicAndAdvancedQueryControls.tsx index 8a2ae6e..7c13dff 100644 --- a/src/qqq/components/query/BasicAndAdvancedQueryControls.tsx +++ b/src/qqq/components/query/BasicAndAdvancedQueryControls.tsx @@ -85,6 +85,26 @@ interface BasicAndAdvancedQueryControlsProps let debounceTimeout: string | number | NodeJS.Timeout; + +/******************************************************************************* + ** function to generate an element that says how a filter is sorted. + *******************************************************************************/ +export function getCurrentSortIndicator(queryFilter: QQueryFilter, tableMetaData: QTableMetaData, toggleSortDirection: (event: React.MouseEvent) => void) +{ + if (queryFilter && queryFilter.orderBys && queryFilter.orderBys.length > 0) + { + const orderBy = queryFilter.orderBys[0]; + const orderByFieldName = orderBy.fieldName; + const [field, fieldTable] = TableUtils.getFieldAndTable(tableMetaData, orderByFieldName); + const fieldLabel = fieldTable.name == tableMetaData.name ? field.label : `${fieldTable.label}: ${field.label}`; + return <>Sort: {fieldLabel} {orderBy.isAscending ? "arrow_upward" : "arrow_downward"}; + } + else + { + return <>Sort...; + } +} + /******************************************************************************* ** Component to provide the basic & advanced query-filter controls for the ** RecordQueryOrig screen. @@ -558,15 +578,7 @@ const BasicAndAdvancedQueryControls = forwardRef((props: BasicAndAdvancedQueryCo ///////////////////////////////// // set up the sort menu button // ///////////////////////////////// - let sortButtonContents = <>Sort...; - if (queryFilter && queryFilter.orderBys && queryFilter.orderBys.length > 0) - { - const orderBy = queryFilter.orderBys[0]; - const orderByFieldName = orderBy.fieldName; - const [field, fieldTable] = TableUtils.getFieldAndTable(tableMetaData, orderByFieldName); - const fieldLabel = fieldTable.name == tableMetaData.name ? field.label : `${fieldTable.label}: ${field.label}`; - sortButtonContents = <>Sort: {fieldLabel} {orderBy.isAscending ? "arrow_upward" : "arrow_downward"}; - } + let sortButtonContents = getCurrentSortIndicator(queryFilter, tableMetaData, toggleSortDirection); //////////////////////////////////////////////////////////////////////////////////////////////////////////// // this is being used as a version of like forcing that we get re-rendered if the query filter changes... // diff --git a/src/qqq/components/widgets/misc/ReportSetupWidget.tsx b/src/qqq/components/widgets/misc/ReportSetupWidget.tsx index 4195139..3466088 100644 --- a/src/qqq/components/widgets/misc/ReportSetupWidget.tsx +++ b/src/qqq/components/widgets/misc/ReportSetupWidget.tsx @@ -34,6 +34,7 @@ import colors from "qqq/assets/theme/base/colors"; import {QCancelButton, QSaveButton} from "qqq/components/buttons/DefaultButtons"; import HelpContent, {hasHelpContent} from "qqq/components/misc/HelpContent"; import AdvancedQueryPreview from "qqq/components/query/AdvancedQueryPreview"; +import {getCurrentSortIndicator} from "qqq/components/query/BasicAndAdvancedQueryControls"; import Widget, {HeaderLinkButtonComponent} from "qqq/components/widgets/Widget"; import QQueryColumns, {Column} from "qqq/models/query/QQueryColumns"; import RecordQuery from "qqq/pages/records/query/RecordQuery"; @@ -101,9 +102,11 @@ export default function ReportSetupWidget({isEditable, widgetMetaData, recordVal // load values from record // ///////////////////////////// let queryFilter = recordValues["queryFilterJson"] && JSON.parse(recordValues["queryFilterJson"]) as QQueryFilter; + let usingDefaultEmptyFilter = false; if(!queryFilter) { queryFilter = new QQueryFilter(); + usingDefaultEmptyFilter = true; } let columns: QQueryColumns = null; @@ -285,7 +288,10 @@ export default function ReportSetupWidget({isEditable, widgetMetaData, recordVal setAlertContent(null)}>{alertContent} -
Query Filter
+ +
Query Filter
+ {mayShowQueryPreview() && getCurrentSortIndicator(frontendQueryFilter, tableMetaData, null)} +
{ mayShowQueryPreview() && 0} removeCriteriaByIndexCallback={null} /> @@ -347,7 +353,7 @@ export default function ReportSetupWidget({isEditable, widgetMetaData, recordVal table={tableMetaData} usage="reportSetup" isModal={true} - initialQueryFilter={frontendQueryFilter} + initialQueryFilter={usingDefaultEmptyFilter ? null : frontendQueryFilter} initialColumns={columns} /> } diff --git a/src/qqq/pages/records/query/RecordQuery.tsx b/src/qqq/pages/records/query/RecordQuery.tsx index 3b6d111..255d642 100644 --- a/src/qqq/pages/records/query/RecordQuery.tsx +++ b/src/qqq/pages/records/query/RecordQuery.tsx @@ -141,6 +141,34 @@ const RecordQuery = forwardRef(({table, usage, isModal, initialQueryFilter, init const [firstRender, setFirstRender] = useState(true); const [isFirstRenderAfterChangingTables, setIsFirstRenderAfterChangingTables] = useState(false); + const [loadedFilterFromInitialFilterParam, setLoadedFilterFromInitialFilterParam] = useState(false); + + const mayWriteLocalStorage = usage == "queryScreen"; + + + /******************************************************************************* + ** + *******************************************************************************/ + function localStorageSet(key: string, value: string) + { + if(mayWriteLocalStorage) + { + localStorage.setItem(key, value); + } + } + + + /******************************************************************************* + ** + *******************************************************************************/ + function localStorageRemove(key: string) + { + if(mayWriteLocalStorage) + { + localStorage.removeItem(key); + } + } + useImperativeHandle(ref, () => { return { @@ -232,13 +260,14 @@ const RecordQuery = forwardRef(({table, usage, isModal, initialQueryFilter, init { ///////////////////////////////////////////////////////////////////////// // allow a caller to send in an initial filter & set of columns. // - // only to be used on "first render" // + // only to be used on "first render". // // JSON.parse(JSON.stringify()) to do deep clone and keep object clean // // unclear why not needed on initialColumns... // ///////////////////////////////////////////////////////////////////////// if (initialQueryFilter) { defaultView.queryFilter = JSON.parse(JSON.stringify(initialQueryFilter)); + setLoadedFilterFromInitialFilterParam(true); } if (initialColumns) @@ -720,7 +749,7 @@ const RecordQuery = forwardRef(({table, usage, isModal, initialQueryFilter, init { FilterUtils.stripAwayIncompleteCriteria(viewForLocalStorage.queryFilter) } - localStorage.setItem(viewLocalStorageKey, JSON.stringify(viewForLocalStorage)); + localStorageSet(viewLocalStorageKey, JSON.stringify(viewForLocalStorage)); } catch(e) { @@ -1108,7 +1137,7 @@ const RecordQuery = forwardRef(({table, usage, isModal, initialQueryFilter, init if (state && state.density && state.density.value !== density) { setDensity(state.density.value); - localStorage.setItem(densityLocalStorageKey, JSON.stringify(state.density.value)); + localStorageSet(densityLocalStorageKey, JSON.stringify(state.density.value)); } }; @@ -1605,7 +1634,7 @@ const RecordQuery = forwardRef(({table, usage, isModal, initialQueryFilter, init //////////////////////////////////////////////////////////////// // todo can/should/does this move into the view's "identity"? // //////////////////////////////////////////////////////////////// - localStorage.setItem(currentSavedViewLocalStorageKey, `${savedViewRecord.values.get("id")}`); + localStorageSet(currentSavedViewLocalStorageKey, `${savedViewRecord.values.get("id")}`); }; @@ -1615,7 +1644,7 @@ const RecordQuery = forwardRef(({table, usage, isModal, initialQueryFilter, init const doClearCurrentSavedView = () => { setCurrentSavedView(null); - localStorage.removeItem(currentSavedViewLocalStorageKey); + localStorageRemove(currentSavedViewLocalStorageKey); }; @@ -1662,7 +1691,7 @@ const RecordQuery = forwardRef(({table, usage, isModal, initialQueryFilter, init // wipe away the saved view // ////////////////////////////// setCurrentSavedView(null); - localStorage.removeItem(currentSavedViewLocalStorageKey); + localStorageRemove(currentSavedViewLocalStorageKey); /////////////////////////////////////////////// // activate a new default view for the table // @@ -2484,7 +2513,7 @@ const RecordQuery = forwardRef(({table, usage, isModal, initialQueryFilter, init // if the last time we were on this table, a currentSavedView was written to local storage - // // then navigate back to that view's URL - unless - it looks like we're on a process! // /////////////////////////////////////////////////////////////////////////////////////////////// - if (localStorage.getItem(currentSavedViewLocalStorageKey) && !urlLooksLikeProcess()) + if (localStorage.getItem(currentSavedViewLocalStorageKey) && !urlLooksLikeProcess() && !loadedFilterFromInitialFilterParam) { const currentSavedViewId = Number.parseInt(localStorage.getItem(currentSavedViewLocalStorageKey)); console.log(`returning to previously active saved view ${currentSavedViewId}`);