From 967c557a58c9482ea7a6d4d0cb3e11a4a345fe47 Mon Sep 17 00:00:00 2001 From: Darin Kelkhoff Date: Thu, 15 Feb 2024 20:21:47 -0600 Subject: [PATCH 1/3] CE-798 - fix typing 'o' bug in quick filters; add missing 'start of' in expression toString calls --- src/qqq/components/query/QuickFilter.tsx | 7 ++++++- src/qqq/utils/qqq/FilterUtils.tsx | 8 ++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/qqq/components/query/QuickFilter.tsx b/src/qqq/components/query/QuickFilter.tsx index 46c7b90..9023f7c 100644 --- a/src/qqq/components/query/QuickFilter.tsx +++ b/src/qqq/components/query/QuickFilter.tsx @@ -480,7 +480,12 @@ export default function QuickFilter({tableMetaData, fullFieldName, fieldMetaData ()} + //////////////////////////////////////////////////////////////////////////////////////////////////// + // ok, so, by default, if you type an 'o' as the first letter in the FilterCriteriaRowValues box, // + // something is causing THIS element to become selected, if the first letter in its label is 'O'. // + // ... work around is to put invisible ‌ entity as first character in label instead... // + //////////////////////////////////////////////////////////////////////////////////////////////////// + renderInput={(params) => (‌Operator} variant="standard" autoComplete="off" type="search" InputProps={{...params.InputProps}} />)} options={operatorOptions} value={operatorSelectedValue as any} inputValue={operatorInputValue} diff --git a/src/qqq/utils/qqq/FilterUtils.tsx b/src/qqq/utils/qqq/FilterUtils.tsx index 88ab5ea..ffdd398 100644 --- a/src/qqq/utils/qqq/FilterUtils.tsx +++ b/src/qqq/utils/qqq/FilterUtils.tsx @@ -64,7 +64,6 @@ class FilterUtils let rs = []; for (let i = 0; i < param.length; i++) { - console.log(param[i]); if (param[i] && param[i].id && param[i].label) { ///////////////////////////////////////////////////////////// @@ -361,7 +360,12 @@ class FilterUtils else if (value.type == "ThisOrLastPeriod") { const expression = new ThisOrLastPeriodExpression(value); - labels.push(expression.toString()); + let startOfPrefix = ""; + if(fieldMetaData.type == QFieldType.DATE_TIME || expression.timeUnit != "DAYS") + { + startOfPrefix = "start of "; + } + labels.push(`${startOfPrefix}${expression.toString()}`); } else if(fieldMetaData.type == QFieldType.BOOLEAN) { From 63479ba282728efd528423dfff6b0dbb949efed0 Mon Sep 17 00:00:00 2001 From: Darin Kelkhoff Date: Thu, 15 Feb 2024 20:24:05 -0600 Subject: [PATCH 2/3] CE-798 - Update to not change the criteria in the query (e.g., not fire a new query) until user clicks out of menu --- src/qqq/components/query/QuickFilter.tsx | 40 +++++++++++++++++++----- 1 file changed, 33 insertions(+), 7 deletions(-) diff --git a/src/qqq/components/query/QuickFilter.tsx b/src/qqq/components/query/QuickFilter.tsx index 9023f7c..7dbbdef 100644 --- a/src/qqq/components/query/QuickFilter.tsx +++ b/src/qqq/components/query/QuickFilter.tsx @@ -30,7 +30,7 @@ import Box from "@mui/material/Box"; import Button from "@mui/material/Button"; import Menu from "@mui/material/Menu"; import TextField from "@mui/material/TextField"; -import React, {SyntheticEvent, useContext, useState} from "react"; +import React, {SyntheticEvent, useContext, useReducer, useState} from "react"; import QContext from "QContext"; import {QFilterCriteriaWithId} from "qqq/components/query/CustomFilterPanel"; import {getDefaultCriteriaValue, getOperatorOptions, getValueModeRequiredCount, OperatorOption, validateCriteria} from "qqq/components/query/FilterCriteriaRow"; @@ -148,7 +148,10 @@ export default function QuickFilter({tableMetaData, fullFieldName, fieldMetaData const [anchorEl, setAnchorEl] = useState(null); const [isMouseOver, setIsMouseOver] = useState(false); - const [criteria, setCriteria] = useState(criteriaParamIsCriteria(criteriaParam) ? criteriaParam as QFilterCriteriaWithId : null); + //////////////////////////////////////////////////////////////////////////////////////////////////////// + // copy the criteriaParam to a new object in here - so changes won't apply until user closes the menu // + //////////////////////////////////////////////////////////////////////////////////////////////////////// + const [criteria, setCriteria] = useState(criteriaParamIsCriteria(criteriaParam) ? Object.assign({}, criteriaParam) as QFilterCriteriaWithId : null); const [id, setId] = useState(criteriaParamIsCriteria(criteriaParam) ? (criteriaParam as QFilterCriteriaWithId).id : ++seedId); const [operatorSelectedValue, setOperatorSelectedValue] = useState(getOperatorSelectedValue(operatorOptions, criteria, defaultOperator)); @@ -158,6 +161,11 @@ export default function QuickFilter({tableMetaData, fullFieldName, fieldMetaData const {accentColor} = useContext(QContext); + ////////////////////// + // ole' faithful... // + ////////////////////// + const [, forceUpdate] = useReducer((x) => x + 1, 0); + /******************************************************************************* ** @@ -182,7 +190,10 @@ export default function QuickFilter({tableMetaData, fullFieldName, fieldMetaData ////////////////////////////////////////////////////////////////////////////////////////////////////////////// if (criteriaParamIsCriteria(criteriaParam) && JSON.stringify(criteriaParam) !== JSON.stringify(criteria)) { - const newCriteria = criteriaParam as QFilterCriteriaWithId; + //////////////////////////////////////////////////////////////////////////////////////////////////////// + // copy the criteriaParam to a new object in here - so changes won't apply until user closes the menu // + //////////////////////////////////////////////////////////////////////////////////////////////////////// + const newCriteria = Object.assign({}, criteriaParam) as QFilterCriteriaWithId; setCriteria(newCriteria); const operatorOption = operatorOptions.filter(o => o.value == newCriteria.operator)[0]; setOperatorSelectedValue(operatorOption); @@ -191,6 +202,8 @@ export default function QuickFilter({tableMetaData, fullFieldName, fieldMetaData /******************************************************************************* ** Test if we need to construct a new criteria object + ** This is (at least for some cases) for when the criteria gets changed + ** from outside of this component - e.g., a reset on the query screen *******************************************************************************/ const criteriaNeedsReset = (): boolean => { @@ -199,6 +212,15 @@ export default function QuickFilter({tableMetaData, fullFieldName, fieldMetaData const defaultOperatorOption = operatorOptions.filter(o => o.value == defaultOperator)[0]; if(criteria.operator !== defaultOperatorOption?.value || JSON.stringify(criteria.values) !== JSON.stringify(getDefaultCriteriaValue())) { + if(isOpen) + { + ////////////////////////////////////////////////////////////////////////////////// + // this was firing too-often for case where: there was no criteria originally, // + // so, by adding this is-open check, we eliminated those. // + ////////////////////////////////////////////////////////////////////////////////// + return (false); + } + return (true); } } @@ -207,7 +229,7 @@ export default function QuickFilter({tableMetaData, fullFieldName, fieldMetaData } /******************************************************************************* - ** Construct a new criteria object - resetting the values tied to the oprator + ** Construct a new criteria object - resetting the values tied to the operator ** autocomplete at the same time. *******************************************************************************/ const makeNewCriteria = (): QFilterCriteria => @@ -241,6 +263,11 @@ export default function QuickFilter({tableMetaData, fullFieldName, fieldMetaData *******************************************************************************/ const closeMenu = () => { + ////////////////////////////////////////////////////////////////////////////////// + // when closing the menu, that's when we'll update the criteria from the caller // + ////////////////////////////////////////////////////////////////////////////////// + updateCriteria(criteria, false, false); + setIsOpen(false); setAnchorEl(null); }; @@ -285,8 +312,6 @@ export default function QuickFilter({tableMetaData, fullFieldName, fieldMetaData setOperatorSelectedValue(null); setOperatorInputValue(""); } - - updateCriteria(criteria, false, false); }; /******************************************************************************* @@ -320,7 +345,8 @@ export default function QuickFilter({tableMetaData, fullFieldName, fieldMetaData criteria.values[valueIndex] = value; } - updateCriteria(criteria, true, false); + setCriteria(criteria); + forceUpdate(); }; /******************************************************************************* From b137b3346d49d2e1ce09028f61211b5cdf2bb3d4 Mon Sep 17 00:00:00 2001 From: Darin Kelkhoff Date: Fri, 16 Feb 2024 10:09:42 -0600 Subject: [PATCH 3/3] CE-798 - A fix for last change here, where if criteria came from outside this component, then changing operator wouldn't take - another check of isOpen in some of the reset code. --- src/qqq/components/query/QuickFilter.tsx | 30 +++++++++++++++++------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/src/qqq/components/query/QuickFilter.tsx b/src/qqq/components/query/QuickFilter.tsx index 7dbbdef..5df73b2 100644 --- a/src/qqq/components/query/QuickFilter.tsx +++ b/src/qqq/components/query/QuickFilter.tsx @@ -190,14 +190,24 @@ export default function QuickFilter({tableMetaData, fullFieldName, fieldMetaData ////////////////////////////////////////////////////////////////////////////////////////////////////////////// if (criteriaParamIsCriteria(criteriaParam) && JSON.stringify(criteriaParam) !== JSON.stringify(criteria)) { - //////////////////////////////////////////////////////////////////////////////////////////////////////// - // copy the criteriaParam to a new object in here - so changes won't apply until user closes the menu // - //////////////////////////////////////////////////////////////////////////////////////////////////////// - const newCriteria = Object.assign({}, criteriaParam) as QFilterCriteriaWithId; - setCriteria(newCriteria); - const operatorOption = operatorOptions.filter(o => o.value == newCriteria.operator)[0]; - setOperatorSelectedValue(operatorOption); - setOperatorInputValue(operatorOption.label); + if(isOpen) + { + //////////////////////////////////////////////////////////////////////////////// + // this was firing too-often for case where: there was a criteria originally // + //////////////////////////////////////////////////////////////////////////////// + console.log("Not handling outside change (A), because dropdown is-open"); + } + else + { + //////////////////////////////////////////////////////////////////////////////////////////////////////// + // copy the criteriaParam to a new object in here - so changes won't apply until user closes the menu // + //////////////////////////////////////////////////////////////////////////////////////////////////////// + const newCriteria = Object.assign({}, criteriaParam) as QFilterCriteriaWithId; + setCriteria(newCriteria); + const operatorOption = operatorOptions.filter(o => o.value == newCriteria.operator)[0]; + setOperatorSelectedValue(operatorOption); + setOperatorInputValue(operatorOption.label); + } } /******************************************************************************* @@ -218,6 +228,7 @@ export default function QuickFilter({tableMetaData, fullFieldName, fieldMetaData // this was firing too-often for case where: there was no criteria originally, // // so, by adding this is-open check, we eliminated those. // ////////////////////////////////////////////////////////////////////////////////// + console.log("Not handling outside change (B), because dropdown is-open"); return (false); } @@ -312,6 +323,9 @@ export default function QuickFilter({tableMetaData, fullFieldName, fieldMetaData setOperatorSelectedValue(null); setOperatorInputValue(""); } + + setCriteria(criteria); + forceUpdate(); }; /*******************************************************************************