Skip to content

feat(orchestrator): pre-populate Execute Workflow form from URL query params#2570

Open
karthikjeeyar wants to merge 4 commits intoredhat-developer:mainfrom
karthikjeeyar:orchestrator-add-query-params
Open

feat(orchestrator): pre-populate Execute Workflow form from URL query params#2570
karthikjeeyar wants to merge 4 commits intoredhat-developer:mainfrom
karthikjeeyar:orchestrator-add-query-params

Conversation

@karthikjeeyar
Copy link
Member

@karthikjeeyar karthikjeeyar commented Mar 18, 2026

prepopulate workflow execution form using query params

https://redhat.atlassian.net/browse/RHDHBUGS-2829

Add support to pre-populate workflow execution form based on the query params.

  • Query params matching schema paths prepopulate the Execute Workflow form.
  • Enum fields use case-insensitive matching; invalid values are skipped.

Path format

  • For flat schemas, use the property name directly: ?language=English&name=John
  • For nested (multi-step) schemas, use dot notation: ?firstStep.fooTheFirst=test or ?secondStep.language=English

Screenshot

image

Full Json schema support:

url: http://rhdh.example.com/orchestrator/workflows/test-prepopulate-query-params/execute?language=english&name=John&count=1&ratio=4&enabled=true&firstStep.fooTheFirst=firstValue&provideInputs.language=spanish&refContainer.nestedEnum=alpha&refContainer.nestedInt=1&refContainer.nestedFlag=true&tags=foo,bar,baz&mode.betaValue=beta

Prepopulates all the fields from queryparams.

image

✔️ Checklist

  • A changeset describing the change and affected packages. (more info)
  • Added or Updated documentation
  • Tests for new functionality and regression tests for bug fixes
  • Screenshots attached (for UI changes)

@rhdh-gh-app
Copy link

rhdh-gh-app bot commented Mar 18, 2026

Changed Packages

Package Name Package Path Changeset Bump Current Version
@red-hat-developer-hub/backstage-plugin-orchestrator workspaces/orchestrator/plugins/orchestrator patch v5.5.2

@rhdh-qodo-merge
Copy link

Review Summary by Qodo

Add URL query parameter prepopulation for Execute Workflow form

✨ Enhancement

Grey Divider

Walkthroughs

Description
• Add URL query parameter support to prepopulate Execute Workflow form fields
• Support flat and nested (dot-notation) schema paths for field mapping
• Implement case-insensitive enum matching with validation and error skipping
• Exclude reserved parameters (targetEntity, instanceId) from form prepopulation
Diagram
flowchart LR
  A["URL Query Params"] -->|"extractSchemaPaths"| B["Valid Schema Paths"]
  A -->|"iterate params"| C["mergeQueryParamsIntoFormData"]
  B -->|"validate against"| C
  D["Base Form Data"] -->|"clone & merge"| C
  C -->|"coerceValueForSchema"| E["Enum Validation"]
  E -->|"case-insensitive match"| F["Final Form Data"]
Loading

Grey Divider

File Changes

1. workspaces/orchestrator/plugins/orchestrator/src/components/ExecuteWorkflowPage/queryParamsToFormData.ts ✨ Enhancement +155/-0

Query parameter to form data conversion utility

• New utility module implementing query parameter to form data conversion logic
• extractSchemaPaths() recursively collects valid leaf property paths from JSON schema
• getSchemaAtPath() retrieves schema definition for dot-notation paths
• coerceValueForSchema() validates and coerces enum values with case-insensitive matching
• mergeQueryParamsIntoFormData() main function that merges query params into base form data while
 respecting schema constraints

workspaces/orchestrator/plugins/orchestrator/src/components/ExecuteWorkflowPage/queryParamsToFormData.ts


2. workspaces/orchestrator/plugins/orchestrator/src/components/ExecuteWorkflowPage/queryParamsToFormData.test.ts 🧪 Tests +356/-0

Complete test coverage for query param merging

• Comprehensive test suite with 20+ test cases covering all functionality
• Tests flat and nested schema property matching with dot notation
• Validates enum coercion with case-insensitive matching and invalid value skipping
• Tests reserved parameter exclusion (targetEntity, instanceId)
• Verifies URL encoding handling and immutability of base data
• Tests edge cases like empty schemas, missing params, and multiple nesting levels

workspaces/orchestrator/plugins/orchestrator/src/components/ExecuteWorkflowPage/queryParamsToFormData.test.ts


3. workspaces/orchestrator/plugins/orchestrator/src/components/ExecuteWorkflowPage/ExecuteWorkflowPage.tsx ✨ Enhancement +9/-1

Integrate query param prepopulation into workflow execution page

• Import new mergeQueryParamsIntoFormData utility function
• Refactor initialFormData from simple assignment to useMemo hook
• Integrate query parameter merging with schema validation in form initialization
• Ensure form data is prepopulated from URL params when schema is available

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


