Skip to content

refactor: migrate remaining locate buttons to shared LocateNodeButton - #13795

Open
mattmillerai wants to merge 8 commits into
mainfrom
matt/be-3475-locate-node-button-migration
Open

refactor: migrate remaining locate buttons to shared LocateNodeButton#13795
mattmillerai wants to merge 8 commits into
mainfrom
matt/be-3475-locate-node-button-migration

Conversation

@mattmillerai

Copy link
Copy Markdown
Contributor

ELI-5

The error / missing-resource panels have several little "locate this node on
the canvas" buttons. #13401 turned that button into one shared
LocateNodeButton component for the errors panel. This PR swaps the five
remaining hand-rolled copies (in the swap-node, missing-model, and
missing-media rows) over to that same shared component so they all look and
behave identically — including a screen-reader label that names the specific
node ("Locate LoadImage" instead of a generic "Locate node on canvas").

Summary

Stacked on #13401 (base branch matt/be-2256-locate-node-button). That PR
extracted LocateNodeButton.vue for the errors panel but intentionally left
the platform-sibling rows untouched. This PR migrates the remaining five inline
Button + icon-[lucide--locate] usages:

  • SwapNodeGroupRow.vue (2 — header + per-node list)
  • MissingModelRow.vue (2 — header + per-reference list)
  • MissingMediaCard.vue (1)

Each inline button becomes <LocateNodeButton :label @locate />, with a
node-specific accessible label built from rightSidePanel.locateNodeFor
(Locate {item}), matching the pattern already used in
ErrorNodeCard / ErrorGroupList / MissingPackGroupRow:

  • MissingMediaCard already used locateNodeFor — label unchanged.
  • SwapNodeGroupRow and MissingModelRow previously used a generic
    "Locate node on canvas" label; they now name the node type / display name.

Behavior note: click.stop

LocateNodeButton stops click propagation, whereas the swap-node and
missing-model rows previously used a plain @click. Stopping propagation is
the desired, consistent behavior and is safe here: the parent components
(SwapNodesCard, MissingModelCard) only bind the custom @locate-node /
@locate-model events and no ancestor binds a DOM click handler on the row,
so nothing relied on the native click bubbling.

Tests

  • SwapNodeGroupRow.test.ts: updated the locate-button assertions to the new
    node-specific accessible names and added a test asserting each control gets a
    node-specific label.
  • MissingModelRow.test.ts: added a test asserting the header locate button
    exposes the node-specific aria-label and emits locateModel.
  • MissingMediaCard.test.ts: added a locate emit test (the existing
    special-characters aria-label test already covers the node-specific label).

All three files' tests plus the parent-card and LocateNodeButton tests pass;
typecheck and eslint are clean on the changed files.

Notes / judgment calls

  • The rightSidePanel.missingModels.locateNode string is now unused but kept in
    main.json to avoid churning the other locale files; happy to drop it if
    preferred.
  • SectionWidgets.vue also has a lucide--locate button, but it lives in the
    parameters panel (a different context, generic label) and is not one of the
    five usages this ticket scopes — left untouched.

mattmillerai and others added 8 commits July 8, 2026 13:27
Deduplicate the byte-identical locate icon-button repeated across four
sites in the errors panel (ErrorNodeCard, TabErrors, MissingPackGroupRow
x2) into a single LocateNodeButton component. Standardizes the decorative
icon's aria-hidden and the click .stop modifier, which previously varied
between sites.
…cate labels

- Replace closure-captured counter with vi.fn() spy in the click-propagation
  test so it actually fails when @click.stop is removed
- Add keyboard-activation coverage and pin aria-label via DOM assertion
- Give each MissingPackGroupRow locate button a distinct accessible name
  via locateNodeFor, matching ErrorGroupList (WCAG 2.4.6)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The LocateNodeButton extraction switched the locate button aria-label
from the static "Locate node on canvas" to the per-item
`rightSidePanel.locateNodeFor` ("Locate {item}"), but these test queries
were not updated, so they failed to find the button.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ange

The extracted LocateNodeButton now carries a per-item accessible name
("Locate {item}"), so getByRole('button', { name }) matched both the row
label button and the locate button, tripping Playwright strict mode. Use
exact matching to target the row label button.
…ode-button

# Conflicts:
#	src/components/rightSidePanel/errors/ErrorGroupList.vue
Use rightSidePanel.locateNodeFor with the card node title (safe fallback to
generic label) so runtime error cards expose distinguishable locate buttons.
Strengthen MissingPackGroupRow negative assertions to check locate-button
count, not only a specific label's absence.
Replace the five inline lucide--locate Button usages in
SwapNodeGroupRow, MissingModelRow, and MissingMediaCard with the shared
LocateNodeButton component, passing node-specific accessible labels via
rightSidePanel.locateNodeFor to match the errors-panel siblings. This
also gives the swap-node and missing-model locate buttons click.stop
(harmless: no ancestor binds a DOM click handler) and node-specific
aria-labels in place of the previous generic label.
@mattmillerai mattmillerai added agent-coded Opened by the agent-work code loop cursor-review Trigger multi-model Cursor agent review on this PR labels Jul 18, 2026
@mattmillerai
mattmillerai marked this pull request as ready for review July 18, 2026 13:50
@coderabbitai

coderabbitai Bot commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 0e8c9f4b-3228-42a4-b13d-95dd36322734

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch matt/be-3475-locate-node-button-migration

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

@dosubot dosubot Bot added the size:M This PR changes 30-99 lines, ignoring generated files. label Jul 18, 2026
@github-actions

github-actions Bot commented Jul 18, 2026

Copy link
Copy Markdown

🎭 Playwright: ❌ 1710 passed, 2 failed · 2 flaky

❌ Failed Tests

📊 Browser Reports
  • chromium: View Report (✅ 1691 / ❌ 2 / ⚠️ 1 / ⏭️ 5)
  • chromium-2x: View Report (✅ 2 / ❌ 0 / ⚠️ 0 / ⏭️ 0)
  • chromium-0.5x: View Report (✅ 1 / ❌ 0 / ⚠️ 0 / ⏭️ 0)
  • mobile-chrome: View Report (✅ 16 / ❌ 0 / ⚠️ 1 / ⏭️ 0)

🎨 Storybook: ✅ Built — View Storybook

Details

⏰ Completed at: 07/18/2026, 01:52:02 PM UTC

Links

📦 Bundle Size

⏳ Size data collection in progress…

⚡ Performance Report

canvas-idle: · 60.0 avg FPS · 59.9 P5 FPS ✅ (target: ≥52) · 0ms TBT · 57.7 MB heap
canvas-mouse-sweep: · 60.0 avg FPS · 59.7 P5 FPS ✅ (target: ≥52) · 0ms TBT · 51.6 MB heap
canvas-zoom-sweep: · 60.0 avg FPS · 59.9 P5 FPS ✅ (target: ≥52) · 0ms TBT · 72.6 MB heap
dom-widget-clipping: · 60.0 avg FPS · 59.5 P5 FPS ✅ (target: ≥52) · 0ms TBT · 54.4 MB heap
large-graph-idle: · 60.0 avg FPS · 59.5 P5 FPS ✅ (target: ≥52) · 0ms TBT · 62.0 MB heap
large-graph-pan: · 60.0 avg FPS · 59.5 P5 FPS ✅ (target: ≥52) · 0ms TBT · 67.2 MB heap
large-graph-zoom: · 60.0 avg FPS · 59.5 P5 FPS ✅ (target: ≥52) · 0ms TBT · 53.9 MB heap
minimap-idle: · 60.0 avg FPS · 59.7 P5 FPS ✅ (target: ≥52) · 0ms TBT · 63.6 MB heap
subgraph-dom-widget-clipping: · 60.0 avg FPS · 59.7 P5 FPS ✅ (target: ≥52) · 0ms TBT · 55.0 MB heap
subgraph-idle: · 60.0 avg FPS · 59.5 P5 FPS ✅ (target: ≥52) · 0ms TBT · 46.2 MB heap
subgraph-mouse-sweep: · 60.0 avg FPS · 59.7 P5 FPS ✅ (target: ≥52) · 0ms TBT · 48.8 MB heap
subgraph-transition-enter: · 60.0 avg FPS · 59.5 P5 FPS ✅ (target: ≥52) · 128ms TBT · 81.2 MB heap
viewport-pan-sweep: · 60.0 avg FPS · 59.5 P5 FPS ✅ (target: ≥52) · 0ms TBT · 72.0 MB heap
vue-large-graph-idle: · 60.0 avg FPS · 59.9 P5 FPS ✅ (target: ≥52) · 0ms TBT · 164.9 MB heap
vue-large-graph-pan: · 58.1 avg FPS · 59.5 P5 FPS ✅ (target: ≥52) · 34ms TBT · 164.0 MB heap
workflow-execution: · 60.0 avg FPS · 59.7 P5 FPS ✅ (target: ≥52) · 0ms TBT · 49.4 MB heap

ℹ️ No baseline found — significance unavailable.

Absolute values
Metric Value
canvas-idle: avg frame time 17ms
canvas-idle: p95 frame time 17ms
canvas-idle: layout duration 0ms
canvas-idle: style recalc duration 11ms
canvas-idle: layout count 0
canvas-idle: style recalc count 9
canvas-idle: task duration 436ms
canvas-idle: script duration 20ms
canvas-idle: TBT 0ms
canvas-idle: heap used 57.7 MB
canvas-idle: DOM nodes -124
canvas-idle: event listeners -65
canvas-mouse-sweep: avg frame time 17ms
canvas-mouse-sweep: p95 frame time 17ms
canvas-mouse-sweep: layout duration 4ms
canvas-mouse-sweep: style recalc duration 39ms
canvas-mouse-sweep: layout count 12
canvas-mouse-sweep: style recalc count 74
canvas-mouse-sweep: task duration 800ms
canvas-mouse-sweep: script duration 111ms
canvas-mouse-sweep: TBT 0ms
canvas-mouse-sweep: heap used 51.6 MB
canvas-mouse-sweep: DOM nodes -264
canvas-mouse-sweep: event listeners -133
canvas-zoom-sweep: avg frame time 17ms
canvas-zoom-sweep: p95 frame time 17ms
canvas-zoom-sweep: layout duration 1ms
canvas-zoom-sweep: style recalc duration 17ms
canvas-zoom-sweep: layout count 6
canvas-zoom-sweep: style recalc count 31
canvas-zoom-sweep: task duration 310ms
canvas-zoom-sweep: script duration 19ms
canvas-zoom-sweep: TBT 0ms
canvas-zoom-sweep: heap used 72.6 MB
canvas-zoom-sweep: DOM nodes 79
canvas-zoom-sweep: event listeners 19
dom-widget-clipping: avg frame time 17ms
dom-widget-clipping: p95 frame time 17ms
dom-widget-clipping: layout duration 0ms
dom-widget-clipping: style recalc duration 9ms
dom-widget-clipping: layout count 0
dom-widget-clipping: style recalc count 13
dom-widget-clipping: task duration 338ms
dom-widget-clipping: script duration 54ms
dom-widget-clipping: TBT 0ms
dom-widget-clipping: heap used 54.4 MB
dom-widget-clipping: DOM nodes 21
dom-widget-clipping: event listeners 0
large-graph-idle: avg frame time 17ms
large-graph-idle: p95 frame time 17ms
large-graph-idle: layout duration 0ms
large-graph-idle: style recalc duration 8ms
large-graph-idle: layout count 0
large-graph-idle: style recalc count 10
large-graph-idle: task duration 549ms
large-graph-idle: script duration 85ms
large-graph-idle: TBT 0ms
large-graph-idle: heap used 62.0 MB
large-graph-idle: DOM nodes -266
large-graph-idle: event listeners -129
large-graph-pan: avg frame time 17ms
large-graph-pan: p95 frame time 17ms
large-graph-pan: layout duration 0ms
large-graph-pan: style recalc duration 13ms
large-graph-pan: layout count 0
large-graph-pan: style recalc count 68
large-graph-pan: task duration 1080ms
large-graph-pan: script duration 368ms
large-graph-pan: TBT 0ms
large-graph-pan: heap used 67.2 MB
large-graph-pan: DOM nodes -270
large-graph-pan: event listeners -127
large-graph-zoom: avg frame time 17ms
large-graph-zoom: p95 frame time 17ms
large-graph-zoom: layout duration 8ms
large-graph-zoom: style recalc duration 15ms
large-graph-zoom: layout count 60
large-graph-zoom: style recalc count 66
large-graph-zoom: task duration 1316ms
large-graph-zoom: script duration 451ms
large-graph-zoom: TBT 0ms
large-graph-zoom: heap used 53.9 MB
large-graph-zoom: DOM nodes -273
large-graph-zoom: event listeners -133
minimap-idle: avg frame time 17ms
minimap-idle: p95 frame time 17ms
minimap-idle: layout duration 0ms
minimap-idle: style recalc duration 7ms
minimap-idle: layout count 0
minimap-idle: style recalc count 9
minimap-idle: task duration 536ms
minimap-idle: script duration 84ms
minimap-idle: TBT 0ms
minimap-idle: heap used 63.6 MB
minimap-idle: DOM nodes -268
minimap-idle: event listeners -129
subgraph-dom-widget-clipping: avg frame time 17ms
subgraph-dom-widget-clipping: p95 frame time 17ms
subgraph-dom-widget-clipping: layout duration 0ms
subgraph-dom-widget-clipping: style recalc duration 11ms
subgraph-dom-widget-clipping: layout count 0
subgraph-dom-widget-clipping: style recalc count 48
subgraph-dom-widget-clipping: task duration 365ms
subgraph-dom-widget-clipping: script duration 118ms
subgraph-dom-widget-clipping: TBT 0ms
subgraph-dom-widget-clipping: heap used 55.0 MB
subgraph-dom-widget-clipping: DOM nodes 21
subgraph-dom-widget-clipping: event listeners 6
subgraph-idle: avg frame time 17ms
subgraph-idle: p95 frame time 17ms
subgraph-idle: layout duration 0ms
subgraph-idle: style recalc duration 8ms
subgraph-idle: layout count 0
subgraph-idle: style recalc count 11
subgraph-idle: task duration 404ms
subgraph-idle: script duration 14ms
subgraph-idle: TBT 0ms
subgraph-idle: heap used 46.2 MB
subgraph-idle: DOM nodes -262
subgraph-idle: event listeners -133
subgraph-mouse-sweep: avg frame time 17ms
subgraph-mouse-sweep: p95 frame time 17ms
subgraph-mouse-sweep: layout duration 4ms
subgraph-mouse-sweep: style recalc duration 38ms
subgraph-mouse-sweep: layout count 16
subgraph-mouse-sweep: style recalc count 77
subgraph-mouse-sweep: task duration 733ms
subgraph-mouse-sweep: script duration 90ms
subgraph-mouse-sweep: TBT 0ms
subgraph-mouse-sweep: heap used 48.8 MB
subgraph-mouse-sweep: DOM nodes -263
subgraph-mouse-sweep: event listeners -133
subgraph-transition-enter: avg frame time 17ms
subgraph-transition-enter: p95 frame time 17ms
subgraph-transition-enter: layout duration 12ms
subgraph-transition-enter: style recalc duration 28ms
subgraph-transition-enter: layout count 15
subgraph-transition-enter: style recalc count 19
subgraph-transition-enter: task duration 694ms
subgraph-transition-enter: script duration 27ms
subgraph-transition-enter: TBT 128ms
subgraph-transition-enter: heap used 81.2 MB
subgraph-transition-enter: DOM nodes 13673
subgraph-transition-enter: event listeners 2369
viewport-pan-sweep: avg frame time 17ms
viewport-pan-sweep: p95 frame time 17ms
viewport-pan-sweep: layout duration 0ms
viewport-pan-sweep: style recalc duration 38ms
viewport-pan-sweep: layout count 0
viewport-pan-sweep: style recalc count 251
viewport-pan-sweep: task duration 3707ms
viewport-pan-sweep: script duration 1159ms
viewport-pan-sweep: TBT 0ms
viewport-pan-sweep: heap used 72.0 MB
viewport-pan-sweep: DOM nodes -265
viewport-pan-sweep: event listeners -113
vue-large-graph-idle: avg frame time 17ms
vue-large-graph-idle: p95 frame time 17ms
vue-large-graph-idle: layout duration 0ms
vue-large-graph-idle: style recalc duration 0ms
vue-large-graph-idle: layout count 0
vue-large-graph-idle: style recalc count 0
vue-large-graph-idle: task duration 11085ms
vue-large-graph-idle: script duration 542ms
vue-large-graph-idle: TBT 0ms
vue-large-graph-idle: heap used 164.9 MB
vue-large-graph-idle: DOM nodes -8311
vue-large-graph-idle: event listeners -16386
vue-large-graph-pan: avg frame time 17ms
vue-large-graph-pan: p95 frame time 17ms
vue-large-graph-pan: layout duration 0ms
vue-large-graph-pan: style recalc duration 12ms
vue-large-graph-pan: layout count 0
vue-large-graph-pan: style recalc count 67
vue-large-graph-pan: task duration 13592ms
vue-large-graph-pan: script duration 828ms
vue-large-graph-pan: TBT 34ms
vue-large-graph-pan: heap used 164.0 MB
vue-large-graph-pan: DOM nodes -8311
vue-large-graph-pan: event listeners -16382
workflow-execution: avg frame time 17ms
workflow-execution: p95 frame time 17ms
workflow-execution: layout duration 1ms
workflow-execution: style recalc duration 21ms
workflow-execution: layout count 3
workflow-execution: style recalc count 16
workflow-execution: task duration 120ms
workflow-execution: script duration 10ms
workflow-execution: TBT 0ms
workflow-execution: heap used 49.4 MB
workflow-execution: DOM nodes 128
workflow-execution: event listeners 65
Raw data
{
  "timestamp": "2026-07-18T14:00:36.959Z",
  "gitSha": "adc479d5192c87a545f3b83458d9d78335e106f3",
  "branch": "matt/be-3475-locate-node-button-migration",
  "measurements": [
    {
      "name": "canvas-idle",
      "durationMs": 2086.0409999999947,
      "styleRecalcs": 9,
      "styleRecalcDurationMs": 7.461999999999998,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 436.89399999999995,
      "heapDeltaBytes": 3935664,
      "heapUsedBytes": 72857588,
      "domNodes": 18,
      "jsHeapTotalBytes": 19677184,
      "scriptDurationMs": 21.178,
      "eventListeners": 4,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.699999999999818
    },
    {
      "name": "canvas-idle",
      "durationMs": 2073.120000000017,
      "styleRecalcs": 9,
      "styleRecalcDurationMs": 14.609999999999998,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 434.464,
      "heapDeltaBytes": -20922168,
      "heapUsedBytes": 48084592,
      "domNodes": -266,
      "jsHeapTotalBytes": 18755584,
      "scriptDurationMs": 18.266,
      "eventListeners": -133,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.66333333333335,
      "p95FrameDurationMs": 16.699999999999818
    },
    {
      "name": "canvas-mouse-sweep",
      "durationMs": 1832.868999999988,
      "styleRecalcs": 73,
      "styleRecalcDurationMs": 40.186,
      "layouts": 12,
      "layoutDurationMs": 3.875,
      "taskDurationMs": 801.6450000000001,
      "heapDeltaBytes": -15160772,
      "heapUsedBytes": 53767068,
      "domNodes": -263,
      "jsHeapTotalBytes": 21114880,
      "scriptDurationMs": 112.949,
      "eventListeners": -133,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.700000000000728
    },
    {
      "name": "canvas-mouse-sweep",
      "durationMs": 1828.125,
      "styleRecalcs": 74,
      "styleRecalcDurationMs": 36.888999999999996,
      "layouts": 12,
      "layoutDurationMs": 3.9390000000000005,
      "taskDurationMs": 797.5070000000001,
      "heapDeltaBytes": -14465376,
      "heapUsedBytes": 54368904,
      "domNodes": -264,
      "jsHeapTotalBytes": 20590592,
      "scriptDurationMs": 109.416,
      "eventListeners": -133,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.800000000000182
    },
    {
      "name": "canvas-zoom-sweep",
      "durationMs": 1664.1180000000304,
      "styleRecalcs": 30,
      "styleRecalcDurationMs": 16.518,
      "layouts": 6,
      "layoutDurationMs": 0.5690000000000001,
      "taskDurationMs": 308.774,
      "heapDeltaBytes": 7127484,
      "heapUsedBytes": 75884432,
      "domNodes": 79,
      "jsHeapTotalBytes": 19677184,
      "scriptDurationMs": 18.362000000000002,
      "eventListeners": 19,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.700000000000728
    },
    {
      "name": "canvas-zoom-sweep",
      "durationMs": 1722.912000000008,
      "styleRecalcs": 32,
      "styleRecalcDurationMs": 16.88,
      "layouts": 6,
      "layoutDurationMs": 0.727,
      "taskDurationMs": 310.86400000000003,
      "heapDeltaBytes": 7480792,
      "heapUsedBytes": 76458032,
      "domNodes": 78,
      "jsHeapTotalBytes": 19415040,
      "scriptDurationMs": 20.135,
      "eventListeners": 19,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.66333333333332,
      "p95FrameDurationMs": 16.700000000000728
    },
    {
      "name": "dom-widget-clipping",
      "durationMs": 581.3150000000178,
      "styleRecalcs": 13,
      "styleRecalcDurationMs": 8.361000000000002,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 342.38,
      "heapDeltaBytes": -11794468,
      "heapUsedBytes": 57136964,
      "domNodes": 22,
      "jsHeapTotalBytes": 19939328,
      "scriptDurationMs": 54.544000000000004,
      "eventListeners": 0,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666682,
      "p95FrameDurationMs": 16.800000000000182
    },
    {
      "name": "dom-widget-clipping",
      "durationMs": 561.5829999999846,
      "styleRecalcs": 12,
      "styleRecalcDurationMs": 9.455000000000002,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 333.982,
      "heapDeltaBytes": -11865876,
      "heapUsedBytes": 56859148,
      "domNodes": 20,
      "jsHeapTotalBytes": 19677184,
      "scriptDurationMs": 52.616,
      "eventListeners": 0,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.799999999999727
    },
    {
      "name": "large-graph-idle",
      "durationMs": 2006.8049999999857,
      "styleRecalcs": 11,
      "styleRecalcDurationMs": 9.536000000000001,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 549.342,
      "heapDeltaBytes": 4676996,
      "heapUsedBytes": 65641732,
      "domNodes": -265,
      "jsHeapTotalBytes": 5193728,
      "scriptDurationMs": 84.14099999999999,
      "eventListeners": -129,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.670000000000012,
      "p95FrameDurationMs": 16.800000000000182
    },
    {
      "name": "large-graph-idle",
      "durationMs": 2024.6669999999654,
      "styleRecalcs": 9,
      "styleRecalcDurationMs": 7.356,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 548.621,
      "heapDeltaBytes": 5365312,
      "heapUsedBytes": 64416812,
      "domNodes": -267,
      "jsHeapTotalBytes": 4931584,
      "scriptDurationMs": 85.253,
      "eventListeners": -129,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.66333333333332,
      "p95FrameDurationMs": 16.800000000000182
    },
    {
      "name": "large-graph-pan",
      "durationMs": 2142.1919999999946,
      "styleRecalcs": 69,
      "styleRecalcDurationMs": 14.232000000000001,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 1088.4930000000002,
      "heapDeltaBytes": 24857920,
      "heapUsedBytes": 85123380,
      "domNodes": -268,
      "jsHeapTotalBytes": 5136384,
      "scriptDurationMs": 375.967,
      "eventListeners": -127,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.66333333333332,
      "p95FrameDurationMs": 16.799999999999272
    },
    {
      "name": "large-graph-pan",
      "durationMs": 2090.8469999999966,
      "styleRecalcs": 67,
      "styleRecalcDurationMs": 12.33,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 1072.492,
      "heapDeltaBytes": -4583128,
      "heapUsedBytes": 55811488,
      "domNodes": -271,
      "jsHeapTotalBytes": 4931584,
      "scriptDurationMs": 359.993,
      "eventListeners": -127,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.800000000000182
    },
    {
      "name": "large-graph-zoom",
      "durationMs": 3136.1870000000067,
      "styleRecalcs": 66,
      "styleRecalcDurationMs": 15.616000000000001,
      "layouts": 60,
      "layoutDurationMs": 7.681,
      "taskDurationMs": 1295.569,
      "heapDeltaBytes": -5220780,
      "heapUsedBytes": 56623404,
      "domNodes": -273,
      "jsHeapTotalBytes": 8077312,
      "scriptDurationMs": 444.821,
      "eventListeners": -133,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.66333333333335,
      "p95FrameDurationMs": 16.800000000000182
    },
    {
      "name": "large-graph-zoom",
      "durationMs": 3152.0830000000046,
      "styleRecalcs": 65,
      "styleRecalcDurationMs": 14.677,
      "layouts": 60,
      "layoutDurationMs": 7.772999999999999,
      "taskDurationMs": 1336.923,
      "heapDeltaBytes": -5502528,
      "heapUsedBytes": 56363460,
      "domNodes": -273,
      "jsHeapTotalBytes": 8339456,
      "scriptDurationMs": 458.09700000000004,
      "eventListeners": -133,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.800000000000182
    },
    {
      "name": "minimap-idle",
      "durationMs": 2032.3480000000131,
      "styleRecalcs": 9,
      "styleRecalcDurationMs": 7.977999999999999,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 533.3090000000001,
      "heapDeltaBytes": 5681684,
      "heapUsedBytes": 67513748,
      "domNodes": -267,
      "jsHeapTotalBytes": 4931584,
      "scriptDurationMs": 82.996,
      "eventListeners": -129,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.699999999999818
    },
    {
      "name": "minimap-idle",
      "durationMs": 2017.1059999999557,
      "styleRecalcs": 8,
      "styleRecalcDurationMs": 6.710000000000001,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 538.932,
      "heapDeltaBytes": 5011960,
      "heapUsedBytes": 65965360,
      "domNodes": -269,
      "jsHeapTotalBytes": 5455872,
      "scriptDurationMs": 85.463,
      "eventListeners": -129,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.800000000000182
    },
    {
      "name": "subgraph-dom-widget-clipping",
      "durationMs": 602.3610000000303,
      "styleRecalcs": 46,
      "styleRecalcDurationMs": 9.621,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 363.453,
      "heapDeltaBytes": -11076504,
      "heapUsedBytes": 57794052,
      "domNodes": 18,
      "jsHeapTotalBytes": 20725760,
      "scriptDurationMs": 120.26200000000001,
      "eventListeners": 6,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.66333333333332,
      "p95FrameDurationMs": 16.700000000000728
    },
    {
      "name": "subgraph-dom-widget-clipping",
      "durationMs": 574.6489999999653,
      "styleRecalcs": 49,
      "styleRecalcDurationMs": 12.74,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 367.39300000000003,
      "heapDeltaBytes": -11280120,
      "heapUsedBytes": 57539108,
      "domNodes": 24,
      "jsHeapTotalBytes": 20987904,
      "scriptDurationMs": 115.82000000000001,
      "eventListeners": 6,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.800000000000182
    },
    {
      "name": "subgraph-idle",
      "durationMs": 2019.8450000000037,
      "styleRecalcs": 11,
      "styleRecalcDurationMs": 7.863000000000002,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 400.47200000000004,
      "heapDeltaBytes": -21212340,
      "heapUsedBytes": 47767988,
      "domNodes": -262,
      "jsHeapTotalBytes": 19804160,
      "scriptDurationMs": 14.191,
      "eventListeners": -133,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.800000000000182
    },
    {
      "name": "subgraph-idle",
      "durationMs": 2032.5300000000084,
      "styleRecalcs": 11,
      "styleRecalcDurationMs": 8.122999999999998,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 408.004,
      "heapDeltaBytes": -19668844,
      "heapUsedBytes": 49201920,
      "domNodes": -261,
      "jsHeapTotalBytes": 20066304,
      "scriptDurationMs": 14.746,
      "eventListeners": -133,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.799999999999272
    },
    {
      "name": "subgraph-mouse-sweep",
      "durationMs": 1749.0319999999997,
      "styleRecalcs": 78,
      "styleRecalcDurationMs": 39.25,
      "layouts": 16,
      "layoutDurationMs": 4.5040000000000004,
      "taskDurationMs": 733.43,
      "heapDeltaBytes": -17779056,
      "heapUsedBytes": 51140636,
      "domNodes": -263,
      "jsHeapTotalBytes": 20328448,
      "scriptDurationMs": 93.741,
      "eventListeners": -133,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.700000000000728
    },
    {
      "name": "subgraph-mouse-sweep",
      "durationMs": 1715.2130000000056,
      "styleRecalcs": 76,
      "styleRecalcDurationMs": 35.939,
      "layouts": 16,
      "layoutDurationMs": 4.144,
      "taskDurationMs": 733.0859999999999,
      "heapDeltaBytes": -17842040,
      "heapUsedBytes": 51150160,
      "domNodes": -263,
      "jsHeapTotalBytes": 20328448,
      "scriptDurationMs": 85.87899999999999,
      "eventListeners": -133,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.800000000000182
    },
    {
      "name": "subgraph-transition-enter",
      "durationMs": 914.8979999999938,
      "styleRecalcs": 19,
      "styleRecalcDurationMs": 28.022999999999993,
      "layouts": 15,
      "layoutDurationMs": 12.431,
      "taskDurationMs": 694.2600000000001,
      "heapDeltaBytes": 1166696,
      "heapUsedBytes": 85154724,
      "domNodes": 13673,
      "jsHeapTotalBytes": 15990784,
      "scriptDurationMs": 26.644000000000002,
      "eventListeners": 2369,
      "totalBlockingTimeMs": 128,
      "frameDurationMs": 16.66333333333332,
      "p95FrameDurationMs": 16.800000000000182
    },
    {
      "name": "viewport-pan-sweep",
      "durationMs": 8206.929000000002,
      "styleRecalcs": 251,
      "styleRecalcDurationMs": 38.800000000000004,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 3734.6650000000004,
      "heapDeltaBytes": 16346584,
      "heapUsedBytes": 77558284,
      "domNodes": -264,
      "jsHeapTotalBytes": 6971392,
      "scriptDurationMs": 1163.6419999999998,
      "eventListeners": -113,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.80000000000109
    },
    {
      "name": "viewport-pan-sweep",
      "durationMs": 8137.034999999969,
      "styleRecalcs": 250,
      "styleRecalcDurationMs": 38.065000000000005,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 3679.7819999999992,
      "heapDeltaBytes": 14211752,
      "heapUsedBytes": 73471076,
      "domNodes": -265,
      "jsHeapTotalBytes": 5136384,
      "scriptDurationMs": 1153.988,
      "eventListeners": -113,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.799999999999272
    },
    {
      "name": "vue-large-graph-idle",
      "durationMs": 11049.216999999999,
      "styleRecalcs": 0,
      "styleRecalcDurationMs": 0,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 11033.335000000001,
      "heapDeltaBytes": -35322184,
      "heapUsedBytes": 170731624,
      "domNodes": -8311,
      "jsHeapTotalBytes": -10395648,
      "scriptDurationMs": 563.013,
      "eventListeners": -16386,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.700000000000728
    },
    {
      "name": "vue-large-graph-idle",
      "durationMs": 11151.402999999958,
      "styleRecalcs": 0,
      "styleRecalcDurationMs": 0,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 11137.455000000002,
      "heapDeltaBytes": -49993164,
      "heapUsedBytes": 175027028,
      "domNodes": -8311,
      "jsHeapTotalBytes": -9900032,
      "scriptDurationMs": 521.909,
      "eventListeners": -16386,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.700000000000728
    },
    {
      "name": "vue-large-graph-pan",
      "durationMs": 13618.743999999992,
      "styleRecalcs": 67,
      "styleRecalcDurationMs": 12.205999999999994,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 13594.025000000001,
      "heapDeltaBytes": -31532976,
      "heapUsedBytes": 177075272,
      "domNodes": -8311,
      "jsHeapTotalBytes": -17063936,
      "scriptDurationMs": 855.193,
      "eventListeners": -16384,
      "totalBlockingTimeMs": 56,
      "frameDurationMs": 17.219999999999953,
      "p95FrameDurationMs": 16.799999999999272
    },
    {
      "name": "vue-large-graph-pan",
      "durationMs": 13609.797999999955,
      "styleRecalcs": 67,
      "styleRecalcDurationMs": 11.943000000000008,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 13590.131,
      "heapDeltaBytes": -51478176,
      "heapUsedBytes": 166954900,
      "domNodes": -8311,
      "jsHeapTotalBytes": -13307904,
      "scriptDurationMs": 800.455,
      "eventListeners": -16380,
      "totalBlockingTimeMs": 11,
      "frameDurationMs": 17.216666666666665,
      "p95FrameDurationMs": 16.80000000000291
    },
    {
      "name": "workflow-execution",
      "durationMs": 456.0989999999947,
      "styleRecalcs": 16,
      "styleRecalcDurationMs": 21.182,
      "layouts": 3,
      "layoutDurationMs": 0.6689999999999999,
      "taskDurationMs": 121.191,
      "heapDeltaBytes": -16110376,
      "heapUsedBytes": 51871236,
      "domNodes": 134,
      "jsHeapTotalBytes": 6569984,
      "scriptDurationMs": 9.577000000000002,
      "eventListeners": 65,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.663333333333338,
      "p95FrameDurationMs": 16.800000000000182
    },
    {
      "name": "workflow-execution",
      "durationMs": 461.3650000000007,
      "styleRecalcs": 16,
      "styleRecalcDurationMs": 20.071,
      "layouts": 3,
      "layoutDurationMs": 0.5820000000000001,
      "taskDurationMs": 118.451,
      "heapDeltaBytes": -16275452,
      "heapUsedBytes": 51796524,
      "domNodes": 121,
      "jsHeapTotalBytes": 7094272,
      "scriptDurationMs": 9.863,
      "eventListeners": 65,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.663333333333338,
      "p95FrameDurationMs": 16.699999999999818
    }
  ]
}

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔍 Cursor Review — Consolidated panel

Triggered by @mattmillerai.

✅ No high-signal findings.

Panel: 8/8 reviewers contributed findings.

@codecov

codecov Bot commented Jul 18, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 90.00000% with 2 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
...omponents/rightSidePanel/errors/ErrorGroupList.vue 50.00% 1 Missing ⚠️
...components/rightSidePanel/errors/ErrorNodeCard.vue 83.33% 1 Missing ⚠️
@@            Coverage Diff             @@
##             main   #13795      +/-   ##
==========================================
- Coverage   78.71%   77.81%   -0.90%     
==========================================
  Files        1683     1687       +4     
  Lines       98634    95613    -3021     
  Branches    34932    32894    -2038     
==========================================
- Hits        77640    74404    -3236     
- Misses      20524    20775     +251     
+ Partials      470      434      -36     
Flag Coverage Δ
unit 67.28% <90.00%> (-0.01%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
...ponents/rightSidePanel/errors/LocateNodeButton.vue 100.00% <100.00%> (ø)
...ents/rightSidePanel/errors/MissingPackGroupRow.vue 99.13% <100.00%> (+4.03%) ⬆️
...tform/missingMedia/components/MissingMediaCard.vue 96.55% <100.00%> (+3.69%) ⬆️
...atform/missingModel/components/MissingModelRow.vue 92.10% <100.00%> (ø)
...rm/nodeReplacement/components/SwapNodeGroupRow.vue 98.43% <100.00%> (-0.10%) ⬇️
...omponents/rightSidePanel/errors/ErrorGroupList.vue 88.23% <50.00%> (+0.54%) ⬆️
...components/rightSidePanel/errors/ErrorNodeCard.vue 97.53% <83.33%> (+13.04%) ⬆️

... and 181 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Base automatically changed from matt/be-2256-locate-node-button to main July 28, 2026 20:38
@mattmillerai
mattmillerai requested a review from a team July 28, 2026 20:38
@dosubot dosubot Bot added size:L This PR changes 100-499 lines, ignoring generated files. and removed size:M This PR changes 30-99 lines, ignoring generated files. labels Jul 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agent-coded Opened by the agent-work code loop cursor-review Trigger multi-model Cursor agent review on this PR size:L This PR changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant