Skip to content

feat(orchestrator): support nested objects in rjsf-widgets config - #4461

Open
lokanandaprabhu wants to merge 3 commits into
redhat-developer:mainfrom
lokanandaprabhu:feat/orchestrator-nested-rjsf-widgets-config
Open

feat(orchestrator): support nested objects in rjsf-widgets config#4461
lokanandaprabhu wants to merge 3 commits into
redhat-developer:mainfrom
lokanandaprabhu:feat/orchestrator-nested-rjsf-widgets-config

Conversation

@lokanandaprabhu

@lokanandaprabhu lokanandaprabhu commented Aug 25, 2026

Copy link
Copy Markdown
Member

Story - https://redhat.atlassian.net/browse/RHIDP-16437

Summary

Adds support for nested objects in orchestrator.rjsf-widgets configuration, enabling Platform Engineers to organize widget parameters hierarchically.

Changes

  • Config Schema: Updated config.d.ts to accept [key: string]: any instead of [key: string]: string
  • Tests: Added comprehensive test coverage for nested path resolution
  • Documentation: Updated orchestratorFormWidgets.md with nested configuration examples
  • Backward Compatible: Existing flat string keys continue to work and can be mixed with nested structures

Video

Screen.Recording.2026-08-25.at.11.09.31.AM.mov

Example Configuration

orchestrator:
  rjsf-widgets:
    # Nested structure
    app-registration:
      xParams:
        name: app-registration
        version: 0.21.0
    # Flat keys still work
    defaultEnvironment: production

How to Test

1. Add Configuration

Add to your app-config.local.yaml:

orchestrator:
  rjsf-widgets:
    app-registration:
      xParams:
        name: app-registration
        version: 0.21.0
      environment: dev
    cloud-run:
      xParams:
        name: cloud-run
        version: 1.0.0
    defaultEnvironment: production

2. Create Test Workflow

Workflow: test-nested-config.sw.yaml

id: test-nested-config
version: "1.0"
specVersion: "0.8"
name: Test Nested rjsf-widgets Configuration
description: "Demonstrates nested and flat config values"
dataInputSchema: schemas/test-nested-config__main-schema.json
start: StartState
functions:
  - name: successResult
    type: expression
    operation: '{ "result": { "message": "Config test completed" } }'
states:
  - name: StartState
    type: operation
    actions:
      - name: setOutput
        functionRef:
          refName: successResult
    end: true

Schema: schemas/test-nested-config__main-schema.json

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "title": "Test Nested Config",
  "type": "object",
  "properties": {
    "flatConfig": {
      "type": "string",
      "title": "Flat Config Value",
      "ui:widget": "ActiveText",
      "ui:props": {
        "ui:text": "**Environment:** $${{rjsfConfig.defaultEnvironment}}"
      }
    },
    "nestedConfig": {
      "type": "string",
      "title": "Nested Config Values",
      "ui:widget": "ActiveText",
      "ui:props": {
        "ui:text": "## App Registration\n\n- **Name:** $${{rjsfConfig.app-registration.xParams.name}}\n- **Version:** $${{rjsfConfig.app-registration.xParams.version}}\n- **Env:** $${{rjsfConfig.app-registration.environment}}"
      }
    },
    "mixedExample": {
      "type": "string",
      "title": "Mixed Config Summary",
      "ui:widget": "ActiveText",
      "ui:props": {
        "ui:text": "# Summary\n\nGlobal: **$${{rjsfConfig.defaultEnvironment}}**\n\nWidgets:\n- $${{rjsfConfig.app-registration.xParams.name}} v$${{rjsfConfig.app-registration.xParams.version}}\n- $${{rjsfConfig.cloud-run.xParams.name}} v$${{rjsfConfig.cloud-run.xParams.version}}"
      }
    }
  }
}

3. Run Tests

yarn workspace @red-hat-developer-hub/backstage-plugin-orchestrator-form-widgets test useTemplateUnitEvaluator

All 10 tests should pass, including new tests for:

  • Nested path resolution
  • Multiple widget namespaces
  • Mixed flat and nested keys
  • Missing paths return undefined