View more (2)
4. workspaces/orchestrator/docs/user-interface.md 📝 Documentation +28/-0

Document form prepopulation feature and usage

• Add new "Execute Workflow Form Prepopulation" section documenting feature
• Document path format for flat and nested schemas with examples
• Explain enum constraint handling and case-insensitive matching behavior
• List reserved query parameters (targetEntity, instanceId) and their purposes
• Provide concrete example URL showing parameter usage

workspaces/orchestrator/docs/user-interface.md


5. workspaces/orchestrator/.changeset/tall-games-fail.md ⚙️ Configuration changes +5/-0

Add changeset for query param prepopulation feature

• Create changeset entry documenting the new feature
• Mark as patch version bump for the orchestrator plugin package

workspaces/orchestrator/.changeset/tall-games-fail.md


Grey Divider

Qodo Logo

@rhdh-qodo-merge
Copy link

rhdh-qodo-merge bot commented Mar 18, 2026

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0) 📐 Spec deviations (0)

Grey Divider


Action required

1. Non-string enums never match🐞 Bug ✓ Correctness
Description
coerceValueForSchema compares enum options against the raw query-param string and returns strings,
so schemas with boolean/number/integer enums cannot be correctly prepopulated (e.g., enum [1,2]
with ?count=1 is skipped).
Code

workspaces/orchestrator/plugins/orchestrator/src/components/ExecuteWorkflowPage/queryParamsToFormData.ts[R99-117]

+function coerceValueForSchema(
+  paramValue: string,
+  propSchema: JSONSchema7 | undefined,
+): string | undefined {
+  if (!propSchema) return paramValue;
+  if (!propSchema.enum || !Array.isArray(propSchema.enum)) return paramValue;
+
+  const enumValues = propSchema.enum as (string | number | boolean)[];
+  const strParam = paramValue.trim();
+
+  // Exact match first
+  if (enumValues.includes(strParam)) return strParam;
+
+  // Case-insensitive match for string enums
+  const match = enumValues.find(
+    v => typeof v === 'string' && v.toLowerCase() === strParam.toLowerCase(),
+  );
+  return match !== undefined ? String(match) : undefined;
+}
Evidence
URLSearchParams yields string values, but coerceValueForSchema only attempts exact string match
(enumValues.includes(strParam)) and only does case-insensitive matching for string enums,
returning a string. Elsewhere in the form stack, enum matching is type-sensitive
(propSchema.enum.includes(value)), so prepopulation with string values cannot satisfy non-string
enums.

workspaces/orchestrator/plugins/orchestrator/src/components/ExecuteWorkflowPage/queryParamsToFormData.ts[99-117]
workspaces/orchestrator/plugins/orchestrator/src/components/ExecuteWorkflowPage/queryParamsToFormData.ts[145-150]
workspaces/orchestrator/plugins/orchestrator-form-react/src/utils/pruneFormData.ts[67-70]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`coerceValueForSchema` only supports string enums. For enums containing numbers/booleans, the code compares the string query param against non-string enum members, which will never match, so the param is skipped even when it represents a valid option.

## Issue Context
- Query params are always strings.
- JSON Schema enums may contain numbers/booleans.
- The form stack performs type-sensitive enum checks, so returning only strings is inconsistent.

## Fix Focus Areas
- workspaces/orchestrator/plugins/orchestrator/src/components/ExecuteWorkflowPage/queryParamsToFormData.ts[99-117]
- workspaces/orchestrator/plugins/orchestrator/src/components/ExecuteWorkflowPage/queryParamsToFormData.test.ts[287-339]

## Implementation notes
- Extend `coerceValueForSchema` to:
 - If `propSchema.type === 'boolean'`, accept `true|false` (case-insensitive) and return a boolean.
 - If `propSchema.type === 'number'` or `'integer'`, parse and return a number (and for integer, reject non-integers).
 - If `propSchema.enum` contains non-strings, attempt to match by parsing the query param into those types.
- Update return type from `string | undefined` to `JsonValue | undefined` (or a compatible type) and ensure `set()` receives the typed value.
- Add unit tests for numeric and boolean enums (and, if desired, plain typed fields without enum).

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. $ref paths not resolved🐞 Bug ✓ Correctness
Description
extractSchemaPaths/getSchemaAtPath only traverse inline schema.properties and never resolve
$ref/$defs, so query params targeting referenced fields (and their enum constraints) will not
prepopulate even though the form utilities expect $ref-heavy schemas.
Code

workspaces/orchestrator/plugins/orchestrator/src/components/ExecuteWorkflowPage/queryParamsToFormData.ts[R35-93]

