From 418f7957a2b1a23e2ab975c78b2306f78d76b10d Mon Sep 17 00:00:00 2001 From: Darin Kelkhoff Date: Fri, 23 Aug 2024 08:51:24 -0500 Subject: [PATCH 1/9] CE-1646 pass useCase (filter or form) into DynamicSelect and down to possibleValue backend calls --- src/qqq/components/forms/DynamicForm.tsx | 1 + src/qqq/components/forms/DynamicSelect.tsx | 7 ++++--- src/qqq/components/query/FilterCriteriaRowValues.tsx | 2 ++ src/qqq/components/scripts/ScriptEditor.tsx | 4 ++-- src/qqq/components/sharing/ShareModal.tsx | 1 + src/qqq/pages/records/query/GridFilterOperators.tsx | 2 ++ 6 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/qqq/components/forms/DynamicForm.tsx b/src/qqq/components/forms/DynamicForm.tsx index f95d42d..0823648 100644 --- a/src/qqq/components/forms/DynamicForm.tsx +++ b/src/qqq/components/forms/DynamicForm.tsx @@ -183,6 +183,7 @@ function QDynamicForm({formData, formLabel, bulkEditMode, bulkEditSwitchChangeHa bulkEditMode={bulkEditMode} bulkEditSwitchChangeHandler={bulkEditSwitchChanged} otherValues={otherValuesMap} + useCase="form" /> {formattedHelpContent} diff --git a/src/qqq/components/forms/DynamicSelect.tsx b/src/qqq/components/forms/DynamicSelect.tsx index 35b3172..ca1e596 100644 --- a/src/qqq/components/forms/DynamicSelect.tsx +++ b/src/qqq/components/forms/DynamicSelect.tsx @@ -53,6 +53,7 @@ interface Props otherValues?: Map; variant: "standard" | "outlined"; initiallyOpen: boolean; + useCase: "form" | "filter"; } DynamicSelect.defaultProps = { @@ -102,7 +103,7 @@ export const getAutocompleteOutlinedStyle = (isDisabled: boolean) => const qController = Client.getInstance(); -function DynamicSelect({tableName, processName, fieldName, possibleValueSourceName, overrideId, fieldLabel, inForm, initialValue, initialDisplayValue, initialValues, onChange, isEditable, isMultiple, bulkEditMode, bulkEditSwitchChangeHandler, otherValues, variant, initiallyOpen}: Props) +function DynamicSelect({tableName, processName, fieldName, possibleValueSourceName, overrideId, fieldLabel, inForm, initialValue, initialDisplayValue, initialValues, onChange, isEditable, isMultiple, bulkEditMode, bulkEditSwitchChangeHandler, otherValues, variant, initiallyOpen, useCase}: Props) { const [open, setOpen] = useState(initiallyOpen); const [options, setOptions] = useState([]); @@ -194,7 +195,7 @@ function DynamicSelect({tableName, processName, fieldName, possibleValueSourceNa (async () => { // console.log(`doing a search with ${searchTerm}`); - const results: QPossibleValue[] = await qController.possibleValues(tableName, processName, possibleValueSourceName ?? fieldName, searchTerm ?? "", null, otherValues); + const results: QPossibleValue[] = await qController.possibleValues(tableName, processName, possibleValueSourceName ?? fieldName, searchTerm ?? "", null, otherValues, useCase); if (tableMetaData == null && tableName) { @@ -227,7 +228,7 @@ function DynamicSelect({tableName, processName, fieldName, possibleValueSourceNa setLoading(true); setOptions([]); console.log("Refreshing possible values..."); - const results: QPossibleValue[] = await qController.possibleValues(tableName, processName, possibleValueSourceName ?? fieldName, searchTerm ?? "", null, otherValues); + const results: QPossibleValue[] = await qController.possibleValues(tableName, processName, possibleValueSourceName ?? fieldName, searchTerm ?? "", null, otherValues, useCase); setLoading(false); setOptions([...results]); setOtherValuesWhenResultsWereLoaded(JSON.stringify(Object.fromEntries(otherValues))); diff --git a/src/qqq/components/query/FilterCriteriaRowValues.tsx b/src/qqq/components/query/FilterCriteriaRowValues.tsx index 5ace799..793497a 100644 --- a/src/qqq/components/query/FilterCriteriaRowValues.tsx +++ b/src/qqq/components/query/FilterCriteriaRowValues.tsx @@ -377,6 +377,7 @@ function FilterCriteriaRowValues({operatorOption, criteria, field, table, valueC inForm={false} onChange={(value: any) => valueChangeHandler(null, 0, value)} variant="standard" + useCase="filter" /> ) @@ -412,6 +413,7 @@ function FilterCriteriaRowValues({operatorOption, criteria, field, table, valueC inForm={false} onChange={(value: any) => valueChangeHandler(null, "all", value)} variant="standard" + useCase="filter" /> ; } diff --git a/src/qqq/components/scripts/ScriptEditor.tsx b/src/qqq/components/scripts/ScriptEditor.tsx index 9ee7ca1..b997759 100644 --- a/src/qqq/components/scripts/ScriptEditor.tsx +++ b/src/qqq/components/scripts/ScriptEditor.tsx @@ -440,10 +440,10 @@ function ScriptEditor({title, scriptId, scriptRevisionRecord, closeCallback, tab - + - + diff --git a/src/qqq/components/sharing/ShareModal.tsx b/src/qqq/components/sharing/ShareModal.tsx index 634b579..1a83082 100644 --- a/src/qqq/components/sharing/ShareModal.tsx +++ b/src/qqq/components/sharing/ShareModal.tsx @@ -397,6 +397,7 @@ export default function ShareModal({open, onClose, tableMetaData, record}: Share initialDisplayValue={selectedAudienceOption?.label} inForm={false} onChange={handleAudienceChange} + useCase="form" /> {/* diff --git a/src/qqq/pages/records/query/GridFilterOperators.tsx b/src/qqq/pages/records/query/GridFilterOperators.tsx index 6201609..c9b9517 100644 --- a/src/qqq/pages/records/query/GridFilterOperators.tsx +++ b/src/qqq/pages/records/query/GridFilterOperators.tsx @@ -786,6 +786,7 @@ function InputPossibleValueSourceSingle(tableName: string, field: QFieldMetaData initialDisplayValue={selectedPossibleValue?.label} inForm={false} onChange={handleChange} + useCase="filter" // InputProps={applying ? {endAdornment: sync} : {}} /> @@ -854,6 +855,7 @@ function InputPossibleValueSourceMultiple(tableName: string, field: QFieldMetaDa initialValues={selectedPossibleValues} inForm={false} onChange={handleChange} + useCase="filter" /> ); From 0c2dcb12159886fe68bfea61799bb494f92ce6de Mon Sep 17 00:00:00 2001 From: Darin Kelkhoff Date: Fri, 23 Aug 2024 10:07:18 -0500 Subject: [PATCH 2/9] Update qqq-frontend-core to 1.0.105 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a70d7b4..af6e459 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "@auth0/auth0-react": "1.10.2", "@emotion/react": "11.7.1", "@emotion/styled": "11.6.0", - "@kingsrook/qqq-frontend-core": "1.0.104", + "@kingsrook/qqq-frontend-core": "1.0.105", "@mui/icons-material": "5.4.1", "@mui/material": "5.11.1", "@mui/styles": "5.11.1", From d9f1642f0a3a55af16cf77f7d556b05a0fb2f41f Mon Sep 17 00:00:00 2001 From: Darin Kelkhoff Date: Fri, 23 Aug 2024 14:10:54 -0500 Subject: [PATCH 3/9] Update for next development version --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 3673bec..abf49fc 100644 --- a/pom.xml +++ b/pom.xml @@ -29,7 +29,7 @@ jar - 0.21.0 + 0.22.0-SNAPSHOT UTF-8 UTF-8 From 1284e3a22ca03200dd14d41375e8e61b702ca933 Mon Sep 17 00:00:00 2001 From: Darin Kelkhoff Date: Fri, 23 Aug 2024 15:11:26 -0500 Subject: [PATCH 4/9] CE-1643 change default operator for DATEs to be equals --- src/qqq/components/query/BasicAndAdvancedQueryControls.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qqq/components/query/BasicAndAdvancedQueryControls.tsx b/src/qqq/components/query/BasicAndAdvancedQueryControls.tsx index f5d82c8..06ef0d6 100644 --- a/src/qqq/components/query/BasicAndAdvancedQueryControls.tsx +++ b/src/qqq/components/query/BasicAndAdvancedQueryControls.tsx @@ -183,7 +183,7 @@ const BasicAndAdvancedQueryControls = forwardRef((props: BasicAndAdvancedQueryCo { // todo - sometimes i want contains instead of equals on strings (client.name, for example...) let defaultOperator = field?.possibleValueSourceName ? QCriteriaOperator.IN : QCriteriaOperator.EQUALS; - if (field?.type == QFieldType.DATE_TIME || field?.type == QFieldType.DATE) + if (field?.type == QFieldType.DATE_TIME) { defaultOperator = QCriteriaOperator.GREATER_THAN; } From 128a748b63a72a2c2ecd0e2390174c7044ca137d Mon Sep 17 00:00:00 2001 From: Darin Kelkhoff Date: Fri, 23 Aug 2024 15:11:52 -0500 Subject: [PATCH 5/9] CE-1643 Add fontVariantNumeric: "tabular-nums" to the thing with numbers that count up, so it's awesome. --- src/qqq/components/query/EvaluatedExpression.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qqq/components/query/EvaluatedExpression.tsx b/src/qqq/components/query/EvaluatedExpression.tsx index 23c3065..17126e3 100644 --- a/src/qqq/components/query/EvaluatedExpression.tsx +++ b/src/qqq/components/query/EvaluatedExpression.tsx @@ -50,7 +50,7 @@ export function EvaluatedExpression({field, expression}: EvaluatedExpressionProp return () => clearInterval(interval); }, []); - return <>{`${evaluateExpression(timeForEvaluations, field, expression)}`}; + return {`${evaluateExpression(timeForEvaluations, field, expression)}`}; } const HOUR_MS = 60 * 60 * 1000; From 2cc7e9ebe140bfd764ff9b84a16f87825aee95c3 Mon Sep 17 00:00:00 2001 From: Darin Kelkhoff Date: Fri, 23 Aug 2024 15:13:44 -0500 Subject: [PATCH 6/9] CE-1643 Add a timezone conversion to the formatDate function for the case where it took a string rather than a Date as input, in which case, the new Date() call would be appying a timezone, and making us off-by-one (for some side of the prime merdian i think) --- src/qqq/utils/qqq/ValueUtils.tsx | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/qqq/utils/qqq/ValueUtils.tsx b/src/qqq/utils/qqq/ValueUtils.tsx index e5a9c55..7d29f63 100644 --- a/src/qqq/utils/qqq/ValueUtils.tsx +++ b/src/qqq/utils/qqq/ValueUtils.tsx @@ -268,7 +268,15 @@ class ValueUtils { if (!(date instanceof Date)) { + //////////////////////////////////////////////////////////////////////////////////// + // so, a new Date here will interpret the string as being at midnight UTC, but // + // the data object will be in the user/browser timezone. // + // so "2024-08-22", for a user in US/Central, will be "2024-08-21T19:00:00-0500". // + // correct for that by adding the date's timezone offset (converted from minutes // + // to millis) back to it // + //////////////////////////////////////////////////////////////////////////////////// date = new Date(date); + date.setTime(date.getTime() + date.getTimezoneOffset() * 60 * 1000) } // @ts-ignore return (`${date.toString("yyyy-MM-dd")}`); From 34a4fc19b4374c08adc5eb9693e0c47a7226bac0 Mon Sep 17 00:00:00 2001 From: Tim Chamberlain Date: Tue, 27 Aug 2024 17:52:34 -0500 Subject: [PATCH 7/9] CE-1647: added preview to query filter widget --- .../misc/FilterAndColumnsSetupWidget.tsx | 30 ++++++++++--- src/qqq/pages/records/query/RecordQuery.tsx | 43 +++++++++++++++---- 2 files changed, 57 insertions(+), 16 deletions(-) diff --git a/src/qqq/components/widgets/misc/FilterAndColumnsSetupWidget.tsx b/src/qqq/components/widgets/misc/FilterAndColumnsSetupWidget.tsx index 5800575..960c163 100644 --- a/src/qqq/components/widgets/misc/FilterAndColumnsSetupWidget.tsx +++ b/src/qqq/components/widgets/misc/FilterAndColumnsSetupWidget.tsx @@ -87,6 +87,7 @@ export default function FilterAndColumnsSetupWidget({isEditable, widgetMetaData, { const [modalOpen, setModalOpen] = useState(false); const [hideColumns, setHideColumns] = useState(widgetData?.hideColumns); + const [hidePreview, setHidePreview] = useState(widgetData?.hidePreview); const [tableMetaData, setTableMetaData] = useState(null as QTableMetaData); const [alertContent, setAlertContent] = useState(null as string); @@ -272,7 +273,7 @@ export default function FilterAndColumnsSetupWidget({isEditable, widgetMetaData, /******************************************************************************* ** *******************************************************************************/ - function mayShowQueryPreview(): boolean + function mayShowQuery(): boolean { if (tableMetaData) { @@ -288,7 +289,7 @@ export default function FilterAndColumnsSetupWidget({isEditable, widgetMetaData, /******************************************************************************* ** *******************************************************************************/ - function mayShowColumnsPreview(): boolean + function mayShowColumns(): boolean { if (tableMetaData) { @@ -356,14 +357,14 @@ export default function FilterAndColumnsSetupWidget({isEditable, widgetMetaData,
Query Filter
- {mayShowQueryPreview() && getCurrentSortIndicator(frontendQueryFilter, tableMetaData, null)} + {mayShowQuery() && getCurrentSortIndicator(frontendQueryFilter, tableMetaData, null)}
{ - mayShowQueryPreview() && + mayShowQuery() && 0} removeCriteriaByIndexCallback={null} /> } { - !mayShowQueryPreview() && + !mayShowQuery() && { isEditable && @@ -382,11 +383,11 @@ export default function FilterAndColumnsSetupWidget({isEditable, widgetMetaData,
Columns
{ - mayShowColumnsPreview() && + mayShowColumns() && columns && columns.columns.map((column, i) => {renderColumn(column)}) } { - !mayShowColumnsPreview() && + !mayShowColumns() && { isEditable && @@ -402,6 +403,21 @@ export default function FilterAndColumnsSetupWidget({isEditable, widgetMetaData, )} + {!hidePreview && !isEditable && frontendQueryFilter && tableMetaData && ( + +
Preview
+ +
+ )} { modalOpen && closeEditor(event, reason)}> diff --git a/src/qqq/pages/records/query/RecordQuery.tsx b/src/qqq/pages/records/query/RecordQuery.tsx index 9c9cf86..6efcd7a 100644 --- a/src/qqq/pages/records/query/RecordQuery.tsx +++ b/src/qqq/pages/records/query/RecordQuery.tsx @@ -33,8 +33,7 @@ import {QCriteriaOperator} from "@kingsrook/qqq-frontend-core/lib/model/query/QC import {QFilterCriteria} from "@kingsrook/qqq-frontend-core/lib/model/query/QFilterCriteria"; import {QFilterOrderBy} from "@kingsrook/qqq-frontend-core/lib/model/query/QFilterOrderBy"; import {QQueryFilter} from "@kingsrook/qqq-frontend-core/lib/model/query/QQueryFilter"; -import {Alert, Collapse, Menu, Typography} from "@mui/material"; -import Box from "@mui/material/Box"; +import {Alert, Box, Collapse, Menu, Typography} from "@mui/material"; import Button from "@mui/material/Button"; import Card from "@mui/material/Card"; import Divider from "@mui/material/Divider"; @@ -92,6 +91,7 @@ interface Props launchProcess?: QProcessMetaData; usage?: QueryScreenUsage; isModal?: boolean; + isPreview?: boolean; initialQueryFilter?: QQueryFilter; initialColumns?: QQueryColumns; allowVariables?: boolean; @@ -126,7 +126,7 @@ const getLoadingScreen = (isModal: boolean) => ** ** Yuge component. The best. Lots of very smart people are saying so. *******************************************************************************/ -const RecordQuery = forwardRef(({table, usage, isModal, allowVariables, initialQueryFilter, initialColumns}: Props, ref) => +const RecordQuery = forwardRef(({table, usage, isModal, isPreview, allowVariables, initialQueryFilter, initialColumns}: Props, ref) => { const tableName = table.name; const [searchParams] = useSearchParams(); @@ -884,6 +884,18 @@ const RecordQuery = forwardRef(({table, usage, isModal, allowVariables, initialQ }; + /******************************************************************************* + ** Opens a new query screen in a new window with the current filter + *******************************************************************************/ + const openFilterInNewWindow = () => + { + let filterForBackend = JSON.parse(JSON.stringify(view.queryFilter)); + filterForBackend = FilterUtils.prepQueryFilterForBackend(tableMetaData, filterForBackend); + const url = `${metaData?.getTablePathByName(tableName)}?filter=${encodeURIComponent(JSON.stringify(filterForBackend))}`; + window.open(url); + }; + + /******************************************************************************* ** This is the method that actually executes a query to update the data in the table. *******************************************************************************/ @@ -2232,12 +2244,25 @@ const RecordQuery = forwardRef(({table, usage, isModal, allowVariables, initialQ return (
- -
-
- {/* @ts-ignore */} - + + +
+ { + !isPreview && ( +
+ {/* @ts-ignore */} + +
+ ) + } + { + isPreview && ( + + + + ) + } { usage == "queryScreen" && @@ -2872,7 +2897,7 @@ const RecordQuery = forwardRef(({table, usage, isModal, allowVariables, initialQ } { - metaData && tableMetaData && + !isPreview && metaData && tableMetaData && Date: Thu, 29 Aug 2024 16:03:26 -0500 Subject: [PATCH 8/9] CE-1405 - Put margin-left on this, so if its used in a big number block, and it wraps, it does right, i think --- src/qqq/components/widgets/blocks/UpOrDownNumberBlock.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qqq/components/widgets/blocks/UpOrDownNumberBlock.tsx b/src/qqq/components/widgets/blocks/UpOrDownNumberBlock.tsx index 20e0106..68e6490 100644 --- a/src/qqq/components/widgets/blocks/UpOrDownNumberBlock.tsx +++ b/src/qqq/components/widgets/blocks/UpOrDownNumberBlock.tsx @@ -58,7 +58,7 @@ export default function UpOrDownNumberBlock({widgetMetaData, data}: StandardBloc return ( <> -
+
From fd5055e5023d3a9aceda6f06f62fcedfe40e5624 Mon Sep 17 00:00:00 2001 From: Darin Kelkhoff Date: Wed, 4 Sep 2024 20:00:10 -0500 Subject: [PATCH 9/9] Update versions for release --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 21202d5..7b0e226 100644 --- a/pom.xml +++ b/pom.xml @@ -29,7 +29,7 @@ jar - 0.22.0-SNAPSHOT + 0.22.0 UTF-8 UTF-8