Skip to content

feat(workspace): add per-member monthly credit limit UI (FE-1277)#13716

Open
dante01yoon wants to merge 6 commits into
mainfrom
jaewon/fe-1277-settings-members-per-member-monthly-credit-limit-ui-owner
Open

feat(workspace): add per-member monthly credit limit UI (FE-1277)#13716
dante01yoon wants to merge 6 commits into
mainfrom
jaewon/fe-1277-settings-members-per-member-monthly-credit-limit-ui-owner

Conversation

@dante01yoon

@dante01yoon dante01yoon commented Jul 16, 2026

Copy link
Copy Markdown
Collaborator

Summary

UI prototype: #13653
Owners can set or clear an optional monthly credit limit per workspace member from Settings > Members, so no single member consumes a disproportionate share of the shared credit pool. UI only; backend persistence and enforcement are tracked in FE-1278.

Changes

  • What:
    • SetMemberCreditLimitDialogContent.vue — radio "Limit monthly credit usage to" + amount, or "No limit"; positive safe-integer validation; warning when the proposed cap is at or below usage already spent
    • Members table gains a Credits used this month column — capped rows show used / limit with a usage progress bar, uncapped rows show usage only
    • Row overflow menu gains Set credit limit; the workspace creator and the current user get a self-cap-only menu, members see no actions
    • teamWorkspaceStore.setMemberCreditLimit (local-only) + optional monthlyCreditLimit / creditsUsedThisMonth on the member model
  • Breaking: none

Review Focus

  • All new credit-limit UI surfaces are gated by the existing billing_control_enabled flag through flags.billingControlEnabled; while disabled, the Members panel remains unchanged until FE-1278 provides persistence and enforcement.
  • Built on the existing owner | member role model. The Admin role remains out of scope (deferred, per the Slack decision thread); role labels/submenu are unchanged.
  • The menu-visibility gate on MemberListItem moves from !isCurrentUser && !isOriginalOwner to menuItems.length > 0, so owners can now cap themselves and the creator (DES-504 permits self-caps).
  • creditsUsedThisMonth has no backend source yet, so usage renders as 0 until real usage lands (DES-479 / FE-1249); the "Last activity" column and credits sorting are out of scope here.
  • Prototype PR feat(workspace): add per-member credit limits #13655 was reference only; this is reimplemented on a fresh branch off main.

screenshots

1-dialog-existing-limit 2-dialog-no-limit 3-dialog-over-usage-warning 4-members-table-capped-and-uncapped 5-row-menu-set-credit-limit

Owners can set or clear an optional monthly credit limit per workspace
member from Settings > Members, so no single member consumes a
disproportionate share of the shared credit pool.

- Set credit limit dialog: radio "limit to" amount / "no limit", with
  positive safe-integer validation and a warning when the proposed cap
  is at or below usage already spent
- Members table gains a "Credits used this month" column: capped rows
  show used / limit with a usage progress bar, uncapped rows show usage
- Row overflow menu gains "Set credit limit"; the creator and the
  current user get a self-cap-only menu, members see no actions
- Local-only store action; backend persistence and runtime enforcement
  are tracked separately (FE-1278)

Built on the existing owner|member role model; the Admin role remains
out of scope.
@dante01yoon
dante01yoon requested a review from a team July 16, 2026 16:50
@dosubot dosubot Bot added the size:L This PR changes 100-499 lines, ignoring generated files. label Jul 16, 2026
@github-actions

github-actions Bot commented Jul 16, 2026

Copy link
Copy Markdown

🎨 Storybook: ✅ Built — View Storybook

Details

⏰ Completed at: 07/17/2026, 10:11:30 PM UTC

Links

🎭 Playwright: ✅ 1713 passed, 0 failed · 2 flaky

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

📦 Bundle: 7.91 MB gzip 🔴 +3.16 kB

Details

Summary

  • Raw size: 33.4 MB baseline 33.4 MB — 🔴 +13.7 kB
  • Gzip: 7.91 MB baseline 7.91 MB — 🔴 +3.16 kB
  • Brotli: 5.46 MB baseline 5.45 MB — 🔴 +2.88 kB
  • Bundles: 303 current • 302 baseline • 214 added / 213 removed

Category Glance
Other 🔴 +12.7 kB (11.9 MB) · Utilities & Hooks 🔴 +921 B (3.4 MB) · Vendor & Third-Party 🔴 +21 B (15.7 MB) · Graph Workspace 🔴 +1 B (1.25 MB) · Panels & Settings 🔴 +1 B (550 kB) · Editors & Dialogs 🔴 +1 B (121 kB) · + 5 more

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

Main entry bundles and manifests

File Before After Δ Raw Δ Gzip Δ Brotli
assets/index-DILAZwoA.js (new) 47.3 kB 🔴 +47.3 kB 🔴 +14 kB 🔴 +12.1 kB
assets/index-JlzmmnQG.js (removed) 47.3 kB 🟢 -47.3 kB 🟢 -14.1 kB 🟢 -12.2 kB

Status: 1 added / 1 removed

Graph Workspace — 1.25 MB (baseline 1.25 MB) • 🔴 +1 B

Graph editor runtime, canvas, workflow orchestration

File Before After Δ Raw Δ Gzip Δ Brotli
assets/GraphView-O5jAFHEO.js (new) 1.25 MB 🔴 +1.25 MB 🔴 +266 kB 🔴 +200 kB
assets/GraphView-XGmZHAUY.js (removed) 1.25 MB 🟢 -1.25 MB 🟢 -266 kB 🟢 -200 kB

Status: 1 added / 1 removed

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

Top-level views, pages, and routed surfaces

File Before After Δ Raw Δ Gzip Δ Brotli
assets/CloudSurveyView-B2QURLEn.js (new) 25 kB 🔴 +25 kB 🔴 +6.25 kB 🔴 +5.52 kB
assets/CloudSurveyView-Dt1lJNwI.js (removed) 25 kB 🟢 -25 kB 🟢 -6.26 kB 🟢 -5.53 kB
assets/OAuthConsentView-B1dKWaRM.js (removed) 15 kB 🟢 -15 kB 🟢 -4.1 kB 🟢 -3.57 kB
assets/OAuthConsentView-CMm4AxWr.js (new) 15 kB 🔴 +15 kB 🔴 +4.09 kB 🔴 +3.57 kB
assets/CloudLoginView-DHPtZRfJ.js (new) 11.4 kB 🔴 +11.4 kB 🔴 +3.07 kB 🔴 +2.7 kB
assets/CloudLoginView-DNB8NSyf.js (removed) 11.4 kB 🟢 -11.4 kB 🟢 -3.07 kB 🟢 -2.69 kB
assets/CloudSignupView-B9CublT9.js (removed) 9.79 kB 🟢 -9.79 kB 🟢 -2.74 kB 🟢 -2.4 kB
assets/CloudSignupView-BmlVHD6g.js (new) 9.79 kB 🔴 +9.79 kB 🔴 +2.74 kB 🔴 +2.4 kB
assets/CloudLayoutView-BZgmlGuU.js (removed) 9.54 kB 🟢 -9.54 kB 🟢 -2.35 kB 🟢 -2.03 kB
assets/CloudLayoutView-CklpzuJe.js (new) 9.54 kB 🔴 +9.54 kB 🔴 +2.35 kB 🔴 +2.03 kB
assets/UserCheckView-HpvlfeY3.js (removed) 8.8 kB 🟢 -8.8 kB 🟢 -2.22 kB 🟢 -1.93 kB
assets/UserCheckView-vteOUt1-.js (new) 8.8 kB 🔴 +8.8 kB 🔴 +2.22 kB 🔴 +1.92 kB
assets/WidgetTextPreview-BAGDBsMs.js (removed) 6.13 kB 🟢 -6.13 kB 🟢 -2.17 kB 🟢 -1.92 kB
assets/WidgetTextPreview-BAyL2uUO.js (new) 6.13 kB 🔴 +6.13 kB 🔴 +2.16 kB 🔴 +1.92 kB
assets/CloudSubscriptionRedirectView-C2klTi37.js (removed) 6.06 kB 🟢 -6.06 kB 🟢 -2.27 kB 🟢 -1.97 kB
assets/CloudSubscriptionRedirectView-DqTGvwwt.js (new) 6.06 kB 🔴 +6.06 kB 🔴 +2.26 kB 🔴 +1.97 kB
assets/UserSelectView-COoLAqEU.js (new) 5.54 kB 🔴 +5.54 kB 🔴 +1.98 kB 🔴 +1.73 kB
assets/UserSelectView-m8jJGLFf.js (removed) 5.54 kB 🟢 -5.54 kB 🟢 -1.99 kB 🟢 -1.74 kB
assets/CloudForgotPasswordView-BgZ0uMUQ.js (new) 5.15 kB 🔴 +5.15 kB 🔴 +1.76 kB 🔴 +1.53 kB
assets/CloudForgotPasswordView-DFxuXoPM.js (removed) 5.15 kB 🟢 -5.15 kB 🟢 -1.76 kB 🟢 -1.54 kB
assets/CloudAuthTimeoutView-B8iUiU5_.js (removed) 4.49 kB 🟢 -4.49 kB 🟢 -1.57 kB 🟢 -1.36 kB
assets/CloudAuthTimeoutView-DdtUaCX8.js (new) 4.49 kB 🔴 +4.49 kB 🔴 +1.57 kB 🔴 +1.37 kB
assets/CloudSorryContactSupportView-BVTdPuOa.js (new) 1.21 kB 🔴 +1.21 kB 🔴 +607 B 🔴 +531 B
assets/CloudSorryContactSupportView-CUB5-o5S.js (removed) 1.21 kB 🟢 -1.21 kB 🟢 -611 B 🟢 -529 B
assets/layout-CrINFGEa.js (removed) 447 B 🟢 -447 B 🟢 -285 B 🟢 -232 B
assets/layout-S1V9_t8s.js (new) 447 B 🔴 +447 B 🔴 +285 B 🔴 +233 B
assets/WidgetTextPreview-CVBIphOs.js (new) 131 B 🔴 +131 B 🔴 +100 B 🔴 +88 B
assets/WidgetTextPreview-DRbv6vd0.js (removed) 131 B 🟢 -131 B 🟢 -100 B 🟢 -88 B

Status: 14 added / 14 removed

Panels & Settings — 550 kB (baseline 550 kB) • 🔴 +1 B

Configuration panels, inspectors, and settings screens

File Before After Δ Raw Δ Gzip Δ Brotli
assets/KeybindingPanel-A1mQqe9u.js (new) 49.5 kB 🔴 +49.5 kB 🔴 +9.97 kB 🔴 +8.83 kB
assets/KeybindingPanel-DUBukUt3.js (removed) 49.5 kB 🟢 -49.5 kB 🟢 -9.97 kB 🟢 -8.83 kB
assets/SecretsPanel-8xkUyoRV.js (removed) 31 kB 🟢 -31 kB 🟢 -7.51 kB 🟢 -6.57 kB
assets/SecretsPanel-CfEWKVSL.js (new) 31 kB 🔴 +31 kB 🔴 +7.51 kB 🔴 +6.57 kB
assets/CreditsPanel-DazvEuVe.js (new) 16 kB 🔴 +16 kB 🔴 +4.66 kB 🔴 +4.11 kB
assets/CreditsPanel-Du6ZIuFo.js (removed) 16 kB 🟢 -16 kB 🟢 -4.67 kB 🟢 -4.09 kB
assets/SubscriptionPanel-Bx2t1-tp.js (removed) 11.5 kB 🟢 -11.5 kB 🟢 -3.64 kB 🟢 -3.21 kB
assets/SubscriptionPanel-DjdCYbbg.js (new) 11.5 kB 🔴 +11.5 kB 🔴 +3.64 kB 🔴 +3.21 kB
assets/AboutPanel-CdR4tmcq.js (removed) 11.2 kB 🟢 -11.2 kB 🟢 -3.06 kB 🟢 -2.75 kB
assets/AboutPanel-CUCoW3Nw.js (new) 11.2 kB 🔴 +11.2 kB 🔴 +3.05 kB 🔴 +2.74 kB
assets/ExtensionPanel-DCpFikxp.js (new) 9.04 kB 🔴 +9.04 kB 🔴 +2.49 kB 🔴 +2.2 kB
assets/ExtensionPanel-DZ3mYGM7.js (removed) 9.04 kB 🟢 -9.04 kB 🟢 -2.5 kB 🟢 -2.19 kB
assets/ServerConfigPanel-D7A63vaS.js (new) 6.15 kB 🔴 +6.15 kB 🔴 +1.97 kB 🔴 +1.76 kB
assets/ServerConfigPanel-C55PNFIl.js (removed) 6.15 kB 🟢 -6.15 kB 🟢 -1.98 kB 🟢 -1.76 kB
assets/UserPanel-DaAeOWQy.js (removed) 5.78 kB 🟢 -5.78 kB 🟢 -1.82 kB 🟢 -1.58 kB
assets/UserPanel-Dj0zCecF.js (new) 5.78 kB 🔴 +5.78 kB 🔴 +1.82 kB 🔴 +1.57 kB
assets/refreshRemoteConfig-DQG94FNe.js (removed) 2.84 kB 🟢 -2.84 kB 🟢 -1.24 kB 🟢 -1.08 kB
assets/refreshRemoteConfig-UwJjx19-.js (new) 2.84 kB 🔴 +2.84 kB 🔴 +1.24 kB 🔴 +1.09 kB
assets/remoteConfig-DmIoA_e_.js (new) 1.5 kB 🔴 +1.5 kB 🔴 +717 B 🔴 +596 B
assets/remoteConfig-DyRtuFyz.js (removed) 1.5 kB 🟢 -1.5 kB 🟢 -716 B 🟢 -594 B
assets/cloudRemoteConfig-aXpmjy1j.js (removed) 990 B 🟢 -990 B 🟢 -541 B 🟢 -471 B
assets/cloudRemoteConfig-B47rBHfi.js (new) 990 B 🔴 +990 B 🔴 +542 B 🔴 +449 B
assets/refreshRemoteConfig-_fL4gUXZ.js (removed) 110 B 🟢 -110 B 🟢 -89 B 🟢 -92 B
assets/refreshRemoteConfig-CrmWUaur.js (new) 110 B 🔴 +110 B 🔴 +89 B 🔴 +82 B

