Skip to content

Commit 3988b16

Browse files
feat(orchestrator): pre-populate Execute Workflow form from URL query params (#2570)
* prepopulate workflow execution page form from URL query params Signed-off-by: Karthik <karthik.jk11@gmail.com> * support enum coercison for case-insenstive match and skip invalid values * add support for fields that are defined via '$ref' * add full support for json schema fields --------- Signed-off-by: Karthik <karthik.jk11@gmail.com>
1 parent a3fe4bb commit 3988b16

7 files changed

Lines changed: 1015 additions & 1 deletion

File tree

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@red-hat-developer-hub/backstage-plugin-orchestrator': patch
3+
---
4+
5+
prepopulate Execute Workflow form from URL query params

workspaces/orchestrator/docs/user-interface.md

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,52 @@ Workflows can also be invoked from Backstage software templates using the `orche
2121
- Monitor workflow execution status
2222
- View workflow results and outputs
2323

24+
### Execute Workflow Form Prepopulation
25+
26+
The Execute Workflow page supports prepopulating form fields from URL query parameters. When the workflow schema defines input fields, any query parameter whose name matches a schema property path will be used to prepopulate the corresponding form field.
27+
28+
**Path format**
29+
30+
- For flat schemas, use the property name directly: `?language=English&name=John`
31+
- For nested (multi-step) schemas, use dot notation: `?firstStep.fooTheFirst=test` or `?provideInputs.language=English`
32+
- For fields inside `oneOf` or `anyOf` branches, use the same dot notation: `?mode.alphaValue=test`
33+
34+
**Schema support**
35+
36+
The prepopulation logic supports the full JSON Schema draft-07 spec, including:
37+
38+
- Fields defined via `$ref` in `$defs` or `definitions`
39+
- `oneOf` and `anyOf` — the correct branch is resolved from the provided data
40+
- Array fields — use comma-separated values: `?tags=foo,bar,baz`
41+
- Type coercion for numbers, integers, and booleans
42+
43+
**Schema constraints**
44+
45+
For fields with `enum` constraints in the schema, the query param value must match one of the allowed values. Case-insensitive matching is supported (e.g. `?language=english` maps to `English` when the enum is `['English', 'Spanish']`). Values that do not match any enum option are ignored and will not prepopulate the field.
46+
47+
Query parameters that do not match any schema property path are ignored and will not be merged into the form.
48+
49+
**Reserved parameters**
50+
51+
The following query parameters are reserved for navigation and are not used for form prepopulation:
52+
53+
- `targetEntity` — Used to associate the workflow run with a catalog entity
54+
- `instanceId` — Used when re-running or viewing a specific workflow instance
55+
56+
**Examples**
57+
58+
```
59+
/orchestrator/workflows/yamlgreet/execute?targetEntity=default:component:my-app&language=English&name=alice
60+
```
61+
62+
In this example, `targetEntity` is excluded (reserved), while `language` and `name` prepopulate the form when those fields exist in the workflow schema.
63+
64+
```
65+
/orchestrator/workflows/my-workflow/execute?language=English&mode.alphaValue=prefilled&tags=a,b,c
66+
```
67+
68+
This example prepopulates a flat field (`language`), a nested field inside an `oneOf` branch (`mode.alphaValue`), and an array field (`tags`).
69+
2470
### Entity Integration
2571

2672
- Workflow tabs on entity pages

workspaces/orchestrator/plugins/orchestrator/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@
8383
"@red-hat-developer-hub/backstage-plugin-orchestrator-form-react": "workspace:^",
8484
"axios": "^1.11.0",
8585
"json-schema": "^0.4.0",
86+
"json-schema-library": "^9.0.0",
8687
"lodash": "^4.17.21",
8788
"luxon": "^3.7.2",
8889
"react-use": "^17.4.0",

workspaces/orchestrator/plugins/orchestrator/src/components/ExecuteWorkflowPage/ExecuteWorkflowPage.tsx

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ import {
5555
import { getErrorObject } from '../../utils/ErrorUtils';
5656
import { BaseOrchestratorPage } from '../ui/BaseOrchestratorPage';
5757
import MissingSchemaNotice from './MissingSchemaNotice';
58+
import { mergeQueryParamsIntoFormData } from './queryParamsToFormData';
5859
import { getSchemaUpdater } from './schemaUpdater';
5960

6061
export const ExecuteWorkflowPage = () => {
@@ -67,6 +68,7 @@ export const ExecuteWorkflowPage = () => {
6768
const [isExecuting, setIsExecuting] = useState(false);
6869
const [updateError, setUpdateError] = useState<Error>();
6970
const [instanceId] = useQueryParamState<string>(QUERY_PARAM_INSTANCE_ID);
71+
7072
const navigate = useNavigate();
7173
const instanceLink = useRouteRef(workflowInstanceRouteRef);
7274
const entityInstanceLink = useRouteRef(entityInstanceRouteRef);
@@ -96,7 +98,13 @@ export const ExecuteWorkflowPage = () => {
9698
[schema],
9799
);
98100

99-
const initialFormData = value?.data ?? {};
101+
const initialFormData = useMemo(() => {
102+
const baseData = value?.data ?? {};
103+
if (!schema) {
104+
return baseData;
105+
}
106+
return mergeQueryParamsIntoFormData(schema, searchParams, baseData);
107+
}, [schema, value?.data, searchParams]);
100108
const {
101109
value: workflowName,
102110
loading: workflowNameLoading,

0 commit comments

Comments
 (0)