mirror of
https://github.com/Kingsrook/qqq-frontend-material-dashboard.git
synced 2025-07-18 13:20:43 +00:00
CE-793 - More cleanup from initial pre-qa qa (human words, values, expressions)
This commit is contained in:
@ -321,9 +321,14 @@ function DynamicSelect({tableName, processName, fieldName, overrideId, fieldLabe
|
|||||||
{
|
{
|
||||||
setOpen(false);
|
setOpen(false);
|
||||||
}}
|
}}
|
||||||
isOptionEqualToValue={(option, value) => option.id === value.id}
|
isOptionEqualToValue={(option, value) => value !== null && value !== undefined && option.id === value.id}
|
||||||
getOptionLabel={(option) =>
|
getOptionLabel={(option) =>
|
||||||
{
|
{
|
||||||
|
if(option === null || option === undefined)
|
||||||
|
{
|
||||||
|
return ("");
|
||||||
|
}
|
||||||
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
if(option && option.length)
|
if(option && option.length)
|
||||||
{
|
{
|
||||||
|
@ -47,7 +47,6 @@ import FormData from "form-data";
|
|||||||
import React, {useEffect, useRef, useState} from "react";
|
import React, {useEffect, useRef, useState} from "react";
|
||||||
import {useLocation, useNavigate} from "react-router-dom";
|
import {useLocation, useNavigate} from "react-router-dom";
|
||||||
import {QCancelButton, QDeleteButton, QSaveButton, QSavedViewsMenuButton} from "qqq/components/buttons/DefaultButtons";
|
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 QQueryColumns from "qqq/models/query/QQueryColumns";
|
||||||
import RecordQueryView from "qqq/models/query/RecordQueryView";
|
import RecordQueryView from "qqq/models/query/RecordQueryView";
|
||||||
import FilterUtils from "qqq/utils/qqq/FilterUtils";
|
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(savedView.queryColumns, activeView.queryColumns, "Turned on ");
|
||||||
diffVisibilityFunction(activeView.queryColumns, savedView.queryColumns, "Turned off visibility for ");
|
diffVisibilityFunction(activeView.queryColumns, savedView.queryColumns, "Turned off ");
|
||||||
diffPinsFunction(savedView.queryColumns, activeView.queryColumns, "Changed pinned state for ");
|
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(","))
|
if(savedView.queryColumns.columns.map(c => c.name).join(",") != activeView.queryColumns.columns.map(c => c.name).join(","))
|
||||||
|
@ -347,7 +347,8 @@ const BasicAndAdvancedQueryControls = forwardRef((props: BasicAndAdvancedQueryCo
|
|||||||
<span>
|
<span>
|
||||||
{queryFilter.criteria.map((criteria, i) =>
|
{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);
|
const [field, fieldTable] = TableUtils.getFieldAndTable(tableMetaData, criteria.fieldName);
|
||||||
counter++;
|
counter++;
|
||||||
|
@ -53,6 +53,27 @@ export enum ValueMode
|
|||||||
PVS_MULTI = "PVS_MULTI",
|
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
|
export interface OperatorOption
|
||||||
{
|
{
|
||||||
label: string;
|
label: string;
|
||||||
@ -367,6 +388,24 @@ export function FilterCriteriaRow({id, index, tableMetaData, metaData, criteria,
|
|||||||
{
|
{
|
||||||
criteria.values = newValue.implicitValues;
|
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
|
else
|
||||||
{
|
{
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
|
|
||||||
import {QQueryFilter} from "@kingsrook/qqq-frontend-core/lib/model/query/QQueryFilter";
|
import {QQueryFilter} from "@kingsrook/qqq-frontend-core/lib/model/query/QQueryFilter";
|
||||||
import QQueryColumns, {PreLoadQueryColumns} from "qqq/models/query/QQueryColumns";
|
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;
|
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)
|
if(json.queryColumns)
|
||||||
{
|
{
|
||||||
view.queryColumns = QQueryColumns.buildFromJSON(json.queryColumns);
|
view.queryColumns = QQueryColumns.buildFromJSON(json.queryColumns);
|
||||||
|
@ -78,7 +78,6 @@ import TableUtils from "qqq/utils/qqq/TableUtils";
|
|||||||
import ValueUtils from "qqq/utils/qqq/ValueUtils";
|
import ValueUtils from "qqq/utils/qqq/ValueUtils";
|
||||||
|
|
||||||
const CURRENT_SAVED_VIEW_ID_LOCAL_STORAGE_KEY_ROOT = "qqq.currentSavedViewId";
|
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 DENSITY_LOCAL_STORAGE_KEY_ROOT = "qqq.density";
|
||||||
const VIEW_LOCAL_STORAGE_KEY_ROOT = "qqq.recordQueryView";
|
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 //
|
// look for defaults in the local storage //
|
||||||
////////////////////////////////////////////
|
////////////////////////////////////////////
|
||||||
const currentSavedViewLocalStorageKey = `${CURRENT_SAVED_VIEW_ID_LOCAL_STORAGE_KEY_ROOT}.${tableName}`;
|
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 tableVariantLocalStorageKey = `${TABLE_VARIANT_LOCAL_STORAGE_KEY_ROOT}.${tableName}`;
|
||||||
const viewLocalStorageKey = `${VIEW_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) //
|
// define some default values (e.g., to be used if nothing in local storage or no active view) //
|
||||||
/////////////////////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
let defaultSort = [] as GridSortItem[];
|
let defaultSort = [] as GridSortItem[];
|
||||||
let didDefaultVisibilityComeFromLocalStorage = false;
|
|
||||||
let defaultRowsPerPage = 10;
|
let defaultRowsPerPage = 10;
|
||||||
let defaultDensity = "standard" as GridDensity;
|
let defaultDensity = "standard" as GridDensity;
|
||||||
let seenJoinTables: {[tableName: string]: boolean} = {};
|
|
||||||
let defaultTableVariant: QTableVariant = null;
|
let defaultTableVariant: QTableVariant = null;
|
||||||
let defaultMode = "basic";
|
let defaultMode = "basic";
|
||||||
let defaultQueryColumns: QQueryColumns = new PreLoadQueryColumns();
|
let defaultQueryColumns: QQueryColumns = new PreLoadQueryColumns();
|
||||||
@ -188,10 +184,6 @@ function RecordQuery({table, launchProcess}: Props): JSX.Element
|
|||||||
{
|
{
|
||||||
defaultDensity = JSON.parse(localStorage.getItem(densityLocalStorageKey));
|
defaultDensity = JSON.parse(localStorage.getItem(densityLocalStorageKey));
|
||||||
}
|
}
|
||||||
if (localStorage.getItem(seenJoinTablesLocalStorageKey))
|
|
||||||
{
|
|
||||||
seenJoinTables = JSON.parse(localStorage.getItem(seenJoinTablesLocalStorageKey));
|
|
||||||
}
|
|
||||||
if (localStorage.getItem(tableVariantLocalStorageKey))
|
if (localStorage.getItem(tableVariantLocalStorageKey))
|
||||||
{
|
{
|
||||||
defaultTableVariant = JSON.parse(localStorage.getItem(tableVariantLocalStorageKey));
|
defaultTableVariant = JSON.parse(localStorage.getItem(tableVariantLocalStorageKey));
|
||||||
@ -719,6 +711,13 @@ function RecordQuery({table, launchProcess}: Props): JSX.Element
|
|||||||
{
|
{
|
||||||
if(pageState != "ready")
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -189,7 +189,7 @@ class FilterUtils
|
|||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
**
|
**
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
private static gridCriteriaValueToExpression(value: any)
|
public static gridCriteriaValueToExpression(value: any)
|
||||||
{
|
{
|
||||||
if (value && value.length)
|
if (value && value.length)
|
||||||
{
|
{
|
||||||
@ -311,6 +311,15 @@ class FilterUtils
|
|||||||
public static getValuesString(fieldMetaData: QFieldMetaData, criteria: QFilterCriteria, maxValuesToShow: number = 3): string
|
public static getValuesString(fieldMetaData: QFieldMetaData, criteria: QFilterCriteria, maxValuesToShow: number = 3): string
|
||||||
{
|
{
|
||||||
let valuesString = "";
|
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)
|
if (criteria.values && criteria.values.length)
|
||||||
{
|
{
|
||||||
let labels = [] as string[];
|
let labels = [] as string[];
|
||||||
@ -323,17 +332,41 @@ class FilterUtils
|
|||||||
|
|
||||||
for (let i = 0; i < maxLoops; i++)
|
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
|
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)
|
if(criteria == null || criteria.operator == null)
|
||||||
{
|
{
|
||||||
return (null);
|
return (null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const isDate = field.type == QFieldType.DATE;
|
||||||
|
const isDateTime = field.type == QFieldType.DATE_TIME;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
switch(criteria.operator)
|
switch(criteria.operator)
|
||||||
@ -428,17 +464,41 @@ class FilterUtils
|
|||||||
case QCriteriaOperator.NOT_CONTAINS:
|
case QCriteriaOperator.NOT_CONTAINS:
|
||||||
return ("does not contain");
|
return ("does not contain");
|
||||||
case QCriteriaOperator.LESS_THAN:
|
case QCriteriaOperator.LESS_THAN:
|
||||||
|
if(isDate || isDateTime)
|
||||||
|
{
|
||||||
|
return ("is before")
|
||||||
|
}
|
||||||
return ("less than");
|
return ("less than");
|
||||||
case QCriteriaOperator.LESS_THAN_OR_EQUALS:
|
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");
|
return ("less than or equals");
|
||||||
case QCriteriaOperator.GREATER_THAN:
|
case QCriteriaOperator.GREATER_THAN:
|
||||||
|
if(isDate || isDateTime)
|
||||||
|
{
|
||||||
|
return ("is after")
|
||||||
|
}
|
||||||
return ("greater than or equals");
|
return ("greater than or equals");
|
||||||
case QCriteriaOperator.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");
|
return ("greater than or equals");
|
||||||
case QCriteriaOperator.IS_BLANK:
|
case QCriteriaOperator.IS_BLANK:
|
||||||
return ("is blank");
|
return ("is empty");
|
||||||
case QCriteriaOperator.IS_NOT_BLANK:
|
case QCriteriaOperator.IS_NOT_BLANK:
|
||||||
return ("is not blank");
|
return ("is not empty");
|
||||||
case QCriteriaOperator.BETWEEN:
|
case QCriteriaOperator.BETWEEN:
|
||||||
return ("is between");
|
return ("is between");
|
||||||
case QCriteriaOperator.NOT_BETWEEN:
|
case QCriteriaOperator.NOT_BETWEEN:
|
||||||
@ -470,12 +530,12 @@ class FilterUtils
|
|||||||
if(styled)
|
if(styled)
|
||||||
{
|
{
|
||||||
return (<>
|
return (<>
|
||||||
<b>{fieldLabel}</b> {FilterUtils.operatorToHumanString(criteria)} <span style={{color: "#0062FF"}}>{valuesString}</span>
|
<b>{fieldLabel}</b> {FilterUtils.operatorToHumanString(criteria, field)} <span style={{color: "#0062FF"}}>{valuesString}</span>
|
||||||
</>);
|
</>);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return (`${fieldLabel} ${FilterUtils.operatorToHumanString(criteria)} ${valuesString}`);
|
return (`${fieldLabel} ${FilterUtils.operatorToHumanString(criteria, field)} ${valuesString}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user