Status: 12 added / 12 removed / 14 unchanged

User & Accounts — 29.1 kB (baseline 29.1 kB) • 🔴 +1 B

Authentication, profile, and account management bundles

File Before After Δ Raw Δ Gzip Δ Brotli
assets/SignUpForm-DkdKrDbj.js (new) 12.3 kB 🔴 +12.3 kB 🔴 +4.18 kB 🔴 +3.65 kB
assets/SignUpForm-B_O8uVch.js (removed) 12.3 kB 🟢 -12.3 kB 🟢 -4.19 kB 🟢 -3.66 kB
assets/PasswordFields-BioJVkTf.js (new) 4.68 kB 🔴 +4.68 kB 🔴 +1.42 kB 🔴 +1.25 kB
assets/PasswordFields-D73kEmbi.js (removed) 4.68 kB 🟢 -4.68 kB 🟢 -1.42 kB 🟢 -1.25 kB
assets/auth-BV6W2x8x.js (new) 3.69 kB 🔴 +3.69 kB 🔴 +1.3 kB 🔴 +1.14 kB
assets/auth-CTt3dwHn.js (removed) 3.69 kB 🟢 -3.69 kB 🟢 -1.3 kB 🟢 -1.14 kB
assets/usePostAuthRedirect-Cg6QLmGn.js (new) 3.33 kB 🔴 +3.33 kB 🔴 +1.27 kB 🔴 +1.1 kB
assets/usePostAuthRedirect-CzvSa36t.js (removed) 3.33 kB 🟢 -3.33 kB 🟢 -1.27 kB 🟢 -1.1 kB
assets/UpdatePasswordContent-BUlG7hv3.js (new) 1.92 kB 🔴 +1.92 kB 🔴 +872 B 🔴 +762 B
assets/UpdatePasswordContent-Tlf3vkeN.js (removed) 1.92 kB 🟢 -1.92 kB 🟢 -876 B 🟢 -764 B
assets/WorkspaceProfilePic-B3kGjh60.js (new) 1.66 kB 🔴 +1.66 kB 🔴 +859 B 🔴 +781 B
assets/WorkspaceProfilePic-BDQRTBkU.js (removed) 1.66 kB 🟢 -1.66 kB 🟢 -862 B 🟢 -781 B
assets/authStore-BpITST15.js (new) 130 B 🔴 +130 B 🔴 +109 B 🔴 +105 B
assets/authStore-D0RGjlj2.js (removed) 130 B 🟢 -130 B 🟢 -109 B 🟢 -122 B
assets/workspaceAuthStore-BHr5jTB0.js (new) 110 B 🔴 +110 B 🔴 +104 B 🔴 +104 B
assets/workspaceAuthStore-DcjkKnMz.js (removed) 110 B 🟢 -110 B 🟢 -104 B 🟢 -114 B
assets/auth-DTU_3x-W.js (removed) 105 B 🟢 -105 B 🟢 -96 B 🟢 -81 B
assets/auth-GB27B-V4.js (new) 105 B 🔴 +105 B 🔴 +96 B 🔴 +94 B

Status: 9 added / 9 removed / 1 unchanged

Editors & Dialogs — 121 kB (baseline 121 kB) • 🔴 +1 B

Modals, dialogs, drawers, and in-app editors

File Before After Δ Raw Δ Gzip Δ Brotli
assets/ComfyHubPublishDialog-DQ_NiLJ6.js (new) 90.5 kB 🔴 +90.5 kB 🔴 +19.3 kB 🔴 +16.5 kB
assets/ComfyHubPublishDialog-nrdpTFhA.js (removed) 90.5 kB 🟢 -90.5 kB 🟢 -19.3 kB 🟢 -16.5 kB
assets/useShareDialog-BmRKWxCv.js (new) 23.7 kB 🔴 +23.7 kB 🔴 +5.59 kB 🔴 +4.96 kB
assets/useShareDialog-ClIgdZP0.js (removed) 23.7 kB 🟢 -23.7 kB 🟢 -5.58 kB 🟢 -4.97 kB
assets/feedbackDialog-D0ejr9CP.js (removed) 4.51 kB 🟢 -4.51 kB 🟢 -1.9 kB 🟢 -1.63 kB
assets/feedbackDialog-on0kUBHB.js (new) 4.51 kB 🔴 +4.51 kB 🔴 +1.9 kB 🔴 +1.63 kB
assets/SubscriptionInactiveMemberDialog-BG7yYpSz.js (new) 2.55 kB 🔴 +2.55 kB 🔴 +1.03 kB 🔴 +887 B
assets/SubscriptionInactiveMemberDialog-Cwns_zRr.js (removed) 2.55 kB 🟢 -2.55 kB 🟢 -1.03 kB 🟢 -883 B
assets/ComfyHubPublishDialog-B9YiZMc3.js (removed) 143 B 🟢 -143 B 🟢 -105 B 🟢 -90 B
assets/ComfyHubPublishDialog-WulqTbyw.js (new) 143 B 🔴 +143 B 🔴 +105 B 🔴 +87 B
assets/useSubscriptionDialog-C8vzntpl.js (removed) 110 B 🟢 -110 B 🟢 -102 B 🟢 -94 B
assets/useSubscriptionDialog-DtZBdKGu.js (new) 110 B 🔴 +110 B 🔴 +102 B 🔴 +98 B

Status: 6 added / 6 removed

UI Components — 56.8 kB (baseline 56.8 kB) • 🔴 +1 B

Reusable component library chunks

File Before After Δ Raw Δ Gzip Δ Brotli
assets/ComfyQueueButton-0T84cxdv.js (removed) 13.6 kB 🟢 -13.6 kB 🟢 -3.8 kB 🟢 -3.39 kB
assets/ComfyQueueButton-CRGU5-oK.js (new) 13.6 kB 🔴 +13.6 kB 🔴 +3.8 kB 🔴 +3.39 kB
assets/useTerminalTabs-Cmge2xpR.js (removed) 11.8 kB 🟢 -11.8 kB 🟢 -3.72 kB 🟢 -3.29 kB
assets/useTerminalTabs-DV6NKGbs.js (new) 11.8 kB 🔴 +11.8 kB 🔴 +3.72 kB 🔴 +3.29 kB
assets/TopbarBadge-DCqbhTxD.js (new) 7.7 kB 🔴 +7.7 kB 🔴 +1.87 kB 🔴 +1.66 kB
assets/TopbarBadge-dCzRER9R.js (removed) 7.7 kB 🟢 -7.7 kB 🟢 -1.87 kB 🟢 -1.65 kB
assets/ScrubableNumberInput-C9wrRIwf.js (new) 6.55 kB 🔴 +6.55 kB 🔴 +2.19 kB 🔴 +1.93 kB
assets/ScrubableNumberInput-CNv5_dqh.js (removed) 6.55 kB 🟢 -6.55 kB 🟢 -2.2 kB 🟢 -1.94 kB
assets/toggle-group-CKXVR29Q.js (removed) 4.16 kB 🟢 -4.16 kB 🟢 -1.45 kB 🟢 -1.28 kB
assets/toggle-group-DvUSbVR8.js (new) 4.16 kB 🔴 +4.16 kB 🔴 +1.45 kB 🔴 +1.28 kB
assets/Button--5ONtWlj.js (removed) 3.69 kB 🟢 -3.69 kB 🟢 -1.4 kB 🟢 -1.22 kB
assets/Button-CPfvuKil.js (new) 3.69 kB 🔴 +3.69 kB 🔴 +1.4 kB 🔴 +1.22 kB
assets/SubscribeButton-8DVlOc3a.js (new) 2.19 kB 🔴 +2.19 kB 🔴 +990 B 🔴 +868 B
assets/SubscribeButton-BqfrbsSU.js (removed) 2.18 kB 🟢 -2.18 kB 🟢 -993 B 🟢 -875 B
assets/WidgetButton-DLPF8aUp.js (new) 1.98 kB 🔴 +1.98 kB 🔴 +916 B 🔴 +804 B
assets/WidgetButton-DmkrPzjy.js (removed) 1.98 kB 🟢 -1.98 kB 🟢 -919 B 🟢 -826 B
assets/Input-BK0_FG0a.js (removed) 1.81 kB 🟢 -1.81 kB 🟢 -904 B 🟢 -795 B
assets/Input-DtTzV8IU.js (new) 1.81 kB 🔴 +1.81 kB 🔴 +904 B 🔴 +789 B
assets/UserAvatar-edSOIurg.js (new) 1.29 kB 🔴 +1.29 kB 🔴 +668 B 🔴 +575 B
assets/UserAvatar-OSIQW4A-.js (removed) 1.29 kB 🟢 -1.29 kB 🟢 -674 B 🟢 -572 B
assets/CloudBadge-12iWnVIf.js (new) 1.18 kB 🔴 +1.18 kB 🔴 +592 B 🔴 +519 B
assets/CloudBadge-BZpghdT9.js (removed) 1.18 kB 🟢 -1.18 kB 🟢 -591 B 🟢 -520 B
assets/cloudFeedbackTopbarButton-JDnZbJfQ.js (removed) 771 B 🟢 -771 B 🟢 -460 B 🟢 -419 B
assets/cloudFeedbackTopbarButton-LnAcRt5Z.js (new) 771 B 🔴 +771 B 🔴 +461 B 🔴 +416 B
assets/ComfyQueueButton-_yAofjA1.js (new) 128 B 🔴 +128 B 🔴 +99 B 🔴 +91 B
assets/ComfyQueueButton-2MuPJiiz.js (removed) 128 B 🟢 -128 B 🟢 -99 B 🟢 -88 B

Status: 13 added / 13 removed

Data & Services — 270 kB (baseline 270 kB) • ⚪ 0 B

Stores, services, APIs, and repositories

File Before After Δ Raw Δ Gzip Δ Brotli
assets/load3dService-B-Wlz10B.js (removed) 132 kB 🟢 -132 kB 🟢 -29.5 kB 🟢 -25 kB
assets/load3dService-BBXmBO47.js (new) 132 kB 🔴 +132 kB 🔴 +29.5 kB 🔴 +24.9 kB
assets/api-BB8xs65v.js (new) 89.1 kB 🔴 +89.1 kB 🔴 +24.5 kB 🔴 +21.1 kB
assets/api-D5BfHjpu.js (removed) 89.1 kB 🟢 -89.1 kB 🟢 -24.5 kB 🟢 -21.1 kB
assets/workflowShareService-CPGZoIXh.js (new) 17 kB 🔴 +17 kB 🔴 +5 kB 🔴 +4.43 kB
assets/workflowShareService-U9d1bM0B.js (removed) 17 kB 🟢 -17 kB 🟢 -5 kB 🟢 -4.44 kB
assets/keybindingService-B7DAlG8a.js (removed) 7.21 kB 🟢 -7.21 kB 🟢 -1.88 kB 🟢 -1.61 kB
assets/keybindingService-C-eAHc4u.js (new) 7.21 kB 🔴 +7.21 kB 🔴 +1.88 kB 🔴 +1.61 kB
assets/releaseStore-CQmFvjkm.js (removed) 6.77 kB 🟢 -6.77 kB 🟢 -2.07 kB 🟢 -1.81 kB
assets/releaseStore-E5ixvws0.js (new) 6.77 kB 🔴 +6.77 kB 🔴 +2.07 kB 🔴 +1.8 kB
assets/dialogStore-CQppOgQb.js (new) 5.36 kB 🔴 +5.36 kB 🔴 +1.66 kB 🔴 +1.43 kB
assets/dialogStore-DiganZ2-.js (removed) 5.36 kB 🟢 -5.36 kB 🟢 -1.66 kB 🟢 -1.43 kB
assets/systemStatsStore-BSoIm-TG.js (new) 4.99 kB 🔴 +4.99 kB 🔴 +1.77 kB 🔴 +1.5 kB
assets/systemStatsStore-DiEJTjGx.js (removed) 4.99 kB 🟢 -4.99 kB 🟢 -1.77 kB 🟢 -1.49 kB
assets/userStore-Dd7B5W0A.js (removed) 2.42 kB 🟢 -2.42 kB 🟢 -931 B 🟢 -820 B
assets/userStore-oqhF2RdF.js (new) 2.42 kB 🔴 +2.42 kB 🔴 +931 B 🔴 +819 B
assets/serverConfigStore-BGIIfRdD.js (removed) 2.35 kB 🟢 -2.35 kB 🟢 -808 B 🟢 -710 B
assets/serverConfigStore-CgTmVvyq.js (new) 2.35 kB 🔴 +2.35 kB 🔴 +807 B 🔴 +707 B
assets/audioService-BUVikOm0.js (removed) 1.76 kB 🟢 -1.76 kB 🟢 -861 B 🟢 -751 B
assets/audioService-NOySQvzN.js (new) 1.76 kB 🔴 +1.76 kB 🔴 +861 B 🔴 +748 B
assets/toastStore-1SZT8hRV.js (removed) 889 B 🟢 -889 B 🟢 -429 B 🟢 -370 B
assets/toastStore-BjI4AtdU.js (new) 889 B 🔴 +889 B 🔴 +428 B 🔴 +371 B
assets/dialogService-DhMecbyl.js (removed) 100 B 🟢 -100 B 🟢 -99 B 🟢 -95 B
assets/dialogService-EJATX4F1.js (new) 100 B 🔴 +100 B 🔴 +99 B 🔴 +96 B
assets/settingStore-BUWc0gWx.js (new) 98 B 🔴 +98 B 🔴 +98 B 🔴 +90 B
assets/settingStore-iCpv4TH9.js (removed) 98 B 🟢 -98 B 🟢 -98 B 🟢 -90 B
assets/assetsStore-1qLGVpvE.js (removed) 96 B 🟢 -96 B 🟢 -97 B 🟢 -85 B
assets/assetsStore-DDpdBHbZ.js (new) 96 B 🔴 +96 B 🔴 +97 B 🔴 +98 B
assets/releaseStore-7Ojpj30z.js (removed) 95 B 🟢 -95 B 🟢 -86 B 🟢 -85 B
assets/releaseStore-Bl7bPzfX.js (new) 95 B 🔴 +95 B 🔴 +86 B 🔴 +78 B
assets/api-CmUzwjcs.js (removed) 62 B 🟢 -62 B 🟢 -74 B 🟢 -66 B
assets/api-DoPpebGI.js (new) 62 B 🔴 +62 B 🔴 +74 B 🔴 +66 B

Status: 16 added / 16 removed

Utilities & Hooks — 3.4 MB (baseline 3.4 MB) • 🔴 +921 B

Helpers, composables, and utility bundles

File Before After Δ Raw Δ Gzip Δ Brotli
assets/promotionUtils-DqrBWh6P.js (new) 3.04 MB 🔴 +3.04 MB 🔴 +704 kB 🔴 +531 kB
assets/promotionUtils-55CLiObf.js (removed) 3.04 MB 🟢 -3.04 MB 🟢 -704 kB 🟢 -531 kB
assets/useConflictDetection-DO7jagrb.js (new) 235 kB 🔴 +235 kB 🔴 +52.3 kB 🔴 +42.6 kB
assets/useConflictDetection-HB6BNsLU.js (removed) 235 kB 🟢 -235 kB 🟢 -52.3 kB 🟢 -42.6 kB
assets/useLoad3d-BAm3EZ1v.js (removed) 25.7 kB 🟢 -25.7 kB 🟢 -5.82 kB 🟢 -5.17 kB
assets/useLoad3d-CazwN_d8.js (new) 25.7 kB 🔴 +25.7 kB 🔴 +5.82 kB 🔴 +5.16 kB
assets/useLoad3dViewer-BlRc2yK6.js (new) 21.2 kB 🔴 +21.2 kB 🔴 +4.99 kB 🔴 +4.38 kB
assets/useLoad3dViewer-DmBjd_Fo.js (removed) 21.2 kB 🟢 -21.2 kB 🟢 -4.99 kB 🟢 -4.38 kB
assets/useImageQuiet-BO5cVAgz.js (removed) 10.3 kB 🟢 -10.3 kB 🟢 -3.47 kB 🟢 -2.98 kB
assets/useImageQuiet-Dc84ShX2.js (new) 10.3 kB 🔴 +10.3 kB 🔴 +3.47 kB 🔴 +2.98 kB
assets/useFeatureFlags-9dGdFCiI.js (new) 6.75 kB 🔴 +6.75 kB 🔴 +2.07 kB 🔴 +1.74 kB
assets/useFeatureFlags-D3GzBDxV.js (removed) 6.75 kB 🟢 -6.75 kB 🟢 -2.07 kB 🟢 -1.74 kB
assets/useTransformState-BzIynGgi.js (removed) 3.58 kB 🟢 -3.58 kB 🟢 -1.57 kB 🟢 -1.3 kB
assets/useTransformState-CBoLdVvL.js (new) 3.58 kB 🔴 +3.58 kB 🔴 +1.57 kB 🔴 +1.31 kB
assets/useDowngradeToPersonal-B13REVo8.js (removed) 3 kB 🟢 -3 kB 🟢 -1.18 kB 🟢 -1.04 kB
assets/useDowngradeToPersonal-CELlDuL-.js (new) 3 kB 🔴 +3 kB 🔴 +1.18 kB 🔴 +1.02 kB
assets/useSurveyEligibility-BkIK055i.js (new) 2.96 kB 🔴 +2.96 kB 🔴 +1.14 kB 🔴 +951 B
assets/useSurveyEligibility-CtDeLZVV.js (removed) 2.96 kB 🟢 -2.96 kB 🟢 -1.14 kB 🟢 -951 B
assets/useExternalLink-BBaDztB-.js (new) 2.86 kB 🔴 +2.86 kB 🔴 +1.08 kB 🔴 +936 B
assets/useExternalLink-sChfxkDQ.js (removed) 2.86 kB 🟢 -2.86 kB 🟢 -1.08 kB 🟢 -934 B
assets/downloadUtil-BuBUZawv.js (removed) 2.45 kB 🟢 -2.45 kB 🟢 -1.12 kB 🟢 -895 B
assets/downloadUtil-DNeFgl7F.js (new) 2.45 kB 🔴 +2.45 kB 🔴 +1.11 kB 🔴 +895 B
assets/assetPreviewUtil-BVMDErcM.js (removed) 2.41 kB 🟢 -2.41 kB 🟢 -1 kB 🟢 -874 B
assets/assetPreviewUtil-Dh9oqu6_.js (new) 2.41 kB 🔴 +2.41 kB 🔴 +1 kB 🔴 +874 B
assets/useFeatureUsageTracker-DdAtB83W.js (new) 2.13 kB 🔴 +2.13 kB 🔴 +942 B 🔴 +802 B
assets/useFeatureUsageTracker-DZFmW9_B.js (removed) 2.13 kB 🟢 -2.13 kB 🟢 -943 B 🟢 -804 B
assets/useTypeformEmbed-BysZpsjT.js (removed) 2.07 kB 🟢 -2.07 kB 🟢 -1.06 kB 🟢 -886 B
assets/useTypeformEmbed-BzjFqusT.js (new) 2.07 kB 🔴 +2.07 kB 🔴 +1.06 kB 🔴 +882 B
assets/useUpstreamValue-BRcgcadh.js (removed) 2.04 kB 🟢 -2.04 kB 🟢 -791 B 🟢 -701 B
assets/useUpstreamValue-L1LcGXhz.js (new) 2.04 kB 🔴 +2.04 kB 🔴 +794 B 🔴 +702 B
assets/useWorkspaceTierLabel-bKTvDund.js (new) 1.99 kB 🔴 +1.99 kB 🔴 +851 B 🔴 +732 B
assets/useWorkspaceTierLabel-DIn0_RWo.js (removed) 1.99 kB 🟢 -1.99 kB 🟢 -852 B 🟢 -739 B
assets/useErrorHandling-BQxLWgCL.js (new) 1.54 kB 🔴 +1.54 kB 🔴 +648 B 🔴 +549 B
assets/useErrorHandling-C-ETM_WX.js (removed) 1.54 kB 🟢 -1.54 kB 🟢 -648 B 🟢 -552 B
assets/useSessionCookie-BTIEi8VF.js (removed) 995 B 🟢 -995 B 🟢 -520 B 🟢 -438 B
assets/useSessionCookie-Cm7MFJVZ.js (new) 995 B 🔴 +995 B 🔴 +520 B 🔴 +438 B
assets/useModalLiftedZIndex-D5Zt3Dt2.js (removed) 966 B 🟢 -966 B 🟢 -585 B 🟢 -492 B
assets/useModalLiftedZIndex-DWSy4lUv.js (new) 966 B 🔴 +966 B 🔴 +584 B 🔴 +492 B
assets/subscriptionCheckoutUtil-BjLP0KPs.js (new) 905 B 🔴 +905 B 🔴 +536 B 🔴 +454 B
assets/subscriptionCheckoutUtil-zpqkgeTR.js (removed) 905 B 🟢 -905 B 🟢 -537 B 🟢 -454 B
assets/useTextFileContent-C6sLgUcS.js (new) 897 B 🔴 +897 B 🔴 +457 B 🔴 +403 B
assets/useTextFileContent-MHyN06kw.js (removed) 897 B 🟢 -897 B 🟢 -458 B 🟢 -427 B
assets/useLoad3d-BsMY2XuD.js (removed) 311 B 🟢 -311 B 🟢 -164 B 🟢 -147 B
assets/useLoad3d-D_KvkHvY.js (new) 311 B 🔴 +311 B 🔴 +163 B 🔴 +147 B
assets/useSessionCookie-5l1EZihU.js (removed) 101 B 🟢 -101 B 🟢 -86 B 🟢 -88 B
assets/useSessionCookie-DOIW8j3W.js (new) 101 B 🔴 +101 B 🔴 +86 B 🔴 +82 B
assets/useFeatureFlags-BLpxDnHN.js (removed) 98 B 🟢 -98 B 🟢 -85 B 🟢 -83 B
assets/useFeatureFlags-KlyPZdYa.js (new) 98 B 🔴 +98 B 🔴 +85 B 🔴 +79 B
assets/useLoad3dViewer-CHFHROIM.js (new) 98 B 🔴 +98 B 🔴 +85 B 🔴 +86 B
assets/useLoad3dViewer-K0QaDIgB.js (removed) 98 B 🟢 -98 B 🟢 -85 B 🟢 -85 B
assets/useCurrentUser-5Ohq9pOK.js (new) 96 B 🔴 +96 B 🔴 +97 B 🔴 +94 B
assets/useCurrentUser-BsL8QNhI.js (removed) 96 B 🟢 -96 B 🟢 -97 B 🟢 -92 B

Status: 26 added / 26 removed / 10 unchanged

Vendor & Third-Party — 15.7 MB (baseline 15.7 MB) • 🔴 +21 B

External libraries and shared vendor chunks

