Skip to content

feat: Replace BuilderExitButton with new BuilderFooterToolbar#9378

Merged
pythongosssss merged 3 commits intomainfrom
pysssss/builder-footer-toolbar
Mar 4, 2026
Merged

feat: Replace BuilderExitButton with new BuilderFooterToolbar#9378
pythongosssss merged 3 commits intomainfrom
pysssss/builder-footer-toolbar

Conversation

@pythongosssss
Copy link
Member

@pythongosssss pythongosssss commented Mar 4, 2026

Summary

Makes it easier and more obvious for users to navigate between steps

Changes

  • What:
  • add back/next navigation to builder footer alongside exit button
  • extract shared step logic into useBuilderSteps composable

Screenshots (if applicable)

image

┆Issue is synchronized with this Notion page by Unito

- add back/next navigation to builder footer alongside exit utton
- extract shared step logic into useBuilderSteps composable
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 4, 2026

📝 Walkthrough

Walkthrough

A new BuilderFooterToolbar component with back/next navigation buttons replaces BuilderExitButton, consolidating step navigation logic into the expanded useBuilderSteps hook. BuilderToolbar refactored to use the new navigation pattern. Tests verify navigation behavior across step boundaries and conditional button states.

Changes

Cohort / File(s) Summary
Navigation Hook Enhancement
src/components/builder/useBuilderSteps.ts
Added navigation methods navigateToStep, goBack, and goNext to handle step transitions with special handling for default view dialog triggers.
New Navigation Component
src/components/builder/BuilderFooterToolbar.vue, src/components/builder/BuilderFooterToolbar.test.ts
New component replacing BuilderExitButton with back/next navigation buttons; includes comprehensive test coverage for button states and click handlers based on step position and app state.
Builder Toolbar Refactor
src/components/builder/BuilderToolbar.vue
Replaced setMode-based handlers with navigateToStep calls; removed useAppMode and useAppSetDefaultView dependencies in favor of useBuilderSteps hook; updated step type declarations from AppMode to BuilderStepId.
View Component Update
src/views/GraphView.vue
Swapped BuilderExitButton import and template usage with BuilderFooterToolbar.

Sequence Diagram

sequenceDiagram
    participant User
    participant BuilderFooterToolbar
    participant useBuilderSteps
    participant appModeStore
    participant useAppSetDefaultView

    User->>BuilderFooterToolbar: Clicks Next Button
    BuilderFooterToolbar->>useBuilderSteps: navigateToStep(stepId)
    alt stepId is 'setDefaultView'
        useBuilderSteps->>appModeStore: setMode('builder:arrange')
        useBuilderSteps->>useAppSetDefaultView: showDialog()
        useAppSetDefaultView-->>User: Display Default View Dialog
    else stepId is regular step
        useBuilderSteps->>appModeStore: setMode(stepId)
    end
    appModeStore-->>BuilderFooterToolbar: State updated
    BuilderFooterToolbar-->>User: Buttons re-render with new state
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~28 minutes

Poem

🐰 Hop-hop through the builder steps we go,
Back and forth with buttons all aglow,
Navigation whispers, dialogs appear,
A cleaner path emerges, crystal clear!

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: replacing BuilderExitButton with a new BuilderFooterToolbar component that includes back/next navigation.
Description check ✅ Passed The description covers the summary and changes, but lacks Review Focus section for critical design decisions and edge cases.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch pysssss/builder-footer-toolbar

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 and usage tips.

@github-actions
Copy link

github-actions bot commented Mar 4, 2026

🎨 Storybook: ✅ Built — View Storybook

Details

⏰ Completed at: 03/04/2026, 05:42:55 PM UTC

Links

@github-actions
Copy link

github-actions bot commented Mar 4, 2026

🎭 Playwright: ✅ 549 passed, 0 failed · 5 flaky

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

@github-actions
Copy link

github-actions bot commented Mar 4, 2026

📦 Bundle: 4.48 MB gzip 🔴 +427 B

Details

Summary

  • Raw size: 21 MB baseline 21 MB — 🔴 +2.23 kB
  • Gzip: 4.48 MB baseline 4.48 MB — 🔴 +427 B
  • Brotli: 3.46 MB baseline 3.46 MB — 🔴 +368 B
  • Bundles: 227 current • 227 baseline • 2 added / 2 removed

