CE-938: improvements to the report setup widget

This commit is contained in:
Tim Chamberlain
2024-05-21 18:26:35 -05:00
parent dc131d5189
commit f44ba8d6d3
2 changed files with 142 additions and 62 deletions

View File

@ -88,7 +88,7 @@ EntityForm.defaultProps = {
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
let formikSetFieldValueFunction = (field: string, value: any, shouldValidate?: boolean): void => let formikSetFieldValueFunction = (field: string, value: any, shouldValidate?: boolean): void =>
{ {
} };
function EntityForm(props: Props): JSX.Element function EntityForm(props: Props): JSX.Element
{ {
@ -351,7 +351,6 @@ function EntityForm(props: Props): JSX.Element
} }
/******************************************************************************* /*******************************************************************************
** if we have a widget that wants to set form-field values, they can take this ** if we have a widget that wants to set form-field values, they can take this
** function in as a callback, and then call it with their values. ** function in as a callback, and then call it with their values.
@ -390,13 +389,18 @@ function EntityForm(props: Props): JSX.Element
if (widgetMetaData.type == "reportSetup") if (widgetMetaData.type == "reportSetup")
{ {
if (widgetMetaData?.defaultValues?.has("tableName"))
{
formValues["tableName"] = widgetMetaData?.defaultValues.get("tableName");
}
return <ReportSetupWidget return <ReportSetupWidget
key={formValues["tableName"]} // todo, is this good? it was added so that editing values actually re-renders... key={formValues["tableName"]} // todo, is this good? it was added so that editing values actually re-renders...
isEditable={true} isEditable={true}
widgetMetaData={widgetMetaData} widgetMetaData={widgetMetaData}
recordValues={formValues} recordValues={formValues}
onSaveCallback={setFormFieldValuesFromWidget} onSaveCallback={setFormFieldValuesFromWidget}
/> />;
} }
if (widgetMetaData.type == "pivotTableSetup") if (widgetMetaData.type == "pivotTableSetup")
@ -407,7 +411,7 @@ function EntityForm(props: Props): JSX.Element
widgetMetaData={widgetMetaData} widgetMetaData={widgetMetaData}
recordValues={formValues} recordValues={formValues}
onSaveCallback={setFormFieldValuesFromWidget} onSaveCallback={setFormFieldValuesFromWidget}
/> />;
} }
if (widgetMetaData.type == "dynamicForm") if (widgetMetaData.type == "dynamicForm")
@ -420,10 +424,10 @@ function EntityForm(props: Props): JSX.Element
recordValues={formValues} recordValues={formValues}
record={record} record={record}
onSaveCallback={setFormFieldValuesFromWidget} onSaveCallback={setFormFieldValuesFromWidget}
/> />;
} }
return (<Box>Unsupported widget type: {widgetMetaData.type}</Box>) return (<Box>Unsupported widget type: {widgetMetaData.type}</Box>);
} }
@ -1005,14 +1009,14 @@ function EntityForm(props: Props): JSX.Element
const queryParamsArray: string[] = []; const queryParamsArray: string[] = [];
if (props.id) if (props.id)
{ {
queryParamsArray.push(`${tableMetaData.primaryKeyField}=${encodeURIComponent(props.id)}`) queryParamsArray.push(`${tableMetaData.primaryKeyField}=${encodeURIComponent(props.id)}`);
} }
if (object) if (object)
{ {
for (let key in object) for (let key in object)
{ {
queryParamsArray.push(`${key}=${encodeURIComponent(object[key])}`) queryParamsArray.push(`${key}=${encodeURIComponent(object[key])}`);
} }
} }
@ -1194,7 +1198,7 @@ function EntityForm(props: Props): JSX.Element
setFieldValue(fieldName, valueChangesToMake[fieldName], false); setFieldValue(fieldName, valueChangesToMake[fieldName], false);
} }
setFormValues(formValues) setFormValues(formValues);
setFormValuesJSON(JSON.stringify(values)); setFormValuesJSON(JSON.stringify(values));
} }
} }

View File

@ -22,6 +22,9 @@
import {QTableMetaData} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QTableMetaData"; import {QTableMetaData} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QTableMetaData";
import {QWidgetMetaData} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QWidgetMetaData"; import {QWidgetMetaData} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QWidgetMetaData";
import {QCriteriaOperator} from "@kingsrook/qqq-frontend-core/lib/model/query/QCriteriaOperator";
import {QFilterCriteria} from "@kingsrook/qqq-frontend-core/lib/model/query/QFilterCriteria";
import {QFilterOrderBy} from "@kingsrook/qqq-frontend-core/lib/model/query/QFilterOrderBy";
import {QQueryFilter} from "@kingsrook/qqq-frontend-core/lib/model/query/QQueryFilter"; import {QQueryFilter} from "@kingsrook/qqq-frontend-core/lib/model/query/QQueryFilter";
import {Alert, Collapse} from "@mui/material"; import {Alert, Collapse} from "@mui/material";
import Box from "@mui/material/Box"; import Box from "@mui/material/Box";
@ -83,6 +86,7 @@ const qController = Client.getInstance();
export default function ReportSetupWidget({isEditable, widgetMetaData, recordValues, onSaveCallback}: ReportSetupWidgetProps): JSX.Element export default function ReportSetupWidget({isEditable, widgetMetaData, recordValues, onSaveCallback}: ReportSetupWidgetProps): JSX.Element
{ {
const [modalOpen, setModalOpen] = useState(false); const [modalOpen, setModalOpen] = useState(false);
const [hideColumns, setHideColumns] = useState(widgetMetaData?.defaultValues?.has("hideColumns") && widgetMetaData?.defaultValues?.get("hideColumns"));
const [tableMetaData, setTableMetaData] = useState(null as QTableMetaData); const [tableMetaData, setTableMetaData] = useState(null as QTableMetaData);
const [alertContent, setAlertContent] = useState(null as string); const [alertContent, setAlertContent] = useState(null as string);
@ -101,15 +105,36 @@ export default function ReportSetupWidget({isEditable, widgetMetaData, recordVal
///////////////////////////// /////////////////////////////
// load values from record // // load values from record //
///////////////////////////// /////////////////////////////
let queryFilter = recordValues["queryFilterJson"] && JSON.parse(recordValues["queryFilterJson"]) as QQueryFilter; let columns: QQueryColumns = null;
let usingDefaultEmptyFilter = false; let usingDefaultEmptyFilter = false;
let queryFilter = recordValues["queryFilterJson"] && JSON.parse(recordValues["queryFilterJson"]) as QQueryFilter;
if (!queryFilter) if (!queryFilter)
{ {
queryFilter = new QQueryFilter(); queryFilter = new QQueryFilter();
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
// if there is no queryFilter provided, see if there are default fields from which a query should be seeded //
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
const defaultFilterFields = getDefaultFilterFieldNames(widgetMetaData);
if (defaultFilterFields?.length > 0)
{
defaultFilterFields.forEach((fieldName: string) =>
{
if (recordValues[fieldName])
{
queryFilter.addCriteria(new QFilterCriteria(fieldName, QCriteriaOperator.EQUALS, [recordValues[fieldName]]));
}
});
queryFilter.addOrderBy(new QFilterOrderBy("id", false));
queryFilter = Object.assign({}, queryFilter);
}
else
{
usingDefaultEmptyFilter = true; usingDefaultEmptyFilter = true;
} }
}
let columns: QQueryColumns = null;
if (recordValues["columnsJson"]) if (recordValues["columnsJson"])
{ {
columns = QQueryColumns.buildFromJSON(recordValues["columnsJson"]); columns = QQueryColumns.buildFromJSON(recordValues["columnsJson"]);
@ -120,11 +145,20 @@ export default function ReportSetupWidget({isEditable, widgetMetaData, recordVal
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
useEffect(() => useEffect(() =>
{ {
if (recordValues["tableName"] && (tableMetaData == null || tableMetaData.name != recordValues["tableName"])) ////////////////////////////////////////////////////////////////////////////////////////
// if a default table name specified, use it, otherwise use it from the record values //
////////////////////////////////////////////////////////////////////////////////////////
let tableName = widgetMetaData?.defaultValues?.get("tableName");
if (!tableName && recordValues["tableName"] && (tableMetaData == null || tableMetaData.name != recordValues["tableName"]))
{
tableName = recordValues["tableName"];
}
if (tableName)
{ {
(async () => (async () =>
{ {
const tableMetaData = await qController.loadTableMetaData(recordValues["tableName"]); const tableMetaData = await qController.loadTableMetaData(tableName);
setTableMetaData(tableMetaData); setTableMetaData(tableMetaData);
const queryFilterForFrontend = Object.assign({}, queryFilter); const queryFilterForFrontend = Object.assign({}, queryFilter);
@ -132,7 +166,21 @@ export default function ReportSetupWidget({isEditable, widgetMetaData, recordVal
setFrontendQueryFilter(queryFilterForFrontend); setFrontendQueryFilter(queryFilterForFrontend);
})(); })();
} }
}, [recordValues]); }, [JSON.stringify(recordValues)]);
/*******************************************************************************
**
*******************************************************************************/
function getDefaultFilterFieldNames(widgetMetaData: QWidgetMetaData)
{
if (widgetMetaData?.defaultValues?.has("filterDefaultFieldNames"))
{
return (widgetMetaData.defaultValues.get("filterDefaultFieldNames").split(","));
}
return ([]);
}
/******************************************************************************* /*******************************************************************************
@ -140,8 +188,27 @@ export default function ReportSetupWidget({isEditable, widgetMetaData, recordVal
*******************************************************************************/ *******************************************************************************/
function openEditor() function openEditor()
{ {
let missingRequiredFields = [] as string[];
getDefaultFilterFieldNames(widgetMetaData)?.forEach((fieldName: string) =>
{
if (!recordValues[fieldName])
{
missingRequiredFields.push(tableMetaData.fields.get(fieldName).label);
}
});
////////////////////////////////////////////////////////////////////
// display an alert and return if any required fields are missing //
////////////////////////////////////////////////////////////////////
if (missingRequiredFields.length > 0)
{
setAlertContent("The following fields must first be selected to add Additional Order Filters: '" + missingRequiredFields.join(", ") + "'");
return;
}
if (recordValues["tableName"]) if (recordValues["tableName"])
{ {
setAlertContent(null);
setModalOpen(true); setModalOpen(true);
} }
} }
@ -271,9 +338,16 @@ export default function ReportSetupWidget({isEditable, widgetMetaData, recordVal
const selectTableFirstTooltipTitle = tableMetaData ? null : "You must select a table before you can set up your report filters and columns"; const selectTableFirstTooltipTitle = tableMetaData ? null : "You must select a table before you can set up your report filters and columns";
const labelAdditionalElementsRight: JSX.Element[] = []; const labelAdditionalElementsRight: JSX.Element[] = [];
if (isEditable) if (isEditable)
{
if (!hideColumns)
{ {
labelAdditionalElementsRight.push(<HeaderLinkButtonComponent key="filterAndColumnsHeader" label="Edit Filters and Columns" onClickCallback={openEditor} disabled={tableMetaData == null} disabledTooltip={selectTableFirstTooltipTitle} />); labelAdditionalElementsRight.push(<HeaderLinkButtonComponent key="filterAndColumnsHeader" label="Edit Filters and Columns" onClickCallback={openEditor} disabled={tableMetaData == null} disabledTooltip={selectTableFirstTooltipTitle} />);
} }
else
{
labelAdditionalElementsRight.push(<HeaderLinkButtonComponent key="filterAndColumnsHeader" label="Edit Filters" onClickCallback={openEditor} disabled={tableMetaData == null} disabledTooltip={selectTableFirstTooltipTitle} />);
}
}
return (<Widget widgetMetaData={widgetMetaData} labelAdditionalElementsRight={labelAdditionalElementsRight}> return (<Widget widgetMetaData={widgetMetaData} labelAdditionalElementsRight={labelAdditionalElementsRight}>
@ -311,6 +385,7 @@ export default function ReportSetupWidget({isEditable, widgetMetaData, recordVal
</Box> </Box>
} }
</Box> </Box>
{!hideColumns && (
<Box pt="1rem"> <Box pt="1rem">
<h5>Columns</h5> <h5>Columns</h5>
<Box display="flex" flexWrap="wrap" fontSize="1rem"> <Box display="flex" flexWrap="wrap" fontSize="1rem">
@ -334,6 +409,7 @@ export default function ReportSetupWidget({isEditable, widgetMetaData, recordVal
} }
</Box> </Box>
</Box> </Box>
)}
{ {
modalOpen && modalOpen &&
<Modal open={modalOpen} onClose={(event, reason) => closeEditor(event, reason)}> <Modal open={modalOpen} onClose={(event, reason) => closeEditor(event, reason)}>