diff --git a/src/qqq/components/forms/EntityForm.tsx b/src/qqq/components/forms/EntityForm.tsx index 98fee7e..d4b3c8d 100644 --- a/src/qqq/components/forms/EntityForm.tsx +++ b/src/qqq/components/forms/EntityForm.tsx @@ -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,25 +348,66 @@ 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 { - widgetData.viewAllLink = null; - widgetMetaData.showExportButton = false; + if(widgetMetaData.type == "childRecordList") + { + widgetData.viewAllLink = null; + widgetMetaData.showExportButton = false; - return openAddChildRecord(widgetMetaData.name, widgetData)} - editRecordCallback={(rowIndex) => openEditChildRecord(widgetMetaData.name, widgetData, rowIndex)} - deleteRecordCallback={(rowIndex) => deleteChildRecord(widgetMetaData.name, widgetData, rowIndex)} - />; + return openAddChildRecord(widgetMetaData.name, widgetData)} + editRecordCallback={(rowIndex) => openEditChildRecord(widgetMetaData.name, widgetData, rowIndex)} + deleteRecordCallback={(rowIndex) => deleteChildRecord(widgetMetaData.name, widgetData, rowIndex)} + />; + } + + if(widgetMetaData.type == "reportSetup") + { + return + } + + if(widgetMetaData.type == "pivotTableSetup") + { + return + } + + return (Unsupported widget type: {widgetMetaData.type}) } @@ -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,13 +633,7 @@ 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) + 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,51 +1003,71 @@ function EntityForm(props: Props): JSX.Element errors, touched, isSubmitting, - }) => ( -
- + setFieldValue, + }) => + { + if(values) + { + const newRecordValuesJSON = JSON.stringify(values); + if(recordValuesJSON != newRecordValuesJSON) + { + setRecordValuesJSON(newRecordValuesJSON); + setFormValues(values) + } + } - - - - - - - {tableMetaData?.iconName} - - - - - {formTitle} - - - {t1section && getSectionHelp(t1section)} - { - t1sectionName && formFields ? ( - - - {getFormSection(t1section, values, touched, formFields.get(t1sectionName), errors, true)} - + /////////////////////////////////////////////////////////////////// + // once we're in the formik form, use its setFieldValue function // + // over top of the default one we created globally // + /////////////////////////////////////////////////////////////////// + formikSetFieldValueFunction = setFieldValue; + + return ( + + + + + + + + + + {tableMetaData?.iconName} + + - ) : null - } - - - {formFields && nonT1Sections.length ? nonT1Sections.map((section: QTableSection) => ( - - {renderSection(section, values, touched, formFields, errors)} + + {formTitle} + + + {t1section && getSectionHelp(t1section)} + { + t1sectionName && formFields ? ( + + + {getFormSection(t1section, values, touched, formFields.get(t1sectionName), errors, true)} + + + ) : null + } + - )) : null} + {formFields && nonT1Sections.length ? nonT1Sections.map((section: QTableSection) => ( + + {renderSection(section, values, touched, formFields, errors)} + + )) : null} - - - - - - + + + + + + - - )} + + ); + }} {