+function extractSchemaPaths(
+  schema: JSONSchema7Definition,
+  path: string,
+): Set<string> {
+  const paths = new Set<string>();
+
+  if (typeof schema === 'boolean') {
+    return paths;
+  }
+
+  if (!schema.properties) {
+    return paths;
+  }
+
+  for (const [key, propSchema] of Object.entries(schema.properties)) {
+    const propPath = path ? `${path}.${key}` : key;
+
+    if (typeof propSchema === 'boolean') {
+      paths.add(propPath);
+      continue;
+    }
+
+    const propSchemaObj = propSchema as JSONSchema7;
+
+    // If this property has nested properties (object type), recurse
+    if (
+      propSchemaObj.type === 'object' &&
+      propSchemaObj.properties &&
+      Object.keys(propSchemaObj.properties).length > 0
+    ) {
+      const nestedPaths = extractSchemaPaths(propSchemaObj, propPath);
+      nestedPaths.forEach(p => paths.add(p));
+    } else {
+      // Leaf node - can be set from a query param
+      paths.add(propPath);
+    }
+  }
+
+  return paths;
+}
+
+/**
+ * Gets the schema definition for a dot-notation path within the root schema.
+ */
+function getSchemaAtPath(
+  schema: JSONSchema7,
+  path: string,
+): JSONSchema7 | undefined {
+  if (!path) return undefined;
+  const pathParts = path.split('.');
+  let current: JSONSchema7Definition = schema;
+  for (const part of pathParts) {
+    if (typeof current === 'boolean' || !current.properties?.[part]) {
+      return undefined;
+    }
+    current = current.properties[part];
+  }
+  return typeof current === 'boolean' ? undefined : (current as JSONSchema7);
+}
Evidence
Prepopulation path discovery and schema lookup stop at direct .properties and ignore $ref, while
other orchestrator form utilities explicitly resolve $ref/$defs, indicating referenced schemas
are expected to work in this codebase. This creates a functional mismatch: the form can render
referenced schemas, but query-param prepopulation won’t find or validate those referenced leaf
fields.

workspaces/orchestrator/plugins/orchestrator/src/components/ExecuteWorkflowPage/queryParamsToFormData.ts[35-93]
workspaces/orchestrator/plugins/orchestrator-form-react/src/utils/extractStaticDefaults.ts[39-59]
workspaces/orchestrator/plugins/orchestrator-form-react/src/utils/pruneFormData.ts[29-48]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`mergeQueryParamsIntoFormData` cannot prepopulate fields defined via `$ref` because `extractSchemaPaths` and `getSchemaAtPath` only walk inline `.properties`. In this codebase, schemas are already expected to use `$ref`/`$defs` (other form utilities resolve them), so prepopulation silently fails for a class of valid workflow schemas.

## Issue Context
- The orchestrator form stack already resolves `$ref` when extracting defaults and pruning data.
- Prepopulation should follow the same resolution rules so that URL params like `?step1.language=English` work even when `step1` or `language` comes from `$ref`.

## Fix Focus Areas
- workspaces/orchestrator/plugins/orchestrator/src/components/ExecuteWorkflowPage/queryParamsToFormData.ts[35-93]
- workspaces/orchestrator/plugins/orchestrator/src/components/ExecuteWorkflowPage/queryParamsToFormData.ts[129-155]
- workspaces/orchestrator/plugins/orchestrator-form-react/src/utils/extractStaticDefaults.ts[39-59]

## Implementation notes
- Introduce a small `$ref` resolver similar to `extractStaticDefaults`/`pruneFormData` (support at least `#/$defs/...` and `#/definitions/...` depending on your schema conventions).
- Update both `extractSchemaPaths` and `getSchemaAtPath` to resolve `$ref` before checking `.properties` / recursing.
- Add unit tests covering `$ref` properties (including nested `$ref`) and enum coercion on referenced schemas.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

ⓘ The new review experience is currently in Beta. Learn more

Grey Divider

Qodo Logo

@karthikjeeyar karthikjeeyar force-pushed the orchestrator-add-query-params branch from f0045b3 to c477103 Compare March 18, 2026 13:00
Copy link
Member

@lokanandaprabhu lokanandaprabhu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • Array prepopulation is not supported (query params are treated as scalar values only).
  • oneOf prepopulation is not supported.

Example schema

{
  "tags": { "type": "array", "items": { "type": "string" } },
  "mode": {
    "oneOf": [
      { "title": "Alpha", "type": "object", "properties": { "alphaValue": { "type": "string" } } },
      { "title": "Beta", "type": "object", "properties": { "betaValue": { "type": "string" } } }
    ]
  }
}

@sonarqubecloud
Copy link

@karthikjeeyar
Copy link
Member Author

@lokanandaprabhu I have added full support for JSON schema. It now supports all the types and all boolean composite paths such as oneOf/anyOf/allOf etc. Refer the PR description for an example image.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants