From ce124cd3079877e7cc0507472ba94d3f878a81a8 Mon Sep 17 00:00:00 2001 From: Cheryl Kong Date: Mon, 17 Aug 2026 11:24:35 +0100 Subject: [PATCH 1/9] feat: add nested editing sample workflows Signed-off-by: Cheryl Kong --- .../workflows/all-task-types.yaml | 97 +++++++++++++++++++ .../workflows/call-endpoint-union.yaml | 66 +++++++++++++ .../workflows/call-headers-map.yaml | 61 ++++++++++++ .../workflows/listen-deep-nesting.yaml | 94 ++++++++++++++++++ .../workflows/nested-validation.yaml | 36 +++++++ .../workflows/run-task-array.yaml | 84 ++++++++++++++++ .../workflows/set-open-map.yaml | 56 +++++++++++ .../workflows/switch-locked-cases.yaml | 55 +++++++++++ 8 files changed, 549 insertions(+) create mode 100644 packages/open-workflow-diagram-editor/stories/nested-editing/workflows/all-task-types.yaml create mode 100644 packages/open-workflow-diagram-editor/stories/nested-editing/workflows/call-endpoint-union.yaml create mode 100644 packages/open-workflow-diagram-editor/stories/nested-editing/workflows/call-headers-map.yaml create mode 100644 packages/open-workflow-diagram-editor/stories/nested-editing/workflows/listen-deep-nesting.yaml create mode 100644 packages/open-workflow-diagram-editor/stories/nested-editing/workflows/nested-validation.yaml create mode 100644 packages/open-workflow-diagram-editor/stories/nested-editing/workflows/run-task-array.yaml create mode 100644 packages/open-workflow-diagram-editor/stories/nested-editing/workflows/set-open-map.yaml create mode 100644 packages/open-workflow-diagram-editor/stories/nested-editing/workflows/switch-locked-cases.yaml diff --git a/packages/open-workflow-diagram-editor/stories/nested-editing/workflows/all-task-types.yaml b/packages/open-workflow-diagram-editor/stories/nested-editing/workflows/all-task-types.yaml new file mode 100644 index 00000000..a2e38d7e --- /dev/null +++ b/packages/open-workflow-diagram-editor/stories/nested-editing/workflows/all-task-types.yaml @@ -0,0 +1,97 @@ +# +# Copyright 2021-Present The Open Workflow Specification Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +document: + dsl: "1.0.3" + namespace: examples + name: all-task-types + version: "0.1.0" +use: + errors: + notFound: + type: https://example.com/errors/not-found + status: 404 + title: Resource Not Found +do: + - callHttpTask: + call: http + with: + method: get + endpoint: https://api.example.com/users + headers: + Accept: application/json + X-Api-Key: ${ .apiKey } + query: + page: "1" + limit: "20" + - setContextTask: + set: + userId: ${ .users[0].id } + userName: ${ .users[0].name } + fetchedAt: ${ now } + meta: + source: api.example.com + version: v2 + - runScriptTask: + run: + script: + language: javascript + arguments: + - --user-id + - ${ .userId } + environment: + NODE_ENV: production + code: | + const [,, flag, id] = process.argv; + console.log(JSON.stringify({ processed: id })); + - listenTask: + listen: + to: + any: + - with: + type: com.example.user.verified + correlate: + userId: + from: .subject + - with: + type: com.example.user.rejected + correlate: + userId: + from: .subject + - switchTask: + switch: + - verified: + when: ${ .eventType == "com.example.user.verified" } + then: doNestedTask + - rejected: + when: ${ .eventType == "com.example.user.rejected" } + then: raiseErrorTask + - default: + then: raiseErrorTask + - doNestedTask: + do: + - enrichProfile: + call: http + with: + method: get + endpoint: https://api.example.com/profile/${ .userId } + - storeProfile: + set: + profile: ${ .body } + enrichedAt: ${ now } + then: exit + - raiseErrorTask: + raise: + error: notFound diff --git a/packages/open-workflow-diagram-editor/stories/nested-editing/workflows/call-endpoint-union.yaml b/packages/open-workflow-diagram-editor/stories/nested-editing/workflows/call-endpoint-union.yaml new file mode 100644 index 00000000..7323693f --- /dev/null +++ b/packages/open-workflow-diagram-editor/stories/nested-editing/workflows/call-endpoint-union.yaml @@ -0,0 +1,66 @@ +# +# Copyright 2021-Present The Open Workflow Specification Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Nested editing focus: endpoint union — the endpoint field can be a plain string URI +# or a structured object with uri + authentication. Both forms appear here so the +# editor can be tested switching between union variants inside nested do containers. +document: + dsl: "1.0.3" + namespace: examples + name: call-endpoint-union + version: "0.1.0" +do: + - prepareRequest: + set: + serviceToken: ${ .auth.token } + inputData: ${ .payload } + - callServices: + do: + - callPublicApi: + call: http + with: + method: get + endpoint: https://public.api.example.com/catalogue + query: + category: ${ .category } + - callSecureApi: + call: http + with: + method: post + endpoint: + uri: https://secure.api.example.com/process + authentication: + bearer: + token: ${ .serviceToken } + body: + payload: ${ .inputData } + - callOAuthApi: + call: http + with: + method: get + endpoint: + uri: https://oauth.api.example.com/data + authentication: + oauth2: + authority: https://auth.example.com + grant: client_credentials + client: + id: ${ .clientId } + secret: ${ .clientSecret } + - mergeResults: + set: + catalogue: ${ .catalogue } + processed: ${ .processed } + data: ${ .data } diff --git a/packages/open-workflow-diagram-editor/stories/nested-editing/workflows/call-headers-map.yaml b/packages/open-workflow-diagram-editor/stories/nested-editing/workflows/call-headers-map.yaml new file mode 100644 index 00000000..ec7107df --- /dev/null +++ b/packages/open-workflow-diagram-editor/stories/nested-editing/workflows/call-headers-map.yaml @@ -0,0 +1,61 @@ +# +# Copyright 2021-Present The Open Workflow Specification Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Nested editing focus: fixed-key headers map on a call task inside a do container. +# The editor must handle drilling into the do block, then into the call task, +# then into the nested headers map — three levels of nesting. +document: + dsl: "1.0.3" + namespace: examples + name: call-headers-map + version: "0.1.0" +do: + - authenticate: + call: http + with: + method: post + endpoint: https://auth.example.com/token + headers: + Content-Type: application/x-www-form-urlencoded + Accept: application/json + body: + grant_type: client_credentials + client_id: ${ .clientId } + client_secret: ${ .clientSecret } + - fetchUserData: + do: + - getProfile: + call: http + with: + method: get + endpoint: https://api.example.com/users/${ .userId } + headers: + Accept: application/json + Authorization: Bearer ${ .accessToken } + X-Correlation-Id: ${ .correlationId } + X-Request-Source: workflow-engine + - getPermissions: + call: http + with: + method: get + endpoint: https://api.example.com/users/${ .userId }/permissions + headers: + Accept: application/json + Authorization: Bearer ${ .accessToken } + - storeResult: + set: + profile: ${ .profile } + permissions: ${ .permissions } + fetchedAt: ${ now } diff --git a/packages/open-workflow-diagram-editor/stories/nested-editing/workflows/listen-deep-nesting.yaml b/packages/open-workflow-diagram-editor/stories/nested-editing/workflows/listen-deep-nesting.yaml new file mode 100644 index 00000000..50acd9c4 --- /dev/null +++ b/packages/open-workflow-diagram-editor/stories/nested-editing/workflows/listen-deep-nesting.yaml @@ -0,0 +1,94 @@ +# +# Copyright 2021-Present The Open Workflow Specification Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Nested editing focus: listen task with deeply nested correlate maps inside +# a to.all array, followed by a foreach block containing its own nested do tasks. +# Tests drill-in navigation: top level -> listen config -> event filter array -> +# correlate map, and separately: foreach -> do -> nested call task. +document: + dsl: "1.0.3" + namespace: examples + name: listen-deep-nesting + version: "0.1.0" +do: + - awaitReadings: + listen: + to: + all: + - with: + source: https://sensors.example.com + type: com.example.sensors.temperature + data: ${ .value > 37.5 } + correlate: + deviceId: + from: .device.id + roomId: + from: .location.room + - with: + source: https://sensors.example.com + type: com.example.sensors.humidity + data: ${ .percent > 80 } + correlate: + deviceId: + from: .device.id + roomId: + from: .location.room + - with: + source: https://sensors.example.com + type: com.example.sensors.pressure + data: ${ .hpa < 980 } + correlate: + deviceId: + from: .device.id + roomId: + from: .location.room + until: ${ .readingCount >= 10 } + foreach: + item: reading + at: i + do: + - logReading: + call: http + with: + method: post + endpoint: https://ingest.example.com/readings + headers: + Content-Type: application/json + X-Device-Id: ${ .reading.deviceId } + body: + reading: ${ .reading } + index: ${ .i } + - updateState: + set: + lastReading: ${ .reading } + readingCount: ${ .i + 1 } + output: + as: .latestReadings + - processReadings: + do: + - summarise: + set: + total: ${ .latestReadings | length } + avgTemp: ${ [ .latestReadings[] | select(.type == "temperature") | .value ] | add / length } + - notifyAlert: + call: http + with: + method: post + endpoint: https://alerts.example.com/notify + headers: + Content-Type: application/json + body: + summary: ${ .summary } + avgTemp: ${ .avgTemp } diff --git a/packages/open-workflow-diagram-editor/stories/nested-editing/workflows/nested-validation.yaml b/packages/open-workflow-diagram-editor/stories/nested-editing/workflows/nested-validation.yaml new file mode 100644 index 00000000..6c395d63 --- /dev/null +++ b/packages/open-workflow-diagram-editor/stories/nested-editing/workflows/nested-validation.yaml @@ -0,0 +1,36 @@ +# +# Copyright 2021-Present The Open Workflow Specification Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +document: + dsl: "1.0.3" + namespace: examples + name: nested-validation-errors + version: "0.1.0" +do: + - validStep: + set: + status: starting + - invalidHttpCall: + call: http + with: + method: post + - processItems: + for: + each: item + do: + - invalidNestedCall: + call: http + with: + method: get diff --git a/packages/open-workflow-diagram-editor/stories/nested-editing/workflows/run-task-array.yaml b/packages/open-workflow-diagram-editor/stories/nested-editing/workflows/run-task-array.yaml new file mode 100644 index 00000000..79ffc583 --- /dev/null +++ b/packages/open-workflow-diagram-editor/stories/nested-editing/workflows/run-task-array.yaml @@ -0,0 +1,84 @@ +# +# Copyright 2021-Present The Open Workflow Specification Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Nested editing focus: run task with an arguments array and environment map, +# inside a do container alongside a for loop that also contains a run task. +# Tests reordering the arguments array and editing the environment map +# at multiple nesting levels. +document: + dsl: "1.0.3" + namespace: examples + name: run-task-array + version: "0.1.0" +do: + - prepare: + set: + fileContents: ${ .input.files } + outputDir: ${ .input.outputDir } + - processFiles: + do: + - validateInput: + run: + script: + language: python + arguments: + - --mode + - validate + - --strict + environment: + LOG_LEVEL: info + TIMEOUT: "30" + code: | + import sys, json + data = json.loads(sys.stdin.read()) + assert data, "empty input" + print(json.dumps({"valid": True})) + - transformFiles: + run: + script: + language: python + stdin: ${ .fileContents } + arguments: + - --output-format + - json + - --verbose + - --max-retries + - "3" + environment: + LOG_LEVEL: info + TIMEOUT: "60" + OUTPUT_DIR: ${ .outputDir } + code: | + import sys, json, argparse + parser = argparse.ArgumentParser() + parser.add_argument('--output-format') + parser.add_argument('--verbose', action='store_true') + parser.add_argument('--max-retries', type=int) + args = parser.parse_args() + data = json.loads(sys.stdin.read()) + print(json.dumps({"processed": data, "format": args.output_format})) + - reportResults: + run: + script: + language: javascript + arguments: + - --summary + - --output + - ${ .outputDir } + environment: + NODE_ENV: production + code: | + const [,, , , dir] = process.argv; + console.log(JSON.stringify({ summary: true, dir })); diff --git a/packages/open-workflow-diagram-editor/stories/nested-editing/workflows/set-open-map.yaml b/packages/open-workflow-diagram-editor/stories/nested-editing/workflows/set-open-map.yaml new file mode 100644 index 00000000..59e1f6ef --- /dev/null +++ b/packages/open-workflow-diagram-editor/stories/nested-editing/workflows/set-open-map.yaml @@ -0,0 +1,56 @@ +# +# Copyright 2021-Present The Open Workflow Specification Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Nested editing focus: open map (set task) inside a for loop container. +# The editor must handle adding/removing arbitrary keys in the set map +# while navigating into the for loop's nested do block — two nesting levels. +document: + dsl: "1.0.3" + namespace: examples + name: set-open-map + version: "0.1.0" +do: + - initContext: + set: + requestedAt: ${ now } + environment: production + featureFlags: + betaEditor: true + darkMode: false + - processItems: + for: + each: item + in: ${ .items } + at: index + do: + - enrichItem: + set: + id: ${ .item.id } + label: ${ .item.name } + index: ${ .index } + processedAt: ${ now } + meta: + source: workflow + version: v2 + - tagItem: + set: + tagged: true + taggedBy: ${ $workflow.definition.document.name } + taggedAt: ${ now } + - finalise: + set: + totalProcessed: ${ .index + 1 } + completedAt: ${ now } + status: done diff --git a/packages/open-workflow-diagram-editor/stories/nested-editing/workflows/switch-locked-cases.yaml b/packages/open-workflow-diagram-editor/stories/nested-editing/workflows/switch-locked-cases.yaml new file mode 100644 index 00000000..9212bc67 --- /dev/null +++ b/packages/open-workflow-diagram-editor/stories/nested-editing/workflows/switch-locked-cases.yaml @@ -0,0 +1,55 @@ +# +# Copyright 2021-Present The Open Workflow Specification Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +document: + dsl: "1.0.3" + namespace: examples + name: switch-locked-cases + version: "0.1.0" +do: + - routeOrder: + switch: + - electronicOrder: + when: ${ .orderType == "electronic" } + then: fulfillElectronic + - physicalOrder: + when: ${ .orderType == "physical" } + then: fulfillPhysical + - subscriptionOrder: + when: ${ .orderType == "subscription" } + then: fulfillSubscription + - default: + then: rejectUnknownOrder + - fulfillElectronic: + set: + deliveryMethod: email + status: queued + then: exit + - fulfillPhysical: + set: + deliveryMethod: courier + status: queued + then: exit + - fulfillSubscription: + set: + deliveryMethod: recurring + status: active + then: exit + - rejectUnknownOrder: + raise: + error: + type: https://example.com/errors/unknown-order-type + status: 400 + title: Unknown Order Type From 3c60c5767d0c40dd0a85157a06c05713dde631d7 Mon Sep 17 00:00:00 2001 From: Cheryl Kong Date: Mon, 17 Aug 2026 11:24:35 +0100 Subject: [PATCH 2/9] feat: add nested editing stories Signed-off-by: Cheryl Kong --- .../.storybook/preview.tsx | 2 +- .../nested-editing/NestedEditing.stories.tsx | 54 +++++++++++++++++++ .../stories/nested-editing/index.ts | 24 +++++++++ 3 files changed, 79 insertions(+), 1 deletion(-) create mode 100644 packages/open-workflow-diagram-editor/stories/nested-editing/NestedEditing.stories.tsx create mode 100644 packages/open-workflow-diagram-editor/stories/nested-editing/index.ts diff --git a/packages/open-workflow-diagram-editor/.storybook/preview.tsx b/packages/open-workflow-diagram-editor/.storybook/preview.tsx index c1d56a04..5c81649d 100644 --- a/packages/open-workflow-diagram-editor/.storybook/preview.tsx +++ b/packages/open-workflow-diagram-editor/.storybook/preview.tsx @@ -43,7 +43,7 @@ const preview: Preview = { options: { storySort: { - order: ["Introduction", "Features", "Examples", "Use Cases"], + order: ["Introduction", "Features", "Examples", "Use Cases", "Nested Editing"], }, }, }, diff --git a/packages/open-workflow-diagram-editor/stories/nested-editing/NestedEditing.stories.tsx b/packages/open-workflow-diagram-editor/stories/nested-editing/NestedEditing.stories.tsx new file mode 100644 index 00000000..35fd9aec --- /dev/null +++ b/packages/open-workflow-diagram-editor/stories/nested-editing/NestedEditing.stories.tsx @@ -0,0 +1,54 @@ +/* + * Copyright 2021-Present The Open Workflow Specification Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { Meta, StoryObj } from "@storybook/react-vite"; +import { DiagramEditor } from "../features/DiagramEditor"; +import * as workflows from "./index"; + +const meta = { + title: "Nested Editing/Workflows", + component: DiagramEditor, + parameters: { + layout: "fullscreen", + }, + render: (args, { globals }) => { + return ; + }, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +const DEFAULT_STORY_ARGS = { + isReadOnly: false, + locale: "en" as const, +} as const; + +const createWorkflowStory = (workflowContent: string): Story => ({ + args: { + ...DEFAULT_STORY_ARGS, + content: workflowContent, + }, +}); + +export const AllTaskTypes: Story = createWorkflowStory(workflows.allTaskTypes); +export const CallEndpointUnion: Story = createWorkflowStory(workflows.callEndpointUnion); +export const CallHeadersMap: Story = createWorkflowStory(workflows.callHeadersMap); +export const ListenDeepNesting: Story = createWorkflowStory(workflows.listenDeepNesting); +export const NestedValidation: Story = createWorkflowStory(workflows.nestedValidation); +export const RunTaskArray: Story = createWorkflowStory(workflows.runTaskArray); +export const SetOpenMap: Story = createWorkflowStory(workflows.setOpenMap); +export const SwitchLockedCases: Story = createWorkflowStory(workflows.switchLockedCases); diff --git a/packages/open-workflow-diagram-editor/stories/nested-editing/index.ts b/packages/open-workflow-diagram-editor/stories/nested-editing/index.ts new file mode 100644 index 00000000..7eefa954 --- /dev/null +++ b/packages/open-workflow-diagram-editor/stories/nested-editing/index.ts @@ -0,0 +1,24 @@ +/* + * Copyright 2021-Present The Open Workflow Specification Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export { default as allTaskTypes } from "./workflows/all-task-types.yaml?raw"; +export { default as callEndpointUnion } from "./workflows/call-endpoint-union.yaml?raw"; +export { default as callHeadersMap } from "./workflows/call-headers-map.yaml?raw"; +export { default as listenDeepNesting } from "./workflows/listen-deep-nesting.yaml?raw"; +export { default as nestedValidation } from "./workflows/nested-validation.yaml?raw"; +export { default as runTaskArray } from "./workflows/run-task-array.yaml?raw"; +export { default as setOpenMap } from "./workflows/set-open-map.yaml?raw"; +export { default as switchLockedCases } from "./workflows/switch-locked-cases.yaml?raw"; From 9780d0ee010abcea389e29f8df8e30c41744a72e Mon Sep 17 00:00:00 2001 From: Cheryl Kong Date: Mon, 17 Aug 2026 11:24:36 +0100 Subject: [PATCH 3/9] feat: add overview doc and configure SwitchLockedCases as read-only Signed-off-by: Cheryl Kong --- .../nested-editing/NestedEditing.stories.tsx | 8 +++++- .../stories/nested-editing/Overview.mdx | 25 +++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 packages/open-workflow-diagram-editor/stories/nested-editing/Overview.mdx diff --git a/packages/open-workflow-diagram-editor/stories/nested-editing/NestedEditing.stories.tsx b/packages/open-workflow-diagram-editor/stories/nested-editing/NestedEditing.stories.tsx index 35fd9aec..6ae8d228 100644 --- a/packages/open-workflow-diagram-editor/stories/nested-editing/NestedEditing.stories.tsx +++ b/packages/open-workflow-diagram-editor/stories/nested-editing/NestedEditing.stories.tsx @@ -51,4 +51,10 @@ export const ListenDeepNesting: Story = createWorkflowStory(workflows.listenDeep export const NestedValidation: Story = createWorkflowStory(workflows.nestedValidation); export const RunTaskArray: Story = createWorkflowStory(workflows.runTaskArray); export const SetOpenMap: Story = createWorkflowStory(workflows.setOpenMap); -export const SwitchLockedCases: Story = createWorkflowStory(workflows.switchLockedCases); +export const SwitchLockedCases: Story = { + args: { + ...DEFAULT_STORY_ARGS, + isReadOnly: true, + content: workflows.switchLockedCases, + }, +}; diff --git a/packages/open-workflow-diagram-editor/stories/nested-editing/Overview.mdx b/packages/open-workflow-diagram-editor/stories/nested-editing/Overview.mdx new file mode 100644 index 00000000..789b7c78 --- /dev/null +++ b/packages/open-workflow-diagram-editor/stories/nested-editing/Overview.mdx @@ -0,0 +1,25 @@ +{/* + * Copyright 2021-Present The Open Workflow Specification Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */} + +import { Meta } from "@storybook/addon-docs/blocks"; + + + +# Nested Editing + +These stories provide isolated environments for building and testing the nested editing system. +Each story targets a specific interaction pattern introduced by a particular task type or shape, +making it easy to develop, review, and regression-test editing behaviour without noise from unrelated features. From 5130fa8b4edf83a06adcaf54ab1e48ccbfa61a73 Mon Sep 17 00:00:00 2001 From: Cheryl Kong Date: Mon, 17 Aug 2026 11:24:37 +0100 Subject: [PATCH 4/9] add changeset Signed-off-by: Cheryl Kong --- .changeset/nested-editing-stories.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/nested-editing-stories.md diff --git a/.changeset/nested-editing-stories.md b/.changeset/nested-editing-stories.md new file mode 100644 index 00000000..e0279708 --- /dev/null +++ b/.changeset/nested-editing-stories.md @@ -0,0 +1,5 @@ +--- +"@openworkflowspec/diagram-editor": minor +--- + +add nested editing sample workflows From 04581ce9a092ed8897f62529626ce7d3ba618089 Mon Sep 17 00:00:00 2001 From: Cheryl Kong Date: Mon, 17 Aug 2026 11:24:37 +0100 Subject: [PATCH 5/9] fix: fix sample workflows Signed-off-by: Cheryl Kong --- .../workflows/all-task-types.yaml | 63 +++++++++++++++++++ .../workflows/listen-deep-nesting.yaml | 6 +- .../workflows/nested-validation.yaml | 9 ++- 3 files changed, 72 insertions(+), 6 deletions(-) diff --git a/packages/open-workflow-diagram-editor/stories/nested-editing/workflows/all-task-types.yaml b/packages/open-workflow-diagram-editor/stories/nested-editing/workflows/all-task-types.yaml index a2e38d7e..1a27f53c 100644 --- a/packages/open-workflow-diagram-editor/stories/nested-editing/workflows/all-task-types.yaml +++ b/packages/open-workflow-diagram-editor/stories/nested-editing/workflows/all-task-types.yaml @@ -56,6 +56,27 @@ do: code: | const [,, flag, id] = process.argv; console.log(JSON.stringify({ processed: id })); + - waitTask: + wait: + seconds: 5 + - forkTask: + fork: + compete: false + branches: + - notifyEmail: + call: http + with: + method: post + endpoint: https://api.example.com/notifications/email + body: + userId: ${ .userId } + - notifySlack: + call: http + with: + method: post + endpoint: https://api.example.com/notifications/slack + body: + userId: ${ .userId } - listenTask: listen: to: @@ -70,6 +91,28 @@ do: correlate: userId: from: .subject + - emitTask: + emit: + event: + with: + source: https://api.example.com + type: com.example.user.processed.v1 + data: + userId: ${ .userId } + userName: ${ .userName } + - forTask: + for: + each: role + in: ${ .roles } + at: index + do: + - assignRole: + call: http + with: + method: post + endpoint: https://api.example.com/users/${ .userId }/roles + body: + role: ${ .role } - switchTask: switch: - verified: @@ -92,6 +135,26 @@ do: profile: ${ .body } enrichedAt: ${ now } then: exit + - tryTask: + try: + - fetchPreferences: + call: http + with: + method: get + endpoint: https://api.example.com/users/${ .userId }/preferences + catch: + errors: + with: + type: https://open-workflow-specification.org/spec/1.0.0/errors/communication + status: 404 + as: error + do: + - setDefaultPreferences: + set: + preferences: + theme: default + language: en + then: exit - raiseErrorTask: raise: error: notFound diff --git a/packages/open-workflow-diagram-editor/stories/nested-editing/workflows/listen-deep-nesting.yaml b/packages/open-workflow-diagram-editor/stories/nested-editing/workflows/listen-deep-nesting.yaml index 50acd9c4..34a45881 100644 --- a/packages/open-workflow-diagram-editor/stories/nested-editing/workflows/listen-deep-nesting.yaml +++ b/packages/open-workflow-diagram-editor/stories/nested-editing/workflows/listen-deep-nesting.yaml @@ -14,7 +14,7 @@ # limitations under the License. # # Nested editing focus: listen task with deeply nested correlate maps inside -# a to.all array, followed by a foreach block containing its own nested do tasks. +# a to.any array, followed by a foreach block containing its own nested do tasks. # Tests drill-in navigation: top level -> listen config -> event filter array -> # correlate map, and separately: foreach -> do -> nested call task. document: @@ -26,7 +26,7 @@ do: - awaitReadings: listen: to: - all: + any: - with: source: https://sensors.example.com type: com.example.sensors.temperature @@ -54,7 +54,7 @@ do: from: .device.id roomId: from: .location.room - until: ${ .readingCount >= 10 } + until: ${ .readingCount >= 10 } foreach: item: reading at: i diff --git a/packages/open-workflow-diagram-editor/stories/nested-editing/workflows/nested-validation.yaml b/packages/open-workflow-diagram-editor/stories/nested-editing/workflows/nested-validation.yaml index 6c395d63..4aa4cb06 100644 --- a/packages/open-workflow-diagram-editor/stories/nested-editing/workflows/nested-validation.yaml +++ b/packages/open-workflow-diagram-editor/stories/nested-editing/workflows/nested-validation.yaml @@ -16,21 +16,24 @@ document: dsl: "1.0.3" namespace: examples - name: nested-validation-errors + name: nested-validation version: "0.1.0" do: - validStep: set: status: starting - - invalidHttpCall: + - httpCall: call: http with: method: post + endpoint: https://api.example.com/process - processItems: for: each: item + in: ${ .items } do: - - invalidNestedCall: + - nestedCall: call: http with: method: get + endpoint: https://api.example.com/items/${ .item.id } From bad8945392b8343d33ff7873f4bb8d6287e42042 Mon Sep 17 00:00:00 2001 From: Cheryl Kong Date: Mon, 17 Aug 2026 11:24:38 +0100 Subject: [PATCH 6/9] fix copilot complaints Signed-off-by: Cheryl Kong --- .../stories/nested-editing/workflows/set-open-map.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/open-workflow-diagram-editor/stories/nested-editing/workflows/set-open-map.yaml b/packages/open-workflow-diagram-editor/stories/nested-editing/workflows/set-open-map.yaml index 59e1f6ef..dd06cbfe 100644 --- a/packages/open-workflow-diagram-editor/stories/nested-editing/workflows/set-open-map.yaml +++ b/packages/open-workflow-diagram-editor/stories/nested-editing/workflows/set-open-map.yaml @@ -51,6 +51,5 @@ do: taggedAt: ${ now } - finalise: set: - totalProcessed: ${ .index + 1 } completedAt: ${ now } status: done From e63ed17d2e63af4fc8f492870456ee07a5e34ce0 Mon Sep 17 00:00:00 2001 From: Cheryl Kong Date: Tue, 18 Aug 2026 10:53:20 +0100 Subject: [PATCH 7/9] fix: fix tryTask render issue Signed-off-by: Cheryl Kong --- .../workflows/all-task-types.yaml | 39 +++++++++---------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/packages/open-workflow-diagram-editor/stories/nested-editing/workflows/all-task-types.yaml b/packages/open-workflow-diagram-editor/stories/nested-editing/workflows/all-task-types.yaml index 1a27f53c..6fac1288 100644 --- a/packages/open-workflow-diagram-editor/stories/nested-editing/workflows/all-task-types.yaml +++ b/packages/open-workflow-diagram-editor/stories/nested-editing/workflows/all-task-types.yaml @@ -113,6 +113,25 @@ do: endpoint: https://api.example.com/users/${ .userId }/roles body: role: ${ .role } + - tryTask: + try: + - fetchPreferences: + call: http + with: + method: get + endpoint: https://api.example.com/users/${ .userId }/preferences + catch: + errors: + with: + type: https://open-workflow-specification.org/spec/1.0.0/errors/communication + status: 404 + as: error + do: + - setDefaultPreferences: + set: + preferences: + theme: default + language: en - switchTask: switch: - verified: @@ -135,26 +154,6 @@ do: profile: ${ .body } enrichedAt: ${ now } then: exit - - tryTask: - try: - - fetchPreferences: - call: http - with: - method: get - endpoint: https://api.example.com/users/${ .userId }/preferences - catch: - errors: - with: - type: https://open-workflow-specification.org/spec/1.0.0/errors/communication - status: 404 - as: error - do: - - setDefaultPreferences: - set: - preferences: - theme: default - language: en - then: exit - raiseErrorTask: raise: error: notFound From 86281d30d0fd90d1917e370149d460bdc73b5a4f Mon Sep 17 00:00:00 2001 From: Cheryl Kong Date: Tue, 18 Aug 2026 11:19:14 +0100 Subject: [PATCH 8/9] docs: add documentation Signed-off-by: Cheryl Kong --- .../stories/nested-editing/Overview.mdx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/open-workflow-diagram-editor/stories/nested-editing/Overview.mdx b/packages/open-workflow-diagram-editor/stories/nested-editing/Overview.mdx index 789b7c78..2ca73bfc 100644 --- a/packages/open-workflow-diagram-editor/stories/nested-editing/Overview.mdx +++ b/packages/open-workflow-diagram-editor/stories/nested-editing/Overview.mdx @@ -23,3 +23,5 @@ import { Meta } from "@storybook/addon-docs/blocks"; These stories provide isolated environments for building and testing the nested editing system. Each story targets a specific interaction pattern introduced by a particular task type or shape, making it easy to develop, review, and regression-test editing behaviour without noise from unrelated features. + +The **All Task Types** story includes all 12 task types (`call`, `set`, `run`, `wait`, `fork`, `listen`, `emit`, `for`, `try`, `switch`, `do`, `raise`) in a single workflow, providing a reference for how each task appears in the diagram editor. From b559a45f24a9c11291d23e355cb351fc042510c4 Mon Sep 17 00:00:00 2001 From: Cheryl Kong Date: Tue, 18 Aug 2026 15:15:14 +0100 Subject: [PATCH 9/9] docs: minor docs change Signed-off-by: Cheryl Kong --- .../stories/nested-editing/Overview.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/open-workflow-diagram-editor/stories/nested-editing/Overview.mdx b/packages/open-workflow-diagram-editor/stories/nested-editing/Overview.mdx index 2ca73bfc..708b1460 100644 --- a/packages/open-workflow-diagram-editor/stories/nested-editing/Overview.mdx +++ b/packages/open-workflow-diagram-editor/stories/nested-editing/Overview.mdx @@ -24,4 +24,4 @@ These stories provide isolated environments for building and testing the nested Each story targets a specific interaction pattern introduced by a particular task type or shape, making it easy to develop, review, and regression-test editing behaviour without noise from unrelated features. -The **All Task Types** story includes all 12 task types (`call`, `set`, `run`, `wait`, `fork`, `listen`, `emit`, `for`, `try`, `switch`, `do`, `raise`) in a single workflow, providing a reference for how each task appears in the diagram editor. +The **All Task Types** story includes all 12 task types (`call`, `set`, `run`, `wait`, `fork`, `listen`, `emit`, `for`, `try/catch`, `switch`, `do`, `raise`) in a single workflow, providing a reference for how each task appears in the diagram editor.