4. Test in UI

  1. Start backend: yarn dev
  2. Navigate to Orchestrator → Workflows
  3. Run "Test Nested rjsf-widgets Configuration" workflow
  4. Verify the form displays:
    • Flat config: defaultEnvironment → "production"
    • Nested config: app-registration.xParams.name → "app-registration"
    • All values rendered as markdown in ActiveText widgets

Customer Request

Resolves customer feature request for hierarchical widget parameter organization (xParams configuration).

- Update config schema to accept nested objects in orchestrator.rjsf-widgets
- Add tests for nested path resolution (flat, nested, mixed scenarios)
- Update documentation with nested configuration examples
- Maintain backward compatibility with existing flat string keys

Templates can now reference nested values using dot-path notation:
$${{rjsfConfig.widget-id.xParams.name}}

Resolves customer request for hierarchical widget parameter organization.
@rhdh-gh-app

rhdh-gh-app Bot commented Aug 25, 2026

Copy link
Copy Markdown

Important

This PR includes changes that affect public-facing API. Please ensure you are adding/updating documentation for new features or behavior.

Changed Packages

Package Name Package Path Changeset Bump Current Version
@red-hat-developer-hub/backstage-plugin-orchestrator-common workspaces/orchestrator/plugins/orchestrator-common minor v3.9.0

Add jest.Mock type casts to fix TypeScript compilation errors:
- mockImplementation expects parameters
- mockReturnValue can accept undefined
Only orchestrator-common has published code changes (config.d.ts).
orchestrator-form-widgets only has test changes which don't require a changeset.
@sonarqubecloud

Copy link
Copy Markdown

@codecov

codecov Bot commented Aug 25, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 61.62%. Comparing base (99da62c) to head (1c2ddaf).
⚠️ Report is 17 commits behind head on main.
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #4461   +/-   ##
=======================================
  Coverage   61.62%   61.62%           
=======================================
  Files        2541     2541           
  Lines      101912   101912           
  Branches    28555    28555           
=======================================
  Hits        62800    62800           
  Misses      37308    37308           
  Partials     1804     1804           
Flag Coverage Δ *Carryforward flag
adoption-insights 84.55% <ø> (ø) Carriedforward from 20d4f02
ai-integrations 67.70% <ø> (ø) Carriedforward from 20d4f02
app-defaults 48.37% <ø> (ø) Carriedforward from 20d4f02
augment 46.67% <ø> (ø) Carriedforward from 20d4f02
boost 79.84% <ø> (ø) Carriedforward from 20d4f02
bulk-import 72.79% <ø> (ø) Carriedforward from 20d4f02
cost-management 13.55% <ø> (ø) Carriedforward from 20d4f02
dcm 72.09% <ø> (ø) Carriedforward from 20d4f02
e2e-adoption-insights 60.00% <ø> (ø) Carriedforward from 20d4f02
e2e-extensions 62.13% <ø> (ø) Carriedforward from 20d4f02
e2e-global-header 49.45% <ø> (ø) Carriedforward from 20d4f02
e2e-homepage 61.11% <ø> (ø) Carriedforward from 20d4f02
e2e-intelligent-assistant 46.68% <ø> (ø) Carriedforward from 20d4f02
e2e-orchestrator 49.52% <ø> (ø) Carriedforward from 20d4f02
e2e-quickstart 55.21% <ø> (ø) Carriedforward from 20d4f02
e2e-scorecard 50.21% <ø> (ø) Carriedforward from 20d4f02
e2e-theme 16.36% <ø> (ø) Carriedforward from 20d4f02
extensions 56.59% <ø> (ø) Carriedforward from 20d4f02
global-floating-action-button 71.18% <ø> (ø) Carriedforward from 20d4f02
global-header 66.50% <ø> (ø) Carriedforward from 20d4f02
homepage 47.46% <ø> (ø) Carriedforward from 20d4f02
install-dynamic-plugins 58.57% <ø> (ø) Carriedforward from 20d4f02
intelligent-assistant 75.35% <ø> (ø) Carriedforward from 20d4f02
konflux 91.98% <ø> (ø) Carriedforward from 20d4f02
lightspeed 69.02% <ø> (ø) Carriedforward from 20d4f02
mcp-integrations 83.40% <ø> (ø) Carriedforward from 20d4f02
orchestrator 70.86% <ø> (ø)
quickstart 63.74% <ø> (ø) Carriedforward from 20d4f02
sandbox 79.56% <ø> (ø) Carriedforward from 20d4f02
scorecard 87.40% <ø> (ø) Carriedforward from 20d4f02
theme 88.91% <ø> (ø) Carriedforward from 20d4f02
translations 5.12% <ø> (ø) Carriedforward from 20d4f02
x2a 79.20% <ø> (ø) Carriedforward from 20d4f02

*This pull request uses carry forward flags. Click here to find out more.


Continue to review full report in Codecov by Harness.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 99da62c...1c2ddaf. Read the comment docs.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@lholmquist

Copy link
Copy Markdown
Member

I'm not sure if I'm missing something with the configuration, but this is what I'm seeing on the UI:

Screenshot 2026-08-25 at 9 06 57 AM

Here is the workflow definition and the schema:

Screenshot 2026-08-25 at 9 07 58 AM

and what i added to my app-config:

Screenshot 2026-08-25 at 9 08 49 AM

@lokanandaprabhu

Copy link
Copy Markdown
Member Author

@lholmquist The schema in the video demonstrates a more detailed example with grouped sections (4 objects with nested properties), while the PR description includes a simplified version (3 flat properties) to keep the testing instructions concise.

Both schemas work correctly and demonstrate the same nested config capability. If you'd like to see the exact schema from the video, you can use:

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "title": "Test Nested rjsf-widgets Configuration",
  "type": "object",
  "description": "Demonstrates accessing both nested and flat configuration values",
  "properties": {
    "flatConfigDisplay": {
      "type": "object",
      "title": "Flat Configuration Values",
      "properties": {
        "defaultEnvironment": {
          "type": "string",
          "title": "Default Environment (Flat Config)",
          "ui:widget": "ActiveText",
          "ui:props": {
            "ui:text": "**Default Environment:** $${{rjsfConfig.defaultEnvironment}}"
          }
        }
      }
    },
    "nestedConfigDisplay": {
      "type": "object",
      "title": "Nested Configuration Values",
      "properties": {
        "appRegistrationInfo": {
          "type": "string",
          "title": "App Registration Widget Config",
          "ui:widget": "ActiveText",
          "ui:props": {
            "ui:text": "## App Registration Widget\n\n- **Name:** $${{rjsfConfig.app-registration.xParams.name}}\n- **Version:** $${{rjsfConfig.app-registration.xParams.version}}\n- **Environment:** $${{rjsfConfig.app-registration.environment}}"
          }
        },
        "cloudRunInfo": {
          "type": "string",
          "title": "Cloud Run Widget Config",
          "ui:widget": "ActiveText",
          "ui:props": {
            "ui:text": "## Cloud Run Widget\n\n- **Name:** $${{rjsfConfig.cloud-run.xParams.name}}\n- **Version:** $${{rjsfConfig.cloud-run.xParams.version}}"
          }
        }
      }
    },
    "mixedConfigDisplay": {
      "type": "object",
      "title": "Mixed Configuration Example",
      "properties": {
        "summary": {
          "type": "string",
          "title": "Configuration Summary",
          "ui:widget": "ActiveText",
          "ui:props": {
            "ui:text": "# Configuration Summary\n\n**Global:** $${{rjsfConfig.defaultEnvironment}}\n\n**Widgets:**\n- $${{rjsfConfig.app-registration.xParams.name}} v$${{rjsfConfig.app-registration.xParams.version}}\n- $${{rjsfConfig.cloud-run.xParams.name}} v$${{rjsfConfig.cloud-run.xParams.version}}"
          }
        }
      }
    }
  }
}

The key feature this PR enables is that orchestrator.rjsf-widgets now officially supports nested objects with proper TypeScript typing, testing, and documentation. Both schemas demonstrate this works correctly.

@lholmquist lholmquist left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

worked like the video

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants