mirror of
https://github.com/Kingsrook/qqq-frontend-material-dashboard.git
synced 2025-07-18 05:10:45 +00:00
Adding possible-value dropdowns to forms and filters
This commit is contained in:
320
src/qqq/pages/entity-list/QGridFilterOperators.tsx
Normal file
320
src/qqq/pages/entity-list/QGridFilterOperators.tsx
Normal file
@ -0,0 +1,320 @@
|
||||
/*
|
||||
* QQQ - Low-code Application Framework for Engineers.
|
||||
* Copyright (C) 2021-2022. Kingsrook, LLC
|
||||
* 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States
|
||||
* contact@kingsrook.com
|
||||
* https://github.com/Kingsrook/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import {QFieldMetaData} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QFieldMetaData";
|
||||
import {QPossibleValue} from "@kingsrook/qqq-frontend-core/lib/model/QPossibleValue";
|
||||
import {TextFieldProps} from "@mui/material";
|
||||
import Box from "@mui/material/Box";
|
||||
import Icon from "@mui/material/Icon";
|
||||
import TextField from "@mui/material/TextField";
|
||||
import {getGridNumericOperators, getGridStringOperators, GridColDef, GridFilterInputValueProps, GridFilterItem} from "@mui/x-data-grid-pro";
|
||||
import {GridFilterInputValue} from "@mui/x-data-grid/components/panel/filterPanel/GridFilterInputValue";
|
||||
import {GridApiCommunity} from "@mui/x-data-grid/internals";
|
||||
import {GridFilterOperator} from "@mui/x-data-grid/models/gridFilterOperator";
|
||||
import React, {useEffect, useRef, useState} from "react";
|
||||
import QDynamicSelect from "qqq/components/QDynamicSelect/QDynamicSelect";
|
||||
|
||||
//////////////////////
|
||||
// string operators //
|
||||
//////////////////////
|
||||
const stringNotEqualsOperator: GridFilterOperator = {
|
||||
label: "does not equal",
|
||||
value: "isNot",
|
||||
getApplyFilterFn: () => null,
|
||||
// @ts-ignore
|
||||
InputComponent: GridFilterInputValue,
|
||||
};
|
||||
|
||||
const stringNotContainsOperator: GridFilterOperator = {
|
||||
label: "does not contain",
|
||||
value: "notContains",
|
||||
getApplyFilterFn: () => null,
|
||||
// @ts-ignore
|
||||
InputComponent: GridFilterInputValue,
|
||||
};
|
||||
|
||||
const stringNotStartsWithOperator: GridFilterOperator = {
|
||||
label: "does not start with",
|
||||
value: "notStartsWith",
|
||||
getApplyFilterFn: () => null,
|
||||
// @ts-ignore
|
||||
InputComponent: GridFilterInputValue,
|
||||
};
|
||||
|
||||
const stringNotEndWithOperator: GridFilterOperator = {
|
||||
label: "does not end with",
|
||||
value: "notEndsWith",
|
||||
getApplyFilterFn: () => null,
|
||||
// @ts-ignore
|
||||
InputComponent: GridFilterInputValue,
|
||||
};
|
||||
|
||||
let gridStringOperators = getGridStringOperators();
|
||||
let equals = gridStringOperators.splice(1, 1)[0];
|
||||
let contains = gridStringOperators.splice(0, 1)[0];
|
||||
let startsWith = gridStringOperators.splice(0, 1)[0];
|
||||
let endsWith = gridStringOperators.splice(0, 1)[0];
|
||||
gridStringOperators = [ equals, stringNotEqualsOperator, contains, stringNotContainsOperator, startsWith, stringNotStartsWithOperator, endsWith, stringNotEndWithOperator, ...gridStringOperators ];
|
||||
|
||||
export const QGridStringOperators = gridStringOperators;
|
||||
|
||||
|
||||
///////////////////////////////////////
|
||||
// input element for numbers-between //
|
||||
///////////////////////////////////////
|
||||
function InputNumberInterval(props: GridFilterInputValueProps)
|
||||
{
|
||||
const SUBMIT_FILTER_STROKE_TIME = 500;
|
||||
const {item, applyValue, focusElementRef = null} = props;
|
||||
|
||||
const filterTimeout = useRef<any>();
|
||||
const [ filterValueState, setFilterValueState ] = useState<[ string, string ]>(
|
||||
item.value ?? "",
|
||||
);
|
||||
const [ applying, setIsApplying ] = useState(false);
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
return () =>
|
||||
{
|
||||
clearTimeout(filterTimeout.current);
|
||||
};
|
||||
}, []);
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
const itemValue = item.value ?? [ undefined, undefined ];
|
||||
setFilterValueState(itemValue);
|
||||
}, [ item.value ]);
|
||||
|
||||
const updateFilterValue = (lowerBound: string, upperBound: string) =>
|
||||
{
|
||||
clearTimeout(filterTimeout.current);
|
||||
setFilterValueState([ lowerBound, upperBound ]);
|
||||
|
||||
setIsApplying(true);
|
||||
filterTimeout.current = setTimeout(() =>
|
||||
{
|
||||
setIsApplying(false);
|
||||
applyValue({...item, value: [ lowerBound, upperBound ]});
|
||||
}, SUBMIT_FILTER_STROKE_TIME);
|
||||
};
|
||||
|
||||
const handleUpperFilterChange: TextFieldProps["onChange"] = (event) =>
|
||||
{
|
||||
const newUpperBound = event.target.value;
|
||||
updateFilterValue(filterValueState[0], newUpperBound);
|
||||
};
|
||||
const handleLowerFilterChange: TextFieldProps["onChange"] = (event) =>
|
||||
{
|
||||
const newLowerBound = event.target.value;
|
||||
updateFilterValue(newLowerBound, filterValueState[1]);
|
||||
};
|
||||
|
||||
return (
|
||||
<Box
|
||||
sx={{
|
||||
display: "inline-flex",
|
||||
flexDirection: "row",
|
||||
alignItems: "end",
|
||||
height: 48,
|
||||
pl: "20px",
|
||||
}}
|
||||
>
|
||||
<TextField
|
||||
name="lower-bound-input"
|
||||
placeholder="From"
|
||||
label="From"
|
||||
variant="standard"
|
||||
value={Number(filterValueState[0])}
|
||||
onChange={handleLowerFilterChange}
|
||||
type="number"
|
||||
inputRef={focusElementRef}
|
||||
sx={{mr: 2}}
|
||||
/>
|
||||
<TextField
|
||||
name="upper-bound-input"
|
||||
placeholder="To"
|
||||
label="To"
|
||||
variant="standard"
|
||||
value={Number(filterValueState[1])}
|
||||
onChange={handleUpperFilterChange}
|
||||
type="number"
|
||||
InputProps={applying ? {endAdornment: <Icon>sync</Icon>} : {}}
|
||||
/>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
//////////////////////
|
||||
// number operators //
|
||||
//////////////////////
|
||||
const betweenOperator: GridFilterOperator = {
|
||||
label: "is between",
|
||||
value: "between",
|
||||
getApplyFilterFn: () => null,
|
||||
// @ts-ignore
|
||||
InputComponent: InputNumberInterval
|
||||
};
|
||||
|
||||
const notBetweenOperator: GridFilterOperator = {
|
||||
label: "is not between",
|
||||
value: "notBetween",
|
||||
getApplyFilterFn: () => null,
|
||||
// @ts-ignore
|
||||
InputComponent: InputNumberInterval
|
||||
};
|
||||
|
||||
export const QGridNumericOperators = [ ...getGridNumericOperators(), betweenOperator, notBetweenOperator ];
|
||||
|
||||
|
||||
///////////////////////
|
||||
// boolean operators //
|
||||
///////////////////////
|
||||
const booleanTrueOperator: GridFilterOperator = {
|
||||
label: "is yes",
|
||||
value: "isTrue",
|
||||
getApplyFilterFn: (filterItem: GridFilterItem, column: GridColDef) => null
|
||||
};
|
||||
|
||||
const booleanFalseOperator: GridFilterOperator = {
|
||||
label: "is no",
|
||||
value: "isFalse",
|
||||
getApplyFilterFn: (filterItem: GridFilterItem, column: GridColDef) => null
|
||||
};
|
||||
|
||||
const booleanEmptyOperator: GridFilterOperator = {
|
||||
label: "is empty",
|
||||
value: "isEmpty",
|
||||
getApplyFilterFn: (filterItem: GridFilterItem, column: GridColDef) => null
|
||||
};
|
||||
|
||||
const booleanNotEmptyOperator: GridFilterOperator = {
|
||||
label: "is not empty",
|
||||
value: "isNotEmpty",
|
||||
getApplyFilterFn: (filterItem: GridFilterItem, column: GridColDef) => null
|
||||
};
|
||||
|
||||
export const QGridBooleanOperators = [ booleanTrueOperator, booleanFalseOperator, booleanEmptyOperator, booleanNotEmptyOperator ];
|
||||
|
||||
|
||||
///////////////////////////////////////
|
||||
// input element for possible values //
|
||||
///////////////////////////////////////
|
||||
function InputPossibleValueSourceSingle(tableName: string, field: QFieldMetaData, props: GridFilterInputValueProps)
|
||||
{
|
||||
const SUBMIT_FILTER_STROKE_TIME = 500;
|
||||
const {item, applyValue, focusElementRef = null} = props;
|
||||
|
||||
console.log("Item.value? " + item.value);
|
||||
|
||||
const filterTimeout = useRef<any>();
|
||||
const [ filterValueState, setFilterValueState ] = useState<any>(item.value ?? null);
|
||||
const [ selectedPossibleValue, setSelectedPossibleValue ] = useState((item.value ?? null) as QPossibleValue);
|
||||
const [ applying, setIsApplying ] = useState(false);
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
return () =>
|
||||
{
|
||||
clearTimeout(filterTimeout.current);
|
||||
};
|
||||
}, []);
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
const itemValue = item.value ?? null;
|
||||
setFilterValueState(itemValue);
|
||||
}, [ item.value ]);
|
||||
|
||||
const updateFilterValue = (value: QPossibleValue) =>
|
||||
{
|
||||
clearTimeout(filterTimeout.current);
|
||||
setFilterValueState(value);
|
||||
|
||||
setIsApplying(true);
|
||||
filterTimeout.current = setTimeout(() =>
|
||||
{
|
||||
setIsApplying(false);
|
||||
applyValue({...item, value: value});
|
||||
}, SUBMIT_FILTER_STROKE_TIME);
|
||||
};
|
||||
|
||||
const handleChange = (value: QPossibleValue) =>
|
||||
{
|
||||
updateFilterValue(value);
|
||||
};
|
||||
|
||||
return (
|
||||
<Box
|
||||
sx={{
|
||||
display: "inline-flex",
|
||||
flexDirection: "row",
|
||||
alignItems: "end",
|
||||
height: 48,
|
||||
}}
|
||||
>
|
||||
<QDynamicSelect
|
||||
tableName={tableName}
|
||||
fieldName={field.name}
|
||||
fieldLabel="Value"
|
||||
initialValue={selectedPossibleValue?.id}
|
||||
initialDisplayValue={selectedPossibleValue?.label}
|
||||
inForm={false}
|
||||
onChange={handleChange}
|
||||
// InputProps={applying ? {endAdornment: <Icon>sync</Icon>} : {}}
|
||||
/>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////
|
||||
// possible value set operators //
|
||||
//////////////////////////////////
|
||||
export const buildQGridPvsOperators = (tableName: string, field: QFieldMetaData): GridFilterOperator[] =>
|
||||
{
|
||||
return ([
|
||||
{
|
||||
label: "is",
|
||||
value: "is",
|
||||
getApplyFilterFn: () => null,
|
||||
InputComponent: (props: GridFilterInputValueProps<GridApiCommunity>) => InputPossibleValueSourceSingle(tableName, field, props)
|
||||
},
|
||||
{
|
||||
label: "is not",
|
||||
value: "isNot",
|
||||
getApplyFilterFn: () => null,
|
||||
InputComponent: (props: GridFilterInputValueProps<GridApiCommunity>) => InputPossibleValueSourceSingle(tableName, field, props)
|
||||
},
|
||||
{
|
||||
label: "is empty",
|
||||
value: "isEmpty",
|
||||
getApplyFilterFn: (filterItem: GridFilterItem, column: GridColDef) => null
|
||||
},
|
||||
{
|
||||
label: "is not empty",
|
||||
value: "isNotEmpty",
|
||||
getApplyFilterFn: (filterItem: GridFilterItem, column: GridColDef) => null
|
||||
}
|
||||
]);
|
||||
};
|
@ -21,7 +21,6 @@
|
||||
|
||||
import {AdornmentType} from "@kingsrook/qqq-frontend-core/lib/model/metaData/AdornmentType";
|
||||
import {QFieldType} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QFieldType";
|
||||
import {QInstance} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QInstance";
|
||||
import {QProcessMetaData} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QProcessMetaData";
|
||||
import {QTableMetaData} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QTableMetaData";
|
||||
import {QRecord} from "@kingsrook/qqq-frontend-core/lib/model/QRecord";
|
||||
@ -39,14 +38,16 @@ import Menu from "@mui/material/Menu";
|
||||
import MenuItem from "@mui/material/MenuItem";
|
||||
import Modal from "@mui/material/Modal";
|
||||
import {
|
||||
DataGridPro, getGridDateOperators, getGridNumericOperators, getGridStringOperators,
|
||||
DataGridPro,
|
||||
getGridDateOperators,
|
||||
getGridNumericOperators,
|
||||
GridCallbackDetails,
|
||||
GridColDef,
|
||||
GridColumnOrderChangeParams,
|
||||
GridColumnVisibilityModel,
|
||||
GridExportMenuItemProps,
|
||||
GridFilterItem,
|
||||
GridFilterModel,
|
||||
GridLinkOperator,
|
||||
GridRowId,
|
||||
GridRowParams,
|
||||
GridRowsProp,
|
||||
@ -70,6 +71,7 @@ import Navbar from "qqq/components/Navbar";
|
||||
import {QActionsMenuButton, QCreateNewButton} from "qqq/components/QButtons";
|
||||
import MDAlert from "qqq/components/Temporary/MDAlert";
|
||||
import MDBox from "qqq/components/Temporary/MDBox";
|
||||
import {buildQGridPvsOperators, QGridBooleanOperators, QGridNumericOperators, QGridStringOperators} from "qqq/pages/entity-list/QGridFilterOperators";
|
||||
import ProcessRun from "qqq/pages/process-run";
|
||||
import QClient from "qqq/utils/QClient";
|
||||
import QFilterUtils from "qqq/utils/QFilterUtils";
|
||||
@ -92,11 +94,13 @@ EntityList.defaultProps = {
|
||||
launchProcess: null
|
||||
};
|
||||
|
||||
const qController = QClient.getInstance();
|
||||
|
||||
/*******************************************************************************
|
||||
** Get the default filter to use on the page - either from query string, or
|
||||
** local storage, or a default (empty).
|
||||
*******************************************************************************/
|
||||
function getDefaultFilter(tableMetaData: QTableMetaData, searchParams: URLSearchParams, filterLocalStorageKey: string): GridFilterModel
|
||||
async function getDefaultFilter(tableMetaData: QTableMetaData, searchParams: URLSearchParams, filterLocalStorageKey: string): Promise<GridFilterModel>
|
||||
{
|
||||
if (tableMetaData.fields !== undefined)
|
||||
{
|
||||
@ -111,16 +115,39 @@ function getDefaultFilter(tableMetaData: QTableMetaData, searchParams: URLSearch
|
||||
//////////////////////////////////////////////////////////////////
|
||||
const defaultFilter = {items: []} as GridFilterModel;
|
||||
let id = 1;
|
||||
qQueryFilter.criteria.forEach((criteria) =>
|
||||
|
||||
for(let i = 0; i < qQueryFilter.criteria.length; i++)
|
||||
{
|
||||
const fieldType = tableMetaData.fields.get(criteria.fieldName).type;
|
||||
const criteria = qQueryFilter.criteria[i];
|
||||
const field = tableMetaData.fields.get(criteria.fieldName);
|
||||
let values = criteria.values;
|
||||
if(field.possibleValueSourceName)
|
||||
{
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// possible-values in query-string are expected to only be their id values. //
|
||||
// e.g., ...values=[1]... //
|
||||
// but we need them to be possibleValue objects (w/ id & label) so the label //
|
||||
// can be shown in the filter dropdown. So, make backend call to look them up. //
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
if(values && values.length > 0)
|
||||
{
|
||||
values = await qController.possibleValues(tableMetaData.name, field.name, "", values);
|
||||
}
|
||||
}
|
||||
|
||||
defaultFilter.items.push({
|
||||
columnField: criteria.fieldName,
|
||||
operatorValue: QFilterUtils.qqqCriteriaOperatorToGrid(criteria.operator, fieldType, criteria.values),
|
||||
value: QFilterUtils.qqqCriteriaValuesToGrid(criteria.operator, criteria.values, fieldType),
|
||||
operatorValue: QFilterUtils.qqqCriteriaOperatorToGrid(criteria.operator, field, values),
|
||||
value: QFilterUtils.qqqCriteriaValuesToGrid(criteria.operator, values, field),
|
||||
id: id++, // not sure what this id is!!
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
defaultFilter.linkOperator = GridLinkOperator.And;
|
||||
if(qQueryFilter.booleanOperator === "OR")
|
||||
{
|
||||
defaultFilter.linkOperator = GridLinkOperator.Or;
|
||||
}
|
||||
|
||||
return (defaultFilter);
|
||||
}
|
||||
@ -145,7 +172,6 @@ function EntityList({table, launchProcess}: Props): JSX.Element
|
||||
{
|
||||
const tableName = table.name;
|
||||
const [searchParams] = useSearchParams();
|
||||
const qController = QClient.getInstance();
|
||||
|
||||
const location = useLocation();
|
||||
const navigate = useNavigate();
|
||||
@ -270,8 +296,11 @@ function EntityList({table, launchProcess}: Props): JSX.Element
|
||||
setActiveModalProcess(null);
|
||||
}, [location]);
|
||||
|
||||
const buildQFilter = () =>
|
||||
const buildQFilter = (filterModel: GridFilterModel) =>
|
||||
{
|
||||
console.log("Building q filter with model:");
|
||||
console.log(filterModel);
|
||||
|
||||
const qFilter = new QQueryFilter();
|
||||
if (columnSortModel)
|
||||
{
|
||||
@ -280,6 +309,7 @@ function EntityList({table, launchProcess}: Props): JSX.Element
|
||||
qFilter.addOrderBy(new QFilterOrderBy(gridSortItem.field, gridSortItem.sort === "asc"));
|
||||
});
|
||||
}
|
||||
|
||||
if (filterModel)
|
||||
{
|
||||
filterModel.items.forEach((item) =>
|
||||
@ -288,6 +318,15 @@ function EntityList({table, launchProcess}: Props): JSX.Element
|
||||
const values = QFilterUtils.gridCriteriaValueToQQQ(operator, item.value, item.operatorValue);
|
||||
qFilter.addCriteria(new QFilterCriteria(item.columnField, operator, values));
|
||||
});
|
||||
|
||||
qFilter.booleanOperator = "AND";
|
||||
if(filterModel.linkOperator == "or")
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// by default qFilter uses AND - so only if we see linkOperator=or do we need to set it //
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
qFilter.booleanOperator = "OR";
|
||||
}
|
||||
}
|
||||
|
||||
return qFilter;
|
||||
@ -307,10 +346,12 @@ function EntityList({table, launchProcess}: Props): JSX.Element
|
||||
// because we need to know field types to translate qqq filter to material filter //
|
||||
// return here ane wait for the next 'turn' to allow doing the actual query //
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
let localFilterModel = filterModel;
|
||||
if (!defaultFilterLoaded)
|
||||
{
|
||||
setDefaultFilterLoaded(true);
|
||||
setFilterModel(getDefaultFilter(tableMetaData, searchParams, filterLocalStorageKey));
|
||||
localFilterModel = await getDefaultFilter(tableMetaData, searchParams, filterLocalStorageKey)
|
||||
setFilterModel(localFilterModel);
|
||||
return;
|
||||
}
|
||||
setTableMetaData(tableMetaData);
|
||||
@ -325,7 +366,7 @@ function EntityList({table, launchProcess}: Props): JSX.Element
|
||||
}
|
||||
setPinnedColumns({left: ["__check__", tableMetaData.primaryKeyField]});
|
||||
|
||||
const qFilter = buildQFilter();
|
||||
const qFilter = buildQFilter(localFilterModel);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// assign a new query id to the query being issued here. then run both the count & query async //
|
||||
@ -394,58 +435,6 @@ function EntityList({table, launchProcess}: Props): JSX.Element
|
||||
delete countResults[latestQueryId];
|
||||
}, [receivedCountTimestamp]);
|
||||
|
||||
const betweenOperator =
|
||||
{
|
||||
label: "Between",
|
||||
value: "between",
|
||||
getApplyFilterFn: (filterItem: GridFilterItem) =>
|
||||
{
|
||||
if (!Array.isArray(filterItem.value) || filterItem.value.length !== 2)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if (filterItem.value[0] == null || filterItem.value[1] == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
return ({value}) =>
|
||||
{
|
||||
return (value !== null && filterItem.value[0] <= value && value <= filterItem.value[1]);
|
||||
};
|
||||
},
|
||||
// InputComponent: InputNumberInterval,
|
||||
};
|
||||
|
||||
const booleanTrueOperator: GridFilterOperator = {
|
||||
label: "is yes",
|
||||
value: "isTrue",
|
||||
getApplyFilterFn: (filterItem: GridFilterItem, column: GridColDef) => null
|
||||
};
|
||||
|
||||
const booleanFalseOperator: GridFilterOperator = {
|
||||
label: "is no",
|
||||
value: "isFalse",
|
||||
getApplyFilterFn: (filterItem: GridFilterItem, column: GridColDef) => null
|
||||
};
|
||||
|
||||
const booleanEmptyOperator: GridFilterOperator = {
|
||||
label: "is empty",
|
||||
value: "isEmpty",
|
||||
getApplyFilterFn: (filterItem: GridFilterItem, column: GridColDef) => null
|
||||
};
|
||||
|
||||
const booleanNotEmptyOperator: GridFilterOperator = {
|
||||
label: "is not empty",
|
||||
value: "isNotEmpty",
|
||||
getApplyFilterFn: (filterItem: GridFilterItem, column: GridColDef) => null
|
||||
};
|
||||
|
||||
const getCustomGridBooleanOperators = (): GridFilterOperator[] =>
|
||||
{
|
||||
return [booleanTrueOperator, booleanFalseOperator, booleanEmptyOperator, booleanNotEmptyOperator];
|
||||
};
|
||||
|
||||
///////////////////////////
|
||||
// display query results //
|
||||
@ -503,11 +492,11 @@ function EntityList({table, launchProcess}: Props): JSX.Element
|
||||
|
||||
let columnType = "string";
|
||||
let columnWidth = 200;
|
||||
let filterOperators: GridFilterOperator<any>[] = getGridStringOperators();
|
||||
let filterOperators: GridFilterOperator<any>[] = QGridStringOperators;
|
||||
|
||||
if (field.possibleValueSourceName)
|
||||
{
|
||||
filterOperators = getGridNumericOperators();
|
||||
filterOperators = buildQGridPvsOperators(tableName, field);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -523,8 +512,7 @@ function EntityList({table, launchProcess}: Props): JSX.Element
|
||||
columnWidth = 75;
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
filterOperators = getGridNumericOperators();
|
||||
filterOperators = QGridNumericOperators;
|
||||
break;
|
||||
case QFieldType.DATE:
|
||||
columnType = "date";
|
||||
@ -539,7 +527,7 @@ function EntityList({table, launchProcess}: Props): JSX.Element
|
||||
case QFieldType.BOOLEAN:
|
||||
columnType = "string"; // using boolean gives an odd 'no' for nulls.
|
||||
columnWidth = 75;
|
||||
filterOperators = getCustomGridBooleanOperators();
|
||||
filterOperators = QGridBooleanOperators;
|
||||
break;
|
||||
default:
|
||||
// noop - leave as string
|
||||
@ -549,33 +537,20 @@ function EntityList({table, launchProcess}: Props): JSX.Element
|
||||
if (field.hasAdornment(AdornmentType.SIZE))
|
||||
{
|
||||
const sizeAdornment = field.getAdornment(AdornmentType.SIZE);
|
||||
const width = sizeAdornment.getValue("width");
|
||||
switch (width)
|
||||
const width: string = sizeAdornment.getValue("width");
|
||||
const widths: Map<string, number> = new Map<string, number>([
|
||||
["small", 100],
|
||||
["medium", 200],
|
||||
["large", 400],
|
||||
["xlarge", 600]
|
||||
]);
|
||||
if(widths.has(width))
|
||||
{
|
||||
case "small":
|
||||
{
|
||||
columnWidth = 100;
|
||||
break;
|
||||
}
|
||||
case "medium":
|
||||
{
|
||||
columnWidth = 200;
|
||||
break;
|
||||
}
|
||||
case "large":
|
||||
{
|
||||
columnWidth = 400;
|
||||
break;
|
||||
}
|
||||
case "xlarge":
|
||||
{
|
||||
columnWidth = 600;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
console.log("Unrecognized size.width adornment value: " + width);
|
||||
}
|
||||
columnWidth = widths.get(width);
|
||||
}
|
||||
else
|
||||
{
|
||||
console.log("Unrecognized size.width adornment value: " + width);
|
||||
}
|
||||
}
|
||||
|
||||
@ -814,7 +789,7 @@ function EntityList({table, launchProcess}: Props): JSX.Element
|
||||
const d = new Date();
|
||||
const dateString = `${d.getFullYear()}-${zp(d.getMonth())}-${zp(d.getDate())} ${zp(d.getHours())}${zp(d.getMinutes())}`;
|
||||
const filename = `${tableMetaData.label} Export ${dateString}.${format}`;
|
||||
const url = `/data/${tableMetaData.name}/export/${filename}?filter=${encodeURIComponent(JSON.stringify(buildQFilter()))}&fields=${visibleFields.join(",")}`;
|
||||
const url = `/data/${tableMetaData.name}/export/${filename}?filter=${encodeURIComponent(JSON.stringify(buildQFilter(filterModel)))}&fields=${visibleFields.join(",")}`;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
// open a window (tab) with a little page that says the file is being generated. //
|
||||
@ -864,7 +839,7 @@ function EntityList({table, launchProcess}: Props): JSX.Element
|
||||
{
|
||||
if (selectFullFilterState === "filter")
|
||||
{
|
||||
return `?recordsParam=filterJSON&filterJSON=${JSON.stringify(buildQFilter())}`;
|
||||
return `?recordsParam=filterJSON&filterJSON=${JSON.stringify(buildQFilter(filterModel))}`;
|
||||
}
|
||||
|
||||
if (selectedIds.length > 0)
|
||||
@ -879,7 +854,7 @@ function EntityList({table, launchProcess}: Props): JSX.Element
|
||||
{
|
||||
if (selectFullFilterState === "filter")
|
||||
{
|
||||
return (buildQFilter());
|
||||
return (buildQFilter(filterModel));
|
||||
}
|
||||
|
||||
if (selectedIds.length > 0)
|
||||
|
Reference in New Issue
Block a user