Skip to content

Commit 5a2da30

Browse files
jmagakGitHub Actions
andauthored
RHIDP-13141: Custom review pages in Orchestrator (redhat-developer#2136)
* Custom review pages in Orchestrator * Custom review pages in Orchestrator * Apply technical review suggestions * Update the master-adoc file * Apply peer suggestions * Apply peer suggestions --------- Co-authored-by: GitHub Actions <github-actions@github.com>
1 parent 11fcf99 commit 5a2da30

5 files changed

Lines changed: 247 additions & 0 deletions

File tree

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
:_mod-docs-content-type: ASSEMBLY
2+
ifdef::context[:parent-context: {context}]
3+
4+
[id="display-workflow-data-with-custom-review-pages_{context}"]
5+
= Display workflow data with custom review pages
6+
7+
:context: display-workflow-data-with-custom-review-pages
8+
9+
[role="_abstract"]
10+
To meet specific approval and validation requirements, configure custom review pages in {product} Orchestrator. You can use these pages to control data layout and add business rules without modifying your existing workflow definitions.
11+
12+
include::../modules/extend_orchestrator-in-rhdh/con-workflow-review-pages-for-your-approval-requirements.adoc[leveloffset=+1]
13+
14+
include::../modules/extend_orchestrator-in-rhdh/proc-build-custom-review-pages-for-workflows.adoc[leveloffset=+1]
15+
16+
include::../modules/extend_orchestrator-in-rhdh/ref-custom-review-page-api-reference.adoc[leveloffset=+1]
17+
ifdef::parent-context[:context: {parent-context}]
18+
ifndef::parent-context[:!context:]
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
:_mod-docs-content-type: CONCEPT
2+
3+
[id="workflow-review-pages-for-your-approval-requirements_{context}"]
4+
= Workflow review pages for your approval requirements
5+
6+
[role="_abstract"]
7+
You can replace the default Orchestrator review page with a custom component to meet organizational standards, show warnings, require acknowledgment before run, or integrate with design systems in {product}.
8+
9+
Custom review pages are optional. If you do not implement a custom review component, the Orchestrator continues to use the default review page without any impact on functionality.
10+
11+
Use a custom review page when you need to perform the following actions:
12+
13+
* Display workflow data in a specific layout that matches your organization's documentation or approval standards.
14+
* Apply client-side checks or show warnings before the workflow runs.
15+
* Include additional context, such as help text or links to documentation, for reviewers.
16+
* Integrate with custom UI component libraries or design systems.
17+
18+
Custom review pages are compatible with existing workflows. The same workflow definitions, schemas, and data structures work with both default and custom review pages. You can switch between review page types without modifying your workflow configurations.
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
:_mod-docs-content-type: PROCEDURE
2+
3+
[id="build-custom-review-pages-for-workflows_{context}"]
4+
= Build custom review pages for workflows
5+
6+
[role="_abstract"]
7+
To build a custom review page that displays workflow data in a specific layout, or integrates with a design system, you must implement the `getReviewComponent()` method in the form API.
8+
9+
.Prerequisites
10+
11+
* You have configured the Orchestrator plugins in your {product-short} instance.
12+
* You have a plugin or module that implements the `OrchestratorFormApi` interface from the `orchestrator-form-api` package.
13+
* You are familiar with React component development and TypeScript.
14+
15+
.Procedure
16+
17+
. In your plugin that implements `OrchestratorFormApi`, import the required types:
18+
+
19+
[source,typescript]
20+
----
21+
import type {
22+
OrchestratorFormApi,
23+
ReviewComponentProps,
24+
} from '@red-hat-developer-hub/backstage-plugin-orchestrator-form-api';
25+
----
26+
27+
. Import the helper utilities from the `orchestrator-form-react` package:
28+
+
29+
[source,typescript]
30+
----
31+
import {
32+
generateReviewTableData,
33+
schemaHasUiHiddenFields,
34+
ReviewHiddenParametersAlert,
35+
NestedReviewTable,
36+
} from '@red-hat-developer-hub/backstage-plugin-orchestrator-form-react';
37+
----
38+
+
39+
These utilities handle hidden fields, password masking, and nested data structures in your custom review page.
40+
41+
. Create your custom review page component:
42+
+
43+
[source,typescript]
44+
----
45+
import React from 'react';
46+
import { Button, Box, Typography } from '@mui/material';
47+
48+
export const CustomReviewPage = (props: ReviewComponentProps) => {
49+
const { busy, schema, data, handleBack, handleExecute } = props;
50+
const [showHiddenFields, setShowHiddenFields] = React.useState(false);
51+
52+
const reviewData = React.useMemo(
53+
() => generateReviewTableData(schema, data, {
54+
includeHiddenFields: showHiddenFields
55+
}),
56+
[schema, data, showHiddenFields]
57+
);
58+
59+
const hasHiddenFields = schemaHasUiHiddenFields(schema);
60+
61+
return (
62+
<Box>
63+
<Typography variant="h5">Review Your Workflow Data</Typography>
64+
65+
{hasHiddenFields && (
66+
<ReviewHiddenParametersAlert
67+
showHiddenFields={showHiddenFields}
68+
onShowHiddenFieldsChange={setShowHiddenFields}
69+
/>
70+
)}
71+
72+
<NestedReviewTable data={reviewData} />
73+
74+
<Box sx={{ mt: 2, display: 'flex', gap: 1 }}>
75+
<Button onClick={handleBack} disabled={busy}>
76+
Back
77+
</Button>
78+
<Button
79+
variant="contained"
80+
onClick={handleExecute}
81+
disabled={busy}
82+
>
83+
Execute Workflow
84+
</Button>
85+
</Box>
86+
</Box>
87+
);
88+
};
89+
----
90+
91+
. Add the `getReviewComponent()` method to your `OrchestratorFormApi` implementation:
92+
+
93+
[source,typescript]
94+
----
95+
export class MyFormApi implements OrchestratorFormApi {
96+
getReviewComponent() {
97+
return CustomReviewPage;
98+
}
99+
100+
// ... other OrchestratorFormApi methods
101+
}
102+
----
103+
104+
. Register your custom form API with the Orchestrator plugin according to your plugin's extension mechanism.
105+
106+
.Verification
107+
108+
. Open the Orchestrator plugin in the {product-short} web interface.
109+
. Select a workflow and complete the workflow form.
110+
. Proceed to the review step.
111+
. Confirm that your custom review page displays with the correct layout and styling.
112+
. Click *Back* and confirm that the workflow form is populated.
113+
. Click *Execute Workflow* and verify that the workflow runs successfully.
114+
115+
.Next steps
116+
117+
To revert to the default Orchestrator review page, return `undefined` from the `getReviewComponent()` method:
118+
119+
[source,typescript]
120+
----
121+
export class MyFormApi implements OrchestratorFormApi {
122+
getReviewComponent() {
123+
return undefined; // Uses default review page
124+
}
125+
}
126+
----
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
:_mod-docs-content-type: REFERENCE
2+
3+
[id="custom-review-page-api-reference_{context}"]
4+
= Custom review page API reference
5+
6+
[role="_abstract"]
7+
The custom review page API provides the `ReviewComponentProps` interface, helper utilities for data processing, and UI components to implement custom review pages for {product} Orchestrator workflows.
8+
9+
== ReviewComponentProps interface
10+
11+
Your custom review component receives the following properties through the `ReviewComponentProps` interface:
12+
13+
[cols="2,2,5",options="header"]
14+
|===
15+
|Property |Type |Description
16+
17+
|`busy`
18+
|`boolean`
19+
|Indicates whether a workflow run is in progress. Disable action buttons when this value is `true` to prevent duplicate submissions.
20+
21+
|`schema`
22+
|`JSONSchema7`
23+
|Defines field structure, titles, and UI hints such as hidden fields for the workflow form.
24+
25+
|`data`
26+
|`JsonObject`
27+
|Contains the user-submitted form values structured according to the schema and awaiting review before the workflow runs.
28+
29+
|`handleBack`
30+
|`() => void`
31+
|Returns to the previous step (same behavior as the default review page). This callback matches the default review page behavior.
32+
33+
|`handleExecute`
34+
|`() => void`
35+
|Runs the workflow with the reviewed data. Call this function when the user clicks *Run* to start the workflow.
36+
|===
37+
38+
== Helper utilities
39+
40+
The `orchestrator-form-react` package exports the following utilities to help you build custom review pages that handle data correctly:
41+
42+
[cols="2,3,4",options="header"]
43+
|===
44+
|Function |Signature |Description
45+
46+
|`generateReviewTableData`
47+
|`(schema: JSONSchema7, data: JsonObject, options?: {includeHiddenFields?: boolean}) => JsonObject`
48+
|Processes form data for display. Respects `ui:hidden` fields, masks password fields, and structures nested data. Use this to prepare data for rendering in your custom review component.
49+
50+
|`schemaHasUiHiddenFields`
51+
|`(schema: JSONSchema7) => boolean`
52+
|Returns `true` if the schema contains fields marked with `ui:hidden` in the UI schema. Use this to determine if the UI should display a toggle for hidden fields.
53+
|===
54+
55+
== Helper components
56+
57+
The `orchestrator-form-react` package exports the following React components for use in custom review pages:
58+
59+
[cols="2,2,5",options="header"]
60+
|===
61+
|Component |Props |Description
62+
63+
|`NestedReviewTable`
64+
|`data: JsonObject`
65+
|Renders form data in a nested table structure. Accepts data processed by `generateReviewTableData()` and displays it with proper formatting for nested objects and arrays.
66+
67+
|`ReviewHiddenParametersAlert`
68+
|`showHiddenFields: boolean, onShowHiddenFieldsChange: (includeHidden: boolean) => void`
69+
|Displays an alert with a toggle switch for showing or hiding fields marked as `ui:hidden` in the schema. Use this component when `schemaHasUiHiddenFields()` returns `true`.
70+
|===
71+
72+
== OrchestratorFormApi method
73+
74+
To provide a custom review page, implement the following method in your `OrchestratorFormApi` implementation:
75+
76+
[cols="2,3,4",options="header"]
77+
|===
78+
|Method |Return Type |Description
79+
80+
|`getReviewComponent()`
81+
|`React.ComponentType<ReviewComponentProps> \| undefined`
82+
|Returns your custom review page component, or `undefined` to use the default Orchestrator review page. The returned component must accept `ReviewComponentProps` as its props.
83+
|===

titles/extend_orchestrator-in-rhdh/master.adoc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ include::assemblies/extend_orchestrator-in-rhdh/assembly-enable-orchestrator-plu
2020

2121
include::assemblies/extend_orchestrator-in-rhdh/assembly-trigger-workflows-from-event-driven-systems-with-cloudevents.adoc[leveloffset=+1]
2222

23+
include::assemblies/extend_orchestrator-in-rhdh/assembly-display-workflow-data-with-custom-review-pages.adoc[leveloffset=+1]
24+
2325
include::assemblies/extend_orchestrator-in-rhdh/assembly-install-rhdh-with-orchestrator-by-using-the-rhdh-operator.adoc[leveloffset=+1]
2426

2527
include::assemblies/extend_orchestrator-in-rhdh/assembly-install-rhdh-with-orchestrator-by-using-the-rhdh-helm-chart.adoc[leveloffset=+1]

0 commit comments

Comments
 (0)