diff --git a/src/qqq/components/forms/EntityForm.tsx b/src/qqq/components/forms/EntityForm.tsx
index bd01e2a..c885367 100644
--- a/src/qqq/components/forms/EntityForm.tsx
+++ b/src/qqq/components/forms/EntityForm.tsx
@@ -88,7 +88,7 @@ EntityForm.defaultProps = {
////////////////////////////////////////////////////////////////////////////
let formikSetFieldValueFunction = (field: string, value: any, shouldValidate?: boolean): void =>
{
-}
+};
function EntityForm(props: Props): JSX.Element
{
@@ -123,7 +123,7 @@ function EntityForm(props: Props): JSX.Element
const [notAllowedError, setNotAllowedError] = useState(null as string);
const [formValuesJSON, setFormValuesJSON] = useState("");
- const [formValues, setFormValues] = useState({} as {[name: string]: any});
+ const [formValues, setFormValues] = useState({} as { [name: string]: any });
const {pageHeader, setPageHeader} = useContext(QContext);
@@ -291,7 +291,7 @@ function EntityForm(props: Props): JSX.Element
*******************************************************************************/
useEffect(() =>
{
- const newRenderedWidgetSections: {[name: string]: JSX.Element} = {};
+ const newRenderedWidgetSections: { [name: string]: JSX.Element } = {};
for (let widgetName in renderedWidgetSections)
{
const widgetMetaData = metaData.widgets.get(widgetName);
@@ -351,12 +351,11 @@ 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})
+ function setFormFieldValuesFromWidget(values: { [name: string]: any })
{
for (let key in values)
{
@@ -370,7 +369,7 @@ function EntityForm(props: Props): JSX.Element
*******************************************************************************/
function getWidgetSection(widgetMetaData: QWidgetMetaData, widgetData: any): JSX.Element
{
- if(widgetMetaData.type == "childRecordList")
+ if (widgetMetaData.type == "childRecordList")
{
widgetData.viewAllLink = null;
widgetMetaData.showExportButton = false;
@@ -388,18 +387,23 @@ 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
+ />;
}
- if(widgetMetaData.type == "pivotTableSetup")
+ if (widgetMetaData.type == "pivotTableSetup")
{
return
+ />;
}
- if(widgetMetaData.type == "dynamicForm")
+ if (widgetMetaData.type == "dynamicForm")
{
return
+ />;
}
- return (Unsupported widget type: {widgetMetaData.type})
+ return (Unsupported widget type: {widgetMetaData.type});
}
@@ -449,12 +453,12 @@ function EntityForm(props: Props): JSX.Element
function setupFieldRules(tableMetaData: QTableMetaData)
{
const mdbMetaData = tableMetaData?.supplementalTableMetaData?.get("materialDashboard");
- if(!mdbMetaData)
+ if (!mdbMetaData)
{
return;
}
- if(mdbMetaData.fieldRules)
+ if (mdbMetaData.fieldRules)
{
const newFieldRules: FieldRule[] = [];
for (let i = 0; i < mdbMetaData.fieldRules.length; i++)
@@ -489,14 +493,14 @@ function EntityForm(props: Props): JSX.Element
const tableSections = TableUtils.getSectionsForRecordSidebar(tableMetaData, [...tableMetaData.fields.keys()], (section: QTableSection) =>
{
const widget = metaData.widgets.get(section.widgetName);
- if(widget)
+ if (widget)
{
- if(widget.type == "childRecordList" && widget.defaultValues?.has("manageAssociationName"))
+ if (widget.type == "childRecordList" && widget.defaultValues?.has("manageAssociationName"))
{
return (true);
}
- if(widget.type == "reportSetup" || widget.type == "pivotTableSetup" || widget.type == "dynamicForm")
+ if (widget.type == "reportSetup" || widget.type == "pivotTableSetup" || widget.type == "dynamicForm")
{
return (true);
}
@@ -680,7 +684,7 @@ function EntityForm(props: Props): JSX.Element
}
const hasFields = section.fieldNames && section.fieldNames.length > 0;
- if(hasFields)
+ if (hasFields)
{
for (let j = 0; j < section.fieldNames.length; j++)
{
@@ -1000,19 +1004,19 @@ function EntityForm(props: Props): JSX.Element
/*******************************************************************************
**
*******************************************************************************/
- function makeQueryStringWithIdAndObject(tableMetaData: QTableMetaData, object: {[key: string]: any})
+ function makeQueryStringWithIdAndObject(tableMetaData: QTableMetaData, object: { [key: string]: any })
{
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)
{
- queryParamsArray.push(`${key}=${encodeURIComponent(object[key])}`)
+ queryParamsArray.push(`${key}=${encodeURIComponent(object[key])}`);
}
}
@@ -1023,7 +1027,7 @@ function EntityForm(props: Props): JSX.Element
/*******************************************************************************
**
*******************************************************************************/
- async function reloadWidget(widgetName: string, additionalQueryParamsForWidget: {[key: string]: any })
+ async function reloadWidget(widgetName: string, additionalQueryParamsForWidget: { [key: string]: any })
{
const widgetData = await qController.widget(widgetName, makeQueryStringWithIdAndObject(tableMetaData, additionalQueryParamsForWidget));
const widgetMetaData = metaData.widgets.get(widgetName);
@@ -1045,11 +1049,11 @@ function EntityForm(props: Props): JSX.Element
/*******************************************************************************
** process a form-field having a changed value (e.g., apply field rules).
*******************************************************************************/
- function handleChangedFieldValue(fieldName: string, oldValue: any, newValue: any, valueChangesToMake: {[fieldName: string]: any})
+ function handleChangedFieldValue(fieldName: string, oldValue: any, newValue: any, valueChangesToMake: { [fieldName: string]: any })
{
for (let fieldRule of fieldRules)
{
- if(fieldRule.trigger == FieldRuleTrigger.ON_CHANGE && fieldRule.sourceField == fieldName)
+ if (fieldRule.trigger == FieldRuleTrigger.ON_CHANGE && fieldRule.sourceField == fieldName)
{
switch (fieldRule.action)
{
@@ -1058,7 +1062,7 @@ function EntityForm(props: Props): JSX.Element
valueChangesToMake[fieldRule.targetField] = null;
break;
case FieldRuleAction.RELOAD_WIDGET:
- const additionalQueryParamsForWidget: {[key: string]: any} = {};
+ const additionalQueryParamsForWidget: { [key: string]: any } = {};
additionalQueryParamsForWidget[fieldRule.sourceField] = newValue;
reloadWidget(fieldRule.targetWidget, additionalQueryParamsForWidget);
}
@@ -1148,21 +1152,21 @@ function EntityForm(props: Props): JSX.Element
/////////////////////////////////////////////////
// if we have values from formik, look at them //
/////////////////////////////////////////////////
- if(values)
+ if (values)
{
////////////////////////////////////////////////////////////////////////
// use stringified values as cheap/easy way to see if any are changed //
////////////////////////////////////////////////////////////////////////
const newFormValuesJSON = JSON.stringify(values);
- if(formValuesJSON != newFormValuesJSON)
+ if (formValuesJSON != newFormValuesJSON)
{
- const valueChangesToMake: {[fieldName: string]: any} = {};
+ const valueChangesToMake: { [fieldName: string]: any } = {};
////////////////////////////////////////////////////////////////////
// if the form is dirty (e.g., we're not doing the initial load), //
// then process rules for any changed fields //
////////////////////////////////////////////////////////////////////
- if(dirty)
+ if (dirty)
{
for (let fieldName in values)
{
@@ -1194,7 +1198,7 @@ function EntityForm(props: Props): JSX.Element
setFieldValue(fieldName, valueChangesToMake[fieldName], false);
}
- setFormValues(formValues)
+ setFormValues(formValues);
setFormValuesJSON(JSON.stringify(values));
}
}
diff --git a/src/qqq/components/widgets/misc/ReportSetupWidget.tsx b/src/qqq/components/widgets/misc/ReportSetupWidget.tsx
index 05ebfa2..2baa811 100644
--- a/src/qqq/components/widgets/misc/ReportSetupWidget.tsx
+++ b/src/qqq/components/widgets/misc/ReportSetupWidget.tsx
@@ -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();
- usingDefaultEmptyFilter = true;
+
+ //////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // 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);
}
}
@@ -272,7 +339,14 @@ export default function ReportSetupWidget({isEditable, widgetMetaData, recordVal
const labelAdditionalElementsRight: JSX.Element[] = [];
if (isEditable)
{
- labelAdditionalElementsRight.push();
+ if (!hideColumns)
+ {
+ labelAdditionalElementsRight.push();
+ }
+ else
+ {
+ labelAdditionalElementsRight.push();
+ }
}
@@ -311,29 +385,31 @@ export default function ReportSetupWidget({isEditable, widgetMetaData, recordVal
}
-
- Columns
-
- {
- mayShowColumnsPreview() &&
- columns.columns.map((column, i) => {renderColumn(column)})
- }
- {
- !mayShowColumnsPreview() &&
-
- {
- isEditable &&
-
-
-
- }
- {
- !isEditable && Your report has no columns.
- }
-
- }
+ {!hideColumns && (
+
+ Columns
+
+ {
+ mayShowColumnsPreview() &&
+ columns.columns.map((column, i) => {renderColumn(column)})
+ }
+ {
+ !mayShowColumnsPreview() &&
+
+ {
+ isEditable &&
+
+
+
+ }
+ {
+ !isEditable && Your report has no columns.
+ }
+
+ }
+
-
+ )}
{
modalOpen &&
closeEditor(event, reason)}>