feat(designer-v2): Make per-action code view editable#9333
Conversation
Allow editing an action's JSON inline from the node-details Code view tab with live JSON validation and save/discard, without going to the whole-workflow code view (issue #9293). - EditableCodeView: controlled editor with save/discard + validation slot - updateNodeFromCodeView thunk: re-initializes only the edited node and merges into operation/token state (preserves other nodes' edits) - replaceOperationDefinition reducer: persists definition + marks dirty - codeViewTab: stateful container; reads useStore().getState() so the post-save refetch serializes fresh state Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
🤖 AI PR Validation ReportPR Review ResultsThank you for your submission! Here's detailed feedback on your PR title and body compliance:✅ PR Title
✅ Commit Type
✅ Risk Level
✅ What & Why
✅ Impact of Change
✅ Test Plan
✅ Contributors
|
| Section | Status | Recommendation |
|---|---|---|
| Title | ✅ | No change needed |
| Commit Type | ✅ | No change needed |
| Risk Level | ✅ | Keep Medium |
| What & Why | ✅ | No change needed |
| Impact of Change | ✅ | No change needed |
| Test Plan | ✅ | No change needed |
| Contributors | ✅ | No change needed |
| Screenshots/Videos | Add a short clip if possible |
Overall: this PR passes. The advised risk level matches the submitter’s risk level (medium). The only recommendation is optional: add a short video/GIF for the UI workflow to complement the screenshots.
Last updated: Wed, 01 Jul 2026 21:43:38 GMT
There was a problem hiding this comment.
Pull request overview
This PR adds an editable per-action Code view experience in the node-details panel, allowing users to edit an action’s JSON inline with validation and Save/Discard controls, and then re-initializing only the edited node to avoid clobbering other unsaved node edits.
Changes:
- Introduces an
EditableCodeViewpresentational component (Monaco-based) with Save/Discard, validation messaging, and saving state. - Updates the designer’s Code view tab to be stateful (dirty tracking, JSON validation, save/discard wiring) and to re-serialize from the latest store state on refetch.
- Adds a new
updateNodeFromCodeViewthunk plus areplaceOperationDefinitionreducer to persist the edited operation definition and re-initialize metadata/tokens for just that node.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| Localize/lang/strings.json | Adds new localized strings for invalid JSON + Save/Discard/Saving labels. |
| libs/designer/src/lib/ui/panel/nodeDetailsPanel/tabs/codeViewTab.tsx | Switches Code view tab to editable mode (when not read-only), adds validation + Save/Discard and post-save refetch. |
| libs/designer/src/lib/core/state/workflow/workflowSlice.ts | Adds replaceOperationDefinition reducer to update a single operation definition in-state. |
| libs/designer/src/lib/core/state/workflow/test/workflowSlice.spec.ts | Adds unit tests for replaceOperationDefinition. |
| libs/designer/src/lib/core/actions/bjsworkflow/updateNodeFromCodeView.ts | Adds thunk to apply edited per-node JSON and re-initialize node metadata/tokens without full workflow re-deserialization. |
| libs/designer/src/lib/core/actions/bjsworkflow/operationdeserializer.ts | Exports helper functions needed for single-node re-initialization. |
| libs/designer-ui/src/lib/peek/index.tsx | Re-exports the new EditableCodeView component. |
| libs/designer-ui/src/lib/peek/editableCodeView.tsx | New presentational editable code editor with toolbar and error surface. |
📊 Coverage CheckThe following changed files need attention:
Please add tests for the uncovered files before merging. |
…ner-v2 Reverts the per-action editable code view from the designer lib and re-implements it in designer-v2 (shared EditableCodeView in designer-ui is unchanged). Adds the replaceOperationDefinition reducer, exports the operationdeserializer helpers, the updateNodeFromCodeView thunk, and the stateful codeViewTab container with JSON validation + save/discard. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…unAfter Editing an action's runAfter inline via the Code preview tab now updates the node's position in the graph. replaceOperationDefinition diffs the old vs new runAfter parents and reconciles the scope's BUTTON/HEADING edges (mirroring the BJS deserializer: parent edges for run-after deps, trigger edge for top-level roots, scope-header edge for scoped roots), then re-syncs isRoot metadata via applyIsRootNode. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…iew save initializeVariables skips operations with no variables, so editing an action to remove its variable declaration left a stale tokens.variables[nodeId] entry. Deinitialize the node's variables before re-initializing so removed variables are dropped. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Adds Vitest suites for the editable code-view feature: - updateNodeFromCodeView thunk: persist+graph reconcile, single-node re-init, variable lifecycle, manifest/swagger/connector/managed-MCP branch selection, no-op guard. - CodeViewTab container: seeding, read-only peek, dirty tracking, JSON validation, discard, and save dispatch. - EditableCodeView (designer-ui): rendering, dirty/saving/error states, read-only, and callback wiring. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Adds hostOptions.enableEditableCodeView (default false) so hosts like the Azure portal must explicitly opt in. When disabled (or read-only), the node code view tab renders the existing read-only Peek; when enabled, it renders the editable editor. - New useEditableCodeViewEnabled selector; codeViewTab gates on it. - Standalone dev harness enables it by default and exposes an 'Editable Code View' settings toggle. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Commit Type
Risk Level
What & Why
Resolves #9293. The per-action Code view tab in the node-details panel was
read-only, so editing an action's inputs/expressions inline was impossible —
users had to drop into the whole-workflow code view to make small JSON edits.
This makes the per-action Code view editable: you can edit an action's JSON
in place, with live JSON validation, then Save to apply it (or Discard
to revert) without leaving the action panel. On save, only the edited node is
re-initialized and merged back into state, so other nodes' unsaved edits are
preserved. Editing an action's
runAfterin this view also repositions thenode in the graph to match the new run-after dependencies.
Impact of Change
enables it (
hostOptions.enableEditableCodeView); by default it staysread-only exactly as before. When enabled, the tab gains Save/Discard buttons +
inline JSON validation. Invalid JSON blocks save with a clear
message. Read-only hosts are unaffected — the tab still renders the existing
read-only viewer. Editing
runAfterre-draws the node's graph edges (parentdependencies, re-attaching to the trigger when run-after is cleared on a
top-level action, or to the scope header inside a scope). Still out of scope
for inline edits: renaming the action key, re-nesting into a different scope,
and adding/removing child actions — those continue to require the
whole-workflow code view.
EditableCodeViewpresentational component indesigner-ui; newupdateNodeFromCodeViewthunk andreplaceOperationDefinitionreducer in
designer-v2; four helpers inoperationdeserializer.tsare nowexported for single-node re-initialization. New opt-in
hostOptions.enableEditableCodeViewflag (surfaced via theuseEditableCodeViewEnabledselector) gates the editable UI.codeViewTabisnow a stateful container that reads
useStore().getState()in its serializequery so the post-save refetch reflects fresh committed state.
replaceOperationDefinitiondiffs old vs. newrunAfterand reconciles thescope's graph edges (mirroring the BJS deserializer), then re-syncs
isRootmetadata via
applyIsRootNode.(manifest/swagger/connector/managed-MCP path) and merges via
initializeNodes({ clearExisting: false })rather than re-deserializing thewhole workflow, keeping the save path cheap and avoiding clobbering other nodes.
Test Plan
workflowSlice.spec.ts—replaceOperationDefinitionreducer plus runAftergraph-reconciliation tests (remove runAfter → re-attach to trigger; change
parent → edge moves; status-only change → edges untouched)
updateNodeFromCodeView.spec.ts(10 tests) — thunk driven against a real storewith the heavy single-node initializers mocked: persist + graph reconcile,
re-init only the edited node while preserving other nodes, variable
clear/re-init, manifest/swagger/connector/managed-MCP branch selection, and the
no-op guard when the node is missing
codeViewTab.spec.tsx(7 tests) — container: seeding, read-only peek,read-only when the
enableEditableCodeViewhost option is off, dirtytracking, JSON validation, discard revert, and save dispatch
editableCodeView.spec.tsx(8 tests, designer-ui) — dirty/saving/error/read-only states and Save/Discard callback wiring
/v2):fromexpression) → Save → persist to Redux and round-trip in the editor andParameters tab; no console errors
and re-lays out the graph; clearing all run-after on a top-level action
re-attaches it to the trigger
Contributors
@rllyy97
Screenshots/Videos