File Before After Δ Raw Δ Gzip Δ Brotli
assets/vendor-other-VcUVgdAV.js (new) 2.23 MB 🔴 +2.23 MB 🔴 +476 kB 🔴 +380 kB
assets/vendor-other-C1at4SN8.js (removed) 2.23 MB 🟢 -2.23 MB 🟢 -476 kB 🟢 -380 kB
assets/vendor-primevue-Ck2rG6Eb.js (removed) 1.69 MB 🟢 -1.69 MB 🟢 -304 kB 🟢 -185 kB
assets/vendor-primevue-D_Jf3ohg.js (new) 1.69 MB 🔴 +1.69 MB 🔴 +304 kB 🔴 +185 kB
assets/vendor-reka-ui-k0TePA2p.js (new) 506 kB 🔴 +506 kB 🔴 +93.1 kB 🔴 +71.7 kB
assets/vendor-reka-ui-Cb3qQInv.js (removed) 506 kB 🟢 -506 kB 🟢 -93.1 kB 🟢 -71.7 kB
assets/vendor-vue-core-CprzoTVh.js (new) 351 kB 🔴 +351 kB 🔴 +87.7 kB 🔴 +73.8 kB
assets/vendor-vue-core-B3nVjuDL.js (removed) 351 kB 🟢 -351 kB 🟢 -87.6 kB 🟢 -73.8 kB
assets/vendor-vueuse-CSDBGF8y.js (removed) 149 kB 🟢 -149 kB 🟢 -37.3 kB 🟢 -32 kB
assets/vendor-vueuse-D-Y3FmKN.js (new) 149 kB 🔴 +149 kB 🔴 +37.3 kB 🔴 +32 kB
assets/vendor-i18n-B3nB-OxK.js (new) 140 kB 🔴 +140 kB 🔴 +30.7 kB 🔴 +25.8 kB
assets/vendor-i18n-c6JC3YZk.js (removed) 140 kB 🟢 -140 kB 🟢 -30.7 kB 🟢 -25.8 kB

Status: 6 added / 6 removed / 10 unchanged

Other — 11.9 MB (baseline 11.9 MB) • 🔴 +12.7 kB

Bundles that do not match a named category

