mirror of
https://github.com/Kingsrook/qqq-frontend-material-dashboard.git
synced 2025-07-18 13:20:43 +00:00
CE-1955 - Add support for 'back' in processes. add a 'loadingRecords' state var, to help validation screen not flicker 'none found'
This commit is contained in:
@ -51,10 +51,9 @@ import {Form, Formik} from "formik";
|
|||||||
import parse from "html-react-parser";
|
import parse from "html-react-parser";
|
||||||
import QContext from "QContext";
|
import QContext from "QContext";
|
||||||
import colors from "qqq/assets/theme/base/colors";
|
import colors from "qqq/assets/theme/base/colors";
|
||||||
import {QCancelButton, QSubmitButton} from "qqq/components/buttons/DefaultButtons";
|
import {QAlternateButton, QCancelButton, QSubmitButton} from "qqq/components/buttons/DefaultButtons";
|
||||||
import QDynamicForm from "qqq/components/forms/DynamicForm";
|
import QDynamicForm from "qqq/components/forms/DynamicForm";
|
||||||
import DynamicFormUtils from "qqq/components/forms/DynamicFormUtils";
|
import DynamicFormUtils from "qqq/components/forms/DynamicFormUtils";
|
||||||
import MDButton from "qqq/components/legacy/MDButton";
|
|
||||||
import MDProgress from "qqq/components/legacy/MDProgress";
|
import MDProgress from "qqq/components/legacy/MDProgress";
|
||||||
import MDTypography from "qqq/components/legacy/MDTypography";
|
import MDTypography from "qqq/components/legacy/MDTypography";
|
||||||
import HelpContent, {hasHelpContent} from "qqq/components/misc/HelpContent";
|
import HelpContent, {hasHelpContent} from "qqq/components/misc/HelpContent";
|
||||||
@ -98,6 +97,8 @@ const INITIAL_RETRY_MILLIS = 1_500;
|
|||||||
const RETRY_MAX_MILLIS = 12_000;
|
const RETRY_MAX_MILLIS = 12_000;
|
||||||
const BACKOFF_AMOUNT = 1.5;
|
const BACKOFF_AMOUNT = 1.5;
|
||||||
|
|
||||||
|
const qController = Client.getInstance();
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// define some functions that we can make reference to, which we'll overwrite //
|
// define some functions that we can make reference to, which we'll overwrite //
|
||||||
// with functions from formik, once we're inside formik. //
|
// with functions from formik, once we're inside formik. //
|
||||||
@ -140,6 +141,7 @@ function ProcessRun({process, table, defaultProcessValues, isModal, isWidget, is
|
|||||||
const [newStep, setNewStep] = useState(null);
|
const [newStep, setNewStep] = useState(null);
|
||||||
const [stepInstanceCounter, setStepInstanceCounter] = useState(0);
|
const [stepInstanceCounter, setStepInstanceCounter] = useState(0);
|
||||||
const [steps, setSteps] = useState([] as QFrontendStepMetaData[]);
|
const [steps, setSteps] = useState([] as QFrontendStepMetaData[]);
|
||||||
|
const [backStepName, setBackStepName] = useState(null as string);
|
||||||
const [needInitialLoad, setNeedInitialLoad] = useState(true);
|
const [needInitialLoad, setNeedInitialLoad] = useState(true);
|
||||||
const [lastForcedReInit, setLastForcedReInit] = useState(null as number);
|
const [lastForcedReInit, setLastForcedReInit] = useState(null as number);
|
||||||
const [processMetaData, setProcessMetaData] = useState(null);
|
const [processMetaData, setProcessMetaData] = useState(null);
|
||||||
@ -216,6 +218,7 @@ function ProcessRun({process, table, defaultProcessValues, isModal, isWidget, is
|
|||||||
// record list state //
|
// record list state //
|
||||||
///////////////////////
|
///////////////////////
|
||||||
const [needRecords, setNeedRecords] = useState(false);
|
const [needRecords, setNeedRecords] = useState(false);
|
||||||
|
const [loadingRecords, setLoadingRecords] = useState(false);
|
||||||
const [recordConfig, setRecordConfig] = useState({} as any);
|
const [recordConfig, setRecordConfig] = useState({} as any);
|
||||||
const [pageNumber, setPageNumber] = useState(0);
|
const [pageNumber, setPageNumber] = useState(0);
|
||||||
const [rowsPerPage, setRowsPerPage] = useState(10);
|
const [rowsPerPage, setRowsPerPage] = useState(10);
|
||||||
@ -905,6 +908,7 @@ function ProcessRun({process, table, defaultProcessValues, isModal, isWidget, is
|
|||||||
processValues={processValues}
|
processValues={processValues}
|
||||||
step={step}
|
step={step}
|
||||||
previewRecords={records}
|
previewRecords={records}
|
||||||
|
loadingRecords={loadingRecords}
|
||||||
formValues={formData.values}
|
formValues={formData.values}
|
||||||
doFullValidationRadioChangedHandler={(event: any) =>
|
doFullValidationRadioChangedHandler={(event: any) =>
|
||||||
{
|
{
|
||||||
@ -1384,7 +1388,7 @@ function ProcessRun({process, table, defaultProcessValues, isModal, isWidget, is
|
|||||||
setNeedRecords(false);
|
setNeedRecords(false);
|
||||||
(async () =>
|
(async () =>
|
||||||
{
|
{
|
||||||
const response = await Client.getInstance().processRecords(
|
const response = await qController.processRecords(
|
||||||
processName,
|
processName,
|
||||||
processUUID,
|
processUUID,
|
||||||
recordConfig.rowsPerPage * recordConfig.pageNo,
|
recordConfig.rowsPerPage * recordConfig.pageNo,
|
||||||
@ -1393,6 +1397,7 @@ function ProcessRun({process, table, defaultProcessValues, isModal, isWidget, is
|
|||||||
|
|
||||||
const {records} = response;
|
const {records} = response;
|
||||||
setRecords(records);
|
setRecords(records);
|
||||||
|
setLoadingRecords(false);
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// re-construct the recordConfig object, so the setState call triggers a new rendering //
|
// re-construct the recordConfig object, so the setState call triggers a new rendering //
|
||||||
@ -1535,7 +1540,7 @@ function ProcessRun({process, table, defaultProcessValues, isModal, isWidget, is
|
|||||||
const fieldName = field.name;
|
const fieldName = field.name;
|
||||||
if (field.possibleValueSourceName && newValues && newValues[fieldName])
|
if (field.possibleValueSourceName && newValues && newValues[fieldName])
|
||||||
{
|
{
|
||||||
const results: QPossibleValue[] = await Client.getInstance().possibleValues(null, processName, fieldName, null, [newValues[fieldName]]);
|
const results: QPossibleValue[] = await qController.possibleValues(null, processName, fieldName, null, [newValues[fieldName]]);
|
||||||
if (results && results.length > 0)
|
if (results && results.length > 0)
|
||||||
{
|
{
|
||||||
if (!cachedPossibleValueLabels[fieldName])
|
if (!cachedPossibleValueLabels[fieldName])
|
||||||
@ -1549,6 +1554,9 @@ function ProcessRun({process, table, defaultProcessValues, isModal, isWidget, is
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////
|
||||||
|
// reset some state between screens //
|
||||||
|
//////////////////////////////////////
|
||||||
setJobUUID(null);
|
setJobUUID(null);
|
||||||
setNewStep(nextStepName);
|
setNewStep(nextStepName);
|
||||||
setStepInstanceCounter(1 + stepInstanceCounter);
|
setStepInstanceCounter(1 + stepInstanceCounter);
|
||||||
@ -1556,6 +1564,7 @@ function ProcessRun({process, table, defaultProcessValues, isModal, isWidget, is
|
|||||||
setRenderedWidgets({});
|
setRenderedWidgets({});
|
||||||
setSubFormPreSubmitCallbacks([]);
|
setSubFormPreSubmitCallbacks([]);
|
||||||
setQJobRunning(null);
|
setQJobRunning(null);
|
||||||
|
setBackStepName(qJobComplete.backStep)
|
||||||
|
|
||||||
if (formikSetFieldValueFunction)
|
if (formikSetFieldValueFunction)
|
||||||
{
|
{
|
||||||
@ -1633,7 +1642,7 @@ function ProcessRun({process, table, defaultProcessValues, isModal, isWidget, is
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
const processResponse = await Client.getInstance().processJobStatus(
|
const processResponse = await qController.processJobStatus(
|
||||||
processName,
|
processName,
|
||||||
processUUID,
|
processUUID,
|
||||||
jobUUID,
|
jobUUID,
|
||||||
@ -1734,7 +1743,7 @@ function ProcessRun({process, table, defaultProcessValues, isModal, isWidget, is
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
const qInstance = await Client.getInstance().loadMetaData();
|
const qInstance = await qController.loadMetaData();
|
||||||
ValueUtils.qInstance = qInstance;
|
ValueUtils.qInstance = qInstance;
|
||||||
setQInstance(qInstance);
|
setQInstance(qInstance);
|
||||||
}
|
}
|
||||||
@ -1746,7 +1755,7 @@ function ProcessRun({process, table, defaultProcessValues, isModal, isWidget, is
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
const processMetaData = await Client.getInstance().loadProcessMetaData(processName);
|
const processMetaData = await qController.loadProcessMetaData(processName);
|
||||||
setProcessMetaData(processMetaData);
|
setProcessMetaData(processMetaData);
|
||||||
setSteps(processMetaData.frontendSteps);
|
setSteps(processMetaData.frontendSteps);
|
||||||
|
|
||||||
@ -1757,7 +1766,7 @@ function ProcessRun({process, table, defaultProcessValues, isModal, isWidget, is
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
const tableMetaData = await Client.getInstance().loadTableMetaData(processMetaData.tableName);
|
const tableMetaData = await qController.loadTableMetaData(processMetaData.tableName);
|
||||||
setTableMetaData(tableMetaData);
|
setTableMetaData(tableMetaData);
|
||||||
}
|
}
|
||||||
catch (e)
|
catch (e)
|
||||||
@ -1788,7 +1797,7 @@ function ProcessRun({process, table, defaultProcessValues, isModal, isWidget, is
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
const processResponse = await Client.getInstance().processInit(processName, queryStringPairsForInit.join("&"));
|
const processResponse = await qController.processInit(processName, queryStringPairsForInit.join("&"));
|
||||||
setProcessUUID(processResponse.processUUID);
|
setProcessUUID(processResponse.processUUID);
|
||||||
setLastProcessResponse(processResponse);
|
setLastProcessResponse(processResponse);
|
||||||
}
|
}
|
||||||
@ -1805,7 +1814,27 @@ function ProcessRun({process, table, defaultProcessValues, isModal, isWidget, is
|
|||||||
//////////////////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
const handleBack = () =>
|
const handleBack = () =>
|
||||||
{
|
{
|
||||||
setNewStep(activeStepIndex - 1);
|
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// note, this is kept out of clearStatesBeforeHittingBackend, because in handleSubmit, the form //
|
||||||
|
// might become invalidated, in which case we'd want a form error, i guess. //
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
setFormError(null);
|
||||||
|
|
||||||
|
clearStatesBeforeHittingBackend();
|
||||||
|
|
||||||
|
setTimeout(async () =>
|
||||||
|
{
|
||||||
|
recordAnalytics({category: "processEvents", action: "processStep", label: activeStep.label});
|
||||||
|
|
||||||
|
const processResponse = await qController.processStep(
|
||||||
|
processName,
|
||||||
|
processUUID,
|
||||||
|
backStepName,
|
||||||
|
"isStepBack=true",
|
||||||
|
qController.defaultMultipartFormDataHeaders(),
|
||||||
|
);
|
||||||
|
setLastProcessResponse(processResponse);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -1872,10 +1901,29 @@ function ProcessRun({process, table, defaultProcessValues, isModal, isWidget, is
|
|||||||
formData.append("bulkEditEnabledFields", bulkEditEnabledFields.join(","));
|
formData.append("bulkEditEnabledFields", bulkEditEnabledFields.join(","));
|
||||||
}
|
}
|
||||||
|
|
||||||
const formDataHeaders = {
|
clearStatesBeforeHittingBackend();
|
||||||
"content-type": "multipart/form-data; boundary=--------------------------320289315924586491558366",
|
|
||||||
};
|
|
||||||
|
|
||||||
|
setTimeout(async () =>
|
||||||
|
{
|
||||||
|
recordAnalytics({category: "processEvents", action: "processStep", label: activeStep.label});
|
||||||
|
|
||||||
|
const processResponse = await qController.processStep(
|
||||||
|
processName,
|
||||||
|
processUUID,
|
||||||
|
activeStep.name,
|
||||||
|
formData,
|
||||||
|
qController.defaultMultipartFormDataHeaders(),
|
||||||
|
);
|
||||||
|
setLastProcessResponse(processResponse);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** common code shared by 'back' and 'submit' (next) - to clear some state values.
|
||||||
|
*******************************************************************************/
|
||||||
|
const clearStatesBeforeHittingBackend = () =>
|
||||||
|
{
|
||||||
setProcessValues({});
|
setProcessValues({});
|
||||||
setRecords([]);
|
setRecords([]);
|
||||||
setOverrideOnLastStep(null);
|
setOverrideOnLastStep(null);
|
||||||
@ -1884,22 +1932,15 @@ function ProcessRun({process, table, defaultProcessValues, isModal, isWidget, is
|
|||||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// clear out the active step now, to avoid a flash of the old one after the job completes, but before the new one is all set //
|
// clear out the active step now, to avoid a flash of the old one after the job completes, but before the new one is all set //
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// setActiveStep(null);
|
setActiveStep(null);
|
||||||
|
|
||||||
setTimeout(async () =>
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
{
|
// setting this flag here (initially, for use in ValidationReview) will ensure that the initial render of //
|
||||||
recordAnalytics({category: "processEvents", action: "processStep", label: activeStep.label});
|
// such a component will show as "loading", rather than a flash of "no records" before going into loading //
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
setLoadingRecords(true);
|
||||||
|
|
||||||
const processResponse = await Client.getInstance().processStep(
|
}
|
||||||
processName,
|
|
||||||
processUUID,
|
|
||||||
activeStep.name,
|
|
||||||
formData,
|
|
||||||
formDataHeaders,
|
|
||||||
);
|
|
||||||
setLastProcessResponse(processResponse);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
@ -1912,7 +1953,7 @@ function ProcessRun({process, table, defaultProcessValues, isModal, isWidget, is
|
|||||||
//////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////
|
||||||
if (!isClose)
|
if (!isClose)
|
||||||
{
|
{
|
||||||
Client.getInstance().processCancel(processName, processUUID);
|
qController.processCancel(processName, processUUID);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isModal && closeModalHandler)
|
if (isModal && closeModalHandler)
|
||||||
@ -2050,12 +2091,7 @@ function ProcessRun({process, table, defaultProcessValues, isModal, isWidget, is
|
|||||||
{/********************************
|
{/********************************
|
||||||
** back &| next/submit buttons **
|
** back &| next/submit buttons **
|
||||||
********************************/}
|
********************************/}
|
||||||
<Box mt={3} width="100%" display="flex" justifyContent="space-between" position={isWidget ? "absolute" : "initial"} bottom={isWidget ? "3rem" : "initial"} right={isWidget ? "1.5rem" : "initial"}>
|
<Box mt={3} width="100%" display="flex" justifyContent="flex-end" position={isWidget ? "absolute" : "initial"} bottom={isWidget ? "3rem" : "initial"} right={isWidget ? "1.5rem" : "initial"}>
|
||||||
{true || activeStepIndex === 0 ? (
|
|
||||||
<Box />
|
|
||||||
) : (
|
|
||||||
<MDButton variant="gradient" color="light" onClick={handleBack}>back</MDButton>
|
|
||||||
)}
|
|
||||||
{processError || qJobRunning || !activeStep || activeStep?.format?.toLowerCase() == "scanner" ? (
|
{processError || qJobRunning || !activeStep || activeStep?.format?.toLowerCase() == "scanner" ? (
|
||||||
<Box />
|
<Box />
|
||||||
) : (
|
) : (
|
||||||
@ -2076,6 +2112,13 @@ function ProcessRun({process, table, defaultProcessValues, isModal, isWidget, is
|
|||||||
<QCancelButton onClickHandler={() => handleCancelClicked(false)} disabled={isSubmitting} />
|
<QCancelButton onClickHandler={() => handleCancelClicked(false)} disabled={isSubmitting} />
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{backStepName ? (
|
||||||
|
<QAlternateButton label="Back" onClick={handleBack} disabled={isSubmitting} iconName="arrow_back" />
|
||||||
|
) : (
|
||||||
|
<Box />
|
||||||
|
)}
|
||||||
|
|
||||||
<QSubmitButton label={nextButtonLabel} iconName={nextButtonIcon} disabled={isSubmitting} />
|
<QSubmitButton label={nextButtonLabel} iconName={nextButtonIcon} disabled={isSubmitting} />
|
||||||
</Grid>
|
</Grid>
|
||||||
</Box>
|
</Box>
|
||||||
|
Reference in New Issue
Block a user