feat(orchestrator): add custom review page API support#2759
feat(orchestrator): add custom review page API support#2759karthikjeeyar merged 4 commits intoredhat-developer:mainfrom
Conversation
|
Important This PR includes changes that affect public-facing API. Please ensure you are adding/updating documentation for new features or behavior. Changed Packages
|
Review Summary by QodoAdd custom review page API support for plugins
WalkthroughsDescription• Add ReviewComponentProps type for custom review components • Add optional getReviewComponent() method to OrchestratorFormApi • Update OrchestratorForm to render custom review components • Provide CustomReviewPage example implementation with Material-UI styling • Document custom review page API in extensibleForm.md Diagramflowchart LR
A["OrchestratorFormApi"] -->|getReviewComponent| B["ReviewComponentProps"]
B -->|defines props for| C["Custom Review Component"]
D["OrchestratorForm"] -->|uses| C
D -->|fallback to| E["Default ReviewStep"]
F["FormWidgetsApi"] -->|implements| A
G["CustomReviewPage"] -->|example of| C
File Changes1. workspaces/orchestrator/plugins/orchestrator-form-api/src/api.ts
|
Code Review by Qodo
|
| // Get custom review component from API if available | ||
| const orchestratorFormApi = useOrchestratorFormApiOrDefault(); | ||
| const CustomReviewComponent = useMemo(() => { | ||
| return orchestratorFormApi.getReviewComponent?.(); | ||
| }, [orchestratorFormApi]); | ||
|
|
||
| const reviewStep = useMemo(() => { | ||
| // Use custom review component if provided, otherwise use default | ||
| const ReviewComponent = CustomReviewComponent || ReviewStep; | ||
| return ( | ||
| <ReviewStep | ||
| <ReviewComponent | ||
| data={prunedFormData} | ||
| schema={schema} | ||
| busy={isExecuting} | ||
| handleExecute={_handleExecute} | ||
| // no schema update here | ||
| /> |
There was a problem hiding this comment.
1. Custom review lacks back 🐞 Bug ≡ Correctness
Custom review components receive no back-navigation capability, while the Stepper step labels are not clickable, so a custom review page can trap users on the review step. The shipped CustomReviewPage example reinforces this by rendering a Back button with no onClick handler.
Agent Prompt
## Issue description
Custom review components can’t navigate back from the review step because the stepper labels aren’t clickable and `ReviewComponentProps` doesn’t provide a back handler (and the example’s Back button has no handler).
## Issue Context
The built-in `ReviewStep` uses `useStepperContext().handleBack`, but custom review components are defined via the API package and should not rely on internal deep imports.
## Fix Focus Areas
- workspaces/orchestrator/plugins/orchestrator-form-api/src/api.ts[119-135]
- workspaces/orchestrator/plugins/orchestrator-form-react/src/components/OrchestratorForm.tsx[175-198]
- workspaces/orchestrator/plugins/orchestrator-form-react/src/components/ReviewStep.tsx[112-191]
- workspaces/orchestrator/plugins/orchestrator-form-widgets/src/components/CustomReviewPage.tsx[181-194]
## Suggested approach
1. Extend `ReviewComponentProps` to include a back callback (e.g., `handleBack: () => void`).
2. In `OrchestratorForm`, render a small wrapper component inside `reviewStep` that calls `useStepperContext()` and passes `handleBack` into the selected review component.
3. Update `ReviewStep` to accept and use the passed `handleBack` (or keep using context, but ensure TS props allow it).
4. Fix `CustomReviewPage` example to wire its Back button to `handleBack`.
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
| const renderValue = (value: any): React.ReactNode => { | ||
| if (value === null || value === undefined) { | ||
| return ( | ||
| <Typography variant="body2" color="textSecondary"> | ||
| N/A | ||
| </Typography> | ||
| ); | ||
| } | ||
| if (typeof value === 'object') { | ||
| return ( | ||
| <Typography | ||
| variant="body2" | ||
| component="pre" | ||
| sx={{ whiteSpace: 'pre-wrap' }} | ||
| > | ||
| {JSON.stringify(value, null, 2)} | ||
| </Typography> | ||
| ); | ||
| } | ||
| return <Typography variant="body2">{String(value)}</Typography>; | ||
| }; |
There was a problem hiding this comment.
2. Example exposes sensitive fields 🐞 Bug ⛨ Security
CustomReviewPage displays the raw submitted form data (including nested objects) without applying the default review-step rules that hide ui:hidden fields and mask password widgets. This can reveal values that the built-in ReviewStep intentionally suppresses (e.g., secrets/passwords).
Agent Prompt
## Issue description
`CustomReviewPage` renders `data` directly and JSON-stringifies objects, which can expose fields the default review step hides/masks (e.g., `ui:hidden` and password widgets).
## Issue Context
The built-in `ReviewStep` uses schema-aware logic (`generateReviewTableData`/`processSchema`) to:
- omit `ui:hidden` values by default
- mask password widget values
Custom review pages should demonstrate or provide an easy path to the same safety guarantees.
## Fix Focus Areas
- workspaces/orchestrator/plugins/orchestrator-form-widgets/src/components/CustomReviewPage.tsx[84-104]
- workspaces/orchestrator/plugins/orchestrator-form-widgets/src/components/CustomReviewPage.tsx[110-178]
- workspaces/orchestrator/plugins/orchestrator/docs/extensibleForm.md[62-117]
## Suggested approach
Pick one:
1. **Update the example to respect schema hiding/masking**: implement a small schema-walk that omits `ui:hidden` (static true) and masks `ui:widget=password` values before rendering.
2. **Provide a shared utility** (preferred): move/export a schema-aware review-data sanitizer (similar to `generateReviewTableData`) into a package that custom review components can depend on, and update the example/docs to use it.
3. If keeping the example as-is, add a prominent warning in docs and inline comments that it may reveal secrets and must be adapted before use.
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
d0ba58d to
20e0cfc
Compare
…tep parity - Add handleBack to ReviewComponentProps; OrchestratorForm uses ReviewStepHost to inject it from stepper context - Export generateReviewTableData, schemaHasUiHiddenFields, and NestedReviewTable from form-react - CustomReviewPage uses the same review data path and hidden-fields toggle as ReviewStep; depend on form-react - Document limitations and recommended helpers in extensibleForm.md; update changeset and API reports Made-with: Cursor
…w step Share hidden-parameters Alert+Switch between ReviewStep and CustomReviewPage to reduce duplication (Sonar). Export component and props from form-react; document in extensibleForm.md. Regenerate API reports. Made-with: Cursor
Made-with: Cursor
|




Hey, I just made a Pull Request!
Story: https://redhat.atlassian.net/browse/RHIDP-13037
Custom Review Page API:
ReviewComponentPropstype to define props for custom review componentsgetReviewComponent()method toOrchestratorFormApiinterfaceOrchestratorFormto support custom review page components from pluginsCustomReviewPageexample component in orchestrator-form-widgets plugingetReviewComponent()returnsundefinedDocumentation:
extensibleForm.mdwith custom review page implementation guide--------Custom review page-----
✔️ Checklist