Category Glance
Graph Workspace 🔴 +2.23 kB (987 kB) · Vendor & Third-Party ⚪ 0 B (8.86 MB) · Other ⚪ 0 B (7.89 MB) · Data & Services ⚪ 0 B (2.64 MB) · Panels & Settings ⚪ 0 B (436 kB) · Views & Navigation ⚪ 0 B (72.1 kB) · + 5 more

App Entry Points — 17.7 kB (baseline 17.7 kB) • ⚪ 0 B

Main entry bundles and manifests

File Before After Δ Raw Δ Gzip Δ Brotli
assets/index-BSjwTVA2.js (new) 17.7 kB 🔴 +17.7 kB 🔴 +6.25 kB 🔴 +5.41 kB
assets/index-D7mVWdq1.js (removed) 17.7 kB 🟢 -17.7 kB 🟢 -6.25 kB 🟢 -5.43 kB

Status: 1 added / 1 removed

Graph Workspace — 987 kB (baseline 985 kB) • 🔴 +2.23 kB

Graph editor runtime, canvas, workflow orchestration

File Before After Δ Raw Δ Gzip Δ Brotli
assets/GraphView-DDBcqSR8.js (new) 987 kB 🔴 +987 kB 🔴 +210 kB 🔴 +159 kB
assets/GraphView-bUm-iPli.js (removed) 985 kB 🟢 -985 kB 🟢 -210 kB 🟢 -159 kB

Status: 1 added / 1 removed

Views & Navigation — 72.1 kB (baseline 72.1 kB) • ⚪ 0 B

Top-level views, pages, and routed surfaces

File Before After Δ Raw Δ Gzip Δ Brotli
assets/CloudAuthTimeoutView-DRr_EBpU.js 4.91 kB 4.91 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/CloudForgotPasswordView-D57Bu9FA.js 5.56 kB 5.56 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/CloudLayoutView-XKbvO_SC.js 6.43 kB 6.43 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/CloudLoginView-Chd9CRj6.js 11.4 kB 11.4 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/CloudSignupView-CuIdJdsX.js 9.37 kB 9.37 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/CloudSorryContactSupportView-oBJgqwAb.js 1.02 kB 1.02 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/CloudSubscriptionRedirectView-p3CT1nf_.js 4.75 kB 4.75 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/CloudSurveyView-CbH6exQD.js 15.5 kB 15.5 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/layout-C7HwWHX2.js 296 B 296 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/UserCheckView-CaDPc2la.js 8.41 kB 8.41 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/UserSelectView-CJwm2qA_.js 4.5 kB 4.5 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
Panels & Settings — 436 kB (baseline 436 kB) • ⚪ 0 B

Configuration panels, inspectors, and settings screens

File Before After Δ Raw Δ Gzip Δ Brotli
assets/AboutPanel-DsX7_EUm.js 9.79 kB 9.79 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/cloudRemoteConfig-CQUPcpJa.js 1.44 kB 1.44 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/config-CGn5JFmU.js 996 B 996 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/ExtensionPanel-D17gULwt.js 9.38 kB 9.38 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/KeybindingPanel-DkgVo6aB.js 12.3 kB 12.3 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/LegacyCreditsPanel-D7XNQacV.js 20.6 kB 20.6 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/refreshRemoteConfig-1pkAygC2.js 1.14 kB 1.14 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/SecretsPanel-Dgzo3ayR.js 21.5 kB 21.5 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/ServerConfigPanel-C1G9MNI-.js 6.44 kB 6.44 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-B5oF6TeI.js 29.9 kB 29.9 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-BVYOg4dh.js 24.5 kB 24.5 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-CBEvSL1z.js 38.5 kB 38.5 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-CGx1t8IZ.js 27.8 kB 27.8 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-CNcb_4nC.js 30.5 kB 30.5 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-Cx1dZM6H.js 23.9 kB 23.9 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-Dw-QS6Nb.js 27.9 kB 27.9 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-DXxgnCSn.js 32.4 kB 32.4 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-GRFn4guL.js 34.2 kB 34.2 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-mgwKIVQ2.js 28.8 kB 28.8 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-s83B801I.js 28.7 kB 28.7 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/SubscriptionPanel-CmqaXQqw.js 18.6 kB 18.6 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/UserPanel-C8nYfyom.js 6.16 kB 6.16 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
User & Accounts — 16 kB (baseline 16 kB) • ⚪ 0 B

