diff --git a/cypress.config.ts b/cypress.config.ts
deleted file mode 100644
index a031ef1..0000000
--- a/cypress.config.ts
+++ /dev/null
@@ -1,12 +0,0 @@
-import {defineConfig} from "cypress";
-
-export default defineConfig({
- e2e: {
- viewportHeight: 1000,
- viewportWidth: 1200,
- setupNodeEvents(on, config)
- {
- // implement node event listeners here
- },
- },
-});
diff --git a/package.json b/package.json
index cb85d4f..feb4fdd 100644
--- a/package.json
+++ b/package.json
@@ -6,7 +6,7 @@
"@auth0/auth0-react": "1.10.2",
"@emotion/react": "11.7.1",
"@emotion/styled": "11.6.0",
- "@kingsrook/qqq-frontend-core": "1.0.101",
+ "@kingsrook/qqq-frontend-core": "1.0.102",
"@mui/icons-material": "5.4.1",
"@mui/material": "5.11.1",
"@mui/styles": "5.11.1",
diff --git a/src/qqq/components/forms/EntityForm.tsx b/src/qqq/components/forms/EntityForm.tsx
index bd01e2a..6e1f87e 100644
--- a/src/qqq/components/forms/EntityForm.tsx
+++ b/src/qqq/components/forms/EntityForm.tsx
@@ -44,9 +44,9 @@ import MDTypography from "qqq/components/legacy/MDTypography";
import HelpContent from "qqq/components/misc/HelpContent";
import QRecordSidebar from "qqq/components/misc/RecordSidebar";
import DynamicFormWidget from "qqq/components/widgets/misc/DynamicFormWidget";
+import FilterAndColumnsSetupWidget from "qqq/components/widgets/misc/FilterAndColumnsSetupWidget";
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 {FieldRule, FieldRuleAction, FieldRuleTrigger} from "qqq/models/fields/FieldRules";
import HtmlUtils from "qqq/utils/HtmlUtils";
import Client from "qqq/utils/qqq/Client";
@@ -88,7 +88,7 @@ EntityForm.defaultProps = {
////////////////////////////////////////////////////////////////////////////
let formikSetFieldValueFunction = (field: string, value: any, shouldValidate?: boolean): void =>
{
-}
+};
function EntityForm(props: Props): JSX.Element
{
@@ -119,11 +119,12 @@ function EntityForm(props: Props): JSX.Element
const [, forceUpdate] = useReducer((x) => x + 1, 0);
const [showEditChildForm, setShowEditChildForm] = useState(null as any);
+ const [modalDataChangedCounter, setModalDataChangedCount] = useState(0);
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);
@@ -282,6 +283,8 @@ function EntityForm(props: Props): JSX.Element
setRenderedWidgetSections(newRenderedWidgetSections);
forceUpdate();
+ setModalDataChangedCount(modalDataChangedCounter + 1);
+
setShowEditChildForm(null);
}
@@ -291,7 +294,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 +354,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,13 +372,13 @@ 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;
return ;
}
- if(widgetMetaData.type == "reportSetup")
+ if (widgetMetaData.type == "filterAndColumnsSetup")
{
- 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 +460,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++)
@@ -488,15 +499,15 @@ 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)
+ const widget = metaData?.widgets.get(section.widgetName);
+ 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 == "filterAndColumnsSetup" || widget.type == "pivotTableSetup" || widget.type == "dynamicForm")
{
return (true);
}
@@ -680,7 +691,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++)
{
@@ -719,7 +730,7 @@ function EntityForm(props: Props): JSX.Element
}
else
{
- const widgetMetaData = metaData.widgets.get(section.widgetName);
+ const widgetMetaData = metaData?.widgets.get(section.widgetName);
const widgetData = await qController.widget(widgetMetaData.name, makeQueryStringWithIdAndObject(tableMetaData, defaultValues));
newRenderedWidgetSections[section.widgetName] = getWidgetSection(widgetMetaData, widgetData);
@@ -1000,19 +1011,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 +1034,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 +1056,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 +1069,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 +1159,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 +1205,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/misc/SavedViews.tsx b/src/qqq/components/misc/SavedViews.tsx
index 32c7c6c..3b50094 100644
--- a/src/qqq/components/misc/SavedViews.tsx
+++ b/src/qqq/components/misc/SavedViews.tsx
@@ -25,7 +25,8 @@ import {QTableMetaData} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QT
import {QJobComplete} from "@kingsrook/qqq-frontend-core/lib/model/processes/QJobComplete";
import {QJobError} from "@kingsrook/qqq-frontend-core/lib/model/processes/QJobError";
import {QRecord} from "@kingsrook/qqq-frontend-core/lib/model/QRecord";
-import {Alert, Box, Button} from "@mui/material";
+import {Alert, Button} from "@mui/material";
+import Box from "@mui/material/Box";
import Dialog from "@mui/material/Dialog";
import DialogActions from "@mui/material/DialogActions";
import DialogContent from "@mui/material/DialogContent";
@@ -94,12 +95,12 @@ function SavedViews({qController, metaData, tableMetaData, currentSavedView, tab
const {accentColor, accentColorLight, userId: currentUserId} = useContext(QContext);
- /////////////////////////////////////////////////////////////////////////////////////////
- // this component is used by - but that component has different usages - //
- // e.g., the full-fledged query screen, but also, within other screens (e.g., a modal //
- // under the ReportSetupWidget). So, there are some behaviors we only want when we're //
- // on the full-fledged query screen, such as changing the URL with saved view ids. //
- /////////////////////////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////////////////////////////
+ // this component is used by - but that component has different usages - //
+ // e.g., the full-fledged query screen, but also, within other screens (e.g., a modal //
+ // under the FilterAndColumnsSetupWidget). So, there are some behaviors we only want when //
+ // we're on the full-fledged query screen, such as changing the URL with saved view ids. //
+ /////////////////////////////////////////////////////////////////////////////////////////////
const isQueryScreen = queryScreenUsage == "queryScreen";
const openSavedViewsMenu = (event: any) => setSavedViewsMenu(event.currentTarget);
diff --git a/src/qqq/components/widgets/DashboardWidgets.tsx b/src/qqq/components/widgets/DashboardWidgets.tsx
index ee57e83..edcf070 100644
--- a/src/qqq/components/widgets/DashboardWidgets.tsx
+++ b/src/qqq/components/widgets/DashboardWidgets.tsx
@@ -40,10 +40,10 @@ import DataBagViewer from "qqq/components/widgets/misc/DataBagViewer";
import DividerWidget from "qqq/components/widgets/misc/Divider";
import DynamicFormWidget from "qqq/components/widgets/misc/DynamicFormWidget";
import FieldValueListWidget from "qqq/components/widgets/misc/FieldValueListWidget";
+import FilterAndColumnsSetupWidget from "qqq/components/widgets/misc/FilterAndColumnsSetupWidget";
import PivotTableSetupWidget from "qqq/components/widgets/misc/PivotTableSetupWidget";
import QuickSightChart from "qqq/components/widgets/misc/QuickSightChart";
import RecordGridWidget from "qqq/components/widgets/misc/RecordGridWidget";
-import ReportSetupWidget from "qqq/components/widgets/misc/ReportSetupWidget";
import ScriptViewer from "qqq/components/widgets/misc/ScriptViewer";
import StepperCard from "qqq/components/widgets/misc/StepperCard";
import USMapWidget from "qqq/components/widgets/misc/USMapWidget";
@@ -598,9 +598,9 @@ function DashboardWidgets({widgetMetaDataList, tableName, entityPrimaryKey, reco
)
}
{
- widgetMetaData.type === "reportSetup" && (
+ widgetMetaData.type === "filterAndColumnsSetup" && (
widgetData && widgetData[i] && widgetData[i].queryParams &&
-
+
{
}} />
)
diff --git a/src/qqq/components/widgets/misc/ReportSetupWidget.tsx b/src/qqq/components/widgets/misc/FilterAndColumnsSetupWidget.tsx
similarity index 72%
rename from src/qqq/components/widgets/misc/ReportSetupWidget.tsx
rename to src/qqq/components/widgets/misc/FilterAndColumnsSetupWidget.tsx
index 05ebfa2..eb15c5e 100644
--- a/src/qqq/components/widgets/misc/ReportSetupWidget.tsx
+++ b/src/qqq/components/widgets/misc/FilterAndColumnsSetupWidget.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";
@@ -42,7 +45,7 @@ import Client from "qqq/utils/qqq/Client";
import FilterUtils from "qqq/utils/qqq/FilterUtils";
import React, {useContext, useEffect, useRef, useState} from "react";
-interface ReportSetupWidgetProps
+interface FilterAndColumnsSetupWidgetProps
{
isEditable: boolean;
widgetMetaData: QWidgetMetaData;
@@ -50,7 +53,7 @@ interface ReportSetupWidgetProps
onSaveCallback?: (values: { [name: string]: any }) => void;
}
-ReportSetupWidget.defaultProps = {
+FilterAndColumnsSetupWidget.defaultProps = {
onSaveCallback: null
};
@@ -80,9 +83,10 @@ const qController = Client.getInstance();
/*******************************************************************************
** Component for editing the main setup of a report - that is: filter & columns
*******************************************************************************/
-export default function ReportSetupWidget({isEditable, widgetMetaData, recordValues, onSaveCallback}: ReportSetupWidgetProps): JSX.Element
+export default function FilterAndColumnsSetupWidget({isEditable, widgetMetaData, recordValues, onSaveCallback}: FilterAndColumnsSetupWidgetProps): 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)}>
diff --git a/src/qqq/components/widgets/misc/PivotTableSetupWidget.tsx b/src/qqq/components/widgets/misc/PivotTableSetupWidget.tsx
index 9c22a98..ebfc4bb 100644
--- a/src/qqq/components/widgets/misc/PivotTableSetupWidget.tsx
+++ b/src/qqq/components/widgets/misc/PivotTableSetupWidget.tsx
@@ -39,9 +39,9 @@ import colors from "qqq/assets/theme/base/colors";
import {QCancelButton, QSaveButton} from "qqq/components/buttons/DefaultButtons";
import FieldAutoComplete from "qqq/components/misc/FieldAutoComplete";
import HelpContent, {hasHelpContent} from "qqq/components/misc/HelpContent";
+import {buttonSX, unborderedButtonSX} from "qqq/components/widgets/misc/FilterAndColumnsSetupWidget";
import {PivotTableGroupByElement} from "qqq/components/widgets/misc/PivotTableGroupByElement";
import {PivotTableValueElement} from "qqq/components/widgets/misc/PivotTableValueElement";
-import {buttonSX, unborderedButtonSX} from "qqq/components/widgets/misc/ReportSetupWidget";
import Widget, {HeaderToggleComponent} from "qqq/components/widgets/Widget";
import {PivotObjectKey, PivotTableDefinition, PivotTableFunction, pivotTableFunctionLabels, PivotTableGroupBy, PivotTableValue} from "qqq/models/misc/PivotTableDefinitionModels";
import QQueryColumns from "qqq/models/query/QQueryColumns";
diff --git a/src/qqq/pages/processes/ProcessRun.tsx b/src/qqq/pages/processes/ProcessRun.tsx
index c99d816..dc04e26 100644
--- a/src/qqq/pages/processes/ProcessRun.tsx
+++ b/src/qqq/pages/processes/ProcessRun.tsx
@@ -94,7 +94,7 @@ const BACKOFF_AMOUNT = 1.5;
////////////////////////////////////////////////////////////////////////////
let formikSetFieldValueFunction = (field: string, value: any, shouldValidate?: boolean): void =>
{
-}
+};
function ProcessRun({process, table, defaultProcessValues, isModal, isWidget, isReport, recordIds, closeModalHandler, forceReInit, overrideLabel}: Props): JSX.Element
{
@@ -134,7 +134,7 @@ function ProcessRun({process, table, defaultProcessValues, isModal, isWidget, is
const [showErrorDetail, setShowErrorDetail] = useState(false);
const [showFullHelpText, setShowFullHelpText] = useState(false);
- const [renderedWidgets, setRenderedWidgets] = useState({} as {[step: string]: {[widgetName: string]: any}});
+ const [renderedWidgets, setRenderedWidgets] = useState({} as { [step: string]: { [widgetName: string]: any } });
const {pageHeader, recordAnalytics, setPageHeader, helpHelpActive} = useContext(QContext);
@@ -238,15 +238,15 @@ function ProcessRun({process, table, defaultProcessValues, isModal, isWidget, is
setShowFullHelpText(!showFullHelpText);
};
- const download = (processValues: {[key: string]: string}) =>
+ const download = (processValues: { [key: string]: string }) =>
{
let url;
let fileName = processValues.downloadFileName;
- if(processValues.serverFilePath)
+ if (processValues.serverFilePath)
{
url = `/download/${encodeURIComponent(processValues.downloadFileName)}?filePath=${encodeURIComponent(processValues.serverFilePath)}`;
}
- else if(processValues.storageTableName && processValues.storageReference)
+ else if (processValues.storageTableName && processValues.storageReference)
{
url = `/download/${encodeURIComponent(processValues.downloadFileName)}?storageTableName=${encodeURIComponent(processValues.storageTableName)}&storageReference=${encodeURIComponent(processValues.storageReference)}`;
}
@@ -291,19 +291,19 @@ function ProcessRun({process, table, defaultProcessValues, isModal, isWidget, is
*******************************************************************************/
function renderWidget(widgetName: string)
{
- if(!renderedWidgets[activeStep.name])
+ if (!renderedWidgets[activeStep.name])
{
renderedWidgets[activeStep.name] = {};
setRenderedWidgets(renderedWidgets);
}
- if(renderedWidgets[activeStep.name][widgetName])
+ if (renderedWidgets[activeStep.name][widgetName])
{
return renderedWidgets[activeStep.name][widgetName];
}
const widgetMetaData = qInstance.widgets.get(widgetName);
- if(!widgetMetaData)
+ if (!widgetMetaData)
{
return (Unrecognized widget name: {widgetName});
}
@@ -311,12 +311,12 @@ function ProcessRun({process, table, defaultProcessValues, isModal, isWidget, is
const queryStringParts: string[] = [];
for (let name in processValues)
{
- queryStringParts.push(`${name}=${encodeURIComponent(processValues[name])}`)
+ queryStringParts.push(`${name}=${encodeURIComponent(processValues[name])}`);
}
const renderedWidget = (
- )
+ );
renderedWidgets[activeStep.name][widgetName] = renderedWidget;
return renderedWidget;
}
@@ -367,8 +367,8 @@ function ProcessRun({process, table, defaultProcessValues, isModal, isWidget, is
- {isModal ?
- : !isWidget &&
+ {isModal ? handleCancelClicked(true)} disabled={false} label="Close" />
+ : !isWidget && handleCancelClicked(true)} disabled={false} />
}
@@ -500,7 +500,7 @@ function ProcessRun({process, table, defaultProcessValues, isModal, isWidget, is
// edit the formData object to just include those. //
//////////////////////////////////////////////////////////////////////////
let formDataToUse = formData;
- if(component.values && component.values.includeFieldNames)
+ if (component.values && component.values.includeFieldNames)
{
formDataToUse = Object.assign({}, formData);
@@ -608,21 +608,21 @@ function ProcessRun({process, table, defaultProcessValues, isModal, isWidget, is
}
{
component.type === QComponentType.EDIT_FORM &&
- <>
- {
- component.values?.sectionLabel ?
-
-
-
- {component.values?.sectionLabel}
-
-
-
-
-
- :
- }
- >
+ <>
+ {
+ component.values?.sectionLabel ?
+
+
+
+ {component.values?.sectionLabel}
+
+
+
+
+
+ :
+ }
+ >
}
{
component.type === QComponentType.VIEW_FORM && step.viewFields && (
@@ -1079,14 +1079,14 @@ function ProcessRun({process, table, defaultProcessValues, isModal, isWidget, is
setProcessValues(qJobComplete.values);
setQJobRunning(null);
- if(formikSetFieldValueFunction)
+ if (formikSetFieldValueFunction)
{
//////////////////////////////////
// reset field values in formik //
//////////////////////////////////
for (let key in qJobComplete.values)
{
- if(Object.hasOwn(formFields, key))
+ if (Object.hasOwn(formFields, key))
{
console.log(`(re)setting form field [${key}] to [${qJobComplete.values[key]}]`);
formikSetFieldValueFunction(key, qJobComplete.values[key]);
@@ -1098,7 +1098,7 @@ function ProcessRun({process, table, defaultProcessValues, isModal, isWidget, is
// if the process step sent a new frontend-step-list, then refresh what we have in state (constructing new full model objects) //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
const updatedFrontendStepList = qJobComplete.updatedFrontendStepList;
- if(updatedFrontendStepList)
+ if (updatedFrontendStepList)
{
setSteps(updatedFrontendStepList);
}
@@ -1401,8 +1401,20 @@ function ProcessRun({process, table, defaultProcessValues, isModal, isWidget, is
});
};
- const handleCancelClicked = () =>
+
+ /*******************************************************************************
+ **
+ *******************************************************************************/
+ const handleCancelClicked = (isClose: boolean) =>
{
+ //////////////////////////////////////////////////////////////////
+ // unless this is a 'close', then tell backend we're cancelling //
+ //////////////////////////////////////////////////////////////////
+ if (!isClose)
+ {
+ Client.getInstance().processCancel(processName, processUUID);
+ }
+
if (isModal && closeModalHandler)
{
closeModalHandler(null, "cancelClicked");
@@ -1415,6 +1427,7 @@ function ProcessRun({process, table, defaultProcessValues, isModal, isWidget, is
navigate(path, {replace: true});
};
+
const mainCardStyles: any = {};
const formStyles: any = {};
mainCardStyles.minHeight = `calc(100vh - ${isModal ? 150 : 400}px)`;
@@ -1490,8 +1503,8 @@ function ProcessRun({process, table, defaultProcessValues, isModal, isWidget, is
{/***************************************************************************
- ** step content - e.g., the appropriate form or other screen for the step **
- ***************************************************************************/}
+ ** step content - e.g., the appropriate form or other screen for the step **
+ ***************************************************************************/}
{getDynamicStepContent(
activeStepIndex,
activeStep,
@@ -1507,8 +1520,8 @@ function ProcessRun({process, table, defaultProcessValues, isModal, isWidget, is
setFieldValue,
)}
{/********************************
- ** back &| next/submit buttons **
- ********************************/}
+ ** back &| next/submit buttons **
+ ********************************/}
{true || activeStepIndex === 0 ? (
@@ -1526,7 +1539,7 @@ function ProcessRun({process, table, defaultProcessValues, isModal, isWidget, is
)}
{
noMoreSteps && handleCancelClicked(true)}
label={isModal ? "Close" : "Return"}
iconName={isModal ? "cancel" : "arrow_back"}
disabled={isSubmitting} />
@@ -1537,7 +1550,7 @@ function ProcessRun({process, table, defaultProcessValues, isModal, isWidget, is
{
!isWidget && (
-
+ handleCancelClicked(false)} disabled={isSubmitting} />
)
}
@@ -1552,7 +1565,7 @@ function ProcessRun({process, table, defaultProcessValues, isModal, isWidget, is
- )
+ );
}}
);
diff --git a/src/test/resources/fixtures/metaData/index.json b/src/test/resources/fixtures/metaData/index.json
index 401fcda..54cd334 100644
--- a/src/test/resources/fixtures/metaData/index.json
+++ b/src/test/resources/fixtures/metaData/index.json
@@ -822,7 +822,7 @@
"reportSetupWidget": {
"name": "reportSetupWidget",
"label": "Filters and Columns",
- "type": "reportSetup",
+ "type": "filterAndColumnsSetup",
"isCard": true,
"storeDropdownSelections": false,
"showReloadButton": true,