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 =>
{
}
};
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
** 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?.defaultValues?.has("tableName"))
{
formValues["tableName"] = widgetMetaData?.defaultValues.get("tableName");
}
return <ReportSetupWidget
key={formValues["tableName"]} // todo, is this good? it was added so that editing values actually re-renders...
isEditable={true}
widgetMetaData={widgetMetaData}
recordValues={formValues}
onSaveCallback={setFormFieldValuesFromWidget}
/>
/>;
}
if (widgetMetaData.type == "pivotTableSetup")
@ -407,7 +411,7 @@ function EntityForm(props: Props): JSX.Element
widgetMetaData={widgetMetaData}
recordValues={formValues}
onSaveCallback={setFormFieldValuesFromWidget}
/>
/>;
}
if (widgetMetaData.type == "dynamicForm")
@ -420,10 +424,10 @@ function EntityForm(props: Props): JSX.Element
recordValues={formValues}
record={record}
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[] = [];
if (props.id)
{
queryParamsArray.push(`${tableMetaData.primaryKeyField}=${encodeURIComponent(props.id)}`)
queryParamsArray.push(`${tableMetaData.primaryKeyField}=${encodeURIComponent(props.id)}`);
}
if (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);
}
setFormValues(formValues)
setFormValues(formValues);
setFormValuesJSON(JSON.stringify(values));
}
}

View File

@ -22,6 +22,9 @@
import {QTableMetaData} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QTableMetaData";
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 {Alert, Collapse} from "@mui/material";
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
{
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 [alertContent, setAlertContent] = useState(null as string);
@ -101,15 +105,36 @@ export default function ReportSetupWidget({isEditable, widgetMetaData, recordVal
/////////////////////////////
// load values from record //
/////////////////////////////
let queryFilter = recordValues["queryFilterJson"] && JSON.parse(recordValues["queryFilterJson"]) as QQueryFilter;
let columns: QQueryColumns = null;
let usingDefaultEmptyFilter = false;
let queryFilter = recordValues["queryFilterJson"] && JSON.parse(recordValues["queryFilterJson"]) as QQueryFilter;
if (!queryFilter)
{
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;
}
}
let columns: QQueryColumns = null;
if (recordValues["columnsJson"])
{
columns = QQueryColumns.buildFromJSON(recordValues["columnsJson"]);
@ -120,11 +145,20 @@ export default function ReportSetupWidget({isEditable, widgetMetaData, recordVal
//////////////////////////////////////////////////////////////////////
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 () =>
{
const tableMetaData = await qController.loadTableMetaData(recordValues["tableName"]);
const tableMetaData = await qController.loadTableMetaData(tableName);
setTableMetaData(tableMetaData);
const queryFilterForFrontend = Object.assign({}, queryFilter);
@ -132,7 +166,21 @@ export default function ReportSetupWidget({isEditable, widgetMetaData, recordVal
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()
{
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"])
{
setAlertContent(null);
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 labelAdditionalElementsRight: JSX.Element[] = [];
if (isEditable)
{
if (!hideColumns)
{
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}>
@ -311,6 +385,7 @@ export default function ReportSetupWidget({isEditable, widgetMetaData, recordVal
</Box>
}
</Box>
{!hideColumns && (
<Box pt="1rem">
<h5>Columns</h5>
<Box display="flex" flexWrap="wrap" fontSize="1rem">
@ -334,6 +409,7 @@ export default function ReportSetupWidget({isEditable, widgetMetaData, recordVal
}
</Box>
</Box>
)}
{
modalOpen &&
<Modal open={modalOpen} onClose={(event, reason) => closeEditor(event, reason)}>