Authentication, profile, and account management bundles

File Before After Δ Raw Δ Gzip Δ Brotli
assets/auth-CL4DYmAQ.js 357 B 357 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/auth-ClrjaSST.js 3.4 kB 3.4 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/firebaseAuthStore-Bsw9kqBQ.js 788 B 788 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/PasswordFields-D2N9Ml9Z.js 4.51 kB 4.51 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/SignUpForm-DMIgpDHC.js 3.01 kB 3.01 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/UpdatePasswordContent-DB0DZyHQ.js 2.37 kB 2.37 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WorkspaceProfilePic-D9lCv5xq.js 1.57 kB 1.57 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
Editors & Dialogs — 736 B (baseline 736 B) • ⚪ 0 B

Modals, dialogs, drawers, and in-app editors

File Before After Δ Raw Δ Gzip Δ Brotli
assets/useSubscriptionDialog-vqrj806i.js 736 B 736 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
UI Components — 47 kB (baseline 47 kB) • ⚪ 0 B

Reusable component library chunks

File Before After Δ Raw Δ Gzip Δ Brotli
assets/Button-Dw6K3LMw.js 3.08 kB 3.08 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/CloudBadge-y8d0lfIa.js 1.16 kB 1.16 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/cloudFeedbackTopbarButton-XnnazvGm.js 1.59 kB 1.59 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/ComfyQueueButton-B1Yato48.js 8.02 kB 8.02 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/ComfyQueueButton-DVkGolry.js 793 B 793 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/FormSearchInput-BJeGeP_m.js 3.73 kB 3.73 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/ScrubableNumberInput-_Rw93HFG.js 5.95 kB 5.95 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/SubscribeButton-nvP0qNv_.js 2.34 kB 2.34 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/TopbarBadge-BpSw2jyq.js 7.44 kB 7.44 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/UserAvatar-4quz6WWI.js 1.17 kB 1.17 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/useTerminalTabs-BlpZjl4M.js 9.84 kB 9.84 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetButton-DQ_BOv-g.js 1.84 kB 1.84 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
Data & Services — 2.64 MB (baseline 2.64 MB) • ⚪ 0 B

Stores, services, APIs, and repositories

File Before After Δ Raw Δ Gzip Δ Brotli
assets/api-UofRsCDP.js 688 kB 688 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/audioService-DjUgrdy4.js 1.73 kB 1.73 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/bootstrapStore-BVZaB43p.js 2.08 kB 2.08 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/dialogService-CccSKQu3.js 1.82 MB 1.82 MB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/dialogService-D46yzbD3.js 725 B 725 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/extensionStore-DVFhhRvC.js 13 kB 13 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/keybindingService-CiemMobf.js 6.52 kB 6.52 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/load3dService-BkY2orCy.js 91 kB 91 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/releaseStore-B6LGLBz6.js 7.96 kB 7.96 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/releaseStore-JeBshA3k.js 760 B 760 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/serverConfigStore-CjFLR4Tj.js 2.32 kB 2.32 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settingStore-Dcl3Fv_J.js 744 B 744 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/userStore-CrVlhKCU.js 1.85 kB 1.85 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/workflowDraftStore-Dby2raXy.js 736 B 736 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
Utilities & Hooks — 55.5 kB (baseline 55.5 kB) • ⚪ 0 B

Helpers, composables, and utility bundles

File Before After Δ Raw Δ Gzip Δ Brotli
assets/_plugin-vue_export-helper-ralzwvFM.js 315 B 315 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/audioUtils-UA6cLxP7.js 858 B 858 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/colorUtil-BdnFBncR.js 7 kB 7 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/envUtil-Clzmwvt4.js 466 B 466 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/markdownRendererUtil-BwTAJqBg.js 1.56 kB 1.56 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/SkeletonUtils-BputJAFn.js 133 B 133 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/subscriptionCheckoutUtil-BNVYnyxT.js 2.53 kB 2.53 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/useCurrentUser-D5I0Myw_.js 722 B 722 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/useErrorHandling-DiH1pvO8.js 1.5 kB 1.5 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/useExternalLink-Sfq_Uz64.js 1.66 kB 1.66 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/useFeatureFlags-PEm4mioB.js 4.14 kB 4.14 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/useLoad3d-DpQnoNmp.js 14.6 kB 14.6 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/useLoad3d-FJYr630c.js 859 B 859 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/useLoad3dViewer-DfHbT5Ia.js 838 B 838 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/useLoad3dViewer-DPt5JqSS.js 14.1 kB 14.1 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/useWorkspaceSwitch-DO2yqvAo.js 1.25 kB 1.25 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/useWorkspaceUI-DIYwMBpy.js 3 kB 3 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
Vendor & Third-Party — 8.86 MB (baseline 8.86 MB) • ⚪ 0 B

