CE-793 - More cleanup from initial pre-qa qa (human words, values, expressions)

This commit is contained in:
2024-01-31 09:46:59 -06:00
parent 3858b40c0f
commit f3ae5ee10b
7 changed files with 145 additions and 24 deletions

View File

@ -321,9 +321,14 @@ function DynamicSelect({tableName, processName, fieldName, overrideId, fieldLabe
{
setOpen(false);
}}
isOptionEqualToValue={(option, value) => option.id === value.id}
isOptionEqualToValue={(option, value) => value !== null && value !== undefined && option.id === value.id}
getOptionLabel={(option) =>
{
if(option === null || option === undefined)
{
return ("");
}
// @ts-ignore
if(option && option.length)
{

View File

@ -47,7 +47,6 @@ import FormData from "form-data";
import React, {useEffect, useRef, useState} from "react";
import {useLocation, useNavigate} from "react-router-dom";
import {QCancelButton, QDeleteButton, QSaveButton, QSavedViewsMenuButton} from "qqq/components/buttons/DefaultButtons";
import CustomWidthTooltip from "qqq/components/tooltips/CustomWidthTooltip";
import QQueryColumns from "qqq/models/query/QQueryColumns";
import RecordQueryView from "qqq/models/query/RecordQueryView";
import FilterUtils from "qqq/utils/qqq/FilterUtils";
@ -390,8 +389,8 @@ function SavedViews({qController, metaData, tableMetaData, currentSavedView, vie
}
};
diffVisibilityFunction(savedView.queryColumns, activeView.queryColumns, "Turned on visibility for ");
diffVisibilityFunction(activeView.queryColumns, savedView.queryColumns, "Turned off visibility for ");
diffVisibilityFunction(savedView.queryColumns, activeView.queryColumns, "Turned on ");
diffVisibilityFunction(activeView.queryColumns, savedView.queryColumns, "Turned off ");
diffPinsFunction(savedView.queryColumns, activeView.queryColumns, "Changed pinned state for ");
if(savedView.queryColumns.columns.map(c => c.name).join(",") != activeView.queryColumns.columns.map(c => c.name).join(","))

View File

@ -347,7 +347,8 @@ const BasicAndAdvancedQueryControls = forwardRef((props: BasicAndAdvancedQueryCo
<span>
{queryFilter.criteria.map((criteria, i) =>
{
if(criteria && criteria.fieldName && criteria.operator)
const {criteriaIsValid} = validateCriteria(criteria, null);
if(criteriaIsValid)
{
const [field, fieldTable] = TableUtils.getFieldAndTable(tableMetaData, criteria.fieldName);
counter++;

View File

@ -53,6 +53,27 @@ export enum ValueMode
PVS_MULTI = "PVS_MULTI",
}
const getValueModeRequiredCount = (valueMode: ValueMode): number =>
{
switch (valueMode)
{
case ValueMode.NONE:
return (0);
case ValueMode.SINGLE:
case ValueMode.SINGLE_DATE:
case ValueMode.SINGLE_DATE_TIME:
case ValueMode.PVS_SINGLE:
return (1);
case ValueMode.DOUBLE:
case ValueMode.DOUBLE_DATE:
case ValueMode.DOUBLE_DATE_TIME:
return (2);
case ValueMode.MULTI:
case ValueMode.PVS_MULTI:
return (null);
}
}
export interface OperatorOption
{
label: string;
@ -367,6 +388,24 @@ export function FilterCriteriaRow({id, index, tableMetaData, metaData, criteria,
{
criteria.values = newValue.implicitValues;
}
//////////////////////////////////////////////////////////////////////////////////////////////////
// we've seen cases where switching operators can sometimes put a null in as the first value... //
// that just causes a bad time (e.g., null pointers in Autocomplete), so, get rid of that. //
//////////////////////////////////////////////////////////////////////////////////////////////////
if(criteria.values && criteria.values.length == 1 && criteria.values[0] == null)
{
criteria.values = [];
}
if(newValue.valueMode)
{
const requiredValueCount = getValueModeRequiredCount(newValue.valueMode);
if(requiredValueCount != null && criteria.values.length > requiredValueCount)
{
criteria.values.splice(requiredValueCount);
}
}
}
else
{

View File

@ -21,6 +21,7 @@
import {QQueryFilter} from "@kingsrook/qqq-frontend-core/lib/model/query/QQueryFilter";
import QQueryColumns, {PreLoadQueryColumns} from "qqq/models/query/QQueryColumns";
import FilterUtils from "qqq/utils/qqq/FilterUtils";
/*******************************************************************************
@ -62,6 +63,23 @@ export default class RecordQueryView
view.queryFilter = json.queryFilter as QQueryFilter;
//////////////////////////////////////////////////////////////////////////////////////////
// it's important that some criteria values exist as expression objects - so - do that. //
//////////////////////////////////////////////////////////////////////////////////////////
for (let i = 0; i < view.queryFilter?.criteria?.length; i++)
{
const criteria = view.queryFilter.criteria[i]
for (let j = 0; j < criteria?.values?.length; j++)
{
const value = criteria.values[j];
const expression = FilterUtils.gridCriteriaValueToExpression(value);
if(expression)
{
criteria.values[j] = expression;
}
}
}
if(json.queryColumns)
{
view.queryColumns = QQueryColumns.buildFromJSON(json.queryColumns);

View File

@ -78,7 +78,6 @@ import TableUtils from "qqq/utils/qqq/TableUtils";
import ValueUtils from "qqq/utils/qqq/ValueUtils";
const CURRENT_SAVED_VIEW_ID_LOCAL_STORAGE_KEY_ROOT = "qqq.currentSavedViewId";
const SEEN_JOIN_TABLES_LOCAL_STORAGE_KEY_ROOT = "qqq.seenJoinTables";
const DENSITY_LOCAL_STORAGE_KEY_ROOT = "qqq.density";
const VIEW_LOCAL_STORAGE_KEY_ROOT = "qqq.recordQueryView";
@ -159,7 +158,6 @@ function RecordQuery({table, launchProcess}: Props): JSX.Element
// look for defaults in the local storage //
////////////////////////////////////////////
const currentSavedViewLocalStorageKey = `${CURRENT_SAVED_VIEW_ID_LOCAL_STORAGE_KEY_ROOT}.${tableName}`;
const seenJoinTablesLocalStorageKey = `${SEEN_JOIN_TABLES_LOCAL_STORAGE_KEY_ROOT}.${tableName}`;
const tableVariantLocalStorageKey = `${TABLE_VARIANT_LOCAL_STORAGE_KEY_ROOT}.${tableName}`;
const viewLocalStorageKey = `${VIEW_LOCAL_STORAGE_KEY_ROOT}.${tableName}`;
@ -167,10 +165,8 @@ function RecordQuery({table, launchProcess}: Props): JSX.Element
// define some default values (e.g., to be used if nothing in local storage or no active view) //
/////////////////////////////////////////////////////////////////////////////////////////////////
let defaultSort = [] as GridSortItem[];
let didDefaultVisibilityComeFromLocalStorage = false;
let defaultRowsPerPage = 10;
let defaultDensity = "standard" as GridDensity;
let seenJoinTables: {[tableName: string]: boolean} = {};
let defaultTableVariant: QTableVariant = null;
let defaultMode = "basic";
let defaultQueryColumns: QQueryColumns = new PreLoadQueryColumns();
@ -188,10 +184,6 @@ function RecordQuery({table, launchProcess}: Props): JSX.Element
{
defaultDensity = JSON.parse(localStorage.getItem(densityLocalStorageKey));
}
if (localStorage.getItem(seenJoinTablesLocalStorageKey))
{
seenJoinTables = JSON.parse(localStorage.getItem(seenJoinTablesLocalStorageKey));
}
if (localStorage.getItem(tableVariantLocalStorageKey))
{
defaultTableVariant = JSON.parse(localStorage.getItem(tableVariantLocalStorageKey));
@ -719,6 +711,13 @@ function RecordQuery({table, launchProcess}: Props): JSX.Element
{
if(pageState != "ready")
{
console.log(`In updateTable, but pageSate[${pageState}] is not ready, so returning with noop`);
return;
}
if(tableMetaData?.usesVariants && (!tableVariant || tableVariantPromptOpen))
{
console.log("In updateTable, but a variant is needed, so returning with noop");
return;
}

View File

@ -189,7 +189,7 @@ class FilterUtils
/*******************************************************************************
**
*******************************************************************************/
private static gridCriteriaValueToExpression(value: any)
public static gridCriteriaValueToExpression(value: any)
{
if (value && value.length)
{
@ -311,6 +311,15 @@ class FilterUtils
public static getValuesString(fieldMetaData: QFieldMetaData, criteria: QFilterCriteria, maxValuesToShow: number = 3): string
{
let valuesString = "";
if(criteria.operator == QCriteriaOperator.IS_BLANK || criteria.operator == QCriteriaOperator.IS_NOT_BLANK)
{
///////////////////////////////////////////////
// we don't want values for these operators. //
///////////////////////////////////////////////
return valuesString;
}
if (criteria.values && criteria.values.length)
{
let labels = [] as string[];
@ -323,17 +332,41 @@ class FilterUtils
for (let i = 0; i < maxLoops; i++)
{
if(fieldMetaData.type == QFieldType.BOOLEAN)
const value = criteria.values[i];
if (value.type == "NowWithOffset")
{
labels.push(criteria.values[i] == true ? "yes" : "no")
const expression = new NowWithOffsetExpression(value);
labels.push(expression.toString());
}
else if (criteria.values[i] && criteria.values[i].label)
else if (value.type == "Now")
{
labels.push(criteria.values[i].label);
const expression = new NowExpression(value);
labels.push(expression.toString());
}
else if (value.type == "ThisOrLastPeriod")
{
const expression = new ThisOrLastPeriodExpression(value);
labels.push(expression.toString());
}
else if(fieldMetaData.type == QFieldType.BOOLEAN)
{
labels.push(value == true ? "yes" : "no")
}
else if(fieldMetaData.type == QFieldType.DATE_TIME)
{
labels.push(ValueUtils.formatDateTime(value));
}
else if(fieldMetaData.type == QFieldType.DATE)
{
labels.push(ValueUtils.formatDate(value));
}
else if (value && value.label)
{
labels.push(value.label);
}
else
{
labels.push(criteria.values[i]);
labels.push(value);
}
}
@ -395,13 +428,16 @@ class FilterUtils
/*******************************************************************************
**
*******************************************************************************/
public static operatorToHumanString(criteria: QFilterCriteria): string
public static operatorToHumanString(criteria: QFilterCriteria, field: QFieldMetaData): string
{
if(criteria == null || criteria.operator == null)
{
return (null);
}
const isDate = field.type == QFieldType.DATE;
const isDateTime = field.type == QFieldType.DATE_TIME;
try
{
switch(criteria.operator)
@ -428,17 +464,41 @@ class FilterUtils
case QCriteriaOperator.NOT_CONTAINS:
return ("does not contain");
case QCriteriaOperator.LESS_THAN:
if(isDate || isDateTime)
{
return ("is before")
}
return ("less than");
case QCriteriaOperator.LESS_THAN_OR_EQUALS:
if(isDate)
{
return ("is on or before")
}
if(isDateTime)
{
return ("is at or before")
}
return ("less than or equals");
case QCriteriaOperator.GREATER_THAN:
if(isDate || isDateTime)
{
return ("is after")
}
return ("greater than or equals");
case QCriteriaOperator.GREATER_THAN_OR_EQUALS:
if(isDate)
{
return ("is on or after")
}
if(isDateTime)
{
return ("is at or after")
}
return ("greater than or equals");
case QCriteriaOperator.IS_BLANK:
return ("is blank");
return ("is empty");
case QCriteriaOperator.IS_NOT_BLANK:
return ("is not blank");
return ("is not empty");
case QCriteriaOperator.BETWEEN:
return ("is between");
case QCriteriaOperator.NOT_BETWEEN:
@ -470,12 +530,12 @@ class FilterUtils
if(styled)
{
return (<>
<b>{fieldLabel}</b> {FilterUtils.operatorToHumanString(criteria)} <span style={{color: "#0062FF"}}>{valuesString}</span>&nbsp;
<b>{fieldLabel}</b> {FilterUtils.operatorToHumanString(criteria, field)} <span style={{color: "#0062FF"}}>{valuesString}</span>&nbsp;
</>);
}
else
{
return (`${fieldLabel} ${FilterUtils.operatorToHumanString(criteria)} ${valuesString}`);
return (`${fieldLabel} ${FilterUtils.operatorToHumanString(criteria, field)} ${valuesString}`);
}
}