CE-1115 - support having the ReportSetupWidget and PivotTableSetupWidget actually edit the form values used on the page

This commit is contained in:
2024-04-09 15:58:19 -05:00
parent e5e49a6db8
commit 3558a91e7b

View File

@ -43,7 +43,9 @@ import DynamicFormUtils from "qqq/components/forms/DynamicFormUtils";
import MDTypography from "qqq/components/legacy/MDTypography";
import HelpContent from "qqq/components/misc/HelpContent";
import QRecordSidebar from "qqq/components/misc/RecordSidebar";
import PivotTableSetupWidget from "qqq/components/widgets/misc/PivotTableSetupWidget";
import RecordGridWidget, {ChildRecordListData} from "qqq/components/widgets/misc/RecordGridWidget";
import ReportSetupWidget from "qqq/components/widgets/misc/ReportSetupWidget";
import HtmlUtils from "qqq/utils/HtmlUtils";
import Client from "qqq/utils/qqq/Client";
import TableUtils from "qqq/utils/qqq/TableUtils";
@ -77,6 +79,15 @@ EntityForm.defaultProps = {
onSubmitCallback: null,
};
////////////////////////////////////////////////////////////////////////////
// define a function that we can make referenes to, which we'll overwrite //
// with formik's setFieldValue function, once we're inside formik. //
////////////////////////////////////////////////////////////////////////////
let formikSetFieldValueFunction = (field: string, value: any, shouldValidate?: boolean): void =>
{
}
function EntityForm(props: Props): JSX.Element
{
const qController = Client.getInstance();
@ -108,6 +119,9 @@ function EntityForm(props: Props): JSX.Element
const [notAllowedError, setNotAllowedError] = useState(null as string);
const [recordValuesJSON, setRecordValuesJSON] = useState("");
const [formValues, setFormValues] = useState({} as {[name: string]: any});
const {pageHeader, setPageHeader} = useContext(QContext);
const navigate = useNavigate();
@ -269,6 +283,21 @@ function EntityForm(props: Props): JSX.Element
}
/*******************************************************************************
** Watch the record values - if they change, re-render widgets
*******************************************************************************/
useEffect(() =>
{
const newRenderedWidgetSections: {[name: string]: JSX.Element} = {};
for (let widgetName in renderedWidgetSections)
{
const widgetMetaData = metaData.widgets.get(widgetName);
newRenderedWidgetSections[widgetName] = getWidgetSection(widgetMetaData, childListWidgetData[widgetName]);
}
setRenderedWidgetSections(newRenderedWidgetSections);
}, [recordValuesJSON]);
/*******************************************************************************
** render a section (full of fields) as a form
*******************************************************************************/
@ -319,10 +348,26 @@ 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.
*******************************************************************************/
function setFormFieldValuesFromWidget(values: {[name: string]: any})
{
for (let key in values)
{
formikSetFieldValueFunction(key, values[key]);
}
}
/*******************************************************************************
** render a section as a widget
*******************************************************************************/
function getWidgetSection(widgetMetaData: QWidgetMetaData, widgetData: any): JSX.Element
{
if(widgetMetaData.type == "childRecordList")
{
widgetData.viewAllLink = null;
widgetMetaData.showExportButton = false;
@ -340,6 +385,31 @@ function EntityForm(props: Props): JSX.Element
/>;
}
if(widgetMetaData.type == "reportSetup")
{
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")
{
return <PivotTableSetupWidget
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}
/>
}
return (<Box>Unsupported widget type: {widgetMetaData.type}</Box>)
}
/*******************************************************************************
** render a form section
@ -373,7 +443,21 @@ function EntityForm(props: Props): JSX.Element
/////////////////////////////////////////////////
const tableSections = TableUtils.getSectionsForRecordSidebar(tableMetaData, [...tableMetaData.fields.keys()], (section: QTableSection) =>
{
return section.widgetName && metaData.widgets.get(section.widgetName)?.type == "childRecordList" && metaData.widgets.get(section.widgetName)?.defaultValues?.has("manageAssociationName");
const widget = metaData.widgets.get(section.widgetName);
if(widget)
{
if(widget.type == "childRecordList" && widget.defaultValues?.has("manageAssociationName"))
{
return (true);
}
if(widget.type == "reportSetup" || widget.type == "pivotTableSetup")
{
return (true);
}
}
return (false);
});
setTableSections(tableSections);
@ -549,12 +633,6 @@ function EntityForm(props: Props): JSX.Element
}
const hasFields = section.fieldNames && section.fieldNames.length > 0;
const hasChildRecordListWidget = section.widgetName && metaData.widgets.get(section.widgetName)?.type == "childRecordList";
if (!hasFields && !hasChildRecordListWidget)
{
continue;
}
if(hasFields)
{
for (let j = 0; j < section.fieldNames.length; j++)
@ -599,6 +677,7 @@ function EntityForm(props: Props): JSX.Element
newRenderedWidgetSections[section.widgetName] = getWidgetSection(widgetMetaData, widgetData);
newChildListWidgetData[section.widgetName] = widgetData;
}
//////////////////////////////////////
// capture the tier1 section's name //
//////////////////////////////////////
@ -924,7 +1003,26 @@ function EntityForm(props: Props): JSX.Element
errors,
touched,
isSubmitting,
}) => (
setFieldValue,
}) =>
{
if(values)
{
const newRecordValuesJSON = JSON.stringify(values);
if(recordValuesJSON != newRecordValuesJSON)
{
setRecordValuesJSON(newRecordValuesJSON);
setFormValues(values)
}
}
///////////////////////////////////////////////////////////////////
// once we're in the formik form, use its setFieldValue function //
// over top of the default one we created globally //
///////////////////////////////////////////////////////////////////
formikSetFieldValueFunction = setFieldValue;
return (
<Form id={formId} autoComplete="off">
<ScrollToFirstError />
@ -968,7 +1066,8 @@ function EntityForm(props: Props): JSX.Element
</Box>
</Form>
)}
);
}}
</Formik>
{