External libraries and shared vendor chunks

File Before After Δ Raw Δ Gzip Δ Brotli
assets/vendor-axios-Cp6hch1I.js 70.7 kB 70.7 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-chart-BxkFiWzp.js 399 kB 399 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-firebase-BvMr43CG.js 836 kB 836 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-i18n-DccD0mxo.js 133 kB 133 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-markdown-D5S6AC80.js 103 kB 103 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-other-5I_5Qfg0.js 1.52 MB 1.52 MB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-primevue-BleJN4K0.js 1.73 MB 1.73 MB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-reka-ui-C-tDe-KL.js 399 kB 399 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-sentry-SQwstEKc.js 182 kB 182 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-three-LBLOE6BD.js 1.8 MB 1.8 MB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-tiptap-z9_RK3Ae.js 634 kB 634 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-vue-core-CmHHRvL9.js 311 kB 311 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-vueuse-cYXYo6hi.js 121 kB 121 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-xterm-MKpa1ZAW.js 374 kB 374 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-yjs-CP_4YO8u.js 143 kB 143 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-zod-DcCUUPIi.js 109 kB 109 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
Other — 7.89 MB (baseline 7.89 MB) • ⚪ 0 B

Bundles that do not match a named category

File Before After Δ Raw Δ Gzip Δ Brotli
assets/AnimationControls-rvj0ANn9.js 4.61 kB 4.61 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/ApiNodesSignInContent-B005EWYJ.js 2.69 kB 2.69 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/AudioPreviewPlayer-dbf5XBtr.js 10.9 kB 10.9 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/auto-BTnZwrs2.js 1.7 kB 1.7 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/BaseViewTemplate-BNRU5hKJ.js 1.78 kB 1.78 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/CancelSubscriptionDialogContent-BPI3wi6u.js 4.79 kB 4.79 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/changeTracker-CO_SFl2o.js 9.38 kB 9.38 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/changeTracker-DWQmHci3.js 757 B 757 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/cloudBadges-CF2RKtrC.js 1.36 kB 1.36 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/CloudRunButtonWrapper-Cbfnep0_.js 1.68 kB 1.68 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/cloudSessionCookie-CSQ8UL2r.js 3.1 kB 3.1 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/cloudSubscription-kyKSbu15.js 1.33 kB 1.33 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/comfy-logo-single-D9MrYETV.js 198 B 198 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/ComfyOrgHeader-BbfHqQlJ.js 910 B 910 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-B-AdR9IA.js 17.5 kB 17.5 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-CbkxT8K8.js 16.1 kB 16.1 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-CJGmjcIS.js 15.9 kB 15.9 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-CMaLgTTb.js 16.7 kB 16.7 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-Cw07MMbJ.js 18.8 kB 18.8 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-D7EtdE6o.js 16.9 kB 16.9 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-DknEFpK3.js 15.2 kB 15.2 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-Ds6WuXnw.js 16.1 kB 16.1 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-Dvq-F-mb.js 17.5 kB 17.5 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-pUOay9Eo.js 15.1 kB 15.1 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-u2AZ8xU4.js 16.1 kB 16.1 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/constants-htt0vt7m.js 579 B 579 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/core-PSzY1pJr.js 73.6 kB 73.6 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/CreateWorkspaceDialogContent-DCoFqxd3.js 5.53 kB 5.53 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/CurrentUserPopoverWorkspace-eA6AeM_L.js 20.4 kB 20.4 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/DeleteWorkspaceDialogContent-6rhRS3P7.js 4.23 kB 4.23 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/EditWorkspaceDialogContent-B-DiSuhB.js 5.33 kB 5.33 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/FreeTierDialogContent-D9Kbvrc3.js 5.39 kB 5.39 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/GlobalToast-BwbRLb1W.js 2.91 kB 2.91 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/graphHasMissingNodes-DQbPyVvT.js 761 B 761 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/groupNode-DLzm2w0x.js 71.8 kB 71.8 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/i18n-BBrdjlX1.js 534 kB 534 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/i18n-h_puSPo9.js 199 B 199 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/InviteMemberDialogContent-8bSOOjPu.js 7.38 kB 7.38 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/InviteMemberUpsellDialogContent-BPoT4INd.js 3.82 kB 3.82 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/LeaveWorkspaceDialogContent-BPFnvPTv.js 4.06 kB 4.06 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/Load3D-CD_JluiX.js 16.2 kB 16.2 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/load3d-l01HYq32.js 14.7 kB 14.7 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/Load3D-nnIQ6vWU.js 1.07 kB 1.07 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/Load3DConfiguration-BBnvF6D-.js 6.27 kB 6.27 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/Load3DControls-4WZBKqGE.js 30.9 kB 30.9 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/Load3dViewerContent-Bh1pFYVg.js 993 B 993 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/Load3dViewerContent-D5KH-TbJ.js 23 kB 23 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-B4gaX-yc.js 148 kB 148 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-BDkWXD94.js 131 kB 131 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-BMRaSx8g.js 132 kB 132 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-BQewqC5f.js 152 kB 152 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-CAdoKrN8.js 154 kB 154 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-CDYHbD1q.js 179 kB 179 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-DEgKa3D5.js 172 kB 172 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-EWELmaLr.js 157 kB 157 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-Mk6d58ld.js 208 kB 208 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-o4jORuCB.js 149 kB 149 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-r2f5phvM.js 186 kB 186 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/Media3DTop-DjGAidD-.js 1.82 kB 1.82 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/MediaAudioTop-CXjvquTX.js 1.43 kB 1.43 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/MediaImageTop-CCi6hDYh.js 1.75 kB 1.75 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/MediaOtherTop-z-FoiFro.js 1.02 kB 1.02 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/MediaTextTop-BUmyBrmT.js 1.01 kB 1.01 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/MediaVideoTop-C5eK56v1.js 2.77 kB 2.77 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nightlyBadges-WuK7OGTC.js 1 kB 1 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-BRiV_JqD.js 451 kB 451 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-BRNi4BQJ.js 404 kB 404 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-BYxgBGHq.js 400 kB 400 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-CRJ1lnRc.js 396 kB 396 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-CYplVYdX.js 364 kB 364 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-Czw9YrJ_.js 368 kB 368 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-Dp7_2zi-.js 391 kB 391 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-DY1M9TFM.js 399 kB 399 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-EIvY3SXE.js 491 kB 491 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-TppPBr5S.js 416 kB 416 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-WGHIzLau.js 450 kB 450 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeTemplates-C6ElPCPL.js 9.29 kB 9.29 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/OBJLoader2WorkerModule-DTMpvldF.js 109 kB 109 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/onboardingCloudRoutes-CRHd7xk-.js 5.41 kB 5.41 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/Popover-CiXBGsU8.js 3.65 kB 3.65 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/Preview3d-BMBRLINy.js 4.81 kB 4.81 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/previousFullPath-DjJ0ZNXE.js 1.39 kB 1.39 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/RemoveMemberDialogContent-CHCbGFor.js 4.04 kB 4.04 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/RevokeInviteDialogContent-Dv7iPmga.js 3.95 kB 3.95 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/rolldown-runtime-DLICfi3-.js 1.97 kB 1.97 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/saveMesh-Csp0yn92.js 3.38 kB 3.38 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/SelectValue-mHgijvCJ.js 8.94 kB 8.94 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/SignInContent-I7hr945e.js 18.9 kB 18.9 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/signInSchema-DCzoRL7r.js 1.53 kB 1.53 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/Slider-CQRjYlXR.js 3.52 kB 3.52 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/src-DqM23qfs.js 251 B 251 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/SubscribeToRun-1d2MotI1.js 2.06 kB 2.06 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/SubscriptionBenefits-CC52XK_P.js 2.01 kB 2.01 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/SubscriptionPanelContentWorkspace-BlbY8Wy_.js 920 B 920 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/SubscriptionPanelContentWorkspace-liMjIvjB.js 22 kB 22 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/SubscriptionRequiredDialogContent-DJDC1NtM.js 25.7 kB 25.7 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/SubscriptionRequiredDialogContentWorkspace-BGEeAxMg.js 46.3 kB 46.3 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/telemetry-zZf2dHJ2.js 226 B 226 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/tierBenefits-F3xIzkj-.js 3.66 kB 3.66 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/types-DT3N7am7.js 204 B 204 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/ValueControlPopover-iGkymuC0.js 4.92 kB 4.92 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/VideoPlayOverlay-D_dHFUc0.js 1.35 kB 1.35 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/widget-NeEr3XWN.js 586 B 586 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetBoundingBox-aM9dgT_H.js 3.19 kB 3.19 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetBoundingBox-BYsbWVeN.js 283 B 283 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetChart-BF6Uqf9O.js 2.21 kB 2.21 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetColorPicker-DfzN4kvf.js 2.9 kB 2.9 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetCurve-D_JEKVtF.js 9.36 kB 9.36 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetGalleria-BHbklsS7.js 3.61 kB 3.61 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetImageCompare-C6hTlaKi.js 7 kB 7 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetImageCrop-CZYwN1i6.js 22.1 kB 22.1 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetInputNumber-eScgzvf-.js 18.8 kB 18.8 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetInputText-CwLynoNC.js 1.86 kB 1.86 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetLayoutField-CIhDMEfL.js 1.98 kB 1.98 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetLegacy-r5UnrUe7.js 744 B 744 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetMarkdown-CFetMknf.js 2.93 kB 2.93 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetPainter-DHnFYZsV.js 32.5 kB 32.5 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/widgetPropFilter-DN03zIgB.js 1.1 kB 1.1 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetRecordAudio-DD4d369w.js 17.4 kB 17.4 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetSelect-BcYIgZMU.js 58.2 kB 58.2 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetTextarea-D4ckclZT.js 3.96 kB 3.96 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetToggleSwitch-BBrQMwt0.js 6.8 kB 6.8 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/widgetTypes-DYLaC2lj.js 393 B 393 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetWithControl-DaxVg3xa.js 4.1 kB 4.1 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WorkspacePanelContent-D0hLrs4i.js 29.3 kB 29.3 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B

@github-actions
Copy link

github-actions bot commented Mar 4, 2026

⚡ Performance Report

Metric Baseline PR Δ
canvas-idle: style recalcs 121 121 +0% ⚪
canvas-idle: layouts 0 0 +0% ⚪
canvas-idle: task duration 370ms 436ms +18% 🟠
canvas-mouse-sweep: style recalcs 173 166 -4% ⚪
canvas-mouse-sweep: layouts 12 12 +0% ⚪
canvas-mouse-sweep: task duration 847ms 780ms -8% ⚪
dom-widget-clipping: style recalcs 45 41 -9% ⚪
dom-widget-clipping: layouts 0 0 +0% ⚪
dom-widget-clipping: task duration 408ms 351ms -14% 🟢
Raw data
{
  "timestamp": "2026-03-04T17:44:38.404Z",
  "gitSha": "0a999aa739add75fecd99db42522c0b9f133fe37",
  "branch": "pysssss/builder-footer-toolbar",
  "measurements": [
    {
      "name": "canvas-idle",
      "durationMs": 2005.608000000052,
      "styleRecalcs": 121,
      "styleRecalcDurationMs": 18.619,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 436.256,
      "heapDeltaBytes": -3815632
    },
    {
      "name": "canvas-mouse-sweep",
      "durationMs": 1831.1330000000225,
      "styleRecalcs": 166,
      "styleRecalcDurationMs": 46.804,
      "layouts": 12,
      "layoutDurationMs": 3.1090000000000004,
      "taskDurationMs": 780.487,
      "heapDeltaBytes": -4480552
    },
    {
      "name": "dom-widget-clipping",
      "durationMs": 584.1740000000755,
      "styleRecalcs": 41,
      "styleRecalcDurationMs": 11.620000000000001,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 350.959,
      "heapDeltaBytes": 7307468
    }
  ]
}

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (1)
src/components/builder/BuilderFooterToolbar.test.ts (1)

66-151: Add keyboard-path tests for Escape handling.

The suite covers click navigation well, but it does not validate the new window Escape flow. Please add cases for:

  • exits when in builder mode and no dialogs are open
  • no exit when dialog stack is non-empty
  • no exit when not in builder mode
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/builder/BuilderFooterToolbar.test.ts` around lines 66 - 151,
Add three unit tests in BuilderFooterToolbar.test.ts that dispatch a window
keydown with key "Escape" and assert exit behavior: (1) when mockState.mode is
'builder:select' or another builder mode and there are no open dialogs (ensure
mockShowDialog or dialog stack is empty/false), dispatch new
KeyboardEvent('keydown', { key: 'Escape' }) on window and expect mockExitBuilder
toHaveBeenCalledOnce(); (2) when the dialog stack is non-empty (stub/mock
whatever tracks dialogs so mockShowDialog or the dialog-stack helper returns
true), dispatch the same Escape event and expect mockExitBuilder not to have
been called; (3) when mockState.mode is not a builder mode (set mockState.mode
to something else), dispatch Escape and expect mockExitBuilder not to have been
called; use mountComponent() to mount the component before dispatching and clear
mocks between tests as in beforeEach.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/components/builder/BuilderFooterToolbar.vue`:
- Around line 49-61: The handler registered with useEventListener currently
reacts to every keydown including repeats; add a guard to ignore repeated
keydown events (use the KeyboardEvent.repeat property) before proceeding to call
onExitBuilder so holding Escape doesn't trigger multiple exits; update the
keydown callback that references isBuilderMode.value and dialogStore.dialogStack
to early-return when e.repeat is true (or alternatively track an
exit-in-progress flag cleared on keyup) to ensure onExitBuilder is invoked only
once per physical key press.

