diff --git a/packages/common/src/wizard/reducer.js b/packages/common/src/wizard/reducer.js
index ff673c026..53f0aeac5 100644
--- a/packages/common/src/wizard/reducer.js
+++ b/packages/common/src/wizard/reducer.js
@@ -22,6 +22,7 @@ const createSchema = ({ formOptions, fields }) => {
field.substepOf,
index,
primary: !schema[schema.length - 1] || !field.substepOf || field.substepOf !== schema[schema.length - 1].substepOf,
+ isProgressAfterSubmissionStep: field.isProgressAfterSubmissionStep,
},
];
diff --git a/packages/pf4-component-mapper/demo/demo-schemas/wizard-schema.js b/packages/pf4-component-mapper/demo/demo-schemas/wizard-schema.js
index 9029b03e2..e108d86d8 100644
--- a/packages/pf4-component-mapper/demo/demo-schemas/wizard-schema.js
+++ b/packages/pf4-component-mapper/demo/demo-schemas/wizard-schema.js
@@ -441,3 +441,62 @@ export const wizardSchemaMoreSubsteps = {
}
]
};
+
+export const wizardSchemaProgressAfterSubmission = {
+ fields: [
+ {
+ component: componentTypes.WIZARD,
+ name: 'progress-wizard',
+ title: 'Progress after submission',
+ description: 'This wizard shows a progress step after submission',
+ fields: [
+ {
+ title: 'Step 1',
+ name: 'step-1',
+ nextStep: 'step-2',
+ fields: [
+ {
+ component: componentTypes.TEXT_FIELD,
+ name: 'name',
+ label: 'Name',
+ isRequired: true,
+ validate: [
+ {
+ type: validatorTypes.REQUIRED
+ }
+ ]
+ }
+ ]
+ },
+ {
+ title: 'Step 2',
+ name: 'step-2',
+ nextStep: 'progress-step',
+ fields: [
+ {
+ component: componentTypes.TEXT_FIELD,
+ name: 'email',
+ label: 'Email',
+ isRequired: true,
+ validate: [
+ {
+ type: validatorTypes.REQUIRED
+ }
+ ]
+ }
+ ]
+ },
+ {
+ name: 'progress-step',
+ isProgressAfterSubmissionStep: true,
+ fields: [
+ {
+ name: 'progress-content',
+ component: 'progress-step-content'
+ }
+ ]
+ }
+ ]
+ }
+ ]
+};
diff --git a/packages/pf4-component-mapper/demo/index.js b/packages/pf4-component-mapper/demo/index.js
index ab384d64d..b23969783 100644
--- a/packages/pf4-component-mapper/demo/index.js
+++ b/packages/pf4-component-mapper/demo/index.js
@@ -1,15 +1,29 @@
import React from 'react';
import { createRoot } from 'react-dom/client';
-import { FormRenderer } from '@data-driven-forms/react-form-renderer';
+import { FormRenderer, WizardContext } from '@data-driven-forms/react-form-renderer';
import { arraySchemaDDF } from './demo-schemas/widget-schema';
import { componentMapper, FormTemplate } from '../src';
-import { Title, Button, Toolbar, ToolbarGroup, ToolbarItem } from '@patternfly/react-core';
+import {
+ Title,
+ Button,
+ Toolbar,
+ ToolbarGroup,
+ ToolbarItem,
+ EmptyState,
+ EmptyStateBody,
+ EmptyStateFooter,
+ EmptyStateActions,
+ Progress,
+ Bullseye
+} from '@patternfly/react-core';
+import { CogsIcon } from '@patternfly/react-icons';
import {
wizardSchema,
wizardSchemaWithFunction,
wizardSchemaSimple,
wizardSchemaSubsteps,
wizardSchemaMoreSubsteps,
+ wizardSchemaProgressAfterSubmission,
} from './demo-schemas/wizard-schema';
import sandboxSchema from './demo-schemas/sandbox';
import dualSchema from './demo-schemas/dual-list-schema';
@@ -18,6 +32,48 @@ import selectSchema from './demo-schemas/select-schema';
const Summary = (props) =>
Custom summary component.
;
+const ProgressStepContent = () => {
+ const { jumpToStep } = React.useContext(WizardContext);
+ const [percentValidated, setPercentValidated] = React.useState(0);
+
+ const tick = React.useCallback(() => {
+ if (percentValidated < 100) {
+ setPercentValidated(prevValue => prevValue + 20);
+ }
+ }, [percentValidated]);
+
+ React.useEffect(() => {
+ const interval = setInterval(() => tick(), 1000);
+ return () => clearInterval(interval);
+ }, [tick]);
+
+ return (
+
+
+
+
+
+
+ Description can be used to further elaborate on the validation step, or give the user a better idea of how
+ long the process will take.
+
+
+
+
+
+
+
+
+ );
+};
+
const fieldArrayState = {
schema: arraySchemaDDF,
additionalOptions: {
@@ -135,6 +191,19 @@ class App extends React.Component {
FormTemplate={(props) => }
{...this.state.additionalOptions}
/>
+ Progress after submission
+ console.log('Cancel action')}
+ schema={wizardSchemaProgressAfterSubmission}
+ FormTemplate={(props) => }
+ {...this.state.additionalOptions}
+ />
>
)}
diff --git a/packages/pf4-component-mapper/src/wizard/wizard-components/wizard-nav.js b/packages/pf4-component-mapper/src/wizard/wizard-components/wizard-nav.js
index f7dc19956..9a4bdd981 100644
--- a/packages/pf4-component-mapper/src/wizard/wizard-components/wizard-nav.js
+++ b/packages/pf4-component-mapper/src/wizard/wizard-components/wizard-nav.js
@@ -22,7 +22,7 @@ const WizardNavigationInternal = React.memo(
({ navSchema, activeStepIndex, maxStepIndex, jumpToStep, valid, validating }) => (
{navSchema
- .filter((field) => field.primary)
+ .filter((field) => field.primary && !field.isProgressAfterSubmissionStep)
.map((step) => {
const substeps = step.substepOf && navSchema.filter((field) => field.substepOf === step.substepOf);
diff --git a/packages/pf4-component-mapper/src/wizard/wizard.js b/packages/pf4-component-mapper/src/wizard/wizard.js
index f8294235f..7ce588484 100644
--- a/packages/pf4-component-mapper/src/wizard/wizard.js
+++ b/packages/pf4-component-mapper/src/wizard/wizard.js
@@ -85,6 +85,8 @@ const WizardInternal = ({
return null;
}
+ const isProgressAfterSubmissionStep = currentStep.isProgressAfterSubmissionStep;
+
return (
)}
-
-
-
-
-
- {({ values, valid, validating }) => (
- {
- state.openNav && dispatch({ type: 'closeNav' });
- return jumpToStep(...args);
- }}
- crossroads={crossroads}
- isDynamic={isDynamic}
- values={values}
- setPrevSteps={setPrevSteps}
- validating={validating}
- />
- )}
-
-
- handleNext(nextStep)}
- handlePrev={handlePrev}
- disableBack={activeStepIndex === 0}
+ {isProgressAfterSubmissionStep ? (
+ currentStep.fields.map((item) => formOptions.renderForm([item], formOptions))
+ ) : (
+ <>
+
-
-
+
+
+
+
+ {({ values, valid, validating }) => (
+ {
+ state.openNav && dispatch({ type: 'closeNav' });
+ return jumpToStep(...args);
+ }}
+ crossroads={crossroads}
+ isDynamic={isDynamic}
+ values={values}
+ setPrevSteps={setPrevSteps}
+ validating={validating}
+ />
+ )}
+
+
+ handleNext(nextStep)}
+ handlePrev={handlePrev}
+ disableBack={activeStepIndex === 0}
+ />
+
+
+ >
+ )}
);
diff --git a/packages/react-form-renderer/src/tests/form-renderer/condition.test.js b/packages/react-form-renderer/src/tests/form-renderer/condition.test.js
index a119b0d21..a8c5f4547 100644
--- a/packages/react-form-renderer/src/tests/form-renderer/condition.test.js
+++ b/packages/react-form-renderer/src/tests/form-renderer/condition.test.js
@@ -676,7 +676,7 @@ describe('condition test', () => {
await waitFor(() => {
expect(errorSpy).toHaveBeenCalled();
// eslint-disable-next-line no-console
- const errorMessage = console.error.mock.calls.map(call => call[0]).join(' ');
+ const errorMessage = console.error.mock.calls.map((call) => call[0]).join(' ');
expect(errorMessage).toContain('Received invalid setterValue. Expected object, received: ');
});
});