Skip to content

[refactor] Migrate SettingDialog to BaseModalLayout design system#8270

Merged
viva-jinyi merged 24 commits intomainfrom
refactor/setting-dialog
Feb 12, 2026
Merged

[refactor] Migrate SettingDialog to BaseModalLayout design system#8270
viva-jinyi merged 24 commits intomainfrom
refactor/setting-dialog

Conversation

@viva-jinyi
Copy link
Copy Markdown
Member

@viva-jinyi viva-jinyi commented Jan 23, 2026

Summary

Replace PrimeVue-based SettingDialog with BaseModalLayout + custom left panel, extract useSettingsDialog composable, and migrate workspace tabs to design system components.

Changes

  • SettingDialog: New component using BaseModalLayout with custom left panel (NavTitle, NavItem), search box, and workspace image support
  • useSettingsDialog: Extracted from dialogService.ts following useManagerDialog pattern; updated all 10 callers
  • WorkspacePanelContent: Replaced PrimeVue Tabs/TabList/Tab/TabPanel/TabPanels with design system TabList/Tab
  • Deleted: SettingDialogContent.vue, SettingDialogHeader.vue, PanelTemplate.vue, WorkspaceSidebarItem.vue
  • Panels: Removed TabPanel/PanelTemplate wrappers from all setting panels (About, Keybinding, Extension, ServerConfig, User, Workspace, Credits, Subscription)
  • GlobalDialog: Removed settings-specific class logic and workspace feature flag imports

UX Improvements

  • Search → nav active: Searching settings auto-selects the first matching category in the left nav
  • Nav click during search: Clicking a different nav item clears the search and shows that category's content
  • Scroll to active: When a nav item becomes active, the nav panel scrolls to keep it visible
  • Accessibility: Added aria-label to clipboard copy button in ServerConfigPanel

Review Focus

  • Left panel layout: workspace image shown when team workspaces enabled, search box between header and nav items
  • useSettingsDialog composable replaces dialogService.showSettingsDialog/showAboutDialog

screen-capture (3).webm
screen-capture (2).webm

@viva-jinyi viva-jinyi added the enhancement New feature or request label Jan 23, 2026
@viva-jinyi viva-jinyi requested a review from ltdrdata as a code owner January 23, 2026 07:56
@viva-jinyi viva-jinyi requested review from a team and pythongosssss as code owners January 23, 2026 07:56
@dosubot dosubot bot added the size:XXL This PR changes 1000+ lines, ignoring generated files. label Jan 23, 2026
@github-actions
Copy link
Copy Markdown

github-actions bot commented Jan 23, 2026

Playwright: ✅ 520 passed, 0 failed · 3 flaky

📊 Browser Reports
  • chromium: View Report (✅ 508 / ❌ 0 / ⚠️ 3 / ⏭️ 8)
  • chromium-2x: View Report (✅ 2 / ❌ 0 / ⚠️ 0 / ⏭️ 0)
  • chromium-0.5x: View Report (✅ 1 / ❌ 0 / ⚠️ 0 / ⏭️ 0)
  • mobile-chrome: View Report (✅ 9 / ❌ 0 / ⚠️ 0 / ⏭️ 0)

@viva-jinyi viva-jinyi marked this pull request as draft January 23, 2026 07:56
@github-actions
Copy link
Copy Markdown

github-actions bot commented Jan 23, 2026

🎨 Storybook Build Status

Build completed successfully!

⏰ Completed at: 02/12/2026, 07:20:51 AM UTC

🔗 Links


🎉 Your Storybook is ready for review!

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Jan 23, 2026

Important

Review skipped

Review was skipped due to path filters