File Before After Δ Raw Δ Gzip Δ Brotli
assets/main-D1op0ITY.js (new) 190 kB 🔴 +190 kB 🔴 +55.5 kB 🔴 +46.6 kB
assets/main-BkkxWTck.js (removed) 189 kB 🟢 -189 kB 🟢 -55.3 kB 🟢 -46.5 kB
assets/core-7N7021So.js (new) 111 kB 🔴 +111 kB 🔴 +28.6 kB 🔴 +24.2 kB
assets/core-BQ2DH-S-.js (removed) 111 kB 🟢 -111 kB 🟢 -28.6 kB 🟢 -24.2 kB
assets/WidgetSelect-CYibi2Ko.js (removed) 88.1 kB 🟢 -88.1 kB 🟢 -20 kB 🟢 -17.1 kB
assets/WidgetSelect-DdyvJFBH.js (new) 88.1 kB 🔴 +88.1 kB 🔴 +20 kB 🔴 +17.1 kB
assets/Load3D-CxtMrjGT.js (new) 68.8 kB 🔴 +68.8 kB 🔴 +11 kB 🔴 +9.5 kB
assets/Load3D-DAx1qtoL.js (removed) 68.8 kB 🟢 -68.8 kB 🟢 -11 kB 🟢 -9.5 kB
assets/Preview3d-dIW8SPn5.js (removed) 51 kB 🟢 -51 kB 🟢 -8.36 kB 🟢 -7.3 kB
assets/Preview3d-nUlhtKxi.js (new) 51 kB 🔴 +51 kB 🔴 +8.36 kB 🔴 +7.28 kB
assets/SubscriptionTransitionPreviewWorkspace-R4GsaHz2.js (new) 46.8 kB 🔴 +46.8 kB 🔴 +9.66 kB 🔴 +8.54 kB
assets/SubscriptionTransitionPreviewWorkspace-WvQOBGSR.js (removed) 46.8 kB 🟢 -46.8 kB 🟢 -9.66 kB 🟢 -8.55 kB
assets/WorkspacePanelContent-Qhgp1O3u.js (new) 44.4 kB 🔴 +44.4 kB 🔴 +9.36 kB 🔴 +8.3 kB
assets/SubscriptionRequiredDialogContentUnified-aUIJaKGI.js (removed) 41.2 kB 🟢 -41.2 kB 🟢 -9.17 kB 🟢 -7.99 kB
assets/SubscriptionRequiredDialogContentUnified-CeRx7Wh6.js (new) 41.2 kB 🔴 +41.2 kB 🔴 +9.16 kB 🔴 +7.98 kB
assets/WorkspacePanelContent-DTXaoKPM.js (removed) 40.8 kB 🟢 -40.8 kB 🟢 -8.63 kB 🟢 -7.63 kB
assets/WidgetBoundingBoxes-1CgJfEj-.js (new) 33.8 kB 🔴 +33.8 kB 🔴 +9.2 kB 🔴 +8.17 kB
assets/WidgetBoundingBoxes-B0YiXz8Z.js (removed) 33.8 kB 🟢 -33.8 kB 🟢 -9.2 kB 🟢 -8.16 kB
assets/WidgetPainter-CJwQGaoO.js (removed) 32.7 kB 🟢 -32.7 kB 🟢 -7.91 kB 🟢 -6.99 kB
assets/WidgetPainter-D3ZAR9xt.js (new) 32.7 kB 🔴 +32.7 kB 🔴 +7.91 kB 🔴 +7.01 kB
assets/Load3dViewerContent-D9Dl7W_q.js (new) 30.9 kB 🔴 +30.9 kB 🔴 +6.31 kB 🔴 +5.49 kB
assets/Load3dViewerContent-BYe17XRB.js (removed) 30.9 kB 🟢 -30.9 kB 🟢 -6.31 kB 🟢 -5.47 kB
assets/HdrViewerContent-CjjyWZUc.js (new) 29.8 kB 🔴 +29.8 kB 🔴 +8.27 kB 🔴 +7.29 kB
assets/HdrViewerContent-dPiQQjZM.js (removed) 29.8 kB 🟢 -29.8 kB 🟢 -8.28 kB 🟢 -7.3 kB
assets/initHostTelemetry-GFCWFbou.js (removed) 26.4 kB 🟢 -26.4 kB 🟢 -6.42 kB 🟢 -5.35 kB
assets/initHostTelemetry-N-Dy56lD.js (new) 26.4 kB 🔴 +26.4 kB 🔴 +6.42 kB 🔴 +5.36 kB
assets/SubscriptionPanelContentWorkspace-Bj5MG-1k.js (removed) 25 kB 🟢 -25 kB 🟢 -5.86 kB 🟢 -5.14 kB
assets/SubscriptionPanelContentWorkspace-w3SOqeBV.js (new) 25 kB 🔴 +25 kB 🔴 +5.85 kB 🔴 +5.14 kB
assets/ColorPicker-0Qi7V4Rk.js (removed) 25 kB 🟢 -25 kB 🟢 -6.54 kB 🟢 -5.77 kB
assets/ColorPicker-Ruk-mwDl.js (new) 25 kB 🔴 +25 kB 🔴 +6.53 kB 🔴 +5.78 kB
assets/SubscriptionRequiredDialogContentWorkspace--cQ5aA13.js (new) 24.6 kB 🔴 +24.6 kB 🔴 +5.66 kB 🔴 +4.97 kB
assets/SubscriptionRequiredDialogContentWorkspace-FSSpO3yT.js (removed) 24.6 kB 🟢 -24.6 kB 🟢 -5.66 kB 🟢 -4.97 kB
assets/SubscriptionRequiredDialogContent-B8s-0Qfc.js (removed) 24.4 kB 🟢 -24.4 kB 🟢 -6 kB 🟢 -5.3 kB
assets/SubscriptionRequiredDialogContent-DLjm21De.js (new) 24.4 kB 🔴 +24.4 kB 🔴 +6 kB 🔴 +5.31 kB
assets/WidgetImageCrop-BY9wE_AJ.js (removed) 23.3 kB 🟢 -23.3 kB 🟢 -5.75 kB 🟢 -5.05 kB
assets/WidgetImageCrop-wIrQkT7t.js (new) 23.3 kB 🔴 +23.3 kB 🔴 +5.75 kB 🔴 +5.05 kB
assets/load3d-DjWsLb7b.js (removed) 22.3 kB 🟢 -22.3 kB 🟢 -5.46 kB 🟢 -4.72 kB
assets/load3d-DSFHZFMm.js (new) 22.3 kB 🔴 +22.3 kB 🔴 +5.46 kB 🔴 +4.72 kB
assets/CurrentUserPopoverWorkspace-CpTCR2dx.js (removed) 20.6 kB 🟢 -20.6 kB 🟢 -4.72 kB 🟢 -4.21 kB
assets/CurrentUserPopoverWorkspace-DZ7fqmyN.js (new) 20.6 kB 🔴 +20.6 kB 🔴 +4.71 kB 🔴 +4.21 kB
assets/SignInContent-BljZtpAT.js (removed) 20 kB 🟢 -20 kB 🟢 -5.05 kB 🟢 -4.41 kB
assets/SignInContent-CN5XxwBB.js (new) 20 kB 🔴 +20 kB 🔴 +5.04 kB 🔴 +4.4 kB
assets/WidgetInputNumber-CJ8EyaAv.js (removed) 19.1 kB 🟢 -19.1 kB 🟢 -4.83 kB 🟢 -4.29 kB
assets/WidgetInputNumber-Cucs_krL.js (new) 19.1 kB 🔴 +19.1 kB 🔴 +4.83 kB 🔴 +4.29 kB
assets/CreditsTile-CddryjFC.js (removed) 17.1 kB 🟢 -17.1 kB 🟢 -4.54 kB 🟢 -4 kB
assets/CreditsTile-xXWXgK_2.js (new) 17.1 kB 🔴 +17.1 kB 🔴 +4.54 kB 🔴 +4 kB
assets/WidgetRecordAudio-BC2DQIBN.js (new) 16.6 kB 🔴 +16.6 kB 🔴 +4.63 kB 🔴 +4.13 kB
assets/WidgetRecordAudio-DnPO_qrK.js (removed) 16.6 kB 🟢 -16.6 kB 🟢 -4.63 kB 🟢 -4.14 kB
assets/WidgetRange-srUdjCbp.js (new) 16.2 kB 🔴 +16.2 kB 🔴 +4.17 kB 🔴 +3.73 kB
assets/WidgetRange-Djkxyxib.js (removed) 16.2 kB 🟢 -16.2 kB 🟢 -4.17 kB 🟢 -3.72 kB
assets/DialogHeader-C6K_gIc4.js (new) 15 kB 🔴 +15 kB 🔴 +4.1 kB 🔴 +3.64 kB
assets/DialogHeader-ChbrJ17B.js (removed) 15 kB 🟢 -15 kB 🟢 -4.1 kB 🟢 -3.64 kB
assets/WaveAudioPlayer-DbsRd6M3.js (new) 12.8 kB 🔴 +12.8 kB 🔴 +3.49 kB 🔴 +3.06 kB
assets/WaveAudioPlayer-KGqD4Pll.js (removed) 12.8 kB 🟢 -12.8 kB 🟢 -3.49 kB 🟢 -3.06 kB
assets/i18n-BF4lr5A8.js (removed) 12.5 kB 🟢 -12.5 kB 🟢 -3.31 kB 🟢 -2.8 kB
assets/i18n-CDzQIFL3.js (new) 12.5 kB 🔴 +12.5 kB 🔴 +3.31 kB 🔴 +2.8 kB
assets/WidgetCurve-Bv0qth3R.js (new) 11.3 kB 🔴 +11.3 kB 🔴 +3.51 kB 🔴 +3.17 kB
assets/WidgetCurve-DWWZMinl.js (removed) 11.3 kB 🟢 -11.3 kB 🟢 -3.51 kB 🟢 -3.16 kB
assets/AudioPreviewPlayer-BcFCO66-.js (removed) 10.6 kB 🟢 -10.6 kB 🟢 -3.08 kB 🟢 -2.75 kB
assets/AudioPreviewPlayer-PU82TefM.js (new) 10.6 kB 🔴 +10.6 kB 🔴 +3.08 kB 🔴 +2.74 kB
assets/TeamWorkspacesDialogContent-B2kAGlx9.js (removed) 10.3 kB 🟢 -10.3 kB 🟢 -3 kB 🟢 -2.66 kB
assets/TeamWorkspacesDialogContent-QWD_cSLq.js (new) 10.3 kB 🔴 +10.3 kB 🔴 +3 kB 🔴 +2.66 kB
assets/SelectValue-g8K3mtln.js (removed) 10.2 kB 🟢 -10.2 kB 🟢 -2.48 kB 🟢 -2.19 kB
assets/SelectValue-x1Cf6BP1.js (new) 10.2 kB 🔴 +10.2 kB 🔴 +2.48 kB 🔴 +2.19 kB
assets/Load3DConfiguration-CszAgU4I.js (new) 9.02 kB 🔴 +9.02 kB 🔴 +2.67 kB 🔴 +2.35 kB
assets/Load3DConfiguration-D7zwR8hK.js (removed) 9.02 kB 🟢 -9.02 kB 🟢 -2.67 kB 🟢 -2.35 kB
assets/SetMemberCreditLimitDialogContent-BZ7ER3Hg.js (new) 8.54 kB 🔴 +8.54 kB 🔴 +2.38 kB 🔴 +2.08 kB
assets/onboardingCloudRoutes-Ck-QnppC.js (removed) 8.44 kB 🟢 -8.44 kB 🟢 -2.63 kB 🟢 -2.27 kB
assets/onboardingCloudRoutes-LjknPc6f.js (new) 8.44 kB 🔴 +8.44 kB 🔴 +2.64 kB 🔴 +2.26 kB
assets/nodeTemplates-Dh-R5kZ6.js (new) 8.33 kB 🔴 +8.33 kB 🔴 +2.88 kB 🔴 +2.54 kB
assets/nodeTemplates-DhxjVj3k.js (removed) 8.33 kB 🟢 -8.33 kB 🟢 -2.88 kB 🟢 -2.53 kB
assets/WidgetImageCompare-C8Uukccj.js (removed) 8.19 kB 🟢 -8.19 kB 🟢 -2.33 kB 🟢 -2.04 kB
assets/WidgetImageCompare-HYVckZrE.js (new) 8.19 kB 🔴 +8.19 kB 🔴 +2.33 kB 🔴 +2.04 kB
assets/NightlySurveyController-BhHnoLOH.js (removed) 7.56 kB 🟢 -7.56 kB 🟢 -2.59 kB 🟢 -2.3 kB
assets/NightlySurveyController-CEzTjrJa.js (new) 7.56 kB 🔴 +7.56 kB 🔴 +2.59 kB 🔴 +2.27 kB
assets/Popover-B7wj-KTb.js (new) 7.52 kB 🔴 +7.52 kB 🔴 +2.71 kB 🔴 +2.39 kB
assets/Popover-BFfMZRpx.js (removed) 7.52 kB 🟢 -7.52 kB 🟢 -2.72 kB 🟢 -2.4 kB
assets/InviteMemberDialogContent-BRtHMBu2.js (new) 6.76 kB 🔴 +6.76 kB 🔴 +2.22 kB 🔴 +1.96 kB
assets/InviteMemberDialogContent-CQ6qfsfc.js (removed) 6.76 kB 🟢 -6.76 kB 🟢 -2.23 kB 🟢 -1.96 kB
assets/WidgetWithControl-Bbh-CQ2S.js (removed) 6.36 kB 🟢 -6.36 kB 🟢 -2.58 kB 🟢 -2.27 kB
assets/WidgetWithControl-DaZL4sbz.js (new) 6.36 kB 🔴 +6.36 kB 🔴 +2.58 kB 🔴 +2.28 kB
assets/AnimationControls-BtASSx0x.js (new) 6.15 kB 🔴 +6.15 kB 🔴 +1.88 kB 🔴 +1.66 kB
assets/AnimationControls-DYRnPsHK.js (removed) 6.15 kB 🟢 -6.15 kB 🟢 -1.88 kB 🟢 -1.67 kB
assets/tierBenefits-BWGSNfbR.js (removed) 6.02 kB 🟢 -6.02 kB 🟢 -1.93 kB 🟢 -1.67 kB
assets/tierBenefits-CCdUoqGE.js (new) 6.02 kB 🔴 +6.02 kB 🔴 +1.92 kB 🔴 +1.67 kB
assets/load3dPreviewExtensions-CzGNK533.js (new) 5.95 kB 🔴 +5.95 kB 🔴 +1.85 kB 🔴 +1.64 kB
assets/load3dPreviewExtensions-nb1w1WBk.js (removed) 5.95 kB 🟢 -5.95 kB 🟢 -1.85 kB 🟢 -1.64 kB
assets/main-C7uMZkTU.js (new) 5.84 kB 🔴 +5.84 kB 🔴 +1.86 kB 🔴 +1.58 kB
assets/main-jTplWtYj.js (removed) 5.84 kB 🟢 -5.84 kB 🟢 -1.86 kB 🟢 -1.58 kB
assets/CancelSubscriptionDialogContent-ChNiBwpW.js (removed) 5.76 kB 🟢 -5.76 kB 🟢 -1.97 kB 🟢 -1.73 kB
assets/CancelSubscriptionDialogContent-DPphp7hv.js (new) 5.76 kB 🔴 +5.76 kB 🔴 +1.97 kB 🔴 +1.73 kB
assets/FreeTierDialogContent-BHKijUBo.js (removed) 5.25 kB 🟢 -5.25 kB 🟢 -1.76 kB 🟢 -1.55 kB
assets/FreeTierDialogContent-DNrX7bR9.js (new) 5.25 kB 🔴 +5.25 kB 🔴 +1.76 kB 🔴 +1.55 kB
assets/CreateWorkspaceDialogContent-DHeon8A0.js (removed) 5.19 kB 🟢 -5.19 kB 🟢 -1.83 kB 🟢 -1.58 kB
assets/CreateWorkspaceDialogContent-vLB6MjKW.js (new) 5.19 kB 🔴 +5.19 kB 🔴 +1.83 kB 🔴 +1.59 kB
assets/CloudNotificationContent-Cqj_U81d.js (new) 5.11 kB 🔴 +5.11 kB 🔴 +1.79 kB 🔴 +1.53 kB
assets/CloudNotificationContent-D1Rmt-PH.js (removed) 5.11 kB 🟢 -5.11 kB 🟢 -1.79 kB 🟢 -1.54 kB
assets/ChangeMemberRoleDialogContent-BmZQYQmW.js (removed) 5.04 kB 🟢 -5.04 kB 🟢 -1.67 kB 🟢 -1.46 kB
assets/ChangeMemberRoleDialogContent-BvIivQnt.js (new) 5.04 kB 🔴 +5.04 kB 🔴 +1.66 kB 🔴 +1.46 kB
assets/missingModelDownload-66qtSGAa.js (new) 5.04 kB 🔴 +5.04 kB 🔴 +1.96 kB 🔴 +1.71 kB
assets/missingModelDownload-yTzXT0uR.js (removed) 5.04 kB 🟢 -5.04 kB 🟢 -1.95 kB 🟢 -1.7 kB
assets/EditWorkspaceDialogContent-s4lOmw1i.js (new) 5 kB 🔴 +5 kB 🔴 +1.79 kB 🔴 +1.56 kB
assets/EditWorkspaceDialogContent-vy3SimWH.js (removed) 5 kB 🟢 -5 kB 🟢 -1.79 kB 🟢 -1.55 kB
assets/PaletteSwatchRow-D7rjYvso.js (removed) 4.91 kB 🟢 -4.91 kB 🟢 -1.9 kB 🟢 -1.69 kB
assets/PaletteSwatchRow-DFZMjSBt.js (new) 4.91 kB 🔴 +4.91 kB 🔴 +1.9 kB 🔴 +1.69 kB
assets/WidgetTextarea-CHYOUnXX.js (new) 4.86 kB 🔴 +4.86 kB 🔴 +1.9 kB 🔴 +1.66 kB
assets/WidgetTextarea-pYis9JKU.js (removed) 4.86 kB 🟢 -4.86 kB 🟢 -1.91 kB 🟢 -1.66 kB
assets/DowngradeRemoveMembersDialogContent-AZY9ZR3n.js (removed) 4.83 kB 🟢 -4.83 kB 🟢 -1.71 kB 🟢 -1.47 kB
assets/DowngradeRemoveMembersDialogContent-Cu1QSfcH.js (new) 4.83 kB 🔴 +4.83 kB 🔴 +1.7 kB 🔴 +1.47 kB
assets/saveMesh-BR_sXK9n.js (removed) 4.81 kB 🟢 -4.81 kB 🟢 -1.56 kB 🟢 -1.38 kB
assets/saveMesh-DLsrK_4s.js (new) 4.81 kB 🔴 +4.81 kB 🔴 +1.56 kB 🔴 +1.38 kB
assets/ValueControlPopover-CoRUHNdG.js (new) 4.55 kB 🔴 +4.55 kB 🔴 +1.58 kB 🔴 +1.42 kB
assets/ValueControlPopover-obXglOB-.js (removed) 4.55 kB 🟢 -4.55 kB 🟢 -1.58 kB 🟢 -1.42 kB
assets/ApiNodesSignInContent-B3C0rub_.js (new) 4.14 kB 🔴 +4.14 kB 🔴 +1.34 kB 🔴 +1.17 kB
assets/ApiNodesSignInContent-p5pvdEVP.js (removed) 4.14 kB 🟢 -4.14 kB 🟢 -1.34 kB 🟢 -1.18 kB
assets/Slider-C_DNS8uS.js (new) 3.92 kB 🔴 +3.92 kB 🔴 +1.45 kB 🔴 +1.25 kB
assets/Slider-teOSgffu.js (removed) 3.92 kB 🟢 -3.92 kB 🟢 -1.45 kB 🟢 -1.25 kB
assets/DeleteWorkspaceDialogContent-BlNBYEWx.js (removed) 3.91 kB 🟢 -3.91 kB 🟢 -1.47 kB 🟢 -1.27 kB
assets/DeleteWorkspaceDialogContent-D_FvPwYs.js (new) 3.91 kB 🔴 +3.91 kB 🔴 +1.47 kB 🔴 +1.26 kB
assets/WidgetBoundingBox-1vKOjtdI.js (new) 3.82 kB 🔴 +3.82 kB 🔴 +1.06 kB 🔴 +941 B
assets/WidgetBoundingBox-Cpsr5u_y.js (removed) 3.82 kB 🟢 -3.82 kB 🟢 -1.06 kB 🟢 -925 B
assets/WidgetGalleria-B3V9pw2_.js (new) 3.8 kB 🔴 +3.8 kB 🔴 +1.48 kB 🔴 +1.32 kB
assets/WidgetGalleria-GMVRz9Ze.js (removed) 3.8 kB 🟢 -3.8 kB 🟢 -1.49 kB 🟢 -1.33 kB
assets/LeaveWorkspaceDialogContent-BpMUFnXG.js (new) 3.73 kB 🔴 +3.73 kB 🔴 +1.42 kB 🔴 +1.22 kB
assets/LeaveWorkspaceDialogContent-dZst7Kmj.js (removed) 3.73 kB 🟢 -3.73 kB 🟢 -1.41 kB 🟢 -1.22 kB
assets/RemoveMemberDialogContent-D85zT133.js (new) 3.71 kB 🔴 +3.71 kB 🔴 +1.37 kB 🔴 +1.19 kB
assets/RemoveMemberDialogContent-NPTP6IFu.js (removed) 3.71 kB 🟢 -3.71 kB 🟢 -1.37 kB 🟢 -1.18 kB
assets/WidgetToggleSwitch-CRBEF1zg.js (removed) 3.67 kB 🟢 -3.67 kB 🟢 -1.41 kB 🟢 -1.24 kB
assets/WidgetToggleSwitch-D1hU6MO3.js (new) 3.67 kB 🔴 +3.67 kB 🔴 +1.4 kB 🔴 +1.24 kB
assets/RevokeInviteDialogContent-Cv54mLPI.js (new) 3.63 kB 🔴 +3.63 kB 🔴 +1.38 kB 🔴 +1.21 kB
assets/RevokeInviteDialogContent-DmBe6_q7.js (removed) 3.63 kB 🟢 -3.63 kB 🟢 -1.38 kB 🟢 -1.2 kB
assets/InviteMemberUpsellDialogContent-BV1sh8NG.js (new) 3.52 kB 🔴 +3.52 kB 🔴 +1.26 kB 🔴 +1.12 kB
assets/InviteMemberUpsellDialogContent-D5BFycky.js (removed) 3.52 kB 🟢 -3.52 kB 🟢 -1.26 kB 🟢 -1.12 kB
assets/workspaceCheckoutTelemetry-dOjWbulV.js (new) 3.47 kB 🔴 +3.47 kB 🔴 +1.56 kB 🔴 +1.36 kB
assets/workspaceCheckoutTelemetry-Gf0xlEYd.js (removed) 3.47 kB 🟢 -3.47 kB 🟢 -1.56 kB 🟢 -1.36 kB
assets/Media3DTop--dF1ElzE.js (new) 3.26 kB 🔴 +3.26 kB 🔴 +1.29 kB 🔴 +1.13 kB
assets/Media3DTop-D5mmX27U.js (removed) 3.26 kB 🟢 -3.26 kB 🟢 -1.3 kB 🟢 -1.13 kB
assets/WidgetMarkdown-DR6f3m7f.js (removed) 3.12 kB 🟢 -3.12 kB 🟢 -1.29 kB 🟢 -1.14 kB
assets/WidgetMarkdown-jPQPm-Wf.js (new) 3.12 kB 🔴 +3.12 kB 🔴 +1.29 kB 🔴 +1.12 kB
assets/WidgetInputText-RqMG02aW.js (removed) 3.06 kB 🟢 -3.06 kB 🟢 -1.3 kB 🟢 -1.16 kB
assets/WidgetInputText-w-qInl8Q.js (new) 3.06 kB 🔴 +3.06 kB 🔴 +1.29 kB 🔴 +1.16 kB
assets/GlobalToast-CeZ3PdBK.js (new) 3.05 kB 🔴 +3.05 kB 🔴 +1.26 kB 🔴 +1.08 kB
assets/GlobalToast-D9FF6Kon.js (removed) 3.05 kB 🟢 -3.05 kB 🟢 -1.26 kB 🟢 -1.08 kB
assets/MediaVideoTop-DB6D9yxY.js (new) 2.91 kB 🔴 +2.91 kB 🔴 +1.18 kB 🔴 +1.03 kB
assets/MediaVideoTop-hggnrapT.js (removed) 2.91 kB 🟢 -2.91 kB 🟢 -1.17 kB 🟢 -1.03 kB
assets/load3dAdvanced-BR7-h7QN.js (new) 2.87 kB 🔴 +2.87 kB 🔴 +1.13 kB 🔴 +997 B
assets/load3dAdvanced-C12mQhfL.js (removed) 2.87 kB 🟢 -2.87 kB 🟢 -1.13 kB 🟢 -987 B
assets/ErrorPanelSurveyCta-CMaIhdRC.js (new) 2.69 kB 🔴 +2.69 kB 🔴 +1.17 kB 🔴 +1.04 kB
assets/ErrorPanelSurveyCta-duKE7gD3.js (removed) 2.69 kB 🟢 -2.69 kB 🟢 -1.18 kB 🟢 -1.04 kB
assets/SubscribeToRun-BMTQ2SIV.js (removed) 2.45 kB 🟢 -2.45 kB 🟢 -1.07 kB 🟢 -933 B
assets/SubscribeToRun-DU5WMj8R.js (new) 2.45 kB 🔴 +2.45 kB 🔴 +1.06 kB 🔴 +930 B
assets/WidgetLayoutField-CM-fjcPT.js (new) 2.43 kB 🔴 +2.43 kB 🔴 +1.05 kB 🔴 +961 B
assets/WidgetLayoutField-DwzD9mg0.js (removed) 2.43 kB 🟢 -2.43 kB 🟢 -1.06 kB 🟢 -979 B
assets/WidgetChart-BT2nCoZp.js (removed) 2.41 kB 🟢 -2.41 kB 🟢 -1.03 kB 🟢 -904 B
assets/WidgetChart-CzdvHUd9.js (new) 2.41 kB 🔴 +2.41 kB 🔴 +1.03 kB 🔴 +908 B
assets/SubscriptionBenefits-B8hFLFQm.js (new) 2.07 kB 🔴 +2.07 kB 🔴 +708 B 🔴 +603 B
assets/SubscriptionBenefits-Dsq699Al.js (removed) 2.07 kB 🟢 -2.07 kB 🟢 -709 B 🟢 -608 B
assets/MediaImageTop-Bvcxas0r.js (new) 2.06 kB 🔴 +2.06 kB 🔴 +991 B 🔴 +875 B
assets/MediaImageTop-nq61iG2C.js (removed) 2.06 kB 🟢 -2.06 kB 🟢 -994 B 🟢 -881 B
assets/graphHasMissingNodes-HUODcxpp.js (new) 1.93 kB 🔴 +1.93 kB 🔴 +902 B 🔴 +793 B
assets/graphHasMissingNodes-Ydn636bR.js (removed) 1.93 kB 🟢 -1.93 kB 🟢 -905 B 🟢 -787 B
assets/TypeformEmbed-R2oOEf4Q.js (removed) 1.88 kB 🟢 -1.88 kB 🟢 -845 B 🟢 -738 B
assets/TypeformEmbed-tlfKOpgZ.js (new) 1.88 kB 🔴 +1.88 kB 🔴 +842 B 🔴 +738 B
assets/MediaTextTop-C_j7E7cR.js (removed) 1.82 kB 🟢 -1.82 kB 🟢 -885 B 🟢 -755 B
assets/MediaTextTop-DnGXFYzC.js (new) 1.82 kB 🔴 +1.82 kB 🔴 +885 B 🔴 +781 B
assets/WidgetColorPicker-BowwlgtN.js (new) 1.74 kB 🔴 +1.74 kB 🔴 +784 B 🔴 +699 B
assets/WidgetColorPicker-DYwQAYg1.js (removed) 1.74 kB 🟢 -1.74 kB 🟢 -790 B 🟢 -701 B
assets/Loader-C5btCxDX.js (removed) 1.69 kB 🟢 -1.69 kB 🟢 -815 B 🟢 -719 B
assets/Loader-DbCfC3aT.js (new) 1.69 kB 🔴 +1.69 kB 🔴 +814 B 🔴 +745 B
assets/WidgetColors-D-t2s_up.js (new) 1.68 kB 🔴 +1.68 kB 🔴 +833 B 🔴 +742 B
assets/WidgetColors-ZX8J8-TA.js (removed) 1.68 kB 🟢 -1.68 kB 🟢 -837 B 🟢 -739 B
assets/MediaAudioTop-C1s1BUFJ.js (removed) 1.67 kB 🟢 -1.67 kB 🟢 -837 B 🟢 -695 B
assets/MediaAudioTop-F-1vG8hq.js (new) 1.67 kB 🔴 +1.67 kB 🔴 +838 B 🔴 +694 B
assets/Textarea-BMiBVb3U.js (removed) 1.61 kB 🟢 -1.61 kB 🟢 -844 B 🟢 -750 B
assets/Textarea-nWFLGVts.js (new) 1.61 kB 🔴 +1.61 kB 🔴 +845 B 🔴 +739 B
assets/signInSchema-C0eq5Dd9.js (new) 1.6 kB 🔴 +1.6 kB 🔴 +585 B 🔴 +549 B
assets/signInSchema-DxznaqFc.js (removed) 1.6 kB 🟢 -1.6 kB 🟢 -584 B 🟢 -507 B
assets/VideoPlayOverlay-BmmI0-KZ.js (removed) 1.52 kB 🟢 -1.52 kB 🟢 -760 B 🟢 -674 B
assets/VideoPlayOverlay-CHy5xUJg.js (new) 1.52 kB 🔴 +1.52 kB 🔴 +761 B 🔴 +676 B
assets/CloudRunButtonWrapper-4sMVSIaC.js (new) 1.11 kB 🔴 +1.11 kB 🔴 +547 B 🔴 +483 B
assets/CloudRunButtonWrapper-CqZLyodd.js (removed) 1.11 kB 🟢 -1.11 kB 🟢 -551 B 🟢 -488 B
assets/MediaOtherTop-Bb6qIWZp.js (removed) 1.07 kB 🟢 -1.07 kB 🟢 -607 B 🟢 -502 B
assets/MediaOtherTop-C2P2pxEk.js (new) 1.07 kB 🔴 +1.07 kB 🔴 +605 B 🔴 +502 B
assets/cloudSessionCookie-BY5dAZfN.js (removed) 991 B 🟢 -991 B 🟢 -468 B 🟢 -413 B
assets/cloudSessionCookie-BY5kEMG-.js (new) 991 B 🔴 +991 B 🔴 +469 B 🔴 +423 B
assets/cloudBadges-CKwNm7sD.js (removed) 973 B 🟢 -973 B 🟢 -549 B 🟢 -467 B
assets/cloudBadges-TeAEKHps.js (new) 973 B 🔴 +973 B 🔴 +550 B 🔴 +469 B
assets/ComfyOrgHeader-C0cx7iXA.js (removed) 958 B 🟢 -958 B 🟢 -527 B 🟢 -462 B
assets/ComfyOrgHeader-C14KriIF.js (new) 958 B 🔴 +958 B 🔴 +527 B 🔴 +461 B
assets/Load3DAdvanced-BQxRYRlG.js (removed) 813 B 🟢 -813 B 🟢 -453 B 🟢 -401 B
assets/Load3DAdvanced-DKKbvopy.js (new) 813 B 🔴 +813 B 🔴 +453 B 🔴 +404 B
assets/widgetTypes-Bwa7uSq3.js (removed) 563 B 🟢 -563 B 🟢 -312 B 🟢 -265 B
assets/widgetTypes-CNK1jMxu.js (new) 563 B 🔴 +563 B 🔴 +310 B 🔴 +263 B
assets/nightlyBadges-DnadzXV6.js (removed) 464 B 🟢 -464 B 🟢 -306 B 🟢 -256 B
assets/nightlyBadges-M07m-vLg.js (new) 464 B 🔴 +464 B 🔴 +308 B 🔴 +255 B
assets/src-BP9ZvTm6.js (new) 446 B 🔴 +446 B 🔴 +320 B 🔴 +268 B
assets/src-BTBP0gHV.js (removed) 446 B 🟢 -446 B 🟢 -321 B 🟢 -270 B
assets/vRekaZIndex-7lKTtd1c.js (new) 360 B 🔴 +360 B 🔴 +262 B 🔴 +216 B
assets/vRekaZIndex-K15ShHuP.js (removed) 360 B 🟢 -360 B 🟢 -264 B 🟢 -215 B
assets/missingModelDownload-BijLI3-P.js (removed) 228 B 🟢 -228 B 🟢 -150 B 🟢 -128 B
assets/missingModelDownload-Cj--Is0o.js (new) 228 B 🔴 +228 B 🔴 +150 B 🔴 +134 B
assets/SubscriptionPanelContentWorkspace-BxmpfjIW.js (removed) 179 B 🟢 -179 B 🟢 -117 B 🟢 -108 B
assets/SubscriptionPanelContentWorkspace-DHuV8tRw.js (new) 179 B 🔴 +179 B 🔴 +117 B 🔴 +103 B
assets/Load3dViewerContent-ChTXerUE.js (removed) 137 B 🟢 -137 B 🟢 -103 B 🟢 -92 B
assets/Load3dViewerContent-COSldePB.js (new) 137 B 🔴 +137 B 🔴 +103 B 🔴 +91 B
assets/WidgetBoundingBox-CFxYhbeS.js (new) 131 B 🔴 +131 B 🔴 +100 B 🔴 +94 B
assets/WidgetBoundingBox-DZVGi1Yh.js (removed) 131 B 🟢 -131 B 🟢 -100 B 🟢 -92 B
assets/Load3DAdvanced-C_QvHLAt.js (removed) 122 B 🟢 -122 B 🟢 -97 B 🟢 -89 B
assets/Load3DAdvanced-DRjdxs61.js (new) 122 B 🔴 +122 B 🔴 +97 B 🔴 +89 B
assets/WidgetLegacy-BHDfWsc7.js (new) 119 B 🔴 +119 B 🔴 +108 B 🔴 +93 B
assets/WidgetLegacy-D_0UfLev.js (removed) 119 B 🟢 -119 B 🟢 -108 B 🟢 -94 B
assets/workflowDraftStoreV2-Ct1KVmED.js (new) 113 B 🔴 +113 B 🔴 +105 B 🔴 +117 B
assets/workflowDraftStoreV2-DX_yNfBk.js (removed) 113 B 🟢 -113 B 🟢 -105 B 🟢 -114 B
assets/Load3D-CNnK6ene.js (new) 98 B 🔴 +98 B 🔴 +89 B 🔴 +78 B
assets/Load3D-hnZSfdmX.js (removed) 98 B 🟢 -98 B 🟢 -89 B 🟢 -88 B
assets/i18n-BogQhhCa.js (removed) 97 B 🟢 -97 B 🟢 -92 B 🟢 -87 B
assets/i18n-CO8F4j93.js (new) 97 B 🔴 +97 B 🔴 +92 B 🔴 +87 B
assets/changeTracker-Bvu5fLLE.js (removed) 93 B 🟢 -93 B 🟢 -95 B 🟢 -92 B
assets/changeTracker-I0OFauzU.js (new) 93 B 🔴 +93 B 🔴 +95 B 🔴 +81 B

Status: 110 added / 109 removed / 54 unchanged

⚡ Performance

⏳ Performance tests in progress…

@coderabbitai

coderabbitai Bot commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

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

Use the following commands to manage reviews:

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

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Workspace member credit usage and monthly limits are added to workspace data, local state, member menus, a feature-gated members-table column, and a localized limit-management dialog with validation.

Changes

Member credit limit management

Layer / File(s) Summary
Credit data and local state
src/platform/workspace/api/workspaceApi.ts, src/platform/workspace/stores/teamWorkspaceStore.ts, src/platform/workspace/stores/teamWorkspaceStore.test.ts
Member credit fields are mapped from API data, stored locally, and updated through setMemberCreditLimit.
Credit limit dialog
src/platform/workspace/components/dialogs/SetMemberCreditLimitDialogContent.vue, src/services/dialogService.ts, src/locales/en/main.json, src/platform/workspace/components/dialogs/SetMemberCreditLimitDialogContent.test.ts, src/components/dialog/GlobalDialog.test.ts
A localized dialog supports limited or unlimited modes, validates limits, warns when usage meets or exceeds the entered limit, and updates member state.
Member menu integration
src/platform/workspace/composables/useMembersPanel.ts, src/platform/workspace/composables/useMembersPanel.test.ts, src/platform/workspace/components/dialogs/settings/MembersPanelContent.test.ts
The feature-gated menu action opens the dialog with member credit data; current-user and original-owner menu behavior is updated and tested.
Member credit presentation and layout
src/platform/workspace/composables/useWorkspaceUI.ts, src/platform/workspace/composables/useWorkspaceUI.test.ts, src/platform/workspace/components/dialogs/settings/MembersPanelContent.vue, src/platform/workspace/components/dialogs/settings/MemberListItem.vue, src/platform/workspace/components/dialogs/settings/MemberListItem.test.ts
Owner team workspaces can display a credits-used column with usage text and a capped progress bar when billing control is enabled.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Possibly related PRs

Suggested reviewers: drjkl

Sequence Diagram(s)

sequenceDiagram
  participant MemberList
  participant useMembersPanel
  participant dialogService
  participant SetMemberCreditLimitDialogContent
  participant teamWorkspaceStore
  MemberList->>useMembersPanel: select set credit limit
  useMembersPanel->>dialogService: showSetMemberCreditLimitDialog(member details)
  dialogService->>SetMemberCreditLimitDialogContent: open dialog
  SetMemberCreditLimitDialogContent->>teamWorkspaceStore: setMemberCreditLimit(userId, limit)
  teamWorkspaceStore-->>MemberList: updated local member limit
Loading

Important

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
End-To-End Regression Coverage For Fixes ❓ Inconclusive Commit subjects and PR title aren’t available here, so I can’t verify the required bug-fix signal without guessing. Please provide the PR title and commit subjects (or confirm none use fix/bugfix/hotfix language) so I can assess whether browser_tests coverage was required.
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: adding per-member monthly credit limit UI in workspace settings.
Description check ✅ Passed The description mostly matches the template and includes Summary, Changes, Review Focus, and screenshots with key details.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Adr Compliance For Entity/Litegraph Changes ✅ Passed No changed files touch src/lib/litegraph/, src/ecs/, or graph entity files, so ADR 0003/0008 checks are not applicable here.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch jaewon/fe-1277-settings-members-per-member-monthly-credit-limit-ui-owner

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

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

Inline comments:
In `@src/platform/workspace/components/dialogs/settings/MemberListItem.vue`:
- Around line 106-110: Use vue-i18n number formatting for both affected credit
displays: in
src/platform/workspace/components/dialogs/settings/MemberListItem.vue lines
106-110, obtain useI18n().n() and format both used credits and
monthlyCreditLimit with it; in
src/platform/workspace/components/dialogs/SetMemberCreditLimitDialogContent.vue
lines 80-83, pass $n(creditsUsed) to the translated warning instead of
browser-locale formatting.

In `@src/platform/workspace/composables/useMembersPanel.test.ts`:
- Line 630: Update the remove-member tests around memberMenuItems to select the
action by its visible label rather than the positional index [2]. Apply the same
change to the additional occurrence, preserving the existing behavioral
assertions while making them independent of menu ordering.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

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

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 87df12aa-e9fe-47f2-b30c-e7a201475c10

📥 Commits

Reviewing files that changed from the base of the PR and between d1d5558 and 42089d2.

📒 Files selected for processing (13)
  • src/locales/en/main.json
  • src/platform/workspace/api/workspaceApi.ts
  • src/platform/workspace/components/dialogs/SetMemberCreditLimitDialogContent.test.ts
  • src/platform/workspace/components/dialogs/SetMemberCreditLimitDialogContent.vue
  • src/platform/workspace/components/dialogs/settings/MemberListItem.vue
  • src/platform/workspace/components/dialogs/settings/MembersPanelContent.test.ts
  • src/platform/workspace/components/dialogs/settings/MembersPanelContent.vue
  • src/platform/workspace/composables/useMembersPanel.test.ts
  • src/platform/workspace/composables/useMembersPanel.ts
  • src/platform/workspace/composables/useWorkspaceUI.test.ts
  • src/platform/workspace/composables/useWorkspaceUI.ts
  • src/platform/workspace/stores/teamWorkspaceStore.ts
  • src/services/dialogService.ts

Comment thread src/platform/workspace/components/dialogs/settings/MemberListItem.vue Outdated
Comment thread src/platform/workspace/composables/useMembersPanel.test.ts
@codecov

codecov Bot commented Jul 16, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 91.45299% with 10 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
...rc/platform/workspace/stores/teamWorkspaceStore.ts 16.66% 5 Missing ⚠️
src/services/dialogService.ts 0.00% 3 Missing ⚠️
...omponents/dialogs/settings/MembersPanelContent.vue 50.00% 1 Missing and 1 partial ⚠️
@@            Coverage Diff             @@
##             main   #13716      +/-   ##
==========================================
- Coverage   78.49%   78.23%   -0.26%     
==========================================
  Files        1677     1684       +7     
  Lines      106121    96954    -9167     
  Branches    38118    34923    -3195     
==========================================
- Hits        83297    75852    -7445     
+ Misses      22022    20642    -1380     
+ Partials      802      460     -342     
Flag Coverage Δ
unit 67.28% <91.45%> (+0.17%) ⬆️

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

Files with missing lines Coverage Δ
src/platform/workspace/api/workspaceApi.ts 85.62% <ø> (+43.90%) ⬆️
...ents/dialogs/SetMemberCreditLimitDialogContent.vue 100.00% <100.00%> (ø)
...ace/components/dialogs/settings/MemberListItem.vue 100.00% <100.00%> (ø)
.../platform/workspace/composables/useMembersPanel.ts 95.93% <100.00%> (+0.28%) ⬆️
...c/platform/workspace/composables/useWorkspaceUI.ts 93.75% <100.00%> (+40.94%) ⬆️
...omponents/dialogs/settings/MembersPanelContent.vue 96.87% <50.00%> (-3.13%) ⬇️
src/services/dialogService.ts 58.29% <0.00%> (-1.40%) ⬇️
...rc/platform/workspace/stores/teamWorkspaceStore.ts 90.51% <16.66%> (+33.01%) ⬆️

... and 476 files with indirect coverage changes

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

@dante01yoon dante01yoon changed the title feat(workspace): add per-member monthly credit limit UI feat(workspace): add per-member monthly credit limit UI (FE-1277) Jul 16, 2026
With the new four-column members grid the right-aligned Role cell butted
against the left-aligned Credits column (e.g. "Owner546 / 3,000"). Left-
align Role in both the header and rows, matching the Figma layout.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Caution

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

⚠️ Outside diff range comments (2)
src/platform/workspace/components/dialogs/settings/MemberListItem.vue (1)

61-61: 🩺 Stability & Availability | 🔴 Critical | ⚡ Quick win

Guard optional menuItems before reading .length.

menuItems is optional, and the parent passes memberMenus.get(member.id), which can be undefined for members without actions. Accessing menuItems.length then throws during rendering and can break the member list.

Proposed fix
-      <DropdownMenu v-if="menuItems.length > 0" :entries="menuItems">
+      <DropdownMenu v-if="menuItems?.length" :entries="menuItems">
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/platform/workspace/components/dialogs/settings/MemberListItem.vue` at
line 61, Update the DropdownMenu condition in MemberListItem to guard menuItems
before accessing its length, so undefined values from memberMenus.get(member.id)
skip rendering safely while non-empty menus continue to render.
src/platform/workspace/components/dialogs/settings/MembersPanelContent.vue (1)

135-140: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Keep the credits header aligned with the row cells.

The credits header is gated only by permissions.canManageMembers, while MemberListItem renders the credits and action cells only when canManageMembers && !isSingleSeatPlan (isSingleSeatPlan is passed as !isOnTeamPlan). If member management is enabled on a single-seat workspace, the header adds columns that the rows omit.

Gate both the credits header and the empty action header with the same team-plan condition.

Proposed fix
-              v-if="permissions.canManageMembers"
+              v-if="permissions.canManageMembers && isOnTeamPlan"
...
-            <div v-if="permissions.canManageMembers" />
+            <div v-if="permissions.canManageMembers && isOnTeamPlan" />
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/platform/workspace/components/dialogs/settings/MembersPanelContent.vue`
around lines 135 - 140, Update the credits header and empty action header
conditions in the members panel to require both permissions.canManageMembers and
the team-plan condition, matching MemberListItem’s canManageMembers &&
!isSingleSeatPlan rendering logic. Reuse the existing isOnTeamPlan value so
single-seat workspaces omit both headers when rows omit those cells.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@src/platform/workspace/components/dialogs/settings/MemberListItem.vue`:
- Line 61: Update the DropdownMenu condition in MemberListItem to guard
menuItems before accessing its length, so undefined values from
memberMenus.get(member.id) skip rendering safely while non-empty menus continue
to render.

In `@src/platform/workspace/components/dialogs/settings/MembersPanelContent.vue`:
- Around line 135-140: Update the credits header and empty action header
conditions in the members panel to require both permissions.canManageMembers and
the team-plan condition, matching MemberListItem’s canManageMembers &&
!isSingleSeatPlan rendering logic. Reuse the existing isOnTeamPlan value so
single-seat workspaces omit both headers when rows omit those cells.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: a7899ed4-b96b-40bc-a8e6-04314e03fedf

📥 Commits

Reviewing files that changed from the base of the PR and between 42089d2 and c8b4c9c.

📒 Files selected for processing (2)
  • src/platform/workspace/components/dialogs/settings/MemberListItem.vue
  • src/platform/workspace/components/dialogs/settings/MembersPanelContent.vue

The credit-limit UI is mock-backed until FE-1278 wires the backend, so
shipping it enabled would expose a Credits-used column reading 0 for
everyone and a Set credit limit action that silently drops writes.

Add a member_credit_limits_enabled server flag (default off). While off,
the Members panel is unchanged: original three-column grid, right-aligned
Role, no credits column, and self/creator rows have no menu. When on, the
credits column, progress bars, and Set credit limit action appear. Flip
the flag with FE-1278.

Also expose the usage bar as an accessible progressbar.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

♻️ Duplicate comments (1)
src/platform/workspace/components/dialogs/settings/MemberListItem.vue (1)

112-117: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Use vue-i18n consistently for credit-number formatting.

The UI currently formats values using the native browser locale instead of the application locale. As per coding guidelines, use vue-i18n for formatting user-facing strings and numbers in the Composition API.

Note: This concern was flagged in a previous review and remains unresolved.

♻️ Proposed refactor

Ensure you import useI18n from vue-i18n in the script setup, then apply this pattern:

+const { n } = useI18n()
+
 const creditsLabel = computed(() => {
-  const used = (member.creditsUsedThisMonth ?? 0).toLocaleString()
-  return member.monthlyCreditLimit
-    ? `${used} / ${member.monthlyCreditLimit.toLocaleString()}`
-    : used
+  const used = n(member.creditsUsedThisMonth ?? 0)
+  return member.monthlyCreditLimit
+    ? `${used} / ${n(member.monthlyCreditLimit)}`
+    : used
 })
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/platform/workspace/components/dialogs/settings/MemberListItem.vue` around
lines 112 - 117, Update the creditsLabel computed value in MemberListItem to use
vue-i18n number formatting instead of native toLocaleString. Import and
initialize useI18n in the script setup, then format both creditsUsedThisMonth
and monthlyCreditLimit through the i18n formatter while preserving the existing
fallback and “used / limit” display behavior.

Source: Coding guidelines

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

Duplicate comments:
In `@src/platform/workspace/components/dialogs/settings/MemberListItem.vue`:
- Around line 112-117: Update the creditsLabel computed value in MemberListItem
to use vue-i18n number formatting instead of native toLocaleString. Import and
initialize useI18n in the script setup, then format both creditsUsedThisMonth
and monthlyCreditLimit through the i18n formatter while preserving the existing
fallback and “used / limit” display behavior.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 26bdea51-a769-4a90-bb13-cc41e7f98e30

📥 Commits

Reviewing files that changed from the base of the PR and between c8b4c9c and 5c1b00d.

📒 Files selected for processing (9)
  • src/composables/useFeatureFlags.ts
  • src/platform/remoteConfig/types.ts
  • src/platform/workspace/components/dialogs/settings/MemberListItem.test.ts
  • src/platform/workspace/components/dialogs/settings/MemberListItem.vue
  • src/platform/workspace/components/dialogs/settings/MembersPanelContent.vue
  • src/platform/workspace/composables/useMembersPanel.test.ts
  • src/platform/workspace/composables/useMembersPanel.ts
  • src/platform/workspace/composables/useWorkspaceUI.test.ts
  • src/platform/workspace/composables/useWorkspaceUI.ts

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Caution

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

⚠️ Outside diff range comments (1)
src/services/dialogService.ts (1)

360-362: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Simplify redundant width utilities.

The max-w and sm:max-w classes duplicate the exact same dimension constraint as the base width and each other. You can simplify this down to standard responsive boundaries (e.g., w-[360px] max-w-[95vw]), which natively restricts the 360px dialog width on smaller screens without needing arbitrary min-functions or responsive prefix redundancy.

♻️ Proposed refactor
-          contentClass:
-            'w-[min(360px,95vw)] max-w-[min(360px,95vw)] sm:max-w-[min(360px,95vw)] border-0 bg-transparent shadow-none'
+          contentClass:
+            'w-[360px] max-w-[95vw] border-0 bg-transparent shadow-none'
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/services/dialogService.ts` around lines 360 - 362, Simplify the
contentClass width utilities in the dialog configuration by replacing the
redundant min-function and responsive max-width classes with standard responsive
boundaries: a fixed 360px width constrained by a 95vw maximum. Preserve the
existing border, background, and shadow classes.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@src/services/dialogService.ts`:
- Around line 360-362: Simplify the contentClass width utilities in the dialog
configuration by replacing the redundant min-function and responsive max-width
classes with standard responsive boundaries: a fixed 360px width constrained by
a 95vw maximum. Preserve the existing border, background, and shadow classes.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: d6befda5-9b7b-470f-a097-702ea4348a7b

📥 Commits

Reviewing files that changed from the base of the PR and between 5c1b00d and 4556065.

📒 Files selected for processing (7)
  • src/locales/en/main.json
  • src/platform/workspace/api/workspaceApi.ts
  • src/platform/workspace/composables/useMembersPanel.test.ts
  • src/platform/workspace/composables/useMembersPanel.ts
  • src/platform/workspace/composables/useWorkspaceUI.test.ts
  • src/platform/workspace/composables/useWorkspaceUI.ts
  • src/services/dialogService.ts

const modeGroupName = useId()
const mode = ref<'limited' | 'unlimited'>(
currentLimit ? 'limited' : 'unlimited'
)

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.

issue: currentLimit=0 is treated as falsy, so the dialog opens in "No limit" mode when a member already has a 0-credit cap. Should be:

currentLimit !== null ? "limited" : "unlimited"

Same falsy-0 pattern affects MemberListItem.vue (v-if="member.monthlyCreditLimit" skips the progress bar and the used / limit label for a zero-limit member).

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Fixed in 3b22457. Limit presence now uses explicit nullish checks in both the dialog and member row. A zero cap opens in limited mode and renders safely without dividing by zero. The focused suite passes 194 tests, plus typecheck, lint, format check, and knip.

<template>
<div
class="flex w-lg max-w-full flex-col rounded-2xl border border-border-default bg-base-background"
>

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.

issue: (non-blocking) The dialog container is a plain <div> with no ARIA dialog semantics. Screen readers won't identify it as a dialog or announce its title. Needs role="dialog" aria-modal="true" and aria-labelledby pointing to the <h2>. No focus trap is implemented either -- Tab will escape to elements behind the overlay.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Addressed the actual accessibility gap in 3b22457. GlobalDialog already renders Reka DialogContent, which provides the dialog/modal semantics and modal focus scope, so adding a second dialog role or focus trap inside the content would duplicate them. I connected its existing aria-labelledby value to the h2 and added an integration test that asserts the rendered dialog has the translated accessible name. All focused validation passes.

aria-valuemin="0"
aria-valuemax="100"
:aria-label="creditsLabel"
>

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.

suggestion: (non-blocking) The progressbar has no aria-valuetext, so screen readers announce a raw percentage (e.g. "73%") with no context. Adding :aria-valuetext="creditsLabel" (or a more descriptive variant like "546 of 3,000 credits used") would give assistive tech the full picture.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Applied in 3b22457. The progress bar now has a localized Monthly credits label and contextual aria-valuetext such as 546 of 3,000 monthly credits used. The component test covers the accessible name and value text; all focused validation passes.

isOriginalOwner: member.is_original_owner ?? false
isOriginalOwner: member.is_original_owner ?? false,
creditsUsedThisMonth: member.credits_used_this_month ?? 0,
monthlyCreditLimit: member.monthly_credit_limit ?? null

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.

suggestion: creditsUsedThisMonth defaults to 0 for a field the backend does not send yet. With the credits column visible (flag on), every member shows 0 -- indistinguishable from a real zero-usage value. Keeping it undefined (matching the ? on WorkspaceMember.creditsUsedThisMonth) would let the UI render a dash or skeleton until FE-1278 delivers real values.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Applied in 3b22457. The API mapping now preserves absent usage as undefined. The row renders an em dash and omits the progress bar until usage is available, and the dialog no longer infers zero usage for warning logic. Tests cover absent versus explicit zero values; all focused validation passes.

Comment thread src/locales/en/main.json
"limitOption": "Limit monthly credit usage to:",
"noLimit": "No limit",
"warning": "This user has already spent {credits} credits. Setting this cap will prevent further runs until next month.",
"invalidLimit": "Enter a credit limit greater than zero.",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

nitpick: (non-blocking) "Setting this cap will prevent further runs until next month" implies any cap triggers a block, but the warning only shows when the proposed limit is at or below current spend. Something like "Setting this limit at or below their current usage will prevent further runs until next month" matches the actual condition more precisely.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Applied in 3b22457. The warning now says that setting the limit at or below current usage will prevent further runs until next month. Format and JSON validation pass.

Comment thread src/locales/en/main.json
"role": "Role"
"role": "Role",
"creditsUsed": "Credits used this month"
},

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

nitpick: (non-blocking) The column header "Credits used this month" only describes the uncapped display (plain usage number). When a cap is set the cell shows 546 / 3,000, making the header incomplete. "Monthly credits" or "Credits (this month)" covers both states.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Applied in 3b22457. The column is now labeled Monthly credits so it covers both usage-only and used-over-limit displays. Format and JSON validation pass.

// Per-member monthly credit limit UI (FE-1277). The cloud OpenAPI carries
// neither usage nor limit yet; persistence and real usage land in FE-1278.
credits_used_this_month?: number
monthly_credit_limit?: number | null

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

nitpick: (non-blocking) credits_used_this_month?: number and monthly_credit_limit?: number | null use both ? and | null, giving a three-valued type (undefined | number | null). The ?? null fallback in mapApiMemberToWorkspaceMember collapses undefined and null together, losing the "field absent vs cap cleared" distinction. A // TODO(FE-1278): remove ? once backend sends these fields comment would prevent the optionals from silently outliving their purpose.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Addressed the underlying distinction in 3b22457. The mapping now preserves undefined versus explicit null for the limit, and undefined versus explicit zero for usage, with tests for both cases. I did not add another tracking comment because the adjacent API contract note already identifies FE-1278 and explains that these fields are not yet in the cloud OpenAPI.

key: 'set-member-credit-limit',
component,
props,
dialogComponentProps: workspaceDialogProps

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

nitpick: (non-blocking) The static key "set-member-credit-limit" means rapid re-open overwrites the first dialog's props. An owner who opens the dialog for member A and immediately triggers it for member B will commit the limit for whichever memberId is in props at submission time. Other workspace dialogs share this pattern, but the local-only mutation makes silent overwrites harder to detect. Keying on set-member-credit-limit-${props.memberId} would make each member's dialog independent.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Checked, but I kept the shared modal key. The member list cannot be activated while this modal is open, and dialogStore.showDialog only raises an existing keyed dialog; it does not overwrite its contentProps. The described cross-member overwrite therefore cannot occur through this flow. Per-member keys would instead allow stacked copies and require dynamic close-key plumbing.

}

function memberMenuItems(member: WorkspaceMember): MenuItem[] {
const creditLimitItem: MenuItem = {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

nitpick: (non-blocking) memberMenuItems() builds credit limit items for all non-self, non-creator rows without checking the caller's role. It works today because MemberListItem gates the whole action column on canManageMembers, but the composable could be more self-contained with an early guard:

if (!permissions.value.canManageMembers) return []

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Applied in 3b22457. memberMenuItems now returns early when canManageMembers is false, with a focused test covering the non-manager path. All focused validation passes.

@@ -198,9 +203,24 @@ function useWorkspaceUIInternal() {
)

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.

question: The isOriginalOwnerByEmail helper (below the diff) re-implements creator detection locally with its own tie-breaking by id.localeCompare, rather than deriving from store.isCurrentUserOriginalOwner, which the store documents as the single source of truth. Could these two signals ever disagree? If not, would it be safe to replace the local computation with store.isCurrentUserOriginalOwner?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Good catch. The signals could disagree when the explicit original-owner field or the owner-only fallback differs from the local earliest-member calculation. In 3b22457 I removed the duplicate helper and now derive this UI state from store.isCurrentUserOriginalOwner, while preserving the personal-workspace behavior. The focused tests now exercise the store signal directly.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

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

Inline comments:
In `@src/platform/workspace/composables/useMembersPanel.test.ts`:
- Around line 677-693: Update the test in the “preserves unavailable usage and
limit values for the dialog” case to select the credit-limit menu action by its
stable translation key or label instead of indexing memberMenuItems(member) at
position 1; keep the existing command invocation and dialog assertion unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

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

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 9ba6ed6b-8e1c-4579-8465-9ee1278d43d3

📥 Commits

Reviewing files that changed from the base of the PR and between 4556065 and 3b22457.

📒 Files selected for processing (13)
  • src/components/dialog/GlobalDialog.test.ts
  • src/locales/en/main.json
  • src/platform/workspace/components/dialogs/SetMemberCreditLimitDialogContent.test.ts
  • src/platform/workspace/components/dialogs/SetMemberCreditLimitDialogContent.vue
  • src/platform/workspace/components/dialogs/settings/MemberListItem.test.ts
  • src/platform/workspace/components/dialogs/settings/MemberListItem.vue
  • src/platform/workspace/composables/useMembersPanel.test.ts
  • src/platform/workspace/composables/useMembersPanel.ts
  • src/platform/workspace/composables/useWorkspaceUI.test.ts
  • src/platform/workspace/composables/useWorkspaceUI.ts
  • src/platform/workspace/stores/teamWorkspaceStore.test.ts
  • src/platform/workspace/stores/teamWorkspaceStore.ts
  • src/services/dialogService.ts

Comment on lines +677 to +693
it('preserves unavailable usage and limit values for the dialog', async () => {
const panel = await setup()
const member = createMember({ id: 'mem-9', name: 'Jane' })
const limitItem = panel.memberMenuItems(member)[1]

limitItem.command?.({
originalEvent: new Event('click'),
item: limitItem
})

expect(mockShowSetMemberCreditLimitDialog).toHaveBeenCalledWith({
memberId: 'mem-9',
memberName: 'Jane',
creditsUsed: undefined,
currentLimit: undefined
})
})

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.

📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Select menu actions by label instead of array index.

To prevent unrelated menu ordering changes from breaking behavioral tests, find the target item by its translation key/label rather than hardcoding its index.

As per path instructions, prefer stable behavioral tests and avoid change-detector expectations.

♻️ Proposed refactor
-      const limitItem = panel.memberMenuItems(member)[1]
+      const limitItem = panel
+        .memberMenuItems(member)
+        .find(
+          (item) =>
+            item.label === 'workspacePanel.members.actions.setCreditLimit'
+        )!
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/platform/workspace/composables/useMembersPanel.test.ts` around lines 677
- 693, Update the test in the “preserves unavailable usage and limit values for
the dialog” case to select the credit-limit menu action by its stable
translation key or label instead of indexing memberMenuItems(member) at position
1; keep the existing command invocation and dialog assertion unchanged.

Source: Path instructions

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