mirror of
https://github.com/Kingsrook/qqq-frontend-material-dashboard.git
synced 2025-07-17 21:00:45 +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);
|
||||
}}
|
||||
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)
|
||||
{
|
||||
|
@ -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(","))
|
||||
|
@ -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++;
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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>
|
||||
<b>{fieldLabel}</b> {FilterUtils.operatorToHumanString(criteria, field)} <span style={{color: "#0062FF"}}>{valuesString}</span>
|
||||
</>);
|
||||
}
|
||||
else
|
||||
{
|
||||
return (`${fieldLabel} ${FilterUtils.operatorToHumanString(criteria)} ${valuesString}`);
|
||||
return (`${fieldLabel} ${FilterUtils.operatorToHumanString(criteria, field)} ${valuesString}`);
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user