⛔ Files ignored due to path filters (1)
  • browser_tests/tests/interaction.spec.ts-snapshots/dragged-node1-chromium-linux.png is excluded by !**/*.png

CodeRabbit blocks several paths by default. You can override this behavior by explicitly including those paths in the path filters. For example, including **/dist/** will override the default block on the dist directory, by removing the pattern from both the lists.

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
📝 Walkthrough

Walkthrough

Replaces legacy settings UI with a new SettingsDialog component and a useSettingsDialog composable, removes PanelTemplate and legacy dialog exports, updates many call sites/tests to use the new composable and data-testid dialog selector, and migrates PrimeVue tabs to Rekau tab primitives.

Changes

Cohort / File(s) Summary
Settings core & types
src/platform/settings/composables/useSettingsDialog.ts, src/platform/settings/components/SettingDialog.vue, src/platform/settings/types.ts, src/platform/settings/composables/useSettingUI.ts
Added useSettingsDialog composable and new SettingDialog component; introduced SettingPanelType; expanded useSettingUI surface (navGroups, teamWorkspacesEnabled, findCategoryByKey, findPanelByKey) and improved default panel lookup.
Removed legacy settings UI
src/platform/settings/components/SettingDialogContent.vue (deleted), src/components/dialog/content/setting/PanelTemplate.vue (deleted), src/components/dialog/header/SettingDialogHeader.vue (deleted), src/components/dialog/content/setting/WorkspaceSidebarItem.vue (deleted)
Deleted legacy settings rendering and wrapper/header/sidebar components — watch for dangling imports.
Wrapper → plain containers
src/components/dialog/content/setting/AboutPanel.vue, src/components/dialog/content/setting/KeybindingPanel.vue, src/components/dialog/content/setting/LegacyCreditsPanel.vue, src/components/dialog/content/setting/UserPanel.vue, src/components/dialog/content/setting/WorkspacePanel.vue, src/platform/cloud/subscription/components/SubscriptionPanel.vue, src/platform/settings/components/ExtensionPanel.vue, src/platform/settings/components/ServerConfigPanel.vue
Replaced PanelTemplate/TabPanel wrappers with plain div containers; removed related imports; internal logic preserved but DOM changed.
Workspace tab refactor
src/components/dialog/content/setting/WorkspacePanelContent.vue, src/platform/workspace/composables/useWorkspaceUI.ts
Converted PrimeVue Tabs to Rekau TabsRoot/TabsList/TabsTrigger/TabsContent; moved active tab to component-local state and removed shared activeTab from useWorkspaceUI.
Dialog service removals & migrations
src/services/dialogService.ts, various call sites (e.g. src/components/.../BottomPanel.vue, TopUpCreditsDialogContent*.vue, TabGlobalSettings.vue, ComfyMenuButton.vue, CurrentUserPopover*.vue, useCoreCommands.ts, UploadModelUrlInput.vue, src/scripts/ui.ts, src/stores/billingOperationStore.ts, src/workbench/.../useManagerState.ts, etc.)
Removed showSettingsDialog/showAboutDialog from dialogService; migrated call sites to useSettingsDialog().show(...), updated imports and local variable names (dialogServicesettingsDialog).
New settings component
src/platform/settings/components/SettingDialog.vue
New SFC implementing sidebar nav, search, and dynamic main content with props onClose, defaultPanel?, scrollToSettingId?; manages search/category/panel state and scrolling.
Browser tests & fixtures
browser_tests/fixtures/components/SettingDialog.ts, browser_tests/tests/dialog.spec.ts, browser_tests/tests/subgraph.spec.ts, browser_tests/tests/useSettingSearch.spec.ts, browser_tests/tests/bottomPanelShortcuts.spec.ts
Tests/fixtures updated to root-scoped locators and [data-testid="settings-dialog"]; fixture adds searchBox, categories, contentArea, and category(name) API; test interactions moved to dialog-scoped locators.
Test mock updates
src/components/topbar/CurrentUserPopoverLegacy.test.ts, src/stores/billingOperationStore.test.ts, src/stores/firebaseAuthStore.test.ts, src/workbench/.../useManagerState.test.ts, src/workbench/extensions/manager/composables/useManagerState.test.ts
Mocks updated from useDialogService/showSettingsDialog to useSettingsDialog exposing { show, hide, showAbout }; tests adjusted accordingly.
Base modal sizing & usages
src/components/widget/layout/BaseModalLayout.vue, src/components/custom/widget/WorkflowTemplateSelectorDialog.vue, src/composables/useWorkflowTemplateSelectorDialog.ts
Added size prop and size classes to BaseModalLayout; updated usages to size="md" and removed per-instance dialogComponentProps styling.
Global dialog style change
src/components/dialog/GlobalDialog.vue
Removed conditional workspace-specific class; root always uses static global-dialog class.
Misc — imports & small refactors
assorted files (ConfirmationDialogContent.vue, MissingModelsWarning.vue, MissingNodesFooter.vue, scripts, stores, storybook, asset dialog, etc.)
Many import path updates, variable renames, selector adjustments, removal of per-instance dialog styling, and small template changes; ensure updated imports compile.

Sequence Diagram(s)

sequenceDiagram
    participant Caller as Caller Component
    participant UseSettings as useSettingsDialog
    participant DialogService as Dialog Store/Service
    participant SettingDialog as SettingDialog Component

    Caller->>UseSettings: show(panel?, settingId?)
    UseSettings->>DialogService: showLayoutDialog(DIALOG_KEY, SettingDialog, { defaultPanel: panel, scrollToSettingId: settingId, onClose })
    DialogService->>SettingDialog: mount with props
    SettingDialog->>SettingDialog: render nav, search, content
    SettingDialog-->>Caller: user triggers onClose / interactions
    Caller->>UseSettings: hide()
    UseSettings->>DialogService: hideDialog(DIALOG_KEY)
    DialogService->>SettingDialog: unmount
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

🐰 I hopped through code and swapped the old for new,
A composable doorway and a dialog with view.
Wrappers slimmed, tests now chase testids bright,
Tabs rearranged and imports set right.
Carrots for reviewers — code cleaned in a night!

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 5.88% 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 '[refactor] Migrate SettingDialog to BaseModalLayout design system' accurately and clearly summarizes the main change—migrating the SettingDialog from PrimeVue to BaseModalLayout.
Description check ✅ Passed The PR description is comprehensive and well-structured, covering summary, detailed changes, UX improvements, and review focus; it follows the template structure and provides sufficient context.

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

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch refactor/setting-dialog

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
Copy Markdown

github-actions bot commented Jan 23, 2026

Bundle Size Report

Summary

  • Raw size: 19.8 MB baseline 19.8 MB — 🔴 +3.55 kB
  • Gzip: 4.22 MB baseline 4.23 MB — 🟢 -3.47 kB
  • Brotli: 3.28 MB baseline 3.28 MB — 🟢 -4.87 kB
  • Bundles: 230 current • 237 baseline • 209 added / 216 removed

Category Glance
Data & Services 🔴 +46.7 kB (2.15 MB) · Panels & Settings 🟢 -30.2 kB (427 kB) · Other 🟢 -25.7 kB (7.27 MB) · Vendor & Third-Party 🔴 +14.6 kB (8.69 MB) · Utilities & Hooks 🟢 -1.25 kB (237 kB) · Graph Workspace 🟢 -502 B (874 kB) · + 5 more

Per-category breakdown
App Entry Points — 21.7 kB (baseline 22.1 kB) • 🟢 -377 B

Main entry bundles and manifests

File Before After Δ Raw Δ Gzip Δ Brotli
assets/index-h3xwYQvb.js (removed) 22.1 kB 🟢 -22.1 kB 🟢 -7.19 kB 🟢 -6.25 kB
assets/index-stY2psGb.js (new) 21.7 kB 🔴 +21.7 kB 🔴 +7.01 kB 🔴 +6.12 kB

Status: 1 added / 1 removed

Graph Workspace — 874 kB (baseline 874 kB) • 🟢 -502 B

Graph editor runtime, canvas, workflow orchestration

File Before After Δ Raw Δ Gzip Δ Brotli
assets/GraphView-CN2I8NSA.js (removed) 874 kB 🟢 -874 kB 🟢 -188 kB 🟢 -144 kB
assets/GraphView-CUvaHEG7.js (new) 874 kB 🔴 +874 kB 🔴 +188 kB 🔴 +144 kB

Status: 1 added / 1 removed

Views & Navigation — 68.9 kB (baseline 68.8 kB) • 🔴 +160 B

Top-level views, pages, and routed surfaces

File Before After Δ Raw Δ Gzip Δ Brotli
assets/CloudSurveyView-_zRTgoXd.js (removed) 15.4 kB 🟢 -15.4 kB 🟢 -3.31 kB 🟢 -2.81 kB
assets/CloudSurveyView-BJvB13Zb.js (new) 15.4 kB 🔴 +15.4 kB 🔴 +3.31 kB 🔴 +2.81 kB
assets/CloudLoginView-CUH_lbmf.js (new) 10.1 kB 🔴 +10.1 kB 🔴 +2.95 kB 🔴 +2.6 kB
assets/CloudLoginView-B0Y7LS7N.js (removed) 10.1 kB 🟢 -10.1 kB 🟢 -2.94 kB 🟢 -2.59 kB
assets/UserCheckView-BEj2fnVr.js (new) 8.38 kB 🔴 +8.38 kB 🔴 +2.21 kB 🔴 +1.92 kB
assets/UserCheckView-CY4QNe9G.js (removed) 8.38 kB 🟢 -8.38 kB 🟢 -2.21 kB 🟢 -1.93 kB
assets/CloudSignupView-a7SFQuGE.js (removed) 7.46 kB 🟢 -7.46 kB 🟢 -2.35 kB 🟢 -2.06 kB
assets/CloudSignupView-BaKh9anJ.js (new) 7.46 kB 🔴 +7.46 kB 🔴 +2.34 kB 🔴 +2.05 kB
assets/CloudLayoutView-O1hQPhrc.js (new) 6.48 kB 🔴 +6.48 kB 🔴 +2.13 kB 🔴 +1.87 kB
assets/CloudLayoutView-BnHg_xur.js (removed) 6.45 kB 🟢 -6.45 kB 🟢 -2.11 kB 🟢 -1.83 kB
assets/CloudForgotPasswordView-CnDXvo9c.js (new) 5.61 kB 🔴 +5.61 kB 🔴 +1.96 kB 🔴 +1.73 kB
assets/CloudForgotPasswordView-2_pSMGRZ.js (removed) 5.57 kB 🟢 -5.57 kB 🟢 -1.94 kB 🟢 -1.76 kB
assets/CloudAuthTimeoutView-xVu35s6P.js (new) 4.96 kB 🔴 +4.96 kB 🔴 +1.79 kB 🔴 +1.57 kB
assets/CloudAuthTimeoutView-oRltyQ_d.js (removed) 4.92 kB 🟢 -4.92 kB 🟢 -1.78 kB 🟢 -1.56 kB
assets/CloudSubscriptionRedirectView-Ci5vg6EN.js (new) 4.76 kB 🔴 +4.76 kB 🔴 +1.8 kB 🔴 +1.59 kB
assets/CloudSubscriptionRedirectView-ZQ5nRqTD.js (removed) 4.72 kB 🟢 -4.72 kB 🟢 -1.79 kB 🟢 -1.58 kB
assets/UserSelectView-CqtYTGwQ.js (new) 4.46 kB 🔴 +4.46 kB 🔴 +1.62 kB 🔴 +1.46 kB
assets/UserSelectView-mX8PNiGb.js (removed) 4.46 kB 🟢 -4.46 kB 🟢 -1.62 kB 🟢 -1.45 kB
assets/CloudSorryContactSupportView-CB2CRlWp.js (removed) 1.02 kB 🟢 -1.02 kB 🟢 -539 B 🟢 -471 B
assets/CloudSorryContactSupportView-CnbSE1aL.js (new) 1.02 kB 🔴 +1.02 kB 🔴 +540 B 🔴 +471 B
assets/layout-BN-ntRG8.js (new) 296 B 🔴 +296 B 🔴 +222 B 🔴 +191 B
assets/layout-DxbdBSNy.js (removed) 296 B 🟢 -296 B 🟢 -222 B 🟢 -190 B

Status: 11 added / 11 removed

Panels & Settings — 427 kB (baseline 457 kB) • 🟢 -30.2 kB

Configuration panels, inspectors, and settings screens

File Before After Δ Raw Δ Gzip Δ Brotli
assets/settings-BwnA4lIc.js (removed) 37.6 kB 🟢 -37.6 kB 🟢 -9.15 kB 🟢 -7.54 kB
assets/settings-CF6cmuWq.js (new) 37.6 kB 🔴 +37.6 kB 🔴 +9.15 kB 🔴 +7.53 kB
assets/settings-B7fETr1a.js (removed) 33.3 kB 🟢 -33.3 kB 🟢 -8.13 kB 🟢 -6.83 kB
assets/settings-ohqijv3i.js (new) 33.3 kB 🔴 +33.3 kB 🔴 +8.12 kB 🔴 +6.83 kB
assets/settings-C5NycgSh.js (new) 31.6 kB 🔴 +31.6 kB 🔴 +7.96 kB 🔴 +6.48 kB
assets/settings-DTiggrd7.js (removed) 31.6 kB 🟢 -31.6 kB 🟢 -7.96 kB 🟢 -6.48 kB
assets/settings-CqJumQQJ.js (removed) 29.8 kB 🟢 -29.8 kB 🟢 -8.25 kB 🟢 -6.94 kB
assets/settings-Djbh331J.js (new) 29.8 kB 🔴 +29.8 kB 🔴 +8.25 kB 🔴 +6.94 kB
assets/WorkspacePanel-ACeuofU5.js (removed) 29.4 kB 🟢 -29.4 kB 🟢 -6.1 kB 🟢 -5.38 kB
assets/settings-8z66fa9o.js (new) 29.2 kB 🔴 +29.2 kB 🔴 +7.91 kB 🔴 +6.92 kB
assets/settings-DmKUGnoS.js (removed) 29.2 kB 🟢 -29.2 kB 🟢 -7.91 kB 🟢 -6.92 kB
assets/settings-CMSM0-YP.js (new) 28.1 kB 🔴 +28.1 kB 🔴 +7.61 kB 🔴 +6.47 kB
assets/settings-CtLKJX0B.js (removed) 28.1 kB 🟢 -28.1 kB 🟢 -7.61 kB 🟢 -6.48 kB
assets/settings-DA58wjMS.js (removed) 28 kB 🟢 -28 kB 🟢 -7.82 kB 🟢 -6.83 kB
assets/settings-HiOqkizv.js (new) 28 kB 🔴 +28 kB 🔴 +7.82 kB 🔴 +6.83 kB
assets/settings-DpJJD4QB.js (removed) 27.3 kB 🟢 -27.3 kB 🟢 -7.52 kB 🟢 -6.55 kB
assets/settings-emoCO0AT.js (new) 27.3 kB 🔴 +27.3 kB 🔴 +7.52 kB 🔴 +6.54 kB
assets/settings-B_EruZyQ.js (new) 27.1 kB 🔴 +27.1 kB 🔴 +7.93 kB 🔴 +6.6 kB
assets/settings-CQwQYDNl.js (removed) 27.1 kB 🟢 -27.1 kB 🟢 -7.93 kB 🟢 -6.6 kB
assets/settings-BPuOKZZg.js (new) 23.9 kB 🔴 +23.9 kB 🔴 +7.72 kB 🔴 +6.21 kB
assets/settings-DbNK1LoE.js (removed) 23.9 kB 🟢 -23.9 kB 🟢 -7.72 kB 🟢 -6.22 kB
assets/settings-H0rWARzj.js (new) 23.3 kB 🔴 +23.3 kB 🔴 +7.47 kB 🔴 +5.85 kB
assets/settings-pVgAToOu.js (removed) 23.3 kB 🟢 -23.3 kB 🟢 -7.47 kB 🟢 -5.85 kB
assets/SecretsPanel-Dkqo56lm.js (removed) 21.5 kB 🟢 -21.5 kB 🟢 -5.29 kB 🟢 -4.64 kB
assets/SecretsPanel-DQUQca3g.js (new) 21.5 kB 🔴 +21.5 kB 🔴 +5.29 kB 🔴 +4.64 kB
assets/LegacyCreditsPanel-CZSkAqKj.js (removed) 20.8 kB 🟢 -20.8 kB 🟢 -5.61 kB 🟢 -4.93 kB
assets/LegacyCreditsPanel-BtlEBlM8.js (new) 20.7 kB 🔴 +20.7 kB 🔴 +5.59 kB 🔴 +4.92 kB
assets/SubscriptionPanel-DsttZdLM.js (removed) 18.7 kB 🟢 -18.7 kB 🟢 -4.75 kB 🟢 -4.24 kB
assets/SubscriptionPanel-CZ03devB.js (new) 18.7 kB 🔴 +18.7 kB 🔴 +4.73 kB 🔴 +4.18 kB
assets/KeybindingPanel-D4JbxZXn.js (removed) 12.6 kB 🟢 -12.6 kB 🟢 -3.63 kB 🟢 -3.21 kB
assets/KeybindingPanel-BvS7rM1h.js (new) 12.4 kB 🔴 +12.4 kB 🔴 +3.6 kB 🔴 +3.19 kB
assets/ExtensionPanel-Da_8RDYR.js (removed) 9.51 kB 🟢 -9.51 kB 🟢 -2.69 kB 🟢 -2.38 kB
assets/ExtensionPanel-DelI6wnm.js (new) 9.43 kB 🔴 +9.43 kB 🔴 +2.67 kB 🔴 +2.38 kB
assets/AboutPanel-CKMef_ZN.js (removed) 8.62 kB 🟢 -8.62 kB 🟢 -2.46 kB 🟢 -2.22 kB
assets/AboutPanel-Dw6A5vXO.js (new) 8.49 kB 🔴 +8.49 kB 🔴 +2.43 kB 🔴 +2.18 kB
assets/ServerConfigPanel-B5oIuISC.js (removed) 6.65 kB 🟢 -6.65 kB 🟢 -2.16 kB 🟢 -1.98 kB
assets/ServerConfigPanel-BJjr2Lcm.js (new) 6.5 kB 🔴 +6.5 kB 🔴 +2.13 kB 🔴 +1.91 kB
assets/UserPanel-CAreNE94.js (removed) 6.29 kB 🟢 -6.29 kB 🟢 -2.03 kB 🟢 -1.78 kB
assets/UserPanel-Y9eN0u53.js (new) 6.21 kB 🔴 +6.21 kB 🔴 +2.02 kB 🔴 +1.77 kB
assets/cloudRemoteConfig-B8G8WhrE.js (new) 1.49 kB 🔴 +1.49 kB 🔴 +733 B 🔴 +634 B
assets/cloudRemoteConfig-CvUqzvi_.js (removed) 1.45 kB 🟢 -1.45 kB 🟢 -715 B 🟢 -622 B
assets/refreshRemoteConfig-CvEz1MWa.js (removed) 1.14 kB 🟢 -1.14 kB 🟢 -524 B 🟢 -458 B
assets/refreshRemoteConfig-K27TdlZJ.js (new) 1.14 kB 🔴 +1.14 kB 🔴 +522 B 🔴 +470 B
assets/config-CepyQFhC.js (new) 996 B 🔴 +996 B 🔴 +541 B 🔴 +475 B
assets/config-jJA9WJge.js (removed) 996 B 🟢 -996 B 🟢 -542 B 🟢 -447 B

Status: 22 added / 23 removed

User & Accounts — 16.1 kB (baseline 16 kB) • 🔴 +68 B

Authentication, profile, and account management bundles

File Before After Δ Raw Δ Gzip Δ Brotli
assets/PasswordFields-CdUdjtQy.js (new) 4.51 kB 🔴 +4.51 kB 🔴 +1.36 kB 🔴 +1.2 kB
assets/PasswordFields-Dz_bXydQ.js (removed) 4.51 kB 🟢 -4.51 kB 🟢 -1.36 kB 🟢 -1.2 kB
assets/auth-3SO9mFlt.js (removed) 3.4 kB 🟢 -3.4 kB 🟢 -1.18 kB 🟢 -987 B
assets/auth-DJsJVhnG.js (new) 3.4 kB 🔴 +3.4 kB 🔴 +1.18 kB 🔴 +987 B
assets/SignUpForm-Ce7_SqZr.js (removed) 3.01 kB 🟢 -3.01 kB 🟢 -1.23 kB 🟢 -1.12 kB
assets/SignUpForm-DUA1rruK.js (new) 3.01 kB 🔴 +3.01 kB 🔴 +1.23 kB 🔴 +1.09 kB
assets/UpdatePasswordContent-K12DxRNn.js (new) 2.42 kB 🔴 +2.42 kB 🔴 +1.09 kB 🔴 +965 B
assets/UpdatePasswordContent-B17_LQFK.js (removed) 2.38 kB 🟢 -2.38 kB 🟢 -1.08 kB 🟢 -953 B
assets/WorkspaceProfilePic-BQO-2kig.js (new) 1.57 kB 🔴 +1.57 kB 🔴 +822 B 🔴 +708 B
assets/WorkspaceProfilePic-D2K-asRs.js (removed) 1.57 kB 🟢 -1.57 kB 🟢 -821 B 🟢 -706 B
assets/firebaseAuthStore-BKhjmbJY.js (new) 837 B 🔴 +837 B 🔴 +414 B 🔴 +369 B
assets/firebaseAuthStore-vkb0jeFr.js (removed) 803 B 🟢 -803 B 🟢 -398 B 🟢 -357 B
assets/auth-C8a9w3oC.js (removed) 317 B 🟢 -317 B 🟢 -206 B 🟢 -179 B
assets/auth-DDeOm_cN.js (new) 317 B 🔴 +317 B 🔴 +204 B 🔴 +177 B

Status: 7 added / 7 removed

Editors & Dialogs — 785 B (baseline 751 B) • 🔴 +34 B

Modals, dialogs, drawers, and in-app editors

File Before After Δ Raw Δ Gzip Δ Brotli
assets/useSubscriptionDialog-CBHwGseg.js (new) 785 B 🔴 +785 B 🔴 +401 B 🔴 +348 B
assets/useSubscriptionDialog-BBxRny3Z.js (removed) 751 B 🟢 -751 B 🟢 -388 B 🟢 -336 B

Status: 1 added / 1 removed

UI Components — 36.6 kB (baseline 36.5 kB) • 🔴 +81 B

Reusable component library chunks

File Before After Δ Raw Δ Gzip Δ Brotli
assets/useTerminalTabs-CCSFsGJM.js (new) 9.89 kB 🔴 +9.89 kB 🔴 +3.42 kB 🔴 +3.02 kB
assets/useTerminalTabs-KtppcCw5.js (removed) 9.86 kB 🟢 -9.86 kB 🟢 -3.41 kB 🟢 -3.01 kB
assets/TopbarBadge-D-6eyEev.js (removed) 7.45 kB 🟢 -7.45 kB 🟢 -1.81 kB 🟢 -1.61 kB
assets/TopbarBadge-Ds7IqP5Z.js (new) 7.45 kB 🔴 +7.45 kB 🔴 +1.81 kB 🔴 +1.6 kB
assets/ComfyQueueButton-B4d4GHQw.js (new) 7.17 kB 🔴 +7.17 kB 🔴 +2.32 kB 🔴 +2.07 kB
assets/ComfyQueueButton-D5cuxeaK.js (removed) 7.17 kB 🟢 -7.17 kB 🟢 -2.32 kB 🟢 -2.07 kB
assets/Button-DJ97zW2s.js (removed) 3 kB 🟢 -3 kB 🟢 -1.21 kB 🟢 -1.06 kB
assets/Button-BlbRDbqy.js (new) 2.98 kB 🔴 +2.98 kB 🔴 +1.21 kB 🔴 +1.05 kB
assets/SubscribeButton-D84iahBS.js (new) 2.35 kB 🔴 +2.35 kB 🔴 +1.02 kB 🔴 +890 B
assets/SubscribeButton-vdgPK1YE.js (removed) 2.35 kB 🟢 -2.35 kB 🟢 -1.02 kB 🟢 -890 B
assets/WidgetButton-Bf5nJNvA.js (removed) 1.84 kB 🟢 -1.84 kB 🟢 -877 B 🟢 -772 B
assets/WidgetButton-DgRwIURU.js (new) 1.84 kB 🔴 +1.84 kB 🔴 +878 B 🔴 +785 B
assets/cloudFeedbackTopbarButton-CewiCHmX.js (new) 1.64 kB 🔴 +1.64 kB 🔴 +878 B 🔴 +783 B
assets/cloudFeedbackTopbarButton-C0XaiKpZ.js (removed) 1.61 kB 🟢 -1.61 kB 🟢 -868 B 🟢 -767 B
assets/CloudBadge-DdmSN2kE.js (removed) 1.24 kB 🟢 -1.24 kB 🟢 -606 B 🟢 -524 B
assets/CloudBadge-hxJOdoys.js (new) 1.24 kB 🔴 +1.24 kB 🔴 +607 B 🔴 +527 B
assets/UserAvatar-DrH_EiZZ.js (new) 1.17 kB 🔴 +1.17 kB 🔴 +619 B 🔴 +521 B
assets/UserAvatar-ki0RgWjr.js (removed) 1.17 kB 🟢 -1.17 kB 🟢 -618 B 🟢 -524 B
assets/ComfyQueueButton-BW6otrjA.js (new) 842 B 🔴 +842 B 🔴 +416 B 🔴 +369 B
assets/ComfyQueueButton-c_nwT_E4.js (removed) 808 B 🟢 -808 B 🟢 -402 B 🟢 -358 B

Status: 10 added / 10 removed

Data & Services — 2.15 MB (baseline 2.11 MB) • 🔴 +46.7 kB

Stores, services, APIs, and repositories

File Before After Δ Raw Δ Gzip Δ Brotli
assets/dialogService-wRWX-9Bx.js (new) 1.38 MB 🔴 +1.38 MB 🔴 +310 kB 🔴 +239 kB
assets/dialogService-CEg6emf1.js (removed) 1.33 MB 🟢 -1.33 MB 🟢 -299 kB 🟢 -232 kB
assets/api-VS-sOTUr.js (new) 647 kB 🔴 +647 kB 🔴 +146 kB 🔴 +116 kB
assets/api-Z6Q087l2.js (removed) 647 kB 🟢 -647 kB 🟢 -146 kB 🟢 -117 kB
assets/load3dService-DMpoIkNv.js (new) 91 kB 🔴 +91 kB 🔴 +19.1 kB 🔴 +16.4 kB
assets/load3dService-C4In4zAI.js (removed) 91 kB 🟢 -91 kB 🟢 -19 kB 🟢 -16.4 kB
assets/systemStatsStore-A_6GpttH.js (removed) 12.2 kB 🟢 -12.2 kB 🟢 -4.27 kB 🟢 -3.74 kB
assets/systemStatsStore-sT7frI2K.js (new) 12.2 kB 🔴 +12.2 kB 🔴 +4.26 kB 🔴 +3.74 kB
assets/releaseStore-CXekHeT8.js (removed) 7.96 kB 🟢 -7.96 kB 🟢 -2.22 kB 🟢 -1.95 kB
assets/releaseStore-DryE11O7.js (new) 7.96 kB 🔴 +7.96 kB 🔴 +2.22 kB 🔴 +1.95 kB
assets/keybindingService-CNFjDaNj.js (new) 6.57 kB 🔴 +6.57 kB 🔴 +1.73 kB 🔴 +1.49 kB
assets/keybindingService-D4B6mChM.js (removed) 6.57 kB 🟢 -6.57 kB 🟢 -1.72 kB 🟢 -1.49 kB
assets/dialogStore-D5Kfd1UD.js (new) 4.1 kB 🔴 +4.1 kB 🔴 +1.24 kB 🔴 +1.1 kB
assets/dialogStore-SMYg02Jv.js (removed) 4.1 kB 🟢 -4.1 kB 🟢 -1.24 kB 🟢 -1.1 kB
assets/serverConfigStore-CoLfNeUe.js (removed) 2.32 kB 🟢 -2.32 kB 🟢 -788 B 🟢 -694 B
assets/serverConfigStore-CRmy-NJp.js (new) 2.32 kB 🔴 +2.32 kB 🔴 +789 B 🔴 +691 B
assets/bootstrapStore-BNoKV7b1.js (new) 2.08 kB 🔴 +2.08 kB 🔴 +874 B 🔴 +794 B
assets/bootstrapStore-D8Y__Cs7.js (removed) 2.08 kB 🟢 -2.08 kB 🟢 -874 B 🟢 -789 B
assets/userStore-Cphu4Fp_.js (removed) 1.85 kB 🟢 -1.85 kB 🟢 -722 B 🟢 -677 B
assets/userStore-CQ_HS8PO.js (new) 1.85 kB 🔴 +1.85 kB 🔴 +721 B 🔴 +676 B
assets/audioService-BONt9FPj.js (new) 1.73 kB 🔴 +1.73 kB 🔴 +848 B 🔴 +725 B
assets/audioService-DaJjemyL.js (removed) 1.73 kB 🟢 -1.73 kB 🟢 -847 B 🟢 -726 B
assets/releaseStore-qDLJIP39.js (new) 809 B 🔴 +809 B 🔴 +407 B 🔴 +359 B
assets/workflowDraftStore-7tNExACm.js (new) 785 B 🔴 +785 B 🔴 +401 B 🔴 +353 B
assets/releaseStore-qFMvEJmt.js (removed) 775 B 🟢 -775 B 🟢 -393 B 🟢 -348 B
assets/dialogService-9nfCQSGf.js (new) 774 B 🔴 +774 B 🔴 +393 B 🔴 +348 B
assets/workflowDraftStore-HSag71qk.js (removed) 751 B 🟢 -751 B 🟢 -389 B 🟢 -340 B
assets/dialogService-hpctWXpz.js (removed) 740 B 🟢 -740 B 🟢 -381 B 🟢 -336 B

Status: 14 added / 14 removed

Utilities & Hooks — 237 kB (baseline 238 kB) • 🟢 -1.25 kB

Helpers, composables, and utility bundles

File Before After Δ Raw Δ Gzip Δ Brotli
assets/useConflictDetection-BgjPUZW-.js (removed) 178 kB 🟢 -178 kB 🟢 -39.4 kB 🟢 -32.8 kB
assets/useConflictDetection-F87ndASb.js (new) 178 kB 🔴 +178 kB 🔴 +39.4 kB 🔴 +32.8 kB
assets/useLoad3d-D_resO25.js (removed) 14.6 kB 🟢 -14.6 kB 🟢 -3.63 kB 🟢 -3.21 kB
assets/useLoad3d-Uw8Yyv9h.js (new) 14.6 kB 🔴 +14.6 kB 🔴 +3.63 kB 🔴 +3.21 kB
assets/useLoad3dViewer-BcIe6i4M.js (removed) 14.1 kB 🟢 -14.1 kB 🟢 -3.15 kB 🟢 -2.8 kB
assets/useLoad3dViewer-Do9fmCDE.js (new) 14.1 kB 🔴 +14.1 kB 🔴 +3.15 kB 🔴 +2.8 kB
assets/colorUtil-BiqWg6CN.js (new) 7 kB 🔴 +7 kB 🔴 +2.15 kB 🔴 +1.9 kB
assets/colorUtil-C8II5OEy.js (removed) 7 kB 🟢 -7 kB 🟢 -2.14 kB 🟢 -1.89 kB
assets/useFeatureFlags--ngek1bF.js (new) 3.32 kB 🔴 +3.32 kB 🔴 +1.04 kB 🔴 +895 B
assets/useFeatureFlags-BGZCcwTj.js (removed) 3.32 kB 🟢 -3.32 kB 🟢 -1.04 kB 🟢 -898 B
assets/useWorkspaceUI-CoQ5LGYB.js (removed) 3.21 kB 🟢 -3.21 kB 🟢 -901 B 🟢 -776 B
assets/useWorkspaceUI-FG63YTkS.js (new) 3 kB 🔴 +3 kB 🔴 +825 B 🔴 +703 B
assets/useSubscriptionCredits-B4l9CbSt.js (removed) 2.75 kB 🟢 -2.75 kB 🟢 -1.04 kB 🟢 -902 B
assets/useSubscriptionCredits-CECd3Jd8.js (new) 2.75 kB 🔴 +2.75 kB 🔴 +1.04 kB 🔴 +897 B
assets/subscriptionCheckoutUtil-_w01Q7PK.js (new) 2.53 kB 🔴 +2.53 kB 🔴 +1.06 kB 🔴 +966 B
assets/subscriptionCheckoutUtil-CD9OzSv3.js (removed) 2.53 kB 🟢 -2.53 kB 🟢 -1.06 kB 🟢 -965 B
assets/useExternalLink-Bvw3SXtQ.js (new) 1.66 kB 🔴 +1.66 kB 🔴 +771 B 🔴 +683 B
assets/useExternalLink-vVGwWGrS.js (removed) 1.66 kB 🟢 -1.66 kB 🟢 -772 B 🟢 -681 B
assets/useCopyToClipboard-BzRlRR4y.js (new) 1.57 kB 🔴 +1.57 kB 🔴 +669 B 🔴 +573 B
assets/useCopyToClipboard-C0mKIHr0.js (removed) 1.57 kB 🟢 -1.57 kB 🟢 -671 B 🟢 -564 B
assets/markdownRendererUtil-CULTZH1z.js (removed) 1.56 kB 🟢 -1.56 kB 🟢 -813 B 🟢 -698 B
assets/markdownRendererUtil-DKmelI5u.js (new) 1.56 kB 🔴 +1.56 kB 🔴 +811 B 🔴 +695 B
assets/useErrorHandling-BC4V9gp9.js (new) 1.34 kB 🔴 +1.34 kB 🔴 +555 B 🔴 +480 B
assets/useErrorHandling-CiMCJsC5.js (removed) 1.34 kB 🟢 -1.34 kB 🟢 -557 B 🟢 -478 B
assets/useWorkspaceSwitch-B_2oAWaX.js (new) 1.25 kB 🔴 +1.25 kB 🔴 +543 B 🔴 +486 B
assets/useWorkspaceSwitch-D-Ou02Km.js (removed) 1.25 kB 🟢 -1.25 kB 🟢 -544 B 🟢 -479 B
assets/networkUtil-BSvcILBc.js (removed) 1.05 kB 🟢 -1.05 kB 🟢 -580 B 🟢 -492 B
assets/useLoad3d-uIF5_kEa.js (new) 908 B 🔴 +908 B 🔴 +447 B 🔴 +403 B
assets/useLoad3dViewer-CpUwLaFw.js (new) 887 B 🔴 +887 B 🔴 +431 B 🔴 +387 B
assets/useLoad3d-YfO32e3u.js (removed) 874 B 🟢 -874 B 🟢 -432 B 🟢 -385 B
assets/audioUtils-CqYTQOQT.js (new) 858 B 🔴 +858 B 🔴 +502 B 🔴 +405 B
assets/audioUtils-Dd-yiwlW.js (removed) 858 B 🟢 -858 B 🟢 -499 B 🟢 -424 B
assets/useLoad3dViewer-5t6q8jGL.js (removed) 853 B 🟢 -853 B 🟢 -417 B 🟢 -377 B
assets/useCurrentUser-Cg83Xvjv.js (new) 771 B 🔴 +771 B 🔴 +396 B 🔴 +347 B
assets/useCurrentUser-DgpLSVOF.js (removed) 737 B 🟢 -737 B 🟢 -384 B 🟢 -335 B
assets/envUtil-BHmbpOtd.js (new) 466 B 🔴 +466 B 🔴 +294 B 🔴 +250 B
assets/envUtil-DiXnWsaz.js (removed) 466 B 🟢 -466 B 🟢 -293 B 🟢 -238 B
assets/_plugin-vue_export-helper-BYZQdlgo.js (removed) 315 B 🟢 -315 B 🟢 -232 B 🟢 -201 B
assets/_plugin-vue_export-helper-CY4XIWDa.js (new) 315 B 🔴 +315 B 🔴 +232 B 🔴 +201 B
assets/SkeletonUtils-BputJAFn.js 133 B 133 B ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 19 added / 20 removed

Vendor & Third-Party — 8.69 MB (baseline 8.67 MB) • 🔴 +14.6 kB

External libraries and shared vendor chunks

File Before After Δ Raw Δ Gzip Δ Brotli
assets/vendor-primevue-B2JBnlqj.js (removed) 1.73 MB 🟢 -1.73 MB 🟢 -312 kB 🟢 -190 kB
assets/vendor-primevue-Bd8j9uVq.js (new) 1.73 MB 🔴 +1.73 MB 🔴 +311 kB 🔴 +190 kB
assets/vendor-other-CON5ZIHM.js (new) 1.52 MB 🔴 +1.52 MB 🔴 +318 kB 🔴 +253 kB
assets/vendor-other-LLCBDOBp.js (removed) 1.52 MB 🟢 -1.52 MB 🟢 -318 kB 🟢 -253 kB
assets/vendor-tiptap-Bi_34iZD.js (new) 625 kB 🔴 +625 kB 🔴 +146 kB 🔴 +119 kB
assets/vendor-tiptap-BSO55ms7.js (removed) 625 kB 🟢 -625 kB 🟢 -146 kB 🟢 -119 kB
assets/vendor-xterm-BmTVDX9J.js (removed) 374 kB 🟢 -374 kB 🟢 -75.5 kB 🟢 -61 kB
assets/vendor-xterm-Yc0APIKH.js (new) 374 kB 🔴 +374 kB 🔴 +75.5 kB 🔴 +61 kB
assets/vendor-reka-ui-B82zTENX.js (new) 255 kB 🔴 +255 kB 🔴 +51.4 kB 🔴 +42.5 kB
assets/vendor-reka-ui-C2SvlJE-.js (removed) 240 kB 🟢 -240 kB 🟢 -49 kB 🟢 -40.7 kB
assets/vendor-markdown-kbZC6x-r.js (removed) 102 kB 🟢 -102 kB 🟢 -24.8 kB 🟢 -22 kB
assets/vendor-markdown-uorjc_FY.js (new) 102 kB 🔴 +102 kB 🔴 +24.8 kB 🔴 +22 kB
assets/vendor-axios-C4mPrLmU.js 70.3 kB 70.3 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-BxsQv-KC.js 131 kB 131 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-vue-core-BjA-tjXK.js 311 kB 311 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-vueuse-Bg1iMAgF.js 111 kB 111 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-yjs-CBmk8HiD.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

Status: 6 added / 6 removed

Other — 7.27 MB (baseline 7.29 MB) • 🟢 -25.7 kB

Bundles that do not match a named category

File Before After Δ Raw Δ Gzip Δ Brotli
assets/i18n-BX0PwQ3_.js (removed) 493 kB 🟢 -493 kB 🟢 -94.4 kB 🟢 -73.6 kB
assets/i18n-Dm9iGMuO.js (new) 493 kB 🔴 +493 kB 🔴 +94.4 kB 🔴 +73.6 kB
assets/nodeDefs-DSVyZPu4.js (removed) 450 kB 🟢 -450 kB 🟢 -68.1 kB 🟢 -47 kB
assets/nodeDefs-wIPHF1fZ.js (new) 450 kB 🔴 +450 kB 🔴 +68.1 kB 🔴 +47 kB
assets/nodeDefs-BqyuNMBC.js (removed) 413 kB 🟢 -413 kB 🟢 -61.7 kB 🟢 -43.4 kB
assets/nodeDefs-IvRYJezo.js (new) 413 kB 🔴 +413 kB 🔴 +61.7 kB 🔴 +43.4 kB
assets/nodeDefs-CLUQETBH.js (removed) 412 kB 🟢 -412 kB 🟢 -64 kB 🟢 -45.1 kB
assets/nodeDefs-DpahK7ap.js (new) 412 kB 🔴 +412 kB 🔴 +64 kB 🔴 +45 kB
assets/nodeDefs-BMGl0iXU.js (new) 381 kB 🔴 +381 kB 🔴 +61.8 kB 🔴 +43.3 kB
assets/nodeDefs-CSMGnabZ.js (removed) 381 kB 🟢 -381 kB 🟢 -61.8 kB 🟢 -43.3 kB
assets/nodeDefs-C2HUVSxx.js (removed) 371 kB 🟢 -371 kB 🟢 -60.7 kB 🟢 -43 kB
assets/nodeDefs-TmpXOPjX.js (new) 371 kB 🔴 +371 kB 🔴 +60.7 kB 🔴 +43 kB
assets/nodeDefs-CN6u8ocX.js (removed) 367 kB 🟢 -367 kB 🟢 -59.3 kB 🟢 -43.4 kB
assets/nodeDefs-wVTOnsHW.js (new) 367 kB 🔴 +367 kB 🔴 +59.3 kB 🔴 +43.4 kB
assets/nodeDefs-DB5Ldc9N.js (removed) 367 kB 🟢 -367 kB 🟢 -60.8 kB 🟢 -44.2 kB
assets/nodeDefs-LSzl5dT5.js (new) 367 kB 🔴 +367 kB 🔴 +60.8 kB 🔴 +44.2 kB
assets/nodeDefs-B9XDI5Rs.js (removed) 364 kB 🟢 -364 kB 🟢 -58 kB 🟢 -42.4 kB
assets/nodeDefs-BUcgzgWQ.js (new) 364 kB 🔴 +364 kB 🔴 +58 kB 🔴 +42.4 kB
assets/nodeDefs-BD3OvPob.js (removed) 360 kB 🟢 -360 kB 🟢 -57.2 kB 🟢 -41.8 kB
assets/nodeDefs-C7n4a9EN.js (new) 360 kB 🔴 +360 kB 🔴 +57.2 kB 🔴 +41.8 kB
assets/nodeDefs-BK097ptO.js (removed) 338 kB 🟢 -338 kB 🟢 -59.2 kB 🟢 -41.7 kB
assets/nodeDefs-CrygT-T7.js (new) 338 kB 🔴 +338 kB 🔴 +59.2 kB 🔴 +41.7 kB
assets/nodeDefs-BLoFwHzM.js (removed) 335 kB 🟢 -335 kB 🟢 -58.2 kB 🟢 -40.5 kB
assets/nodeDefs-CM6prlTl.js (new) 335 kB 🔴 +335 kB 🔴 +58.2 kB 🔴 +40.5 kB
assets/main-QORGKgws.js (removed) 185 kB 🟢 -185 kB 🟢 -48.8 kB 🟢 -38.9 kB
assets/main-xAqSMOxB.js (new) 185 kB 🔴 +185 kB 🔴 +48.8 kB 🔴 +38.9 kB
assets/main-B_Yo8BwJ.js (removed) 166 kB 🟢 -166 kB 🟢 -44 kB 🟢 -35.9 kB
assets/main-CVbrt2xJ.js (new) 166 kB 🔴 +166 kB 🔴 +44 kB 🔴 +35.9 kB
assets/main-BDCMOE42.js (removed) 160 kB 🟢 -160 kB 🟢 -43.9 kB 🟢 -35.5 kB
assets/main-CYkJjz8b.js (new) 160 kB 🔴 +160 kB 🔴 +43.9 kB 🔴 +35.5 kB
assets/main-BARstPJ6.js (removed) 153 kB 🟢 -153 kB 🟢 -43.7 kB 🟢 -35.3 kB
assets/main-C57pQi_9.js (new) 153 kB 🔴 +153 kB 🔴 +43.7 kB 🔴 +35.2 kB
assets/main-3TCtshf_.js (new) 140 kB 🔴 +140 kB 🔴 +42.4 kB 🔴 +35.9 kB
assets/main-D7ArBIgD.js (removed) 140 kB 🟢 -140 kB 🟢 -42.4 kB 🟢 -35.9 kB
assets/main-8IrONIXi.js (new) 137 kB 🔴 +137 kB 🔴 +41.9 kB 🔴 +34.3 kB
assets/main-Gf0zFdA4.js (removed) 137 kB 🟢 -137 kB 🟢 -41.9 kB 🟢 -34.3 kB
assets/main-CTt9hO2a.js (new) 135 kB 🔴 +135 kB 🔴 +41.4 kB 🔴 +34.8 kB
assets/main-DX34Yjs_.js (removed) 135 kB 🟢 -135 kB 🟢 -41.4 kB 🟢 -34.8 kB
assets/main-BsG_6bQ8.js (removed) 133 kB 🟢 -133 kB 🟢 -41.2 kB 🟢 -34.9 kB
assets/main-Bwkwz3jD.js (new) 133 kB 🔴 +133 kB 🔴 +41.2 kB 🔴 +34.9 kB
assets/main-BVehLoqr.js (new) 132 kB 🔴 +132 kB 🔴 +40.7 kB 🔴 +34.4 kB
assets/main-D9VI25DN.js (removed) 132 kB 🟢 -132 kB 🟢 -40.7 kB 🟢 -34.4 kB
assets/main-CIhLd1Gi.js (new) 118 kB 🔴 +118 kB 🔴 +40.4 kB 🔴 +32.5 kB
assets/main-D5aT5-7X.js (removed) 118 kB 🟢 -118 kB 🟢 -40.4 kB 🟢 -32.5 kB
assets/main-CG07h4K5.js (new) 117 kB 🔴 +117 kB 🔴 +40.4 kB 🔴 +32.3 kB
assets/main-VRBzkgSu.js (removed) 117 kB 🟢 -117 kB 🟢 -40.4 kB 🟢 -32.3 kB
assets/core-losR3H7V.js (new) 72.4 kB 🔴 +72.4 kB 🔴 +18.6 kB 🔴 +16 kB
assets/core-LKaIG49h.js (removed) 72.4 kB 🟢 -72.4 kB 🟢 -18.6 kB 🟢 -16 kB
assets/groupNode-Bu9mSLk6.js (new) 72.1 kB 🔴 +72.1 kB 🔴 +17.7 kB 🔴 +15.6 kB
assets/groupNode-CrSErnOq.js (removed) 72.1 kB 🟢 -72.1 kB 🟢 -17.7 kB 🟢 -15.6 kB
assets/WidgetSelect-CoUT2nIB.js (new) 57.5 kB 🔴 +57.5 kB 🔴 +12.2 kB 🔴 +10.5 kB
assets/WidgetSelect-DIp80G77.js (removed) 57.5 kB 🟢 -57.5 kB 🟢 -12.2 kB 🟢 -10.5 kB
assets/SubscriptionRequiredDialogContentWorkspace-b_ZX6Tr1.js (new) 45.9 kB 🔴 +45.9 kB 🔴 +8.59 kB 🔴 +7.47 kB
assets/SubscriptionRequiredDialogContentWorkspace-Du-B49aW.js (removed) 45.8 kB 🟢 -45.8 kB 🟢 -8.57 kB 🟢 -7.45 kB
assets/SettingDialogContent-BPH8miuz.js (removed) 31.9 kB 🟢 -31.9 kB 🟢 -8.33 kB 🟢 -7.33 kB
assets/Load3DControls-BdEL9S0O.js (new) 30.9 kB 🔴 +30.9 kB 🔴 +5.34 kB 🔴 +4.64 kB
assets/Load3DControls-DrCPprGB.js (removed) 30.9 kB 🟢 -30.9 kB 🟢 -5.34 kB 🟢 -4.64 kB
assets/WorkspacePanelContent-coJCdhbX.js (new) 29.3 kB 🔴 +29.3 kB 🔴 +6.13 kB 🔴 +5.41 kB
assets/SubscriptionRequiredDialogContent-YzDKWvGz.js (new) 26.2 kB 🔴 +26.2 kB 🔴 +6.6 kB 🔴 +5.8 kB
assets/SubscriptionRequiredDialogContent-DFlRM9Wl.js (removed) 26.2 kB 🟢 -26.2 kB 🟢 -6.59 kB 🟢 -5.8 kB
assets/Load3dViewerContent-kr56xgr2.js (removed) 23.1 kB 🟢 -23.1 kB 🟢 -5.19 kB 🟢 -4.5 kB
assets/Load3dViewerContent-CHQDpz7O.js (new) 23.1 kB 🔴 +23.1 kB 🔴 +5.2 kB 🔴 +4.5 kB
assets/WidgetImageCrop-CmWXhksQ.js (new) 22.4 kB 🔴 +22.4 kB 🔴 +5.54 kB 🔴 +4.87 kB
assets/WidgetImageCrop-Uptjg3Bq.js (removed) 22.3 kB 🟢 -22.3 kB 🟢 -5.52 kB 🟢 -4.84 kB
assets/SubscriptionPanelContentWorkspace-C0Wgyrdl.js (removed) 21.6 kB 🟢 -21.6 kB 🟢 -5.02 kB 🟢 -4.43 kB
assets/SubscriptionPanelContentWorkspace-D6aszFh4.js (new) 21.6 kB 🔴 +21.6 kB 🔴 +5.02 kB 🔴 +4.44 kB
assets/FormItem-Cceh4Anp.js (removed) 20.2 kB 🟢 -20.2 kB 🟢 -4.86 kB 🟢 -4.25 kB
assets/CurrentUserPopoverWorkspace-BLPDitAN.js (new) 19.9 kB 🔴 +19.9 kB 🔴 +4.88 kB 🔴 +4.35 kB
assets/CurrentUserPopoverWorkspace-BgEFKCxg.js (removed) 19.8 kB 🟢 -19.8 kB 🟢 -4.86 kB 🟢 -4.33 kB
assets/SignInContent-s56JWOVt.js (removed) 19 kB 🟢 -19 kB 🟢 -4.81 kB 🟢 -4.21 kB
assets/SignInContent-BtoNkLgs.js (new) 19 kB 🔴 +19 kB 🔴 +4.81 kB 🔴 +4.21 kB
assets/commands-BNrOGgF0.js (removed) 18.4 kB 🟢 -18.4 kB 🟢 -3.93 kB 🟢 -3.05 kB
assets/commands-BrjHW_IV.js (new) 18.4 kB 🔴 +18.4 kB 🔴 +3.93 kB 🔴 +3.05 kB
assets/WidgetRecordAudio-Br0JSej6.js (new) 17.4 kB 🔴 +17.4 kB 🔴 +4.97 kB 🔴 +4.45 kB
assets/WidgetRecordAudio-e9jjXVJc.js (removed) 17.3 kB 🟢 -17.3 kB 🟢 -4.95 kB 🟢 -4.44 kB
assets/MissingModelsWarning-BEmRhC3z.js (new) 17.2 kB 🔴 +17.2 kB 🔴 +4.7 kB 🔴 +4.17 kB
assets/MissingModelsWarning-Tp9HzLFO.js (removed) 17.2 kB 🟢 -17.2 kB 🟢 -4.7 kB 🟢 -4.16 kB
assets/commands-C75oMQKS.js (removed) 17.2 kB 🟢 -17.2 kB 🟢 -3.63 kB 🟢 -2.84 kB
assets/commands-D1Ii1DEp.js (new) 17.2 kB 🔴 +17.2 kB 🔴 +3.63 kB 🔴 +2.83 kB
assets/commands-BuCfvdT4.js (new) 17.1 kB 🔴 +17.1 kB 🔴 +3.67 kB 🔴 +2.94 kB
assets/commands-syah9x10.js (removed) 17.1 kB 🟢 -17.1 kB 🟢 -3.67 kB 🟢 -2.94 kB
assets/commands-Cq5uT6l1.js (new) 16.6 kB 🔴 +16.6 kB 🔴 +3.71 kB 🔴 +2.92 kB
assets/commands-E7XryaaF.js (removed) 16.6 kB 🟢 -16.6 kB 🟢 -3.71 kB 🟢 -2.92 kB
assets/commands-CYe6qcqJ.js (removed) 16.3 kB 🟢 -16.3 kB 🟢 -3.46 kB 🟢 -2.88 kB
assets/commands-D_Nd488H.js (new) 16.3 kB 🔴 +16.3 kB 🔴 +3.46 kB 🔴 +2.88 kB
assets/Load3D-Ctc0cH8p.js (new) 16.2 kB 🔴 +16.2 kB 🔴 +4.04 kB 🔴 +3.53 kB
assets/Load3D-TvTT1UZF.js (removed) 16.2 kB 🟢 -16.2 kB 🟢 -4.04 kB 🟢 -3.52 kB
assets/WidgetInputNumber-DL4pN8jR.js (removed) 15.8 kB 🟢 -15.8 kB 🟢 -4.26 kB 🟢 -3.79 kB
assets/WidgetInputNumber-DN5msvW1.js (new) 15.8 kB 🔴 +15.8 kB 🔴 +4.26 kB 🔴 +3.8 kB
assets/commands-BaaH9k8-.js (removed) 15.8 kB 🟢 -15.8 kB 🟢 -3.45 kB 🟢 -2.85 kB
assets/commands-BNvNJ49l.js (new) 15.8 kB 🔴 +15.8 kB 🔴 +3.45 kB 🔴 +2.86 kB
assets/commands-BumftKwc.js (new) 15.8 kB 🔴 +15.8 kB 🔴 +3.35 kB 🔴 +2.75 kB
assets/commands-CC1YhlTZ.js (removed) 15.8 kB 🟢 -15.8 kB 🟢 -3.35 kB 🟢 -2.76 kB
assets/commands-BhzDZEGT.js (new) 15.7 kB 🔴 +15.7 kB 🔴 +3.31 kB 🔴 +2.78 kB
assets/commands-BYwUg0u3.js (removed) 15.7 kB 🟢 -15.7 kB 🟢 -3.31 kB 🟢 -2.77 kB
assets/commands-B2weSArC.js (removed) 15.5 kB 🟢 -15.5 kB 🟢 -3.58 kB 🟢 -2.81 kB
assets/commands-uLreJTDW.js (new) 15.5 kB 🔴 +15.5 kB 🔴 +3.58 kB 🔴 +2.81 kB
assets/commands-CxH3xT8b.js (new) 14.9 kB 🔴 +14.9 kB 🔴 +3.5 kB 🔴 +2.65 kB
assets/commands-DCB1KE7a.js (removed) 14.9 kB 🟢 -14.9 kB 🟢 -3.5 kB 🟢 -2.65 kB
assets/load3d-TiyVuabS.js (new) 14.8 kB 🔴 +14.8 kB 🔴 +4.21 kB 🔴 +3.64 kB
assets/load3d-DNgNSqad.js (removed) 14.8 kB 🟢 -14.8 kB 🟢 -4.2 kB 🟢 -3.63 kB
assets/commands-BA_pLDIO.js (new) 14.7 kB 🔴 +14.7 kB 🔴 +3.47 kB 🔴 +2.58 kB
assets/commands-rxQ7tYRq.js (removed) 14.7 kB 🟢 -14.7 kB 🟢 -3.47 kB 🟢 -2.58 kB
assets/LazyImage-AZixTo5D.js (removed) 12.3 kB 🟢 -12.3 kB 🟢 -3.8 kB 🟢 -3.33 kB
assets/LazyImage-Bl0O3IpO.js (new) 12.3 kB 🔴 +12.3 kB 🔴 +3.79 kB 🔴 +3.33 kB
assets/AudioPreviewPlayer-CnJ7aJw9.js (new) 10.9 kB 🔴 +10.9 kB 🔴 +3.22 kB 🔴 +2.87 kB
assets/AudioPreviewPlayer-CpIOnjr4.js (removed) 10.9 kB 🟢 -10.9 kB 🟢 -3.21 kB 🟢 -2.87 kB
assets/NodeConflictDialogContent-Dgzuk9ZR.js (new) 10.5 kB 🔴 +10.5 kB 🔴 +2.37 kB 🔴 +2.09 kB
assets/NodeConflictDialogContent-vjWWNdAC.js (removed) 10.5 kB 🟢 -10.5 kB 🟢 -2.35 kB 🟢 -2.07 kB
assets/changeTracker-B2y2rrjC.js (removed) 9.38 kB 🟢 -9.38 kB 🟢 -2.89 kB 🟢 -2.54 kB
assets/changeTracker-evEA8qcY.js (new) 9.38 kB 🔴 +9.38 kB 🔴 +2.89 kB 🔴 +2.55 kB
assets/nodeTemplates-D3SkMk0m.js (new) 9.35 kB 🔴 +9.35 kB 🔴 +3.28 kB 🔴 +2.88 kB
assets/nodeTemplates-BVBOXYMf.js (removed) 9.31 kB 🟢 -9.31 kB 🟢 -3.27 kB 🟢 -2.87 kB
assets/SelectValue-CdzHv1VF.js (new) 8.94 kB 🔴 +8.94 kB 🔴 +2.27 kB 🔴 +2 kB
assets/SelectValue-DBHUo1Qx.js (removed) 8.94 kB 🟢 -8.94 kB 🟢 -2.27 kB 🟢 -1.99 kB
assets/InviteMemberDialogContent-CaG7nBA8.js (new) 7.44 kB 🔴 +7.44 kB 🔴 +2.31 kB 🔴 +2.02 kB
assets/InviteMemberDialogContent-CvYMqVgJ.js (removed) 7.41 kB 🟢 -7.41 kB 🟢 -2.3 kB 🟢 -2 kB
assets/WidgetWithControl-DgMmCR63.js (new) 7.08 kB 🔴 +7.08 kB 🔴 +2.65 kB 🔴 +2.36 kB
assets/WidgetWithControl-BGuc6OOb.js (removed) 7.05 kB 🟢 -7.05 kB 🟢 -2.64 kB 🟢 -2.35 kB
assets/MissingNodesFooter-vldFvYZV.js (new) 6.75 kB 🔴 +6.75 kB 🔴 +2.3 kB 🔴 +2.06 kB
assets/MissingNodesFooter-B4KDCWxp.js (removed) 6.73 kB 🟢 -6.73 kB 🟢 -2.29 kB 🟢 -2.04 kB
assets/Load3DConfiguration-uIWhamxu.js (removed) 6.27 kB 🟢 -6.27 kB 🟢 -1.92 kB 🟢 -1.68 kB
assets/Load3DConfiguration-vp1ZyA4V.js (new) 6.27 kB 🔴 +6.27 kB 🔴 +1.91 kB 🔴 +1.68 kB
assets/MissingNodesContent-Bw7u1op6.js (new) 6.18 kB 🔴 +6.18 kB 🔴 +2.1 kB 🔴 +1.87 kB
assets/MissingNodesContent-cd2SGjSM.js (removed) 6.15 kB 🟢 -6.15 kB 🟢 -2.09 kB 🟢 -1.86 kB
assets/CreateWorkspaceDialogContent-DWr9RCOR.js (new) 5.58 kB 🔴 +5.58 kB 🔴 +2.01 kB 🔴 +1.76 kB
assets/CreateWorkspaceDialogContent-DKHy6Joh.js (removed) 5.55 kB 🟢 -5.55 kB 🟢 -2 kB 🟢 -1.75 kB
assets/EditWorkspaceDialogContent-CesViVaa.js (new) 5.38 kB 🔴 +5.38 kB 🔴 +1.97 kB 🔴 +1.72 kB
assets/EditWorkspaceDialogContent-SvzemAtJ.js (removed) 5.35 kB 🟢 -5.35 kB 🟢 -1.95 kB 🟢 -1.7 kB
assets/ValueControlPopover-I7zyMzNP.js (new) 4.97 kB 🔴 +4.97 kB 🔴 +1.79 kB 🔴 +1.61 kB
assets/ValueControlPopover-Z0einzMS.js (removed) 4.93 kB 🟢 -4.93 kB 🟢 -1.78 kB 🟢 -1.59 kB
assets/Preview3d-Djyet4sz.js (new) 4.86 kB 🔴 +4.86 kB 🔴 +1.59 kB 🔴 +1.39 kB
assets/CancelSubscriptionDialogContent-Bn8ZsyE2.js (new) 4.85 kB 🔴 +4.85 kB 🔴 +1.81 kB 🔴 +1.58 kB
assets/Preview3d-D40ZC6K6.js (removed) 4.83 kB 🟢 -4.83 kB 🟢 -1.58 kB 🟢 -1.37 kB
assets/CancelSubscriptionDialogContent-BGWEILJ3.js (removed) 4.81 kB 🟢 -4.81 kB 🟢 -1.79 kB 🟢 -1.57 kB
assets/AnimationControls-B9-AYA1O.js (new) 4.61 kB 🔴 +4.61 kB 🔴 +1.6 kB 🔴 +1.41 kB
assets/AnimationControls-C-b2wYkX.js (removed) 4.61 kB 🟢 -4.61 kB 🟢 -1.6 kB 🟢 -1.41 kB
assets/DeleteWorkspaceDialogContent-GVp6JErJ.js (new) 4.29 kB 🔴 +4.29 kB 🔴 +1.66 kB 🔴 +1.44 kB
assets/DeleteWorkspaceDialogContent-Bwdvtrz_.js (removed) 4.25 kB 🟢 -4.25 kB 🟢 -1.64 kB 🟢 -1.42 kB
assets/LeaveWorkspaceDialogContent-pP0ACuYm.js (new) 4.12 kB 🔴 +4.12 kB 🔴 +1.6 kB 🔴 +1.4 kB
assets/RemoveMemberDialogContent-Cqqtrz_o.js (new) 4.1 kB 🔴 +4.1 kB 🔴 +1.55 kB 🔴 +1.35 kB
assets/LeaveWorkspaceDialogContent-Ck_0ilB2.js (removed) 4.08 kB 🟢 -4.08 kB 🟢 -1.58 kB 🟢 -1.38 kB
assets/RemoveMemberDialogContent-D3rNiLit.js (removed) 4.06 kB 🟢 -4.06 kB 🟢 -1.53 kB 🟢 -1.33 kB
assets/RevokeInviteDialogContent-DoxtWZ8J.js (new) 4.01 kB 🔴 +4.01 kB 🔴 +1.56 kB 🔴 +1.38 kB
assets/RevokeInviteDialogContent-DWvmzBuD.js (removed) 3.98 kB 🟢 -3.98 kB 🟢 -1.55 kB 🟢 -1.36 kB
assets/InviteMemberUpsellDialogContent-COAA8_57.js (new) 3.88 kB 🔴 +3.88 kB 🔴 +1.43 kB 🔴 +1.25 kB
assets/InviteMemberUpsellDialogContent-Du4M8tpm.js (removed) 3.85 kB 🟢 -3.85 kB 🟢 -1.41 kB 🟢 -1.23 kB
assets/WidgetGalleria-DhRGcwZO.js (new) 3.61 kB 🔴 +3.61 kB 🔴 +1.4 kB 🔴 +1.25 kB
assets/WidgetGalleria-oXNsAZHB.js (removed) 3.61 kB 🟢 -3.61 kB 🟢 -1.39 kB 🟢 -1.25 kB
assets/Slider-BbekHBau.js (removed) 3.52 kB 🟢 -3.52 kB 🟢 -1.36 kB 🟢 -1.19 kB
assets/Slider-CW3Huad4.js (new) 3.52 kB 🔴 +3.52 kB 🔴 +1.36 kB 🔴 +1.19 kB
assets/saveMesh-BYIK4RkN.js (new) 3.43 kB 🔴 +3.43 kB 🔴 +1.48 kB 🔴 +1.31 kB
assets/saveMesh-BWzwWVxF.js (removed) 3.4 kB 🟢 -3.4 kB 🟢 -1.47 kB 🟢 -1.3 kB
assets/WidgetTextarea-bavVor9x.js (new) 3.18 kB 🔴 +3.18 kB 🔴 +1.31 kB 🔴 +1.16 kB
assets/WidgetTextarea-CDuK7I7Q.js (removed) 3.18 kB 🟢 -3.18 kB 🟢 -1.31 kB 🟢 -1.14 kB
assets/cloudSessionCookie-DXFKjtKN.js (new) 3.15 kB 🔴 +3.15 kB 🔴 +1.11 kB 🔴 +969 B
assets/cloudSessionCookie-g5hIjXT_.js (removed) 3.12 kB 🟢 -3.12 kB 🟢 -1.1 kB 🟢 -1 kB
assets/WidgetImageCompare-BB5_HE49.js (removed) 3.1 kB 🟢 -3.1 kB 🟢 -1.15 kB 🟢 -1 kB
assets/WidgetImageCompare-CJB-4oup.js (new) 3.1 kB 🔴 +3.1 kB 🔴 +1.15 kB 🔴 +1 kB
assets/GlobalToast-5F0wuANM.js (removed) 2.91 kB 🟢 -2.91 kB 🟢 -1.21 kB 🟢 -1.06 kB
assets/GlobalToast-DfzXcWY1.js (new) 2.91 kB 🔴 +2.91 kB 🔴 +1.21 kB 🔴 +1.06 kB
assets/WidgetColorPicker-BUNId5TS.js (new) 2.9 kB 🔴 +2.9 kB 🔴 +1.23 kB 🔴 +1.11 kB
assets/WidgetColorPicker-GkwCC4zW.js (removed) 2.9 kB 🟢 -2.9 kB 🟢 -1.23 kB 🟢 -1.11 kB
assets/WidgetMarkdown-CnTGrGUn.js (new) 2.88 kB 🔴 +2.88 kB 🔴 +1.22 kB 🔴 +1.06 kB
assets/WidgetMarkdown-Oxm2bkfb.js (removed) 2.88 kB 🟢 -2.88 kB 🟢 -1.22 kB 🟢 -1.06 kB
assets/ApiNodesSignInContent-CDj-EWo2.js (removed) 2.69 kB 🟢 -2.69 kB 🟢 -1.05 kB 🟢 -922 B
assets/ApiNodesSignInContent-DSVQKCl7.js (new) 2.69 kB 🔴 +2.69 kB 🔴 +1.05 kB 🔴 +964 B
assets/WidgetToggleSwitch-CYFSDGXH.js (new) 2.5 kB 🔴 +2.5 kB 🔴 +1.09 kB 🔴 +973 B
assets/WidgetToggleSwitch-Jkq5q2qU.js (removed) 2.5 kB 🟢 -2.5 kB 🟢 -1.09 kB 🟢 -971 B
assets/ImportFailedNodeContent-CarrrhMQ.js (removed) 2.48 kB 🟢 -2.48 kB 🟢 -970 B 🟢 -823 B
assets/ImportFailedNodeContent-CNb288kC.js (new) 2.48 kB 🔴 +2.48 kB 🔴 +971 B 🔴 +823 B
assets/NodeConflictFooter-Cfk5qbI9.js (new) 2.37 kB 🔴 +2.37 kB 🔴 +1.03 kB 🔴 +907 B
assets/NodeConflictFooter-CSCmq5Mp.js (removed) 2.37 kB 🟢 -2.37 kB 🟢 -1.03 kB 🟢 -911 B
assets/MediaVideoTop-C7I_Nivi.js (new) 2.23 kB 🔴 +2.23 kB 🔴 +938 B 🔴 +800 B
assets/MediaVideoTop-uMXngBYC.js (removed) 2.23 kB 🟢 -2.23 kB 🟢 -939 B 🟢 -801 B
assets/WidgetChart-B1i-QEjC.js (new) 2.21 kB 🔴 +2.21 kB 🔴 +953 B 🔴 +825 B
assets/WidgetChart-CAgBxfCv.js (removed) 2.21 kB 🟢 -2.21 kB 🟢 -952 B 🟢 -824 B
assets/SubscribeToRun-CZoJAmI7.js (removed) 2.2 kB 🟢 -2.2 kB 🟢 -1.01 kB 🟢 -893 B
assets/SubscribeToRun-H_0K6Dms.js (new) 2.2 kB 🔴 +2.2 kB 🔴 +1.01 kB 🔴 +887 B
assets/WidgetLayoutField-CLaC3IDH.js (new) 1.95 kB 🔴 +1.95 kB 🔴 +878 B 🔴 +764 B
assets/WidgetLayoutField-uBhtgiRo.js (removed) 1.95 kB 🟢 -1.95 kB 🟢 -876 B 🟢 -760 B
assets/ImportFailedNodeFooter-Brqi93bi.js (new) 1.88 kB 🔴 +1.88 kB 🔴 +868 B 🔴 +761 B
assets/ImportFailedNodeFooter-m_olYFXy.js (removed) 1.88 kB 🟢 -1.88 kB 🟢 -868 B 🟢 -757 B
assets/WidgetInputText-j2lExZrY.js (removed) 1.86 kB 🟢 -1.86 kB 🟢 -872 B 🟢 -789 B
assets/WidgetInputText-Ww-Tpbsi.js (new) 1.86 kB 🔴 +1.86 kB 🔴 +874 B 🔴 +796 B
assets/Media3DTop-CHdzdEY0.js (new) 1.82 kB 🔴 +1.82 kB 🔴 +900 B 🔴 +767 B
assets/Media3DTop-D4npDFVr.js (removed) 1.82 kB 🟢 -1.82 kB 🟢 -898 B 🟢 -769 B
assets/SettingDialogHeader-5Jp8WEzy.js (removed) 1.8 kB 🟢 -1.8 kB 🟢 -894 B 🟢 -809 B
assets/BaseViewTemplate-D1Wkn_Pz.js (new) 1.78 kB 🔴 +1.78 kB 🔴 +927 B 🔴 +804 B
assets/BaseViewTemplate-Dk4WDuio.js (removed) 1.78 kB 🟢 -1.78 kB 🟢 -926 B 🟢 -806 B
assets/MediaImageTop-DxQNM8VJ.js (new) 1.75 kB 🔴 +1.75 kB 🔴 +880 B 🔴 +751 B
assets/MediaImageTop-VR8ZNAgL.js (removed) 1.75 kB 🟢 -1.75 kB 🟢 -880 B 🟢 -751 B
assets/CloudRunButtonWrapper-B6KkKvk5.js (new) 1.72 kB 🔴 +1.72 kB 🔴 +811 B 🔴 +739 B
assets/CloudRunButtonWrapper-B4Z_EcYa.js (removed) 1.69 kB 🟢 -1.69 kB 🟢 -795 B 🟢 -720 B
assets/signInSchema-BHotMpO6.js (new) 1.53 kB 🔴 +1.53 kB 🔴 +563 B 🔴 +517 B
assets/signInSchema-DEDedNDs.js (removed) 1.53 kB 🟢 -1.53 kB 🟢 -563 B 🟢 -490 B
assets/MediaAudioTop-aTfN9fO4.js (new) 1.43 kB 🔴 +1.43 kB 🔴 +764 B 🔴 +636 B
assets/MediaAudioTop-DxrqFzPW.js (removed) 1.43 kB 🟢 -1.43 kB 🟢 -765 B 🟢 -635 B
assets/cloudBadges-DV4Go5pQ.js (new) 1.42 kB 🔴 +1.42 kB 🔴 +730 B 🔴 +628 B
assets/cloudBadges-Cy2SGqB7.js (removed) 1.38 kB 🟢 -1.38 kB 🟢 -718 B 🟢 -614 B
assets/cloudSubscription-C_2p0Wxs.js (new) 1.38 kB 🔴 +1.38 kB 🔴 +684 B 🔴 +586 B
assets/cloudSubscription-DDi-sCpK.js (removed) 1.34 kB 🟢 -1.34 kB 🟢 -668 B 🟢 -573 B
assets/PanelTemplate-B9lPSLJe.js (removed) 1.2 kB 🟢 -1.2 kB 🟢 -613 B 🟢 -534 B
assets/Load3D-DSK6qNo5.js (new) 1.12 kB 🔴 +1.12 kB 🔴 +521 B 🔴 +459 B
assets/widgetPropFilter-Cd0O5LPR.js (new) 1.1 kB 🔴 +1.1 kB 🔴 +510 B 🔴 +431 B
assets/widgetPropFilter-DVXr684F.js (removed) 1.1 kB 🟢 -1.1 kB 🟢 -512 B 🟢 -457 B
assets/NodeConflictHeader-BZ6UAUkz.js (removed) 1.09 kB 🟢 -1.09 kB 🟢 -567 B 🟢 -479 B
assets/NodeConflictHeader-Dw3rwJjr.js (new) 1.09 kB 🔴 +1.09 kB 🔴 +568 B 🔴 +477 B
assets/Load3D-DLN4ADKd.js (removed) 1.09 kB 🟢 -1.09 kB 🟢 -501 B 🟢 -447 B
assets/ImportFailedNodeHeader-CVRLPvz-.js (removed) 1.08 kB 🟢 -1.08 kB 🟢 -552 B 🟢 -468 B
assets/ImportFailedNodeHeader-LMkGR62F.js (new) 1.08 kB 🔴 +1.08 kB 🔴 +556 B 🔴 +509 B
assets/nightlyBadges--Wb1Dawj.js (new) 1.05 kB 🔴 +1.05 kB 🔴 +557 B 🔴 +493 B
assets/Load3dViewerContent-3q0x86bx.js (new) 1.04 kB 🔴 +1.04 kB 🔴 +489 B 🔴 +435 B
assets/nightlyBadges-Cy_WnALo.js (removed) 1.02 kB 🟢 -1.02 kB 🟢 -544 B 🟢 -483 B
assets/Load3dViewerContent-zw8w2otA.js (removed) 1.01 kB 🟢 -1.01 kB 🟢 -473 B 🟢 -421 B
assets/SubscriptionPanelContentWorkspace-D8c3HB1l.js (new) 979 B 🔴 +979 B 🔴 +460 B 🔴 +402 B
assets/SubscriptionPanelContentWorkspace-D7gQ9vtj.js (removed) 945 B 🟢 -945 B 🟢 -443 B 🟢 -388 B
assets/ComfyOrgHeader-COHzfhdj.js (removed) 910 B 🟢 -910 B 🟢 -497 B 🟢 -432 B
assets/ComfyOrgHeader-DAYiT6Xw.js (new) 910 B 🔴 +910 B 🔴 +498 B 🔴 +425 B
assets/SettingDialogContent-BSZdf1EP.js (removed) 887 B 🟢 -887 B 🟢 -428 B 🟢 -377 B
assets/changeTracker-Cx8WREi0.js (new) 806 B 🔴 +806 B 🔴 +408 B 🔴 +355 B
assets/WidgetLegacy-7Jw1FZ_l.js (new) 794 B 🔴 +794 B 🔴 +407 B 🔴 +356 B
assets/changeTracker-el3XamVg.js (removed) 772 B 🟢 -772 B 🟢 -393 B 🟢 -343 B
assets/graphHasMissingNodes-B_0FtdCy.js (new) 761 B 🔴 +761 B 🔴 +372 B 🔴 +315 B
assets/graphHasMissingNodes-m7ALglKM.js (removed) 761 B 🟢 -761 B 🟢 -374 B 🟢 -316 B
assets/WidgetLegacy-Bk_s3cQ7.js (removed) 760 B 🟢 -760 B 🟢 -395 B 🟢 -342 B
assets/previousFullPath-DChudpvH.js (removed) 665 B 🟢 -665 B 🟢 -367 B 🟢 -332 B
assets/previousFullPath-DEaITebJ.js (new) 665 B 🔴 +665 B 🔴 +367 B 🔴 +313 B
assets/constants-CLMaSJCl.js (removed) 579 B 🟢 -579 B 🟢 -256 B 🟢 -219 B
assets/constants-fZH7ZM7u.js (new) 579 B 🔴 +579 B 🔴 +256 B 🔴 +212 B
assets/WidgetInputNumber-DvWaGsaO.js (removed) 392 B 🟢 -392 B 🟢 -231 B 🟢 -210 B
assets/WidgetInputNumber-MtPbW-wn.js (new) 392 B 🔴 +392 B 🔴 +233 B 🔴 +197 B
assets/SettingDialogHeader-BTi0rBRx.js (removed) 345 B 🟢 -345 B 🟢 -210 B 🟢 -204 B
assets/src--CSlktKB.js (new) 251 B 🔴 +251 B 🔴 +212 B 🔴 +184 B
assets/src-C3JCjcCo.js (removed) 251 B 🟢 -251 B 🟢 -209 B 🟢 -196 B
assets/i18n-BpocuGHD.js (removed) 199 B 🟢 -199 B 🟢 -162 B 🟢 -139 B
assets/i18n-BxaBTfDw.js (new) 199 B 🔴 +199 B 🔴 +160 B 🔴 +138 B
assets/comfy-logo-single-C1jP7VA7.js (removed) 198 B 🟢 -198 B 🟢 -163 B 🟢 -132 B
assets/comfy-logo-single-IINhk7dd.js (new) 198 B 🔴 +198 B 🔴 +162 B 🔴 +135 B
assets/auto-BTnZwrs2.js 1.7 kB 1.7 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/MissingNodesHeader-BAZcszup.js 1.09 kB 1.09 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/OBJLoader2WorkerModule-DTMpvldF.js 109 kB 109 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/telemetry-Db2yG1o2.js 226 B 226 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/types-DT3N7am7.js 204 B 204 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/widget-BhHc6T04.js 445 B 445 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetBoundingBox-05_iDuzU.js 131 B 131 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetBoundingBox-JezhrbLj.js 3.91 kB 3.91 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/widgetTypes-Cp8f93Pk.js 393 B 393 B ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 117 added / 122 removed

@github-actions
Copy link
Copy Markdown

🔧 Auto-fixes Applied

This PR has been automatically updated to fix linting and formatting issues.

⚠️ Important: Your local branch is now behind. Run git pull before making additional changes to avoid conflicts.

Changes made:

  • ESLint auto-fixes
  • Oxfmt formatting

@viva-jinyi viva-jinyi force-pushed the refactor/setting-dialog branch from 2121c8a to c747132 Compare February 10, 2026 05:27
Copy link
Copy Markdown
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: 3

🤖 Fix all issues with AI agents
In `@browser_tests/tests/useSettingSearch.spec.ts`:
- Around line 53-55: Replace hardcoded '[data-testid="settings-dialog"]' locator
with the centralized TestIds constant: update the comfyPage.page.locator call
that assigns settingsDialog to use TestIds.dialogs.settings (import TestIds from
browser_tests/fixtures/selectors.ts) or, even better, refactor the test to use
the SettingDialog fixture class
(browser_tests/fixtures/components/SettingDialog.ts) which already encapsulates
the selector and interactions; ensure imports are added and all other
occurrences in this spec use TestIds.dialogs.settings or the SettingDialog
instance instead of the hardcoded string.

In `@src/platform/settings/components/ServerConfigPanel.vue`:
- Around line 27-33: The icon-only clipboard Button inside ServerConfigPanel.vue
lacks an accessible label; update the Button element that invokes
copyCommandLineArgs to include an aria-label (e.g., aria-label="Copy
command-line arguments") so screen readers can announce its purpose, and
optionally add a matching title attribute for hover/tooltips; locate the Button
that has size="icon", variant="muted-textonly" and `@click`="copyCommandLineArgs"
and add the aria-label there.

In `@src/platform/settings/components/SettingDialog.vue`:
- Around line 196-200: Remove the <style> block in SettingDialog.vue and stop
using !important; instead apply the max-width via a Tailwind class (e.g., add
max-w-[1400px] to the BaseModalLayout element or the wrapper rendered by
SettingsDialog) and remove the .settings-dialog.base-widget-layout CSS. For the
aspect-ratio override, inspect BaseModalLayout (the component that sets the base
aspect-ratio) and either fix its default, add/adjust a prop on BaseModalLayout
to control aspect-ratio, or override it with a non-!important Tailwind-friendly
approach (modify the base component rather than using !important in
SettingsDialog).
🧹 Nitpick comments (15)
src/components/dialog/GlobalDialog.vue (1)

87-97: Dead CSS: .settings-dialog-workspace rules are now unreachable.

The class settings-dialog-workspace was removed from the template binding on line 7, so these style rules will never match any element. They should be removed to avoid confusion.

♻️ Remove dead CSS
-/* Workspace mode: wider settings dialog */
-.settings-dialog-workspace {
-  width: 100%;
-  max-width: 1440px;
-  height: 100%;
-}
-
-.settings-dialog-workspace .p-dialog-content {
-  width: 100%;
-  height: 100%;
-  overflow-y: auto;
-}
src/platform/settings/components/ServerConfigPanel.vue (1)

86-93: Prefer function declarations over function expressions for non-closures.

revertChanges and restartApp could be function declarations per project conventions. restartApp does capture restartTriggered, but since it's a module-level let, a declaration would work too.

♻️ Suggested change
-const revertChanges = () => {
-  serverConfigStore.revertChanges()
-}
+function revertChanges() {
+  serverConfigStore.revertChanges()
+}

-const restartApp = async () => {
-  restartTriggered = true
-  await electronAPI().restartApp()
-}
+async function restartApp() {
+  restartTriggered = true
+  await electronAPI().restartApp()
+}
src/platform/workspace/composables/useWorkspaceUI.ts (1)

162-165: Stale JSDoc: "tab state" reference is no longer accurate.

The doc comment still mentions "ensure tab state is shared across components," but tab state was removed in this change.

📝 Suggested doc update
 /**
  * UI configuration composable derived from workspace state.
  * Controls what UI elements are visible/enabled based on role and workspace type.
- * Uses createSharedComposable to ensure tab state is shared across components.
+ * Uses createSharedComposable to ensure state is shared across components.
  */
src/components/sidebar/ComfyMenuButton.vue (1)

167-169: Type assertion masks a loose defaultPanel parameter type.

showSettings accepts string | undefined but settingsDialog.show() expects a specific union type. The as Parameters<...> cast silences the compiler but won't prevent invalid strings at runtime. Consider narrowing the parameter type to match the composable's expected type directly.

♻️ Suggested narrowing
-const showSettings = (defaultPanel?: string) => {
-  settingsDialog.show(defaultPanel as Parameters<typeof settingsDialog.show>[0])
+const showSettings = (defaultPanel?: Parameters<typeof settingsDialog.show>[0]) => {
+  settingsDialog.show(defaultPanel)
 }
browser_tests/tests/subgraph.spec.ts (1)

823-833: Use the centralized TestIds.dialogs.settings constant instead of hardcoded string.

Replace '[data-testid="settings-dialog"]' with the centralized selector from browser_tests/fixtures/selectors.ts. The constant is available as TestIds.dialogs.settings, which should be used to construct the full selector pattern: `[data-testid="${TestIds.dialogs.settings}"]`.

src/workbench/extensions/manager/composables/useManagerState.ts (1)

151-151: Consider hoisting useSettingsDialog() to the composable scope.

useSettingsDialog() is instantiated inside openManager on every call. Other migration sites (e.g., useCoreCommands.ts line 77) hoist the instance to the composable's top-level scope. Moving it next to useManagerDialog() at line 23 would be consistent and avoids repeated instantiation.

♻️ Suggested change
   const managerDialog = useManagerDialog()
+  const settingsDialog = useSettingsDialog()

   // ...

   const openManager = async (options?: {
     // ...
   }): Promise<void> => {
     const state = managerUIState.value
-    const settingsDialog = useSettingsDialog()
     const commandStore = useCommandStore()
src/stores/billingOperationStore.ts (1)

146-146: Consider hoisting useSettingsDialog() to the store scope for consistency.

useSettingsDialog() is instantiated inline on each handleSuccess call. Since this runs inside a defineStore setup (executed once), you could hoist it alongside other composable calls to match the pattern used in other migrated files.

♻️ Suggested change
 export const useBillingOperationStore = defineStore('billingOperation', () => {
   const operations = ref<Map<string, BillingOperation>>(new Map())
+  const settingsDialog = useSettingsDialog()
   // ...

   async function handleSuccess(opId: string) {
     // ...
-    useSettingsDialog().show('workspace')
+    settingsDialog.show('workspace')
browser_tests/fixtures/components/SettingDialog.ts (1)

39-45: Prefer a locator-based assertion over waitForSelector.

this.page.waitForSelector('.about-container') works but is less idiomatic than a retrying Playwright assertion. Consider:

Suggested change
   async goToAboutPanel() {
     const aboutButton = this.root.locator('nav [role="button"]', {
       hasText: 'About'
     })
     await aboutButton.click()
-    await this.page.waitForSelector('.about-container')
+    await expect(this.root.locator('.about-container')).toBeVisible()
   }

Note: you'll need to import expect from @playwright/test in this file.

As per coding guidelines: "In Playwright tests, do not use waitForTimeout; use Locator actions and retrying assertions instead." While waitForSelector is not waitForTimeout, the same principle of preferring retrying assertions applies.

browser_tests/tests/dialog.spec.ts (1)

284-295: Prefer locator-based assertions over waitForSelector.

Lines 284 and 293-295 use page.waitForSelector(...). Consider using await expect(locator).toBeVisible() for consistency with Playwright best practices.

Suggested change
-    await comfyPage.page.waitForSelector('[data-testid="settings-dialog"]')
+    const settingsDialog = comfyPage.page.locator('[data-testid="settings-dialog"]')
+    await expect(settingsDialog).toBeVisible()

     // Open the keybinding tab
-    const settingsDialog = comfyPage.page.locator(
-      '[data-testid="settings-dialog"]'
-    )
     await settingsDialog
       .locator('nav [role="button"]', { hasText: 'Keybinding' })
       .click()
-    await comfyPage.page.waitForSelector(
-      '[placeholder="Search Keybindings..."]'
-    )
+    await expect(
+      comfyPage.page.locator('[placeholder="Search Keybindings..."]')
+    ).toBeVisible()

As per coding guidelines, Playwright tests should prefer retrying assertions over imperative wait methods.

browser_tests/tests/useSettingSearch.spec.ts (1)

118-124: Category selection test may silently pass without asserting.

When categoryCount <= 1, the if block is skipped entirely and the test passes vacuously. Consider using test.skip or an explicit assumption (expect(categoryCount).toBeGreaterThan(1)) to make this visible in test reports rather than silently passing.

Also, asserting on a specific Tailwind class (bg-interface-menu-component-surface-selected) couples the test to styling implementation. A data-testid or aria-selected attribute on the active item would be more resilient.

src/platform/settings/composables/useSettingUI.ts (1)

352-368: Repeated type assertion for translatedLabel is a type smell.

The cast (group as SettingTreeNode & { translatedLabel?: string }).translatedLabel appears twice (Lines 355 and 360) because translateCategory augments nodes with translatedLabel but the arrays are typed as SettingTreeNode[], losing that information.

Consider defining a local type (e.g., TranslatedSettingTreeNode) or adjusting translateCategory's return type and the computed array types to avoid the inline assertion.

♻️ Suggested approach
+interface TranslatedSettingTreeNode extends SettingTreeNode {
+  translatedLabel?: string
+}
+
 const navGroups = computed<NavGroupData[]>(() =>
-    groupedMenuTreeNodes.value.map((group) => ({
+    (groupedMenuTreeNodes.value as TranslatedSettingTreeNode[]).map((group) => ({
       title:
-        (group as SettingTreeNode & { translatedLabel?: string })
-          .translatedLabel ?? group.label,
-      items: (group.children ?? []).map((child) => ({
+        group.translatedLabel ?? group.label,
+      items: ((group.children ?? []) as TranslatedSettingTreeNode[]).map((child) => ({
         id: child.key,
         label:
-          (child as SettingTreeNode & { translatedLabel?: string })
-            .translatedLabel ?? child.label,
+          child.translatedLabel ?? child.label,
         icon:
           CATEGORY_ICONS[child.key] ??
           CATEGORY_ICONS[child.label] ??
           'icon-[lucide--plug]'
       }))
     }))
   )
src/components/dialog/content/setting/WorkspacePanelContent.vue (1)

58-62: Use cn() utility instead of :class="[]" array syntax.

The coding guidelines state: "Use cn() utility from @/utils/tailwindUtil to merge class names; never use :class="[]" syntax."

♻️ Proposed fix
-              :class="[
-                'flex items-center gap-2 px-3 py-2',
-                item.class,
-                item.disabled ? 'pointer-events-auto' : ''
-              ]"
+              :class="
+                cn(
+                  'flex items-center gap-2 px-3 py-2',
+                  item.class,
+                  item.disabled && 'pointer-events-auto'
+                )
+              "

You'll also need to import cn:

import { cn } from '@/utils/tailwindUtil'

As per coding guidelines: "Use cn() utility from @/utils/tailwindUtil to merge class names; never use :class="[]" syntax."

src/platform/settings/components/SettingDialog.vue (3)

87-87: Avoid new PrimeVue component usage — Tag from primevue/tag.

This is a new file introducing a PrimeVue Tag import. The coding guidelines state "Avoid new usage of PrimeVue components." Consider using an existing design system tag component or a simple styled <span> instead.

As per coding guidelines: "Avoid new usage of PrimeVue components."


27-29: v-model:model-value is redundant — use v-model directly.

v-model:model-value="searchQuery" is equivalent to v-model="searchQuery" since modelValue is the default v-model prop.

♻️ Simplification
         <SearchBox
-          v-model:model-value="searchQuery"
+          v-model="searchQuery"
           size="md"

155-156: Math.max(0, ...spread) on potentially large arrays.

flattenTree<SettingParams>(group).map(...) spreads an entire array into Math.max. For very large settings trees, this could exceed the call stack limit. In practice, settings categories are small, so this is unlikely to be an issue—but reduce would be safer if the data scale is uncertain.

♻️ Safer alternative
-const getGroupSortOrder = (group: SettingTreeNode): number =>
-  Math.max(0, ...flattenTree<SettingParams>(group).map((s) => s.sortOrder ?? 0))
+const getGroupSortOrder = (group: SettingTreeNode): number =>
+  flattenTree<SettingParams>(group).reduce(
+    (max, s) => Math.max(max, s.sortOrder ?? 0),
+    0
+  )

Comment on lines +196 to +200
<style>
.settings-dialog.base-widget-layout {
max-width: 1400px;
aspect-ratio: auto !important;
}
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot Feb 10, 2026

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major

!important and <style> block violate coding guidelines.

The guidelines state: "Never use !important" and "Use Tailwind CSS for styling; avoid <style> blocks." The aspect-ratio: auto !important; overrides a base style from BaseModalLayout—consider fixing the source of the conflicting style instead.

For max-width, a Tailwind class can be used directly on the component (e.g., max-w-[1400px]).

♻️ Proposed approach

Remove the <style> block and apply the max-width via Tailwind on the BaseModalLayout:

   <BaseModalLayout
     content-title=""
     data-testid="settings-dialog"
-    class="settings-dialog"
+    class="max-w-[1400px]"
   >

For the aspect-ratio: auto, investigate what BaseModalLayout sets and override it properly (e.g., via a prop or by fixing the base component's default).

As per coding guidelines: "Never use !important or the ! important prefix for Tailwind classes; instead find and correct interfering existing !important classes" and "Use Tailwind CSS for styling in Vue components; avoid <style> blocks."

🤖 Prompt for AI Agents
In `@src/platform/settings/components/SettingDialog.vue` around lines 196 - 200,
Remove the <style> block in SettingDialog.vue and stop using !important; instead
apply the max-width via a Tailwind class (e.g., add max-w-[1400px] to the
BaseModalLayout element or the wrapper rendered by SettingsDialog) and remove
the .settings-dialog.base-widget-layout CSS. For the aspect-ratio override,
inspect BaseModalLayout (the component that sets the base aspect-ratio) and
either fix its default, add/adjust a prop on BaseModalLayout to control
aspect-ratio, or override it with a non-!important Tailwind-friendly approach
(modify the base component rather than using !important in SettingsDialog).

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.

There's got to be a better way

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.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Find and examine the BaseModalLayout component
cat src/components/widget/layout/BaseModalLayout.vue

Length of output: 6481


@DrJKL, absolutely! Here's the better way:

The root cause is that BaseModalLayout's scoped style sets aspect-ratio: 20/13 which has higher specificity due to Vue's scoped attribute mechanism. Here are two solutions:

Quick Fix: Use Tailwind on the Root Element

Since a child component's root node will be affected by both the parent's scoped CSS and the child's scoped CSS, you can apply Tailwind classes directly:

<BaseModalLayout
  content-title=""
  data-testid="settings-dialog"
  class="aspect-auto max-w-[1400px]"
>

Remove the <style> block entirely. The aspect-auto Tailwind class sets aspect-ratio: auto and should work because it's applied to the root element.

Better Fix: Add Props to BaseModalLayout

Modify BaseModalLayout.vue to accept optional props for controlling dimensions:

<!-- BaseModalLayout.vue -->
<script setup lang="ts">
const { 
  contentTitle, 
  rightPanelTitle,
  autoAspectRatio = false,  // New prop
  maxWidth  // New optional prop
} = defineProps<{
  contentTitle: string
  rightPanelTitle?: string
  autoAspectRatio?: boolean
  maxWidth?: string
}>()
</script>

<style scoped>
.base-widget-layout {
  height: 80vh;
  width: 90vw;
  max-width: 1280px;
}

.base-widget-layout:not(.auto-aspect) {
  aspect-ratio: 20/13;
}

`@media` (min-width: 1450px) {
  .base-widget-layout {
    max-width: 1724px;
  }
}
</style>

Then use it in SettingDialog:

<BaseModalLayout
  content-title=""
  data-testid="settings-dialog"
  :auto-aspect-ratio="true"
  max-width="1400px"
>

The prop-based approach is cleaner and makes BaseModalLayout more reusable. Which approach would you prefer?


🧠 Learnings used
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 8256
File: src/components/widget/layout/BaseModalLayout.vue:39-47
Timestamp: 2026-01-24T00:06:25.318Z
Learning: In `src/components/widget/layout/BaseModalLayout.vue`, the left panel toggle button conditions are intentionally different for mobile vs desktop. The "show left panel" button uses `!notMobile && !showLeftPanel` to appear only on mobile devices when the panel is hidden, which is the intended mobile-first design pattern.

Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 8256
File: src/components/widget/layout/BaseModalLayout.vue:20-28
Timestamp: 2026-01-24T00:07:58.981Z
Learning: In `src/components/widget/layout/BaseModalLayout.vue`, the left panel toggle buttons are intentionally mobile-only. The hide button (line 20) uses `!notMobile && showLeftPanel` and the show button (line 40) uses `!notMobile && !showLeftPanel`. On desktop, the left panel is persistent and doesn't need toggle controls.

Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-02-03T20:30:57.039Z
Learning: Applies to **/*.{vue,ts,tsx} : Never use `!important` or the `!` important prefix for Tailwind classes; instead find and correct interfering existing `!important` classes

Learnt from: jtydhr88
Repo: Comfy-Org/ComfyUI_frontend PR: 7621
File: src/components/load3d/Load3DScene.vue:4-4
Timestamp: 2025-12-18T20:39:30.137Z
Learning: In src/components/load3d/Load3DScene.vue, the scoped `<style>` block with `!important` declarations for the canvas element is necessary because Three.js dynamically creates the canvas with inline styles, preventing direct application of Tailwind classes. This is a valid exception to the Tailwind-only styling guideline.

Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-02-03T20:30:57.039Z
Learning: Applies to **/*.{vue,ts,tsx} : Never use arbitrary percentage values like `w-[80%]` when a Tailwind fraction utility exists; use `w-4/5` instead of `w-[80%]`, `w-1/2` instead of `w-[50%]`, etc.

Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-02-03T20:30:57.039Z
Learning: Applies to **/*.vue : Use Tailwind 4 for styling in Vue components; avoid `<style>` blocks

Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-02-03T20:30:57.039Z
Learning: Applies to **/*.{vue,ts,tsx} : Never use `dark:` Tailwind variant; use semantic values from `style.css` theme instead (e.g., `bg-node-component-surface`)

Learnt from: benceruleanlu
Repo: Comfy-Org/ComfyUI_frontend PR: 7297
File: src/components/actionbar/ComfyActionbar.vue:33-43
Timestamp: 2025-12-09T21:40:19.792Z
Learning: In the Comfy-Org/ComfyUI_frontend repository, inline Tailwind CSS class strings, even when long, are acceptable and preferred over extracting them to computed properties when the classes are static. This is a common Tailwind pattern and doesn't need to be flagged as a readability issue.

@viva-jinyi viva-jinyi added the New Browser Test Expectations New browser test screenshot should be set by github action label Feb 10, 2026
Copy link
Copy Markdown
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

🤖 Fix all issues with AI agents
In `@src/platform/settings/components/SettingDialog.vue`:
- Around line 17-22: Replace the PrimeVue <Tag> usage in SettingDialog.vue (the
v-if check on isStaging that renders Tag) with a plain element styled using your
design system/Tailwind: remove the import/usage of 'primevue/tag', render a
<span> (or design-system component) when isStaging is true, apply appropriate
Tailwind classes for background, text, padding and rounded corners to mimic a
badge, and use your semantic color tokens (avoid dark: variants) so the badge
matches the app styles.
- Line 144: Add a watch to keep activeCategoryKey in sync with the computed
defaultCategory so it updates when feature flags/settings load asynchronously:
inside the component, call watch on defaultCategory and when newCategory is
truthy and searchQuery.value is empty, set activeCategoryKey.value =
newCategory.key; reference the existing refs/computed names activeCategoryKey,
defaultCategory, and searchQuery so the active category only auto-updates when
the user is not actively searching.
🧹 Nitpick comments (3)
src/platform/settings/components/SettingDialog.vue (3)

28-28: v-model:model-value is redundant — use v-model directly.

v-model:model-value is equivalent to v-model but reads awkwardly and is non-idiomatic. Vue's v-model already binds to modelValue by default.

♻️ Proposed fix
-        <SearchBox
-          v-model:model-value="searchQuery"
+        <SearchBox
+          v-model="searchQuery"

209-222: Watcher on activeCategoryKey writes back to itself — potential infinite trigger.

Line 211 assigns to activeCategoryKey.value inside its own watcher. Vue 3 does guard against infinite recursion for synchronous self-writes, but this is still a code smell that makes the data flow hard to reason about — a reader can't easily tell when the watcher re-fires.

Consider moving the "restore previous key" logic into the functions that clear activeCategoryKey (e.g., handleSearch, the searchResultsCategories watcher) rather than relying on a self-referencing watcher.

Additionally, line 219 uses querySelector with an interpolated newKey:

?.querySelector(`[data-nav-id="${newKey}"]`)

If newKey ever contains quotes or brackets (e.g., from user/extension-provided IDs), this breaks or could cause unexpected behavior. Consider using querySelector with CSS.escape(newKey) or document.querySelector with an attribute-value match via Element.matches.

♻️ Safer selector
      void nextTick(() => {
-       navRef.value
-         ?.querySelector(`[data-nav-id="${newKey}"]`)
-         ?.scrollIntoView({ block: 'nearest', behavior: 'smooth' })
+       const escaped = CSS.escape(newKey)
+       navRef.value
+         ?.querySelector(`[data-nav-id="${escaped}"]`)
+         ?.scrollIntoView({ block: 'nearest', behavior: 'smooth' })
      })

146-155: Search-result category matching relies on label comparison — should use key.

searchResultsCategories is a Set of category labels (strings), and line 152 matches via node.label. This has the same fragility concern as the template comparisons — if searchResultsCategories could use keys instead of labels, the match would be more robust.

@github-actions
Copy link
Copy Markdown

Updating Playwright Expectations

@github-actions github-actions bot removed the New Browser Test Expectations New browser test screenshot should be set by github action label Feb 10, 2026
@viva-jinyi viva-jinyi marked this pull request as ready for review February 10, 2026 07:37
  - WorkspacePanelContent: use semantic <header>/<button>, simplify member count,
   replace :class="[]" with cn()
  - useSettingUI: sort CATEGORY_ICONS keys alphabetically
  - types.ts: sort SettingPanelType union members alphabetically
@viva-jinyi viva-jinyi assigned DrJKL and unassigned viva-jinyi Feb 11, 2026
@viva-jinyi viva-jinyi added the New Browser Test Expectations New browser test screenshot should be set by github action label Feb 11, 2026
@github-actions github-actions bot removed the New Browser Test Expectations New browser test screenshot should be set by github action label Feb 11, 2026
DrJKL
DrJKL previously approved these changes Feb 11, 2026
Copy link
Copy Markdown
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: 1

🤖 Fix all issues with AI agents
In `@src/components/dialog/content/setting/WorkspacePanelContent.vue`:
- Around line 134-139: The Tailwind class `text-bold` used in the
tabTriggerActive constant is invalid; update the tabTriggerActive string
(alongside tabTriggerBase/tabTriggerInactive references if needed) to replace
`text-bold` with the correct utility `font-bold` so the active tab text renders
bold.
🧹 Nitpick comments (8)
browser_tests/tests/subgraph.spec.ts (1)

829-840: Replace hardcoded selector strings with centralized TestIds.

The [data-testid="settings-dialog"] selector is hardcoded in two places. Use TestIds.dialogs.settings from browser_tests/fixtures/selectors.ts instead, following the pattern used across other test files in the project.

Add the import:

import { TestIds } from '../fixtures/selectors'

Then replace both occurrences with [data-testid="${TestIds.dialogs.settings}"] or use the locator directly: comfyPage.page.locator([data-testid="${TestIds.dialogs.settings}"]).

src/platform/settings/composables/useSettingUI.ts (2)

372-388: Repeated type assertion for translatedLabel — consider a local type alias.

The as SettingTreeNode & { translatedLabel?: string } cast appears twice (lines 375 and 380). Since translateCategory augments nodes with translatedLabel, a small type alias would eliminate the inline casts and improve readability.

♻️ Suggested improvement

Define at the top of the file (near SettingPanelItem):

type TranslatedSettingTreeNode = SettingTreeNode & { translatedLabel?: string }

Then use it in navGroups:

  const navGroups = computed<NavGroupData[]>(() =>
    groupedMenuTreeNodes.value.map((group) => ({
      title:
-       (group as SettingTreeNode & { translatedLabel?: string })
-         .translatedLabel ?? group.label,
+       (group as TranslatedSettingTreeNode).translatedLabel ?? group.label,
      items: (group.children ?? []).map((child) => ({
        id: child.key,
        label:
-         (child as SettingTreeNode & { translatedLabel?: string })
-           .translatedLabel ?? child.label,
+         (child as TranslatedSettingTreeNode).translatedLabel ?? child.label,
        icon:
          CATEGORY_ICONS[child.key] ??
          CATEGORY_ICONS[child.label] ??
          'icon-[lucide--plug]'
      }))
    }))
  )

Even better, update translateCategory's return type to TranslatedSettingTreeNode so the groups are already properly typed and no cast is needed.


20-37: CATEGORY_ICONS keys mix labels and panel keys — consider documenting the convention.

The map uses a mix of display labels ('Appearance', 'Comfy', '3D') and panel keys ('about', 'credits', 'server-config'). The navGroups computed correctly falls back from child.key to child.label, but this dual-lookup convention is implicit. A brief inline note would help future contributors understand why both forms are present.

src/platform/settings/components/SettingDialog.vue (3)

10-11: Simplify v-model:model-value to v-model.

v-model:model-value is equivalent to v-model in Vue 3. The explicit form is redundant here.

♻️ Proposed fix
         <SearchBox
-          v-model:model-value="searchQuery"
+          v-model="searchQuery"
           size="md"

146-147: Use a function declaration instead of a function expression.

Per coding guidelines, prefer function declarations over function expressions when possible.

♻️ Proposed fix
-const getGroupSortOrder = (group: SettingTreeNode): number =>
-  Math.max(0, ...flattenTree<SettingParams>(group).map((s) => s.sortOrder ?? 0))
+function getGroupSortOrder(group: SettingTreeNode): number {
+  return Math.max(0, ...flattenTree<SettingParams>(group).map((s) => s.sortOrder ?? 0))
+}

As per coding guidelines: "Do not use function expressions if it's possible to use function declarations instead."


185-199: Side-effect–heavy watcher mixes unrelated concerns.

This single watcher handles three distinct responsibilities: preventing null resets, fetching balance for credits, and scrolling the nav item into view. Consider splitting into focused watchers for clarity, though this is a minor readability nit.

src/components/dialog/content/setting/WorkspacePanelContent.vue (2)

141-143: Consider narrowing defaultTab to a union type.

defaultTab accepts any string, but only 'plan' and 'members' are valid tab values. A literal union would catch typos at compile time and improve discoverability.

Proposed fix
-const { defaultTab = 'plan' } = defineProps<{
-  defaultTab?: string
-}>()
+type WorkspaceTab = 'plan' | 'members'
+
+const { defaultTab = 'plan' } = defineProps<{
+  defaultTab?: WorkspaceTab
+}>()

117-117: PrimeVue Menu retained — consider migrating in a follow-up.

The Menu import from primevue/menu is pre-existing usage being preserved during this migration, which is reasonable for scope. A follow-up to replace it with a Reka UI equivalent (e.g., DropdownMenu) would complete the PrimeVue removal for this component. Based on learnings: "Avoid new usage of PrimeVue components."

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
DrJKL
DrJKL previously approved these changes Feb 12, 2026
@viva-jinyi viva-jinyi added the New Browser Test Expectations New browser test screenshot should be set by github action label Feb 12, 2026
@github-actions github-actions bot removed the New Browser Test Expectations New browser test screenshot should be set by github action label Feb 12, 2026
DrJKL
DrJKL previously approved these changes Feb 12, 2026
@viva-jinyi viva-jinyi added the New Browser Test Expectations New browser test screenshot should be set by github action label Feb 12, 2026
@github-actions github-actions bot removed the New Browser Test Expectations New browser test screenshot should be set by github action label Feb 12, 2026
@viva-jinyi viva-jinyi merged commit 553ea63 into main Feb 12, 2026
28 checks passed
@viva-jinyi viva-jinyi deleted the refactor/setting-dialog branch February 12, 2026 07:27
viva-jinyi added a commit that referenced this pull request Feb 15, 2026
## Summary
Restores the scroll-to-setting and highlight animation that was lost
during the BaseModalLayout migration in #8270. Originally implemented in
#8761.

## Changes
- **What**: Re-added scroll-into-view + pulse highlight logic and CSS
animation to `SettingDialog.vue`, ported from the deleted
`SettingDialogContent.vue`

Fixes #3437

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-8833-bugfix-Restore-scroll-to-setting-in-SettingDialog-3056d73d36508161abeee047a40dc1e5)
by [Unito](https://www.unito.io)
@dosubot dosubot bot mentioned this pull request Feb 16, 2026
2 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:settings enhancement New feature or request size:XL This PR changes 500-999 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants