Skip to content

feat(Canvas): copy-paste yaml support#3449

Open
PVinaches wants to merge 2 commits into
KaotoIO:mainfrom
PVinaches:copy-paste-to-yaml
Open

feat(Canvas): copy-paste yaml support#3449
PVinaches wants to merge 2 commits into
KaotoIO:mainfrom
PVinaches:copy-paste-to-yaml

Conversation

@PVinaches

@PVinaches PVinaches commented Jul 7, 2026

Copy link
Copy Markdown
Member

Summary

This PR introduces native YAML clipboard support for copying and pasting visual entities (routes, pipes,
kamelets, steps) in the Kaoto canvas. Users can now copy entities as YAML and paste them from external sources
or between different parts of the application.


What changed

Core clipboard functionality

  • Replaced ClipboardManager utility with new ClipboardService
    (packages/ui/src/services/visualization/clipboard.service.ts)
  • Added a new ClipboardService
    (packages/ui/src/services/visualization/clipboard.service.ts)
  • Removed the type field from IClipboardContent interface - clipboard compatibility is now inferred from YAML
    key names instead of metadata
  • Added bidirectional YAML serialization:
    • Copy: Serializes entities to YAML format (top-level entities like route, pipe as objects; steps as arrays
      with leading dash)
    • Paste: Parses YAML from clipboard, accepting both Kaoto format ([{ stepName: {...} }]) and external format
      ({ stepName: {...} })
  • Added dual MIME type support: web text/kaoto (Chrome) and text/plain (all browsers) for better
    interoperability

Updated components and hooks

  • Updated all visualization hooks (copy-step.hook, paste-step.hook, duplicate-step.hook) to use new clipboard
    service
  • Updated usePasteEntity hook to use inferClipboardCompatibility() - determines compatibility by matching YAML
    key names against active canvas type
  • Updated DataMapper copy/paste/duplicate operations
  • Updated context menu item interaction helpers
  • Updated all visual entity classes to use IClipboardContent without the type field

Test updates

  • Updated 167 lines of new clipboard service tests covering YAML parsing, serialization, and edge cases
  • Updated Cypress e2e tests to verify YAML structure instead of metadata
  • Updated all unit tests for visual entities, hooks, and DataMapper operations
  • Removed 193 lines of old ClipboardManager tests

Why it changed

User value

  • Enables copying entities as human-readable YAML that can be shared, edited externally, and pasted back
  • Supports pasting YAML from external sources (documentation, chat, text editors) directly into the canvas
  • Improves cross-application workflows and knowledge sharing

Technical improvements

  • Simpler compatibility model: Infers entity type from YAML structure (route:, pipe:, to:) instead of requiring
    metadata
  • Better separation of concerns: Dedicated service class instead of static utility
  • Standards-aligned: Uses proper YAML serialization with appropriate formatting for entities vs steps
  • More robust parsing: Handles both array and object YAML formats

How it was verified

Unit tests

  • ✅ All existing tests updated and passing
  • ✅ New clipboard.service.test.ts covers:
    • Parsing both array and object YAML formats
    • Serialization for entities (route, pipe, kamelet) and steps
    • MIME type detection and fallback behavior
    • Edge cases (invalid YAML, empty content, multiple keys)

E2e tests

  • ✅ Updated Cypress tests verify:
    • Copy operations write correct YAML structure
    • Paste operations accept YAML without metadata
    • Step, route, and pipe copy/paste flows work end-to-end

Manual testing checklist

  • Copy a route from canvas → verify YAML in clipboard is properly formatted
  • Copy a step from canvas → verify YAML includes leading dash for array format
  • Paste external YAML (e.g., route: { id: 'test', ... }) → verify it creates entity on canvas
  • Paste Kaoto YAML (e.g., [{ to: { uri: 'log:test' } }]) → verify it creates step
  • Test on both Chrome (with web text/kaoto) and Firefox (with text/plain)
  • Verify incompatible paste shows error modal

Reviewer notes

Key files to review

  1. packages/ui/src/services/visualization/clipboard.service.ts - New clipboard service with YAML serialization
    logic
  2. packages/ui/src/hooks/usePasteEntity.ts - Updated compatibility inference logic
  3. packages/ui/src/models/visualization/clipboard.ts - Simplified interface (removed type field)
  4. Cypress tests (stepCopy.cy.ts, stepPaste.cy.ts) - E2e verification

Design decisions

  • Entity vs step formatting: Top-level entities (route, pipe, etc.) serialize as objects; steps serialize as
    single-element arrays to match YAML DSL conventions (leading dash)
  • Compatibility inference: Matches clipboard YAML key name against supportedEntities or resource type
  • Entity vs step formatting: Top-level entities (route, pipe, etc.) serialize as objects; steps serialize as single-element arrays to match YAML DSL conventions (leading dash)
  • Compatibility inference: Matches clipboard YAML key name against supportedEntities or resource type (case-insensitive) instead of using metadata
  • MIME type strategy: Chrome gets both web text/kaoto and text/plain; other browsers get text/plain only

Backwards compatibility

  • ✅ All existing copy/paste functionality preserved
  • ✅ Internal clipboard operations continue to work
  • ⚠️ Old clipboard format (with type field) is no longer written, but paste compatibility is maintained via key name inference

fix: #2652

Summary by CodeRabbit

Summary by CodeRabbit

  • New Features
    • Clipboard copy/paste now uses a YAML-based format with Kaoto-aware MIME support for better interoperability with external editors.
  • Bug Fixes
    • Pasting steps from raw YAML (without any app-specific marker) works reliably.
    • Simplified clipboard payloads and updated compatibility checks make paste behavior align with supported components.
  • Chores
    • Updated automated UI and unit tests to match the new clipboard format and parsing behavior.

@coderabbitai

coderabbitai Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

This PR replaces the JSON clipboard model with YAML-backed IClipboardContent, removes schema-type wrappers, adds ClipboardService, updates copy/paste compatibility flows, and expands unit and Cypress coverage for external YAML clipboard data.

Changes

Clipboard model migration

Layer / File(s) Summary
Clipboard contract and YAML service
packages/ui/src/models/visualization/clipboard.ts, packages/ui/src/services/visualization/clipboard.service.ts, packages/ui/src/services/visualization/clipboard.service.test.ts
IClipboardContent contains name and definition; ClipboardService writes and reads YAML using supported clipboard MIME types.
Visualization entity payloads
packages/ui/src/models/visualization/flows/*, packages/ui/src/models/visualization/visualization-node.ts, packages/ui/src/models/visualization/base-visual-entity.ts
Entity copy and paste APIs use the new payload shape, including root-path copies for Citrus, Kamelet, and Pipe entities.
DataMapper and interaction typing
packages/ui/src/components/DataMapper/*, packages/ui/src/components/registers/interactions/*, packages/ui/src/components/Visualization/Custom/ContextMenu/*
DataMapper handlers, interaction callbacks, and forward-drop processing use IClipboardContent.
Hook compatibility wiring
packages/ui/src/components/Visualization/Custom/hooks/*, packages/ui/src/hooks/usePasteEntity.ts
Copy and paste hooks call ClipboardService; compatibility is inferred from clipboard names and resource compatibility data.
Clipboard test coverage
packages/ui-tests/cypress/e2e/designer/basicNodeActions/*, packages/ui-tests/cypress/support/next-commands/default.ts
Cypress assertions parse YAML and cover raw external YAML paste without a Kaoto marker.

Estimated code review effort: 4 (Complex) | ~60 minutes

Possibly related PRs

Poem

A rabbit hopped through YAML bright,
External snippets took to flight.
name and definition came through,
With copy and paste made new. 🐇

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning Most changes are in scope, but the Monaco worker import in main.tsx appears unrelated to YAML clipboard support. Remove or justify the main.tsx worker import if it is not required for the clipboard YAML feature.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: Canvas copy-paste YAML support.
Linked Issues check ✅ Passed The changes implement YAML-based copy/paste and external YAML compatibility as requested in #2652.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@PVinaches
PVinaches force-pushed the copy-paste-to-yaml branch from 3bf1fa1 to a8405c9 Compare July 7, 2026 17:29
@PVinaches
PVinaches marked this pull request as ready for review July 7, 2026 17:29

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/ui/src/models/visualization/flows/citrus-test-visual-entity.ts (1)

243-267: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Return the raw action payload from getCopiedContent()
definition should be the action object itself, not { print: {...} }; ClipboardService.copy() already wraps it under name, so the current shape serializes to double-nested YAML and breaks cross-app clipboard compatibility.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/ui/src/models/visualization/flows/citrus-test-visual-entity.ts`
around lines 243 - 267, getCopiedContent() is returning the action payload in an
extra wrapper shape, which causes clipboard data to be nested incorrectly.
Update CitrusTestVisualEntity.getCopiedContent() so the returned clipboard
definition is the raw action object itself for a copied step, while still
keeping the root test case behavior unchanged; this will let
ClipboardService.copy() handle the outer name wrapper and avoid double-nested
serialization. Ensure the same structure is what pasteStep() expects when it
reads clipboardContent.definition.
🧹 Nitpick comments (5)
packages/ui/src/services/visualization/clipboard.service.ts (1)

39-43: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Duplicated ClipboardItem.supports?.(KAOTO_MIME_TYPE) check.

copy() and getBestMimeType() both re-implement the same "is the custom Kaoto MIME type supported" check. Extracting a small private helper (e.g. isKaotoMimeTypeSupported()) would remove the duplication.

Also applies to: 55-70

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/ui/src/services/visualization/clipboard.service.ts` around lines 39
- 43, The Kaoto MIME type support check is duplicated in ClipboardService
between copy() and getBestMimeType(), so extract it into a private helper such
as isKaotoMimeTypeSupported() and use that helper in both places. Update the
ClipboardService methods to call the shared helper instead of rechecking
ClipboardItem.supports?.(ClipboardService.KAOTO_MIME_TYPE) inline, keeping the
existing behavior unchanged.
packages/ui/src/services/visualization/clipboard.service.test.ts (1)

151-165: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Consider adding a test for shorthand string step values.

Coverage is solid, but there's no test for parsing YAML where the value under the key is a plain string (e.g. to: mock:middle), which is valid Camel YAML DSL syntax and currently accepted as-is by parseYamlToClipboardContent despite the definition: object contract. Adding a case here would pin down the intended behavior once the parsing gap in clipboard.service.ts is addressed.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/ui/src/services/visualization/clipboard.service.test.ts` around
lines 151 - 165, Add a test case in ClipboardService.paste coverage for
shorthand string step values, since parseYamlToClipboardContent currently
accepts plain-string YAML values even though the clipboard content contract
expects an object definition. Extend the existing clipboard.service.test.ts
suite near the current raw-YAML test to cover an input like a key mapped to a
string, and assert the intended ClipboardService.paste result so the behavior is
pinned down once clipboard.service.ts is updated.
packages/ui/src/models/visualization/flows/pipe-visual-entity.test.ts (1)

730-757: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Missing test coverage for the new root-path copy branch.

getCopiedContent now special-cases path === this.getRootPath() to return { name: 'pipe', definition: this.pipe } (pipe-visual-entity.ts, lines 150-153), but this describe('getCopiedContent', ...) block only covers step paths and the invalid-path case. Consider adding a test asserting the root-path branch returns the full pipe CR.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/ui/src/models/visualization/flows/pipe-visual-entity.test.ts` around
lines 730 - 757, Add a test in getCopiedContent to cover the new root-path
branch in pipeVisualEntity.getCopiedContent. The current
describe('getCopiedContent', ...) only verifies step paths and invalid/undefined
input, so include a case where the path matches pipeVisualEntity.getRootPath()
and assert it returns the full pipe CR shape with name 'pipe' and definition set
to pipeVisualEntity.pipe.
packages/ui-tests/cypress/support/next-commands/default.ts (2)

395-410: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Deduplicate the two MIME-type parsing branches.

The web text/kaoto and text/plain branches are identical apart from the MIME type string; extract a shared helper to read/parse/normalize a clipboard item.

♻️ Proposed refactor
+async function readAndNormalize(item: ClipboardItem, mimeType: string) {
+  const blob = await item.getType(mimeType);
+  const yamlText = await blob.text();
+  return normalizeClipboardContent(parse(yamlText));
+}
+
           if (item.types.includes('web text/kaoto')) {
-            const blob = await item.getType('web text/kaoto');
-            const yamlText = await blob.text();
-            const parsedContent = parse(yamlText);
-
-            // Normalize parsed YAML to IClipboardContent format
-            const clipboardContent = normalizeClipboardContent(parsedContent);
+            const clipboardContent = await readAndNormalize(item, 'web text/kaoto');
             expect(clipboardContent).to.deep.equal(value);
           }

           if (item.types.includes('text/plain')) {
-            const blob = await item.getType('text/plain');
-            const yamlText = await blob.text();
-            const parsedContent = parse(yamlText);
-
-            // Normalize parsed YAML to IClipboardContent format
-            const clipboardContent = normalizeClipboardContent(parsedContent);
+            const clipboardContent = await readAndNormalize(item, 'text/plain');
             expect(clipboardContent).to.deep.equal(value);
           }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/ui-tests/cypress/support/next-commands/default.ts` around lines 395
- 410, The `item.types.includes('web text/kaoto')` and
`item.types.includes('text/plain')` branches in `next-commands/default.ts`
duplicate the same read/parse/normalize/assert flow. Extract that repeated logic
into a shared helper near the clipboard handling code, and have both MIME-type
checks call it with the item; keep the existing `normalizeClipboardContent` and
`parse` behavior unchanged.

421-445: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Export the clipboard parser and reuse it here. packages/ui-tests can’t import packages/ui/src/services/visualization/clipboard.service.ts directly, so this helper duplicates ClipboardService.parseYamlToClipboardContent and can drift. Re-export that parser through packages/ui’s testing API and import it here instead.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/ui-tests/cypress/support/next-commands/default.ts` around lines 421
- 445, The YAML clipboard normalization logic in normalizeClipboardContent is
duplicating ClipboardService.parseYamlToClipboardContent, which risks
divergence. Re-export the parser through the packages/ui testing API and update
the Cypress support code to import and use that shared parser instead of
maintaining a local copy. Keep the existing normalizeClipboardContent call sites
aligned with the shared parser’s return shape.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/ui-tests/cypress/support/next-commands/default.ts`:
- Around line 421-445: The normalizeClipboardContent helper still accepts a null
first element in the array branch because typeof null is object, which can cause
Object.keys(parsed[0]) to throw. Update the array handling in
normalizeClipboardContent to explicitly reject null before reading keys,
alongside the existing parsed[0] shape checks, so invalid clipboard payloads
return null safely for both array and object formats.

In `@packages/ui/src/models/visualization/flows/kamelet-visual-entity.ts`:
- Around line 94-104: Add test coverage for the root-path branch in
getCopiedContent on KameletVisualEntity: verify that when the input matches
getRootPath() it returns an IClipboardContent with name set to kamelet and
definition pointing to this.kamelet, and also confirm that non-root paths still
fall through to the inherited super.getCopiedContent(path) behavior.

In `@packages/ui/src/services/visualization/clipboard.service.ts`:
- Around line 17-18: The hardcoded ENTITY_TYPES whitelist in ClipboardService is
missing root entities like errorHandler and restConfiguration, causing copy() to
wrap them in arrays and alter the YAML shape. Update ClipboardService.copy() to
treat all canonical root entity names as top-level entities by deriving
ENTITY_TYPES from the shared entity-type source instead of maintaining a
separate static list, and ensure the logic that decides whether to wrap in an
array uses that canonical set.

---

Outside diff comments:
In `@packages/ui/src/models/visualization/flows/citrus-test-visual-entity.ts`:
- Around line 243-267: getCopiedContent() is returning the action payload in an
extra wrapper shape, which causes clipboard data to be nested incorrectly.
Update CitrusTestVisualEntity.getCopiedContent() so the returned clipboard
definition is the raw action object itself for a copied step, while still
keeping the root test case behavior unchanged; this will let
ClipboardService.copy() handle the outer name wrapper and avoid double-nested
serialization. Ensure the same structure is what pasteStep() expects when it
reads clipboardContent.definition.

---

Nitpick comments:
In `@packages/ui-tests/cypress/support/next-commands/default.ts`:
- Around line 395-410: The `item.types.includes('web text/kaoto')` and
`item.types.includes('text/plain')` branches in `next-commands/default.ts`
duplicate the same read/parse/normalize/assert flow. Extract that repeated logic
into a shared helper near the clipboard handling code, and have both MIME-type
checks call it with the item; keep the existing `normalizeClipboardContent` and
`parse` behavior unchanged.
- Around line 421-445: The YAML clipboard normalization logic in
normalizeClipboardContent is duplicating
ClipboardService.parseYamlToClipboardContent, which risks divergence. Re-export
the parser through the packages/ui testing API and update the Cypress support
code to import and use that shared parser instead of maintaining a local copy.
Keep the existing normalizeClipboardContent call sites aligned with the shared
parser’s return shape.

In `@packages/ui/src/models/visualization/flows/pipe-visual-entity.test.ts`:
- Around line 730-757: Add a test in getCopiedContent to cover the new root-path
branch in pipeVisualEntity.getCopiedContent. The current
describe('getCopiedContent', ...) only verifies step paths and invalid/undefined
input, so include a case where the path matches pipeVisualEntity.getRootPath()
and assert it returns the full pipe CR shape with name 'pipe' and definition set
to pipeVisualEntity.pipe.

In `@packages/ui/src/services/visualization/clipboard.service.test.ts`:
- Around line 151-165: Add a test case in ClipboardService.paste coverage for
shorthand string step values, since parseYamlToClipboardContent currently
accepts plain-string YAML values even though the clipboard content contract
expects an object definition. Extend the existing clipboard.service.test.ts
suite near the current raw-YAML test to cover an input like a key mapped to a
string, and assert the intended ClipboardService.paste result so the behavior is
pinned down once clipboard.service.ts is updated.

In `@packages/ui/src/services/visualization/clipboard.service.ts`:
- Around line 39-43: The Kaoto MIME type support check is duplicated in
ClipboardService between copy() and getBestMimeType(), so extract it into a
private helper such as isKaotoMimeTypeSupported() and use that helper in both
places. Update the ClipboardService methods to call the shared helper instead of
rechecking ClipboardItem.supports?.(ClipboardService.KAOTO_MIME_TYPE) inline,
keeping the existing behavior unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: da11c9f2-9ec0-4463-a29f-5192d0451f47

📥 Commits

Reviewing files that changed from the base of the PR and between 564f76b and a8405c9.

📒 Files selected for processing (42)
  • packages/ui-tests/cypress/e2e/designer/basicNodeActions/stepCopy.cy.ts
  • packages/ui-tests/cypress/e2e/designer/basicNodeActions/stepPaste.cy.ts
  • packages/ui-tests/cypress/support/next-commands/default.ts
  • packages/ui/src/components/DataMapper/on-copy-datamapper.test.ts
  • packages/ui/src/components/DataMapper/on-copy-datamapper.ts
  • packages/ui/src/components/DataMapper/on-duplicate-datamapper.test.ts
  • packages/ui/src/components/DataMapper/on-duplicate-datamapper.ts
  • packages/ui/src/components/DataMapper/on-paste-data-mapper.test.ts
  • packages/ui/src/components/DataMapper/on-paste-data-mapper.ts
  • packages/ui/src/components/Visualization/Custom/ContextMenu/item-interaction-helper.ts
  • packages/ui/src/components/Visualization/Custom/Node/CustomNodeUtils.ts
  • packages/ui/src/components/Visualization/Custom/hooks/copy-step.hook.test.tsx
  • packages/ui/src/components/Visualization/Custom/hooks/copy-step.hook.tsx
  • packages/ui/src/components/Visualization/Custom/hooks/duplicate-step.hook.tsx
  • packages/ui/src/components/Visualization/Custom/hooks/move-step.hook.test.tsx
  • packages/ui/src/components/Visualization/Custom/hooks/paste-step.hook.test.tsx
  • packages/ui/src/components/Visualization/Custom/hooks/paste-step.hook.tsx
  • packages/ui/src/components/registers/interactions/node-interaction-addon.model.ts
  • packages/ui/src/hooks/usePasteEntity.test.tsx
  • packages/ui/src/hooks/usePasteEntity.ts
  • packages/ui/src/main.tsx
  • packages/ui/src/models/visualization/base-visual-entity.ts
  • packages/ui/src/models/visualization/clipboard.ts
  • packages/ui/src/models/visualization/flows/abstract-camel-visual-entity.test.ts
  • packages/ui/src/models/visualization/flows/abstract-camel-visual-entity.ts
  • packages/ui/src/models/visualization/flows/camel-error-handler-visual-entity.test.ts
  • packages/ui/src/models/visualization/flows/camel-error-handler-visual-entity.ts
  • packages/ui/src/models/visualization/flows/camel-rest-configuration-visual-entity.test.ts
  • packages/ui/src/models/visualization/flows/camel-rest-configuration-visual-entity.ts
  • packages/ui/src/models/visualization/flows/citrus-test-visual-entity.test.ts
  • packages/ui/src/models/visualization/flows/citrus-test-visual-entity.ts
  • packages/ui/src/models/visualization/flows/kamelet-visual-entity.ts
  • packages/ui/src/models/visualization/flows/pipe-visual-entity.test.ts
  • packages/ui/src/models/visualization/flows/pipe-visual-entity.ts
  • packages/ui/src/models/visualization/flows/support/camel-component-schema.service.test.ts
  • packages/ui/src/models/visualization/flows/support/camel-component-schema.service.ts
  • packages/ui/src/models/visualization/visualization-node.test.ts
  • packages/ui/src/models/visualization/visualization-node.ts
  • packages/ui/src/services/visualization/clipboard.service.test.ts
  • packages/ui/src/services/visualization/clipboard.service.ts
  • packages/ui/src/utils/ClipboardManager.test.ts
  • packages/ui/src/utils/ClipboardManager.ts
💤 Files with no reviewable changes (4)
  • packages/ui/src/utils/ClipboardManager.ts
  • packages/ui/src/utils/ClipboardManager.test.ts
  • packages/ui/src/components/Visualization/Custom/hooks/move-step.hook.test.tsx
  • packages/ui/src/models/visualization/flows/citrus-test-visual-entity.test.ts

Comment thread packages/ui-tests/cypress/support/next-commands/default.ts
Comment thread packages/ui/src/models/visualization/flows/kamelet-visual-entity.ts
Comment thread packages/ui/src/services/visualization/clipboard.service.ts Outdated

@igarashitm igarashitm 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.

No issue is found from DataMapper PoV 👍

@lordrip lordrip 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.

I tried it locally and it works very well. Considering that we're reading/writing XLM from/to the clipboard, I think we should move away from using markers and custom serialization and instead use plain string. XML support should be added in an upcoming PR.

Comment thread packages/ui/src/main.tsx Outdated
@@ -1,3 +1,4 @@
import './components/SourceCode/workers/enable-workers'; // Configure Monaco loader before anything else

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.

Interesting, why is this? 👀

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

It was a Claude suggestion and I digged a bit and what this does is to load Monaco first so that it avoids falling into the CDN based loading. If for ex. it uses the CDN one, we could have version incompatibility at some point or possible failures. I think it's worth trying out. In my end I didn't notice any issue so I decided to keep the change here in case we can enjoy some benefits also in the E2E experience.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I deleted this file from the PR as it doesn't influence directly tnis. But I think we should think about this in relation of those random E2E fails

definition: { id: 'to-1913', uri: 'amqp', parameters: {} },
__kaoto_marker: 'kaoto-node',
cy.window().then(async (win) => {
const yamlContent = '- to:\n id: to-1913\n uri: amqp\n parameters: {}\n';

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.

Suggested change
const yamlContent = '- to:\n id: to-1913\n uri: amqp\n parameters: {}\n';
const yamlContent = ```
- to:
id: to-1913
uri: amqp
parameters: {}
```;

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

pushed with just one `

cy.uploadFixture('flows/camelRoute/basic.yaml');
// Simulate clipboard content written by an external editor — raw YAML, no __kaoto_marker
cy.window().then(async (win) => {
const externalYaml = '- log:\n message: hello from external\n';

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.

Suggested change
const externalYaml = '- log:\n message: hello from external\n';
const externalYaml = ```
- log:
message: hello from external
```;

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

pushed with just one `

@PVinaches
PVinaches force-pushed the copy-paste-to-yaml branch 2 times, most recently from cb6378f to e635bf3 Compare July 9, 2026 12:44

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
packages/ui/src/services/visualization/clipboard.service.test.ts (1)

99-101: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Consider using stringify() instead of hardcoded YAML strings.

Lines 100, 120, and 140 assert exact YAML output with hardcoded strings. If the yaml library changes formatting (indentation, quoting, etc.), these tests will break even though the service logic is correct. Using stringify() to compute expected values (as done at line 43) would make these tests more resilient.

♻️ Optional refactor example for line 100
-      expect(yaml).toBe('errorHandler:\n  deadLetterChannel:\n    deadLetterUri: log:dlq\n');
+      expect(yaml).toBe(stringify({ errorHandler: { deadLetterChannel: { deadLetterUri: 'log:dlq' } } }));

Also applies to: 119-121, 139-141

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/ui/src/services/visualization/clipboard.service.test.ts` around
lines 99 - 101, The clipboard service tests are asserting exact YAML with
hardcoded strings, which makes them brittle to formatting changes in the yaml
library. Update the expectations in clipboard.service.test.ts to build the
expected YAML using stringify() like the existing pattern in the file, and
compare against that value in the affected cases around the clipboard
serialization checks (including the errorHandler, nested map, and array cases).
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@packages/ui/src/services/visualization/clipboard.service.test.ts`:
- Around line 99-101: The clipboard service tests are asserting exact YAML with
hardcoded strings, which makes them brittle to formatting changes in the yaml
library. Update the expectations in clipboard.service.test.ts to build the
expected YAML using stringify() like the existing pattern in the file, and
compare against that value in the affected cases around the clipboard
serialization checks (including the errorHandler, nested map, and array cases).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: e30ead18-c0a1-4b60-a0cc-367687f95c10

📥 Commits

Reviewing files that changed from the base of the PR and between cb6378f and e635bf3.

📒 Files selected for processing (42)
  • packages/ui-tests/cypress/e2e/designer/basicNodeActions/stepCopy.cy.ts
  • packages/ui-tests/cypress/e2e/designer/basicNodeActions/stepPaste.cy.ts
  • packages/ui-tests/cypress/support/next-commands/default.ts
  • packages/ui/src/components/DataMapper/on-copy-datamapper.test.ts
  • packages/ui/src/components/DataMapper/on-copy-datamapper.ts
  • packages/ui/src/components/DataMapper/on-duplicate-datamapper.test.ts
  • packages/ui/src/components/DataMapper/on-duplicate-datamapper.ts
  • packages/ui/src/components/DataMapper/on-paste-data-mapper.test.ts
  • packages/ui/src/components/DataMapper/on-paste-data-mapper.ts
  • packages/ui/src/components/Visualization/Custom/ContextMenu/item-interaction-helper.ts
  • packages/ui/src/components/Visualization/Custom/Node/CustomNodeUtils.ts
  • packages/ui/src/components/Visualization/Custom/hooks/copy-step.hook.test.tsx
  • packages/ui/src/components/Visualization/Custom/hooks/copy-step.hook.tsx
  • packages/ui/src/components/Visualization/Custom/hooks/duplicate-step.hook.tsx
  • packages/ui/src/components/Visualization/Custom/hooks/move-step.hook.test.tsx
  • packages/ui/src/components/Visualization/Custom/hooks/paste-step.hook.test.tsx
  • packages/ui/src/components/Visualization/Custom/hooks/paste-step.hook.tsx
  • packages/ui/src/components/registers/interactions/node-interaction-addon.model.ts
  • packages/ui/src/hooks/usePasteEntity.test.tsx
  • packages/ui/src/hooks/usePasteEntity.ts
  • packages/ui/src/main.tsx
  • packages/ui/src/models/visualization/base-visual-entity.ts
  • packages/ui/src/models/visualization/clipboard.ts
  • packages/ui/src/models/visualization/flows/abstract-camel-visual-entity.test.ts
  • packages/ui/src/models/visualization/flows/abstract-camel-visual-entity.ts
  • packages/ui/src/models/visualization/flows/camel-error-handler-visual-entity.test.ts
  • packages/ui/src/models/visualization/flows/camel-error-handler-visual-entity.ts
  • packages/ui/src/models/visualization/flows/camel-rest-configuration-visual-entity.test.ts
  • packages/ui/src/models/visualization/flows/camel-rest-configuration-visual-entity.ts
  • packages/ui/src/models/visualization/flows/citrus-test-visual-entity.test.ts
  • packages/ui/src/models/visualization/flows/citrus-test-visual-entity.ts
  • packages/ui/src/models/visualization/flows/kamelet-visual-entity.ts
  • packages/ui/src/models/visualization/flows/pipe-visual-entity.test.ts
  • packages/ui/src/models/visualization/flows/pipe-visual-entity.ts
  • packages/ui/src/models/visualization/flows/support/camel-component-schema.service.test.ts
  • packages/ui/src/models/visualization/flows/support/camel-component-schema.service.ts
  • packages/ui/src/models/visualization/visualization-node.test.ts
  • packages/ui/src/models/visualization/visualization-node.ts
  • packages/ui/src/services/visualization/clipboard.service.test.ts
  • packages/ui/src/services/visualization/clipboard.service.ts
  • packages/ui/src/utils/ClipboardManager.test.ts
  • packages/ui/src/utils/ClipboardManager.ts
💤 Files with no reviewable changes (4)
  • packages/ui/src/utils/ClipboardManager.ts
  • packages/ui/src/utils/ClipboardManager.test.ts
  • packages/ui/src/components/Visualization/Custom/hooks/move-step.hook.test.tsx
  • packages/ui/src/models/visualization/flows/citrus-test-visual-entity.test.ts
✅ Files skipped from review due to trivial changes (4)
  • packages/ui/src/components/DataMapper/on-copy-datamapper.ts
  • packages/ui/src/components/Visualization/Custom/hooks/copy-step.hook.tsx
  • packages/ui/src/components/Visualization/Custom/Node/CustomNodeUtils.ts
  • packages/ui/src/components/DataMapper/on-duplicate-datamapper.ts
🚧 Files skipped from review as they are similar to previous changes (33)
  • packages/ui/src/models/visualization/visualization-node.test.ts
  • packages/ui/src/models/visualization/flows/support/camel-component-schema.service.ts
  • packages/ui/src/models/visualization/flows/camel-rest-configuration-visual-entity.test.ts
  • packages/ui/src/components/DataMapper/on-copy-datamapper.test.ts
  • packages/ui/src/models/visualization/flows/abstract-camel-visual-entity.ts
  • packages/ui/src/models/visualization/clipboard.ts
  • packages/ui/src/models/visualization/flows/support/camel-component-schema.service.test.ts
  • packages/ui/src/components/Visualization/Custom/ContextMenu/item-interaction-helper.ts
  • packages/ui/src/models/visualization/flows/camel-rest-configuration-visual-entity.ts
  • packages/ui-tests/cypress/support/next-commands/default.ts
  • packages/ui/src/models/visualization/visualization-node.ts
  • packages/ui/src/components/DataMapper/on-duplicate-datamapper.test.ts
  • packages/ui-tests/cypress/e2e/designer/basicNodeActions/stepPaste.cy.ts
  • packages/ui/src/components/DataMapper/on-paste-data-mapper.ts
  • packages/ui/src/models/visualization/base-visual-entity.ts
  • packages/ui/src/main.tsx
  • packages/ui/src/components/Visualization/Custom/hooks/duplicate-step.hook.tsx
  • packages/ui/src/models/visualization/flows/camel-error-handler-visual-entity.test.ts
  • packages/ui/src/components/Visualization/Custom/hooks/copy-step.hook.test.tsx
  • packages/ui/src/models/visualization/flows/citrus-test-visual-entity.ts
  • packages/ui/src/models/visualization/flows/pipe-visual-entity.ts
  • packages/ui/src/models/visualization/flows/kamelet-visual-entity.ts
  • packages/ui/src/models/visualization/flows/camel-error-handler-visual-entity.ts
  • packages/ui/src/components/DataMapper/on-paste-data-mapper.test.ts
  • packages/ui/src/components/Visualization/Custom/hooks/paste-step.hook.tsx
  • packages/ui/src/models/visualization/flows/abstract-camel-visual-entity.test.ts
  • packages/ui/src/components/Visualization/Custom/hooks/paste-step.hook.test.tsx
  • packages/ui-tests/cypress/e2e/designer/basicNodeActions/stepCopy.cy.ts
  • packages/ui/src/components/registers/interactions/node-interaction-addon.model.ts
  • packages/ui/src/services/visualization/clipboard.service.ts
  • packages/ui/src/hooks/usePasteEntity.ts
  • packages/ui/src/models/visualization/flows/pipe-visual-entity.test.ts
  • packages/ui/src/hooks/usePasteEntity.test.tsx

@PVinaches
PVinaches force-pushed the copy-paste-to-yaml branch 2 times, most recently from 8d9cc8d to d7c8eb8 Compare July 13, 2026 14:55

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/ui/src/services/visualization/clipboard.service.test.ts`:
- Around line 45-47: Update the beforeEach setup in the clipboard service tests
to call vi.restoreAllMocks() so spy implementations, including
navigator.clipboard.write and console.error, are restored between tests; retain
mock history reset if needed for independent assertions.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 507b91be-2f31-4d16-9df6-7f2982751835

📥 Commits

Reviewing files that changed from the base of the PR and between 8d9cc8d and d7c8eb8.

📒 Files selected for processing (42)
  • packages/ui-tests/cypress/e2e/designer/basicNodeActions/stepCopy.cy.ts
  • packages/ui-tests/cypress/e2e/designer/basicNodeActions/stepPaste.cy.ts
  • packages/ui-tests/cypress/support/next-commands/default.ts
  • packages/ui/src/components/DataMapper/on-copy-datamapper.test.ts
  • packages/ui/src/components/DataMapper/on-copy-datamapper.ts
  • packages/ui/src/components/DataMapper/on-duplicate-datamapper.test.ts
  • packages/ui/src/components/DataMapper/on-duplicate-datamapper.ts
  • packages/ui/src/components/DataMapper/on-paste-data-mapper.test.ts
  • packages/ui/src/components/DataMapper/on-paste-data-mapper.ts
  • packages/ui/src/components/Visualization/Custom/ContextMenu/item-interaction-helper.ts
  • packages/ui/src/components/Visualization/Custom/Node/CustomNodeUtils.ts
  • packages/ui/src/components/Visualization/Custom/hooks/copy-step.hook.test.tsx
  • packages/ui/src/components/Visualization/Custom/hooks/copy-step.hook.tsx
  • packages/ui/src/components/Visualization/Custom/hooks/duplicate-step.hook.tsx
  • packages/ui/src/components/Visualization/Custom/hooks/move-step.hook.test.tsx
  • packages/ui/src/components/Visualization/Custom/hooks/paste-step.hook.test.tsx
  • packages/ui/src/components/Visualization/Custom/hooks/paste-step.hook.tsx
  • packages/ui/src/components/registers/interactions/node-interaction-addon.model.ts
  • packages/ui/src/hooks/usePasteEntity.test.tsx
  • packages/ui/src/hooks/usePasteEntity.ts
  • packages/ui/src/main.tsx
  • packages/ui/src/models/visualization/base-visual-entity.ts
  • packages/ui/src/models/visualization/clipboard.ts
  • packages/ui/src/models/visualization/flows/abstract-camel-visual-entity.test.ts
  • packages/ui/src/models/visualization/flows/abstract-camel-visual-entity.ts
  • packages/ui/src/models/visualization/flows/camel-error-handler-visual-entity.test.ts
  • packages/ui/src/models/visualization/flows/camel-error-handler-visual-entity.ts
  • packages/ui/src/models/visualization/flows/camel-rest-configuration-visual-entity.test.ts
  • packages/ui/src/models/visualization/flows/camel-rest-configuration-visual-entity.ts
  • packages/ui/src/models/visualization/flows/citrus-test-visual-entity.test.ts
  • packages/ui/src/models/visualization/flows/citrus-test-visual-entity.ts
  • packages/ui/src/models/visualization/flows/kamelet-visual-entity.ts
  • packages/ui/src/models/visualization/flows/pipe-visual-entity.test.ts
  • packages/ui/src/models/visualization/flows/pipe-visual-entity.ts
  • packages/ui/src/models/visualization/flows/support/camel-component-schema.service.test.ts
  • packages/ui/src/models/visualization/flows/support/camel-component-schema.service.ts
  • packages/ui/src/models/visualization/visualization-node.test.ts
  • packages/ui/src/models/visualization/visualization-node.ts
  • packages/ui/src/services/visualization/clipboard.service.test.ts
  • packages/ui/src/services/visualization/clipboard.service.ts
  • packages/ui/src/utils/ClipboardManager.test.ts
  • packages/ui/src/utils/ClipboardManager.ts
💤 Files with no reviewable changes (4)
  • packages/ui/src/utils/ClipboardManager.test.ts
  • packages/ui/src/utils/ClipboardManager.ts
  • packages/ui/src/components/Visualization/Custom/hooks/move-step.hook.test.tsx
  • packages/ui/src/models/visualization/flows/citrus-test-visual-entity.test.ts
🚧 Files skipped from review as they are similar to previous changes (32)
  • packages/ui/src/main.tsx
  • packages/ui/src/components/Visualization/Custom/hooks/duplicate-step.hook.tsx
  • packages/ui/src/components/DataMapper/on-duplicate-datamapper.ts
  • packages/ui/src/components/DataMapper/on-copy-datamapper.ts
  • packages/ui/src/components/DataMapper/on-duplicate-datamapper.test.ts
  • packages/ui/src/models/visualization/flows/camel-error-handler-visual-entity.test.ts
  • packages/ui/src/models/visualization/visualization-node.ts
  • packages/ui/src/models/visualization/flows/camel-error-handler-visual-entity.ts
  • packages/ui/src/models/visualization/flows/kamelet-visual-entity.ts
  • packages/ui/src/models/visualization/visualization-node.test.ts
  • packages/ui/src/models/visualization/flows/pipe-visual-entity.test.ts
  • packages/ui-tests/cypress/e2e/designer/basicNodeActions/stepPaste.cy.ts
  • packages/ui/src/models/visualization/base-visual-entity.ts
  • packages/ui/src/models/visualization/flows/citrus-test-visual-entity.ts
  • packages/ui/src/components/registers/interactions/node-interaction-addon.model.ts
  • packages/ui/src/components/Visualization/Custom/hooks/copy-step.hook.test.tsx
  • packages/ui/src/models/visualization/flows/support/camel-component-schema.service.test.ts
  • packages/ui/src/models/visualization/flows/support/camel-component-schema.service.ts
  • packages/ui/src/models/visualization/clipboard.ts
  • packages/ui-tests/cypress/support/next-commands/default.ts
  • packages/ui/src/models/visualization/flows/abstract-camel-visual-entity.test.ts
  • packages/ui/src/models/visualization/flows/camel-rest-configuration-visual-entity.test.ts
  • packages/ui/src/components/Visualization/Custom/Node/CustomNodeUtils.ts
  • packages/ui/src/services/visualization/clipboard.service.ts
  • packages/ui/src/models/visualization/flows/pipe-visual-entity.ts
  • packages/ui/src/hooks/usePasteEntity.ts
  • packages/ui/src/components/Visualization/Custom/hooks/paste-step.hook.tsx
  • packages/ui/src/components/DataMapper/on-paste-data-mapper.ts
  • packages/ui/src/components/DataMapper/on-paste-data-mapper.test.ts
  • packages/ui/src/models/visualization/flows/abstract-camel-visual-entity.ts
  • packages/ui-tests/cypress/e2e/designer/basicNodeActions/stepCopy.cy.ts
  • packages/ui/src/hooks/usePasteEntity.test.tsx

Comment thread packages/ui/src/services/visualization/clipboard.service.test.ts
@PVinaches
PVinaches force-pushed the copy-paste-to-yaml branch 2 times, most recently from c4e8109 to f613100 Compare July 22, 2026 15:45
@PVinaches
PVinaches marked this pull request as draft July 23, 2026 16:20
@PVinaches
PVinaches force-pushed the copy-paste-to-yaml branch from f613100 to 243d8df Compare July 24, 2026 15:25
@sonarqubecloud

Copy link
Copy Markdown

@PVinaches
PVinaches marked this pull request as ready for review July 24, 2026 15:42
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.

Copy / Paste YAML support

3 participants