In `@src/components/builder/useBuilderSteps.ts`:
- Around line 23-33: The code currently force-casts mode.value to BuilderStepId
in the activeStep computed which can produce an invalid step not present in
BUILDER_STEPS; update activeStep (and thereby activeStepIndex) to first check
whether mode.value is a valid member of BUILDER_STEPS (e.g.,
BUILDER_STEPS.includes(mode.value)) before casting/returning it, and if not
present fall back to a safe default such as 'builder:select' (or
'setDefaultView' when settingView.value) so that
BUILDER_STEPS.indexOf(activeStep.value) never returns -1 and downstream
navigation always receives a valid step id.

---

Nitpick comments:
In `@src/components/builder/BuilderFooterToolbar.test.ts`:
- Around line 66-151: Add three unit tests in BuilderFooterToolbar.test.ts that
dispatch a window keydown with key "Escape" and assert exit behavior: (1) when
mockState.mode is 'builder:select' or another builder mode and there are no open
dialogs (ensure mockShowDialog or dialog stack is empty/false), dispatch new
KeyboardEvent('keydown', { key: 'Escape' }) on window and expect mockExitBuilder
toHaveBeenCalledOnce(); (2) when the dialog stack is non-empty (stub/mock
whatever tracks dialogs so mockShowDialog or the dialog-stack helper returns
true), dispatch the same Escape event and expect mockExitBuilder not to have
been called; (3) when mockState.mode is not a builder mode (set mockState.mode
to something else), dispatch Escape and expect mockExitBuilder not to have been
called; use mountComponent() to mount the component before dispatching and clear
mocks between tests as in beforeEach.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 7fb87c61-d51f-4444-a56f-1ec5831b5a62

📥 Commits

Reviewing files that changed from the base of the PR and between 9933d9b and 38e0fee.

📒 Files selected for processing (7)
  • src/components/builder/BuilderExitButton.vue
  • src/components/builder/BuilderFooterToolbar.test.ts
  • src/components/builder/BuilderFooterToolbar.vue
  • src/components/builder/BuilderToolbar.vue
  • src/components/builder/useBuilderSteps.ts
  • src/locales/en/main.json
  • src/views/GraphView.vue
💤 Files with no reviewable changes (1)
  • src/components/builder/BuilderExitButton.vue

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

♻️ Duplicate comments (1)
src/components/builder/BuilderFooterToolbar.vue (1)

45-57: ⚠️ Potential issue | 🟡 Minor

Guard Escape key-repeat to prevent repeated exits.

Line 45 currently handles every repeated keydown; holding Escape can trigger multiple onExitBuilder() calls.

Patch
 useEventListener(window, 'keydown', (e: KeyboardEvent) => {
   if (
+    !e.repeat &&
     e.key === 'Escape' &&
     !e.ctrlKey &&
     !e.altKey &&
     !e.metaKey &&
#!/bin/bash
# Verify the keydown guard and whether repeat is handled.
rg -n "useEventListener\\(window, 'keydown'" src/components/builder/BuilderFooterToolbar.vue -A20
rg -n "e\\.repeat" src/components/builder/BuilderFooterToolbar.vue
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/builder/BuilderFooterToolbar.vue` around lines 45 - 57, The
keydown handler registered via useEventListener currently calls onExitBuilder
repeatedly while Escape is held; add a guard to ignore repeated keydown events
by checking the KeyboardEvent.repeat property (e.repeat) before proceeding,
i.e., in the handler for useEventListener(window, 'keydown', (e: KeyboardEvent)
=> { ... }) return early if e.repeat is true so that onExitBuilder is only
invoked once when dialogStore.dialogStack.length === 0 and isBuilderMode.value
is true.
🧹 Nitpick comments (1)
src/components/builder/BuilderFooterToolbar.test.ts (1)

80-87: Use label-driven button lookup instead of positional indexing.

Index-based selection (buttons[0..2]) is brittle; selecting by visible label keeps the test focused on user-observable behavior.

Based on learnings: "In test files, prefer selecting or asserting on accessible properties (text content, aria-label, role, accessible name) over data-testid attributes."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/builder/BuilderFooterToolbar.test.ts` around lines 80 - 87,
Replace the brittle positional button lookup in getButtons by selecting buttons
by their visible/accessible labels: instead of using wrapper.findAll('button')
and indexing, locate each control via its text content or accessible name (e.g.,
filter/find buttons whose text() or aria-label matches "Exit", "Back", "Next")
so getButtons returns { exit, back, next } based on label-driven queries; update
the getButtons function to use wrapper.find/findAll with text/aria assertions
(or wrapper.find('[aria-label="..."]')) to make the test resilient to DOM order
changes.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@src/components/builder/BuilderFooterToolbar.vue`:
- Around line 45-57: The keydown handler registered via useEventListener
currently calls onExitBuilder repeatedly while Escape is held; add a guard to
ignore repeated keydown events by checking the KeyboardEvent.repeat property
(e.repeat) before proceeding, i.e., in the handler for useEventListener(window,
'keydown', (e: KeyboardEvent) => { ... }) return early if e.repeat is true so
that onExitBuilder is only invoked once when dialogStore.dialogStack.length ===
0 and isBuilderMode.value is true.

---

Nitpick comments:
In `@src/components/builder/BuilderFooterToolbar.test.ts`:
- Around line 80-87: Replace the brittle positional button lookup in getButtons
by selecting buttons by their visible/accessible labels: instead of using
wrapper.findAll('button') and indexing, locate each control via its text content
or accessible name (e.g., filter/find buttons whose text() or aria-label matches
"Exit", "Back", "Next") so getButtons returns { exit, back, next } based on
label-driven queries; update the getButtons function to use wrapper.find/findAll
with text/aria assertions (or wrapper.find('[aria-label="..."]')) to make the
test resilient to DOM order changes.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 1d20ce0e-beb2-4711-8ca3-1db901399492

📥 Commits

Reviewing files that changed from the base of the PR and between 38e0fee and 6f6ac00.

📒 Files selected for processing (4)
  • src/components/builder/BuilderFooterToolbar.test.ts
  • src/components/builder/BuilderFooterToolbar.vue
  • src/components/builder/BuilderToolbar.vue
  • src/components/builder/useBuilderSteps.ts

@pythongosssss pythongosssss marked this pull request as ready for review March 4, 2026 17:51
@pythongosssss pythongosssss requested a review from a team as a code owner March 4, 2026 17:51
@dosubot dosubot bot added the size:L This PR changes 100-499 lines, ignoring generated files. label Mar 4, 2026
@pythongosssss pythongosssss merged commit c759fe5 into main Mar 4, 2026
37 checks passed
@pythongosssss pythongosssss deleted the pysssss/builder-footer-toolbar branch March 4, 2026 17:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L This PR changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants