feat(ui): Schema-driven dynamic forms for source/reaction configuration#88
Open
danielgerlag wants to merge 4 commits intomainfrom
Open
feat(ui): Schema-driven dynamic forms for source/reaction configuration#88danielgerlag wants to merge 4 commits intomainfrom
danielgerlag wants to merge 4 commits intomainfrom
Conversation
Replace flat YAML editor with schema-driven forms using RJSF (React JSON Schema Form) that render typed fields from each plugin's JSON Schema. Key changes: - Custom RJSF theme (widgets.tsx, templates.tsx) matching Drasi Tailwind design - x-ui:* extension parser (uiSchemaMapper.ts) for UI hints from plugin schemas - ConfigEditor with Form/YAML toggle and bidirectional sync - SchemaConfigForm upgraded with uiSchema, formContext, custom theme - schemaResolver.ts: preserve x-ui:* annotations during $ref resolution, build ref lookup to resolve utoipa short names (e.g. CallSpecDto) to fully-qualified definition keys (e.g. reaction.http.CallSpec) - SourceForms/ReactionForms: deletion-aware onChange handlers - humanizeLabel for camelCase→Title Case field labels Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
utoipa names (e.g. TemplateSpecDto, QueryConfigDto) don't always match definition key suffixes (e.g. LogTemplateSpec, LogQueryConfig). Add suffixMatchRef() that strips 'Dto' and finds definitions whose short name ends with the base name, resolving the mismatch. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
… queries When creating a reaction, the 'routes' map (per-query config) is now automatically expanded into named sections for each selected query. Instead of a generic key/value map editor, users see a dedicated config form section for each query they've selected in the checkbox list. Works by detecting map-type properties (type: object + additionalProperties) and rewriting them to fixed properties keyed by selected query IDs. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Contributor
There was a problem hiding this comment.
Pull request overview
This PR replaces the flat YAML configuration editor in the UI with schema-driven dynamic forms powered by RJSF, using plugin-provided JSON Schemas (including x-ui:* extension hints) while retaining a YAML fallback editor.
Changes:
- Added an
x-ui:*→ RJSFuiSchemamapper (including grouping/order/conditions). - Introduced a Drasi-tailored RJSF theme (custom widgets + templates for grouping/collapsing and inline errors).
- Reworked config editing to support Form/YAML toggle, improved
$refrewriting, and deletion-aware config updates in source/reaction forms.
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 10 comments.
Show a summary per file
| File | Description |
|---|---|
| ui/src/utils/uiSchemaMapper.ts | New utility to extract x-ui:* annotations into an RJSF uiSchema (order/groups/conditions). |
| ui/src/utils/schemaResolver.ts | Enhances $ref rewriting (short-name lookup, preserves siblings for known refs/ConfigValue). |
| ui/src/components/create/rjsf-theme/widgets.tsx | Adds Tailwind-styled RJSF widgets (text/password/textarea/select/checkbox/range/number). |
| ui/src/components/create/rjsf-theme/templates.tsx | Adds templates for conditional visibility, grouped/collapsible object sections, arrays, and hides default error list. |
| ui/src/components/create/rjsf-theme/index.ts | Exports the Drasi RJSF theme (widgets + templates). |
| ui/src/components/create/SchemaConfigForm.tsx | Wires the Drasi theme into RJSF and passes formContext for conditions. |
| ui/src/components/create/ConfigEditor.tsx | Main rewrite: Form/YAML toggle, schema rewriting for query-keyed maps, YAML/template syncing, uiSchema extraction. |
| ui/src/components/create/SourceForms.tsx | Makes config updates deletion-aware (“atomic replacement”). |
| ui/src/components/create/ReactionForms.tsx | Same deletion-aware behavior + passes selected queries for per-query config expansion. |
Comments suppressed due to low confidence (1)
ui/src/components/create/ReactionForms.tsx:104
- This handler filters reserved keys (
id,autoStart,kind,queries) when clearing old config, but when applying new keys it doesn’t excludekind. If a user addskindmanually in YAML mode, it will be written into the parent state. Consider applying the same reserved-key filter in the second loop too.
for (const [key, val] of Object.entries(data)) {
if (key !== "id" && key !== "autoStart" && key !== "queries") {
onChange(key, val);
}
}
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- CheckboxWidget: add aria-labelledby for screen reader accessibility,
unify disabled/readonly visual styling
- All widgets: use e.target.value in onBlur/onFocus for current value
- SourceForms: filter 'kind' from applied config keys to prevent
reserved field leakage from YAML mode
- schemaResolver: preserve sibling x-ui:* keys in unknown ref fallback
- SchemaConfigForm: place submitButtonOptions after uiSchema spread
so it cannot be overridden
- ConfigEditor: extract uiSchema from effectiveSchema (not raw resolved)
to keep UI hints in sync with query-expanded schema; reset state when
kind/category changes; propagate empty {} from YAML to parent state
to allow clearing all config
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
ruokun-niu
reviewed
Apr 30, 2026
agentofreality
approved these changes
May 6, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Replaces the flat YAML editor in the Drasi UI with schema-driven dynamic forms using RJSF (React JSON Schema Form). Forms are auto-generated from each plugin's JSON Schema with support for
x-ui:*extension hints.Key Changes
New files
rjsf-theme/widgets.tsx— 7 custom RJSF widgets (Text, Password, Textarea, Select, Checkbox, Range, Number) matching Drasi's Tailwind designrjsf-theme/templates.tsx— FieldTemplate (x-ui:condition + humanizeLabel), ObjectFieldTemplate (collapsible x-ui:group sections), ArrayFieldTemplate, ErrorListTemplaterjsf-theme/index.ts— Theme exportuiSchemaMapper.ts— Extracts x-ui:* extensions from JSON Schema → RJSF uiSchema + field groupsModified files
ConfigEditor.tsx— Complete rewrite with Form/YAML toggle and bidirectional syncSchemaConfigForm.tsx— Uses Drasi theme, uiSchema, formContextSourceForms.tsx/ReactionForms.tsx— Deletion-aware onChange handlersschemaResolver.ts— Preserve x-ui:* annotations during $ref resolution; build ref lookup to resolve utoipa short names (e.g.CallSpecDto) to fully-qualified definition keys (e.g.reaction.http.CallSpec)Features
Companion PR
Requires drasi-project/drasi-core#421 for the plugin-side x-ui schema annotations.