mirror of
https://github.com/Kingsrook/qqq-frontend-material-dashboard.git
synced 2025-07-17 21:00:45 +00:00
Merged feature/CE-1068-add-basic-functionality-of into integration/sprint-41
This commit is contained in:
@ -174,7 +174,8 @@ function QDynamicForm({formData, formLabel, bulkEditMode, bulkEditSwitchChangeHa
|
|||||||
<DynamicSelect
|
<DynamicSelect
|
||||||
tableName={field.possibleValueProps.tableName}
|
tableName={field.possibleValueProps.tableName}
|
||||||
processName={field.possibleValueProps.processName}
|
processName={field.possibleValueProps.processName}
|
||||||
fieldName={fieldName}
|
possibleValueSourceName={field.possibleValueProps.possibleValueSourceName}
|
||||||
|
fieldName={field.possibleValueProps.fieldName}
|
||||||
isEditable={field.isEditable}
|
isEditable={field.isEditable}
|
||||||
fieldLabel=""
|
fieldLabel=""
|
||||||
initialValue={values[fieldName]}
|
initialValue={values[fieldName]}
|
||||||
|
@ -172,6 +172,7 @@ class DynamicFormUtils
|
|||||||
{
|
{
|
||||||
isPossibleValue: true,
|
isPossibleValue: true,
|
||||||
tableName: tableName,
|
tableName: tableName,
|
||||||
|
fieldName: field.name,
|
||||||
initialDisplayValue: initialDisplayValue,
|
initialDisplayValue: initialDisplayValue,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -181,6 +182,7 @@ class DynamicFormUtils
|
|||||||
{
|
{
|
||||||
isPossibleValue: true,
|
isPossibleValue: true,
|
||||||
processName: processName,
|
processName: processName,
|
||||||
|
fieldName: field.name,
|
||||||
initialDisplayValue: initialDisplayValue,
|
initialDisplayValue: initialDisplayValue,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -190,6 +192,8 @@ class DynamicFormUtils
|
|||||||
{
|
{
|
||||||
isPossibleValue: true,
|
isPossibleValue: true,
|
||||||
initialDisplayValue: initialDisplayValue,
|
initialDisplayValue: initialDisplayValue,
|
||||||
|
fieldName: field.name,
|
||||||
|
possibleValueSourceName: field.possibleValueSourceName
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -124,19 +124,15 @@ function DynamicSelect({tableName, processName, fieldName, possibleValueSourceNa
|
|||||||
{
|
{
|
||||||
console.log("DynamicSelect - if you provide a processName, you must also provide a fieldName");
|
console.log("DynamicSelect - if you provide a processName, you must also provide a fieldName");
|
||||||
}
|
}
|
||||||
if(fieldName && possibleValueSourceName)
|
|
||||||
{
|
|
||||||
console.log("DynamicSelect - if you provide a fieldName and a possibleValueSourceName, the possibleValueSourceName will be ignored");
|
|
||||||
}
|
|
||||||
if(!fieldName && !possibleValueSourceName)
|
if(!fieldName && !possibleValueSourceName)
|
||||||
{
|
{
|
||||||
console.log("DynamicSelect - you must provide either a fieldName (and a tableName or processName) or a possibleValueSourceName");
|
console.log("DynamicSelect - you must provide either a fieldName (and a tableName or processName) or a possibleValueSourceName");
|
||||||
}
|
}
|
||||||
if(fieldName)
|
if(fieldName && !possibleValueSourceName)
|
||||||
{
|
{
|
||||||
if(!tableName || !processName)
|
if(!tableName || !processName)
|
||||||
{
|
{
|
||||||
console.log("DynamicSelect - if you provide a fieldName, you must also provide a tableName or processName");
|
console.log("DynamicSelect - if you provide a fieldName and not a possibleValueSourceName, then you must also provide a tableName or processName");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(possibleValueSourceName)
|
if(possibleValueSourceName)
|
||||||
@ -198,7 +194,7 @@ function DynamicSelect({tableName, processName, fieldName, possibleValueSourceNa
|
|||||||
(async () =>
|
(async () =>
|
||||||
{
|
{
|
||||||
// console.log(`doing a search with ${searchTerm}`);
|
// console.log(`doing a search with ${searchTerm}`);
|
||||||
const results: QPossibleValue[] = await qController.possibleValues(tableName, processName, fieldName ?? possibleValueSourceName, searchTerm ?? "", null, otherValues);
|
const results: QPossibleValue[] = await qController.possibleValues(tableName, processName, possibleValueSourceName ?? fieldName, searchTerm ?? "", null, otherValues);
|
||||||
|
|
||||||
if(tableMetaData == null && tableName)
|
if(tableMetaData == null && tableName)
|
||||||
{
|
{
|
||||||
@ -231,7 +227,7 @@ function DynamicSelect({tableName, processName, fieldName, possibleValueSourceNa
|
|||||||
setLoading(true);
|
setLoading(true);
|
||||||
setOptions([]);
|
setOptions([]);
|
||||||
console.log("Refreshing possible values...");
|
console.log("Refreshing possible values...");
|
||||||
const results: QPossibleValue[] = await qController.possibleValues(tableName, processName, fieldName ?? possibleValueSourceName, searchTerm ?? "", null, otherValues);
|
const results: QPossibleValue[] = await qController.possibleValues(tableName, processName, possibleValueSourceName ?? fieldName, searchTerm ?? "", null, otherValues);
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
setOptions([ ...results ]);
|
setOptions([ ...results ]);
|
||||||
setOtherValuesWhenResultsWereLoaded(JSON.stringify(Object.fromEntries(otherValues)));
|
setOtherValuesWhenResultsWereLoaded(JSON.stringify(Object.fromEntries(otherValues)));
|
||||||
|
@ -57,7 +57,7 @@ export default function AssignFilterVariable({valueIndex, field, valueChangeHand
|
|||||||
|
|
||||||
return <Box display="flex" alignItems="flex-end">
|
return <Box display="flex" alignItems="flex-end">
|
||||||
<Box>
|
<Box>
|
||||||
<Tooltip title={`Use a variable as the value for the ${field.name} field`} placement="bottom">
|
<Tooltip title={`Use a variable as the value for the ${field.label} field`} placement="bottom">
|
||||||
<Icon fontSize="small" color="info" sx={{mx: 0.25, cursor: "pointer", position: "relative", top: "2px"}} onClick={handleVariableButtonOnClick}>functions</Icon>
|
<Icon fontSize="small" color="info" sx={{mx: 0.25, cursor: "pointer", position: "relative", top: "2px"}} onClick={handleVariableButtonOnClick}>functions</Icon>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</Box>
|
</Box>
|
||||||
|
@ -196,12 +196,49 @@ export default function CriteriaDateField({valueIndex, label, idPrefix, field, c
|
|||||||
setTimeout(() => setForceAdvancedDateTimeDialogOpen(false), 100);
|
setTimeout(() => setForceAdvancedDateTimeDialogOpen(false), 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const makeFilterVariableTextField = (expression: FilterVariableExpression, valueIndex: number = 0, label = "Value", idPrefix = "value-") =>
|
||||||
|
{
|
||||||
|
const clearValue = (event: React.MouseEvent<HTMLAnchorElement> | React.MouseEvent<HTMLButtonElement>, index: number) =>
|
||||||
|
{
|
||||||
|
valueChangeHandler(event, index, "");
|
||||||
|
document.getElementById(`${idPrefix}${criteria.id}`).focus();
|
||||||
|
};
|
||||||
|
|
||||||
|
const inputProps2: any = {};
|
||||||
|
inputProps2.endAdornment = (
|
||||||
|
<InputAdornment position="end">
|
||||||
|
<IconButton sx={{visibility: expression ? "visible" : "hidden"}} onClick={(event) => clearValue(event, valueIndex)}>
|
||||||
|
<Icon>closer</Icon>
|
||||||
|
</IconButton>
|
||||||
|
</InputAdornment>
|
||||||
|
);
|
||||||
|
|
||||||
|
return <NoWrapTooltip title={<EvaluatedExpression field={field} expression={expression} />} placement="bottom" enterDelay={1000} sx={{marginLeft: "-75px !important", marginTop: "-8px !important"}}><TextField
|
||||||
|
id={`${idPrefix}${criteria.id}`}
|
||||||
|
label={label}
|
||||||
|
variant="standard"
|
||||||
|
autoComplete="off"
|
||||||
|
InputProps={{disabled: true, readOnly: true, unselectable: "off", ...inputProps2}}
|
||||||
|
InputLabelProps={{shrink: true}}
|
||||||
|
value="${VARIABLE}"
|
||||||
|
fullWidth
|
||||||
|
/></NoWrapTooltip>;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
return <Box display="flex" alignItems="flex-end">
|
return <Box display="flex" alignItems="flex-end">
|
||||||
{
|
{
|
||||||
isExpression ? makeDateTimeExpressionTextField(criteria.values[valueIndex], valueIndex, label, idPrefix)
|
isExpression ?
|
||||||
|
currentExpression?.type == "FilterVariableExpression" ? (
|
||||||
|
makeFilterVariableTextField(criteria.values[valueIndex], valueIndex, label, idPrefix)
|
||||||
|
) : (
|
||||||
|
makeDateTimeExpressionTextField(criteria.values[valueIndex], valueIndex, label, idPrefix)
|
||||||
|
)
|
||||||
: makeTextField(field, criteria, valueChangeHandler, valueIndex, label, idPrefix, allowVariables)
|
: makeTextField(field, criteria, valueChangeHandler, valueIndex, label, idPrefix, allowVariables)
|
||||||
}
|
}
|
||||||
<Box>
|
{
|
||||||
|
(!isExpression || currentExpression?.type != "FilterVariableExpression") && (
|
||||||
|
<><Box>
|
||||||
<Tooltip title={`Choose a common relative ${field.type == QFieldType.DATE ? "date" : "date-time"} expression`} placement="bottom">
|
<Tooltip title={`Choose a common relative ${field.type == QFieldType.DATE ? "date" : "date-time"} expression`} placement="bottom">
|
||||||
<Icon fontSize="small" color="info" sx={{mx: 0.25, cursor: "pointer", position: "relative", top: "2px"}} onClick={openRelativeDateTimeMenu}>date_range</Icon>
|
<Icon fontSize="small" color="info" sx={{mx: 0.25, cursor: "pointer", position: "relative", top: "2px"}} onClick={openRelativeDateTimeMenu}>date_range</Icon>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
@ -211,8 +248,7 @@ export default function CriteriaDateField({valueIndex, label, idPrefix, field, c
|
|||||||
transformOrigin={{horizontal: "left", vertical: "top"}}
|
transformOrigin={{horizontal: "left", vertical: "top"}}
|
||||||
onClose={closeRelativeDateTimeMenu}
|
onClose={closeRelativeDateTimeMenu}
|
||||||
>
|
>
|
||||||
{
|
{field.type == QFieldType.DATE ?
|
||||||
field.type == QFieldType.DATE ?
|
|
||||||
<Box display="flex">
|
<Box display="flex">
|
||||||
<Box>
|
<Box>
|
||||||
{tooltipMenuItemFromExpression(valueIndex, "left", newNowWithOffsetExpression("MINUS", 7, "DAYS"))}
|
{tooltipMenuItemFromExpression(valueIndex, "left", newNowWithOffsetExpression("MINUS", 7, "DAYS"))}
|
||||||
@ -267,13 +303,13 @@ export default function CriteriaDateField({valueIndex, label, idPrefix, field, c
|
|||||||
{tooltipMenuItemFromExpression(valueIndex, "right", newThisOrLastPeriodExpression("THIS", "YEARS"))}
|
{tooltipMenuItemFromExpression(valueIndex, "right", newThisOrLastPeriodExpression("THIS", "YEARS"))}
|
||||||
{tooltipMenuItemFromExpression(valueIndex, "right", newThisOrLastPeriodExpression("LAST", "YEARS"))}
|
{tooltipMenuItemFromExpression(valueIndex, "right", newThisOrLastPeriodExpression("LAST", "YEARS"))}
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>}
|
||||||
}
|
|
||||||
</Menu>
|
</Menu>
|
||||||
</Box>
|
</Box><Box>
|
||||||
<Box>
|
|
||||||
<AdvancedDateTimeFilterValues type={field.type} expression={currentExpression} onSave={(expression: any) => saveNewDateTimeExpression(valueIndex, expression)} forcedOpen={forceAdvancedDateTimeDialogOpen} />
|
<AdvancedDateTimeFilterValues type={field.type} expression={currentExpression} onSave={(expression: any) => saveNewDateTimeExpression(valueIndex, expression)} forcedOpen={forceAdvancedDateTimeDialogOpen} />
|
||||||
</Box>
|
</Box></>
|
||||||
|
)
|
||||||
|
}
|
||||||
</Box>;
|
</Box>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,8 +28,8 @@ import Box from "@mui/material/Box";
|
|||||||
import Button from "@mui/material/Button/Button";
|
import Button from "@mui/material/Button/Button";
|
||||||
import Icon from "@mui/material/Icon/Icon";
|
import Icon from "@mui/material/Icon/Icon";
|
||||||
import {GridFilterPanelProps, GridSlotsComponentsProps} from "@mui/x-data-grid-pro";
|
import {GridFilterPanelProps, GridSlotsComponentsProps} from "@mui/x-data-grid-pro";
|
||||||
import React, {forwardRef, useReducer} from "react";
|
|
||||||
import {FilterCriteriaRow, getDefaultCriteriaValue} from "qqq/components/query/FilterCriteriaRow";
|
import {FilterCriteriaRow, getDefaultCriteriaValue} from "qqq/components/query/FilterCriteriaRow";
|
||||||
|
import React, {forwardRef, useReducer} from "react";
|
||||||
|
|
||||||
|
|
||||||
declare module "@mui/x-data-grid"
|
declare module "@mui/x-data-grid"
|
||||||
@ -49,7 +49,7 @@ declare module "@mui/x-data-grid"
|
|||||||
|
|
||||||
export class QFilterCriteriaWithId extends QFilterCriteria
|
export class QFilterCriteriaWithId extends QFilterCriteria
|
||||||
{
|
{
|
||||||
id: number
|
id: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -62,6 +62,7 @@ export const CustomFilterPanel = forwardRef<any, GridFilterPanelProps>(
|
|||||||
const [, forceUpdate] = useReducer((x) => x + 1, 0);
|
const [, forceUpdate] = useReducer((x) => x + 1, 0);
|
||||||
|
|
||||||
const queryFilter = props.queryFilter;
|
const queryFilter = props.queryFilter;
|
||||||
|
|
||||||
// console.log(`CustomFilterPanel: filter: ${JSON.stringify(queryFilter)}`);
|
// console.log(`CustomFilterPanel: filter: ${JSON.stringify(queryFilter)}`);
|
||||||
|
|
||||||
function focusLastField()
|
function focusLastField()
|
||||||
@ -124,7 +125,7 @@ export const CustomFilterPanel = forwardRef<any, GridFilterPanelProps>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(queryFilter.criteria.length == 1 && !queryFilter.criteria[0].fieldName)
|
if (queryFilter.criteria.length == 1 && !queryFilter.criteria[0].fieldName)
|
||||||
{
|
{
|
||||||
focusLastField();
|
focusLastField();
|
||||||
}
|
}
|
||||||
@ -142,7 +143,7 @@ export const CustomFilterPanel = forwardRef<any, GridFilterPanelProps>(
|
|||||||
{
|
{
|
||||||
queryFilter.criteria[index] = newCriteria;
|
queryFilter.criteria[index] = newCriteria;
|
||||||
|
|
||||||
clearTimeout(debounceTimeout)
|
clearTimeout(debounceTimeout);
|
||||||
debounceTimeout = setTimeout(() => props.updateFilter(queryFilter), needDebounce ? 500 : 1);
|
debounceTimeout = setTimeout(() => props.updateFilter(queryFilter), needDebounce ? 500 : 1);
|
||||||
|
|
||||||
forceUpdate();
|
forceUpdate();
|
||||||
@ -178,6 +179,7 @@ export const CustomFilterPanel = forwardRef<any, GridFilterPanelProps>(
|
|||||||
updateCriteria={(newCriteria, needDebounce) => updateCriteria(newCriteria, index, needDebounce)}
|
updateCriteria={(newCriteria, needDebounce) => updateCriteria(newCriteria, index, needDebounce)}
|
||||||
removeCriteria={() => removeCriteria(index)}
|
removeCriteria={() => removeCriteria(index)}
|
||||||
updateBooleanOperator={(newValue) => updateBooleanOperator(newValue)}
|
updateBooleanOperator={(newValue) => updateBooleanOperator(newValue)}
|
||||||
|
queryScreenUsage={props.queryScreenUsage}
|
||||||
/>
|
/>
|
||||||
{/*JSON.stringify(criteria)*/}
|
{/*JSON.stringify(criteria)*/}
|
||||||
</Box>
|
</Box>
|
||||||
|
@ -35,6 +35,7 @@ import TextField from "@mui/material/TextField";
|
|||||||
import Tooltip from "@mui/material/Tooltip";
|
import Tooltip from "@mui/material/Tooltip";
|
||||||
import FieldAutoComplete from "qqq/components/misc/FieldAutoComplete";
|
import FieldAutoComplete from "qqq/components/misc/FieldAutoComplete";
|
||||||
import FilterCriteriaRowValues from "qqq/components/query/FilterCriteriaRowValues";
|
import FilterCriteriaRowValues from "qqq/components/query/FilterCriteriaRowValues";
|
||||||
|
import {QueryScreenUsage} from "qqq/pages/records/query/RecordQuery";
|
||||||
import FilterUtils from "qqq/utils/qqq/FilterUtils";
|
import FilterUtils from "qqq/utils/qqq/FilterUtils";
|
||||||
import React, {ReactNode, SyntheticEvent, useState} from "react";
|
import React, {ReactNode, SyntheticEvent, useState} from "react";
|
||||||
|
|
||||||
@ -197,6 +198,7 @@ interface FilterCriteriaRowProps
|
|||||||
updateCriteria: (newCriteria: QFilterCriteria, needDebounce: boolean) => void;
|
updateCriteria: (newCriteria: QFilterCriteria, needDebounce: boolean) => void;
|
||||||
removeCriteria: () => void;
|
removeCriteria: () => void;
|
||||||
updateBooleanOperator: (newValue: string) => void;
|
updateBooleanOperator: (newValue: string) => void;
|
||||||
|
queryScreenUsage?: QueryScreenUsage;
|
||||||
}
|
}
|
||||||
|
|
||||||
FilterCriteriaRow.defaultProps =
|
FilterCriteriaRow.defaultProps =
|
||||||
@ -265,7 +267,7 @@ export function validateCriteria(criteria: QFilterCriteria, operatorSelectedValu
|
|||||||
return {criteriaIsValid, criteriaStatusTooltip};
|
return {criteriaIsValid, criteriaStatusTooltip};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function FilterCriteriaRow({id, index, tableMetaData, metaData, criteria, booleanOperator, updateCriteria, removeCriteria, updateBooleanOperator}: FilterCriteriaRowProps): JSX.Element
|
export function FilterCriteriaRow({id, index, tableMetaData, metaData, criteria, booleanOperator, updateCriteria, removeCriteria, updateBooleanOperator, queryScreenUsage}: FilterCriteriaRowProps): JSX.Element
|
||||||
{
|
{
|
||||||
// console.log(`FilterCriteriaRow: criteria: ${JSON.stringify(criteria)}`);
|
// console.log(`FilterCriteriaRow: criteria: ${JSON.stringify(criteria)}`);
|
||||||
const [operatorSelectedValue, setOperatorSelectedValue] = useState(null as OperatorOption);
|
const [operatorSelectedValue, setOperatorSelectedValue] = useState(null as OperatorOption);
|
||||||
@ -513,6 +515,7 @@ export function FilterCriteriaRow({id, index, tableMetaData, metaData, criteria,
|
|||||||
field={field}
|
field={field}
|
||||||
table={fieldTable}
|
table={fieldTable}
|
||||||
valueChangeHandler={(event, valueIndex, newValue) => handleValueChange(event, valueIndex, newValue)}
|
valueChangeHandler={(event, valueIndex, newValue) => handleValueChange(event, valueIndex, newValue)}
|
||||||
|
queryScreenUsage={queryScreenUsage}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
<Box display="inline-block">
|
<Box display="inline-block">
|
||||||
|
@ -220,6 +220,8 @@ function FilterCriteriaRowValues({operatorOption, criteria, field, table, valueC
|
|||||||
forceUpdate();
|
forceUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const isExpression = criteria.values && criteria.values[0] && criteria.values[0].type;
|
||||||
|
|
||||||
switch (operatorOption.valueMode)
|
switch (operatorOption.valueMode)
|
||||||
{
|
{
|
||||||
case ValueMode.NONE:
|
case ValueMode.NONE:
|
||||||
@ -227,18 +229,18 @@ function FilterCriteriaRowValues({operatorOption, criteria, field, table, valueC
|
|||||||
case ValueMode.SINGLE:
|
case ValueMode.SINGLE:
|
||||||
return makeTextField(field, criteria, valueChangeHandler, 0, undefined, undefined, allowVariables);
|
return makeTextField(field, criteria, valueChangeHandler, 0, undefined, undefined, allowVariables);
|
||||||
case ValueMode.SINGLE_DATE:
|
case ValueMode.SINGLE_DATE:
|
||||||
return <CriteriaDateField field={field} valueChangeHandler={valueChangeHandler} criteria={criteria} />;
|
return <CriteriaDateField field={field} valueChangeHandler={valueChangeHandler} criteria={criteria} allowVariables={allowVariables} />;
|
||||||
case ValueMode.DOUBLE_DATE:
|
case ValueMode.DOUBLE_DATE:
|
||||||
return <Box>
|
return <Box>
|
||||||
<CriteriaDateField field={field} valueChangeHandler={valueChangeHandler} criteria={criteria} valueIndex={0} label="From" idPrefix="from-" />
|
<CriteriaDateField field={field} valueChangeHandler={valueChangeHandler} criteria={criteria} valueIndex={0} label="From" idPrefix="from-" allowVariables={allowVariables} />
|
||||||
<CriteriaDateField field={field} valueChangeHandler={valueChangeHandler} criteria={criteria} valueIndex={1} label="To" idPrefix="to-" />
|
<CriteriaDateField field={field} valueChangeHandler={valueChangeHandler} criteria={criteria} valueIndex={1} label="To" idPrefix="to-" allowVariables={allowVariables} />
|
||||||
</Box>;
|
</Box>;
|
||||||
case ValueMode.SINGLE_DATE_TIME:
|
case ValueMode.SINGLE_DATE_TIME:
|
||||||
return <CriteriaDateField field={field} valueChangeHandler={valueChangeHandler} criteria={criteria} allowVariables={allowVariables} />;
|
return <CriteriaDateField field={field} valueChangeHandler={valueChangeHandler} criteria={criteria} allowVariables={allowVariables} />;
|
||||||
case ValueMode.DOUBLE_DATE_TIME:
|
case ValueMode.DOUBLE_DATE_TIME:
|
||||||
return <Box>
|
return <Box>
|
||||||
<CriteriaDateField field={field} valueChangeHandler={valueChangeHandler} criteria={criteria} valueIndex={0} label="From" idPrefix="from-" />
|
<CriteriaDateField field={field} valueChangeHandler={valueChangeHandler} criteria={criteria} valueIndex={0} label="From" idPrefix="from-" allowVariables={allowVariables} />
|
||||||
<CriteriaDateField field={field} valueChangeHandler={valueChangeHandler} criteria={criteria} valueIndex={1} label="To" idPrefix="to-" />
|
<CriteriaDateField field={field} valueChangeHandler={valueChangeHandler} criteria={criteria} valueIndex={1} label="To" idPrefix="to-" allowVariables={allowVariables} />
|
||||||
</Box>;
|
</Box>;
|
||||||
case ValueMode.DOUBLE:
|
case ValueMode.DOUBLE:
|
||||||
return <Box>
|
return <Box>
|
||||||
@ -279,7 +281,12 @@ function FilterCriteriaRowValues({operatorOption, criteria, field, table, valueC
|
|||||||
{
|
{
|
||||||
selectedPossibleValue = criteria.values[0];
|
selectedPossibleValue = criteria.values[0];
|
||||||
}
|
}
|
||||||
return <Box mb={-1.5}>
|
return <Box display="flex">
|
||||||
|
{
|
||||||
|
isExpression ? (
|
||||||
|
makeTextField(field, criteria, valueChangeHandler, 0, undefined, undefined, allowVariables)
|
||||||
|
) : (
|
||||||
|
<Box mb={-1.5} width={allowVariables && !isExpression ? "100%" : "100%"}>
|
||||||
<DynamicSelect
|
<DynamicSelect
|
||||||
tableName={table.name}
|
tableName={table.name}
|
||||||
fieldName={field.name}
|
fieldName={field.name}
|
||||||
@ -292,6 +299,12 @@ function FilterCriteriaRowValues({operatorOption, criteria, field, table, valueC
|
|||||||
onChange={(value: any) => valueChangeHandler(null, 0, value)}
|
onChange={(value: any) => valueChangeHandler(null, 0, value)}
|
||||||
variant="standard"
|
variant="standard"
|
||||||
/>
|
/>
|
||||||
|
</Box>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
{
|
||||||
|
allowVariables && !isExpression && <Box mt={2.0}><AssignFilterVariable field={field} valueChangeHandler={valueChangeHandler} valueIndex={0} /></Box>
|
||||||
|
}
|
||||||
</Box>;
|
</Box>;
|
||||||
case ValueMode.PVS_MULTI:
|
case ValueMode.PVS_MULTI:
|
||||||
console.log("Doing pvs multi: " + criteria.values);
|
console.log("Doing pvs multi: " + criteria.values);
|
||||||
@ -307,7 +320,12 @@ function FilterCriteriaRowValues({operatorOption, criteria, field, table, valueC
|
|||||||
initialValues = criteria.values;
|
initialValues = criteria.values;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return <Box mb={-1.5}>
|
return <Box display="flex">
|
||||||
|
{
|
||||||
|
isExpression ? (
|
||||||
|
makeTextField(field, criteria, valueChangeHandler, 0, undefined, undefined, allowVariables)
|
||||||
|
) : (
|
||||||
|
<Box mb={-1.5} width={allowVariables && !isExpression ? "90%" : "100%"}>
|
||||||
<DynamicSelect
|
<DynamicSelect
|
||||||
tableName={table.name}
|
tableName={table.name}
|
||||||
fieldName={field.name}
|
fieldName={field.name}
|
||||||
@ -321,6 +339,12 @@ function FilterCriteriaRowValues({operatorOption, criteria, field, table, valueC
|
|||||||
onChange={(value: any) => valueChangeHandler(null, "all", value)}
|
onChange={(value: any) => valueChangeHandler(null, "all", value)}
|
||||||
variant="standard"
|
variant="standard"
|
||||||
/>
|
/>
|
||||||
|
</Box>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
{
|
||||||
|
allowVariables && !isExpression && <Box mt={2.0} sx={{width: "10%"}}><AssignFilterVariable field={field} valueChangeHandler={valueChangeHandler} valueIndex={0} /></Box>
|
||||||
|
}
|
||||||
</Box>;
|
</Box>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,9 +99,10 @@ export default function DynamicFormWidget({isEditable, widgetMetaData, widgetDat
|
|||||||
|
|
||||||
if(newFields.length > 0)
|
if(newFields.length > 0)
|
||||||
{
|
{
|
||||||
|
const recordOfFieldValues = widgetData.recordOfFieldValues ? new QRecord(widgetData.recordOfFieldValues) : null;
|
||||||
const {dynamicFormFields: newDynamicFormFields, formValidations: newFormValidations} = DynamicFormUtils.getFormData(newFields);
|
const {dynamicFormFields: newDynamicFormFields, formValidations: newFormValidations} = DynamicFormUtils.getFormData(newFields);
|
||||||
const defaultDisplayValues = new Map<string,string>(); // todo - seems not right?
|
const defaultDisplayValues = new Map<string,string>(); // todo - seems not right?
|
||||||
DynamicFormUtils.addPossibleValueProps(newDynamicFormFields, newFields, recordValues.tableName, null, record ? record.displayValues : defaultDisplayValues);
|
DynamicFormUtils.addPossibleValueProps(newDynamicFormFields, newFields, recordValues.tableName, null, recordOfFieldValues ? recordOfFieldValues.displayValues : defaultDisplayValues);
|
||||||
setDynamicFormFields(newDynamicFormFields)
|
setDynamicFormFields(newDynamicFormFields)
|
||||||
setFormValidations(newFormValidations)
|
setFormValidations(newFormValidations)
|
||||||
}
|
}
|
||||||
@ -226,7 +227,7 @@ export default function DynamicFormWidget({isEditable, widgetMetaData, widgetDat
|
|||||||
{
|
{
|
||||||
const fieldNames: string[] = [];
|
const fieldNames: string[] = [];
|
||||||
const fieldMap: {[name: string]: QFieldMetaData} = {};
|
const fieldMap: {[name: string]: QFieldMetaData} = {};
|
||||||
const fakeRecord = new QRecord({});
|
const fakeRecord = new QRecord(widgetData.recordOfFieldValues ?? {});
|
||||||
|
|
||||||
const mergedDynamicFormValuesIntoFieldName = widgetData.mergedDynamicFormValuesIntoFieldName;
|
const mergedDynamicFormValuesIntoFieldName = widgetData.mergedDynamicFormValuesIntoFieldName;
|
||||||
|
|
||||||
|
@ -900,6 +900,26 @@ const RecordQuery = forwardRef(({table, usage, isModal, initialQueryFilter, init
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// if any values in the query are of type "FilterVariableExpression", display an error showing //
|
||||||
|
// that a backend query cannot be made because of missing values for that expression //
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
setWarningAlert(null);
|
||||||
|
for (var i = 0; i < queryFilter?.criteria.length; i++)
|
||||||
|
{
|
||||||
|
for (var j = 0; j < queryFilter?.criteria[i].values.length; j++)
|
||||||
|
{
|
||||||
|
const value = queryFilter.criteria[i].values[j];
|
||||||
|
if (value?.type == "FilterVariableExpression")
|
||||||
|
{
|
||||||
|
setWarningAlert("Cannot perform query because of a missing value for a variable.");
|
||||||
|
setLoading(false);
|
||||||
|
setRows([]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
recordAnalytics({category: "tableEvents", action: "query", label: tableMetaData.label});
|
recordAnalytics({category: "tableEvents", action: "query", label: tableMetaData.label});
|
||||||
|
|
||||||
console.log(`In updateTable for ${reason} ${JSON.stringify(queryFilter)}`);
|
console.log(`In updateTable for ${reason} ${JSON.stringify(queryFilter)}`);
|
||||||
@ -2888,6 +2908,7 @@ const RecordQuery = forwardRef(({table, usage, isModal, initialQueryFilter, init
|
|||||||
filterPanel:
|
filterPanel:
|
||||||
{
|
{
|
||||||
tableMetaData: tableMetaData,
|
tableMetaData: tableMetaData,
|
||||||
|
queryScreenUsage: usage,
|
||||||
metaData: metaData,
|
metaData: metaData,
|
||||||
queryFilter: queryFilter,
|
queryFilter: queryFilter,
|
||||||
updateFilter: doSetQueryFilter,
|
updateFilter: doSetQueryFilter,
|
||||||
|
@ -693,6 +693,11 @@ input[type="search"]::-webkit-search-results-decoration
|
|||||||
padding: 24px;
|
padding: 24px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.entityForm .widget
|
||||||
|
{
|
||||||
|
padding: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
.recordView .widget .recordGridWidget
|
.recordView .widget .recordGridWidget
|
||||||
{
|
{
|
||||||
margin: -8px;
|
margin: -8px;
|
||||||
|
Reference in New Issue
Block a user