Skip to content

Conversation

@viva-jinyi
Copy link
Member

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

Summary

Show active jobs in grid view matching the list view behavior, with refactored component structure.

Changes

  • ActiveJobCard: New component for grid view job display with progress bar
  • AssetsSidebarGridView: Extracted grid view logic from AssetsSidebarTab (matching ListView pattern)
  • Progress styling: Use useProgressBarBackground composable for consistent progress bar styling
  • Assets header: Add "Generated/Imported assets" header in grid view

Files Changed

  • src/components/sidebar/tabs/assets/ActiveJobCard.vue (new)
  • src/components/sidebar/tabs/AssetsSidebarGridView.vue (new)
  • src/components/sidebar/tabs/AssetsSidebarTab.vue (refactored)
screen-capture.webm

┆Issue is synchronized with this Notion page by Unito

@viva-jinyi viva-jinyi requested a review from a team as a code owner January 21, 2026 06:00
@viva-jinyi viva-jinyi added enhancement New feature or request area:queue area:ui General user interface and experience improvements labels Jan 21, 2026
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 21, 2026

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

📝 Walkthrough

Walkthrough

Adds a new AssetsSidebarGridView component and ActiveJobCard (with tests); replaces per-item grid rendering in AssetsSidebarTab with the new grid component; moves active-job detection into shared isActiveJobState in src/utils/queueUtil.ts; adds a locale string.

Changes

Cohort / File(s) Summary
New Grid View Component
src/components/sidebar/tabs/AssetsSidebarGridView.vue
New Vue 3 TS script-setup component: renders active jobs (via ActiveJobCard) and assets in a virtualized grid; props assets, isSelected, assetType, showOutputCount, getOutputCount; emits select-asset, context-menu, approach-end, zoom, output-count-click.
New Job Card & tests
src/components/sidebar/tabs/assets/ActiveJobCard.vue, src/components/sidebar/tabs/assets/ActiveJobCard.test.ts
New ActiveJobCard showing spinner, optional progress bar and status text; tests cover running/pending/error states, progress rendering, preview image and accessibility.
Tab Integration
src/components/sidebar/tabs/AssetsSidebarTab.vue
Replaced per-item VirtualGrid + MediaAssetCard rendering with AssetsSidebarGridView; updated imports, props and event wiring to the new component API.
List View & util
src/components/sidebar/tabs/AssetsSidebarListView.vue, src/utils/queueUtil.ts
AssetsSidebarListView.vue now imports and uses shared isActiveJobState from src/utils/queueUtil.ts; added isActiveJobState(state: JobState): boolean.
Locale
src/locales/en/main.json
Added sideToolbar.labels.activeJobStatus translation string.
Manifest / package files
manifest_file, package.json
Minor manifest/package updates referenced by additions.

Sequence Diagram(s)

sequenceDiagram
  participant Tab as AssetsSidebarTab
  participant Grid as AssetsSidebarGridView
  participant Store as useJobList
  participant JobCard as ActiveJobCard

  Tab->>Grid: pass props (assets, isSelected, assetType, showOutputCount, getOutputCount)
  Grid->>Store: call/useJobList (compute active jobs via isActiveJobState)
  Store-->>Grid: return activeJobItems
  Grid->>JobCard: render ActiveJobCard for each active job (pass job)
  JobCard-->>Grid: render spinner/progress/status
  Grid-->>Tab: emit events (select-asset, context-menu, approach-end, zoom, output-count-click)
  Tab-->>Tab: handle emitted events (selection, context menu, zoom)
Loading

Possibly related PRs

Suggested reviewers

  • shinshin86
  • KarryCharon
  • Yorha4D
  • benceruleanlu

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

❤️ Share

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

@github-actions
Copy link

github-actions bot commented Jan 21, 2026

🎨 Storybook Build Status

Build completed successfully!

⏰ Completed at: 01/22/2026, 01:47:03 AM UTC

🔗 Links


🎉 Your Storybook is ready for review!

@dosubot dosubot bot added the size:L This PR changes 100-499 lines, ignoring generated files. label Jan 21, 2026
@github-actions
Copy link

github-actions bot commented Jan 21, 2026

🎭 Playwright Tests: ⚠️ Passed with flaky tests

Results: 505 passed, 0 failed, 1 flaky, 8 skipped (Total: 514)

❌ Failed Tests

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

@github-actions
Copy link

github-actions bot commented Jan 21, 2026

Bundle Size Report

Summary

  • Raw size: 21.4 MB baseline 21.4 MB — 🔴 +7.03 kB
  • Gzip: 4.44 MB baseline 4.44 MB — 🔴 +1.25 kB
  • Brotli: 3.29 MB baseline 3.29 MB — 🔴 +751 B
  • Bundles: 151 current • 151 baseline • 62 added / 62 removed

Category Glance
Data & Services 🔴 +7.03 kB (3.06 MB) · Vendor & Third-Party ⚪ 0 B (10.4 MB) · Other ⚪ 0 B (6.28 MB) · Graph Workspace ⚪ 0 B (1.02 MB) · Panels & Settings ⚪ 0 B (430 kB) · Views & Navigation ⚪ 0 B (80.7 kB) · + 5 more

Per-category breakdown
App Entry Points — 22.3 kB (baseline 22.3 kB) • ⚪ 0 B

Main entry bundles and manifests

File Before After Δ Raw Δ Gzip Δ Brotli
assets/index-BsitZtcQ.js (new) 22.3 kB 🔴 +22.3 kB 🔴 +6.73 kB 🔴 +5.91 kB
assets/index-CXV9y9mn.js (removed) 22.3 kB 🟢 -22.3 kB 🟢 -6.72 kB 🟢 -5.89 kB

Status: 1 added / 1 removed

Graph Workspace — 1.02 MB (baseline 1.02 MB) • ⚪ 0 B

Graph editor runtime, canvas, workflow orchestration

File Before After Δ Raw Δ Gzip Δ Brotli
assets/GraphView-DxvvO-Zl.js (removed) 1.02 MB 🟢 -1.02 MB 🟢 -201 kB 🟢 -153 kB
assets/GraphView-Pj2PgCgs.js (new) 1.02 MB 🔴 +1.02 MB 🔴 +201 kB 🔴 +153 kB

Status: 1 added / 1 removed

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

Top-level views, pages, and routed surfaces

File Before After Δ Raw Δ Gzip Δ Brotli
assets/CloudSurveyView-C4K1gm9h.js (new) 17.1 kB 🔴 +17.1 kB 🔴 +3.6 kB 🔴 +3.06 kB
assets/CloudSurveyView-W2zYSC2G.js (removed) 17.1 kB 🟢 -17.1 kB 🟢 -3.61 kB 🟢 -3.06 kB
assets/CloudLoginView-BD_AumUC.js (removed) 11.8 kB 🟢 -11.8 kB 🟢 -3.09 kB 🟢 -2.72 kB
assets/CloudLoginView-CQzbGxdc.js (new) 11.8 kB 🔴 +11.8 kB 🔴 +3.09 kB 🔴 +2.72 kB
assets/UserCheckView-BRF75L7j.js (removed) 10.5 kB 🟢 -10.5 kB 🟢 -2.44 kB 🟢 -2.14 kB
assets/UserCheckView-Ck9QsSaf.js (new) 10.5 kB 🔴 +10.5 kB 🔴 +2.44 kB 🔴 +2.14 kB
assets/CloudLayoutView-BpkZFoqc.js (new) 8.54 kB 🔴 +8.54 kB 🔴 +2.24 kB 🔴 +1.96 kB
assets/CloudLayoutView-Dyo94A2h.js (removed) 8.54 kB 🟢 -8.54 kB 🟢 -2.25 kB 🟢 -1.96 kB
assets/CloudSignupView-CGe0SS8Q.js (new) 8.18 kB 🔴 +8.18 kB 🔴 +2.33 kB 🔴 +2.02 kB
assets/CloudSignupView-DI_1LIgJ.js (removed) 8.18 kB 🟢 -8.18 kB 🟢 -2.33 kB 🟢 -2.02 kB
assets/CloudForgotPasswordView-C_aQHZci.js (removed) 6.26 kB 🟢 -6.26 kB 🟢 -1.92 kB 🟢 -1.69 kB
assets/CloudForgotPasswordView-Dd9hQvjS.js (new) 6.26 kB 🔴 +6.26 kB 🔴 +1.92 kB 🔴 +1.69 kB
assets/UserSelectView-BkUGFcWJ.js (new) 5.28 kB 🔴 +5.28 kB 🔴 +1.76 kB 🔴 +1.57 kB
assets/UserSelectView-C8S_UX4d.js (removed) 5.28 kB 🟢 -5.28 kB 🟢 -1.76 kB 🟢 -1.57 kB
assets/CloudSubscriptionRedirectView-B3rV26jM.js (removed) 5.27 kB 🟢 -5.27 kB 🟢 -1.73 kB 🟢 -1.53 kB
assets/CloudSubscriptionRedirectView-Bzr5UdaE.js (new) 5.27 kB 🔴 +5.27 kB 🔴 +1.73 kB 🔴 +1.53 kB
assets/CloudAuthTimeoutView-BEXW8T0h.js (new) 5.24 kB 🔴 +5.24 kB 🔴 +1.7 kB 🔴 +1.49 kB
assets/CloudAuthTimeoutView-BLdWjKXC.js (removed) 5.24 kB 🟢 -5.24 kB 🟢 -1.7 kB 🟢 -1.49 kB
assets/CloudSorryContactSupportView-41RMhsFA.js 1.97 kB 1.97 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/layout-DT-CUejm.js 500 B 500 B ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 9 added / 9 removed

Panels & Settings — 430 kB (baseline 430 kB) • ⚪ 0 B

Configuration panels, inspectors, and settings screens

File Before After Δ Raw Δ Gzip Δ Brotli
assets/LegacyCreditsPanel-1rV5IkGG.js (new) 23.8 kB 🔴 +23.8 kB 🔴 +5.94 kB 🔴 +5.23 kB
assets/LegacyCreditsPanel-Ba2KKxyW.js (removed) 23.8 kB 🟢 -23.8 kB 🟢 -5.94 kB 🟢 -5.23 kB
assets/SubscriptionPanel-CGSYp5OC.js (removed) 20.6 kB 🟢 -20.6 kB 🟢 -4.99 kB 🟢 -4.38 kB
assets/SubscriptionPanel-Dx9Wiasi.js (new) 20.6 kB 🔴 +20.6 kB 🔴 +4.99 kB 🔴 +4.37 kB
assets/KeybindingPanel-CNJXZdDF.js (new) 14.2 kB 🔴 +14.2 kB 🔴 +3.73 kB 🔴 +3.31 kB
assets/KeybindingPanel-Nqi9eICr.js (removed) 14.2 kB 🟢 -14.2 kB 🟢 -3.73 kB 🟢 -3.31 kB
assets/AboutPanel-CehBXQjN.js (new) 10.8 kB 🔴 +10.8 kB 🔴 +2.68 kB 🔴 +2.43 kB
assets/AboutPanel-D06JYWTJ.js (removed) 10.8 kB 🟢 -10.8 kB 🟢 -2.68 kB 🟢 -2.43 kB
assets/ExtensionPanel-Dfqg7UFg.js (removed) 10.2 kB 🟢 -10.2 kB 🟢 -2.71 kB 🟢 -2.41 kB
assets/ExtensionPanel-DquSVxpY.js (new) 10.2 kB 🔴 +10.2 kB 🔴 +2.71 kB 🔴 +2.4 kB
assets/ServerConfigPanel-9kKuKbFQ.js (removed) 7.23 kB 🟢 -7.23 kB 🟢 -2.16 kB 🟢 -1.93 kB
assets/ServerConfigPanel-D-PI8NkW.js (new) 7.23 kB 🔴 +7.23 kB 🔴 +2.16 kB 🔴 +1.93 kB
assets/UserPanel-CTgJHnkx.js (new) 6.58 kB 🔴 +6.58 kB 🔴 +1.9 kB 🔴 +1.67 kB
assets/UserPanel-VA-IyRZo.js (removed) 6.58 kB 🟢 -6.58 kB 🟢 -1.9 kB 🟢 -1.67 kB
assets/cloudRemoteConfig-CQf2Q32k.js (new) 1.82 kB 🔴 +1.82 kB 🔴 +771 B 🔴 +658 B
assets/cloudRemoteConfig-h_We1NbT.js (removed) 1.82 kB 🟢 -1.82 kB 🟢 -769 B 🟢 -664 B
assets/remoteConfig-BEkdBLxH.js 1.07 kB 1.07 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/remoteConfig-D_gf6SLU.js 188 B 188 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-6DVADt2n.js 34.3 kB 34.3 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-B0j03ezr.js 38.3 kB 38.3 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-BHe-AJJN.js 29.6 kB 29.6 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-BT2lfy0S.js 29.5 kB 29.5 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-Cp0lF2Mp.js 31.2 kB 31.2 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-CwdesOpm.js 32.1 kB 32.1 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-D3SeHgho.js 28.6 kB 28.6 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-D42m_JEJ.js 25.9 kB 25.9 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-FF_vLB0C.js 25.2 kB 25.2 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-reUMVWRn.js 30.4 kB 30.4 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-s7kHNBdQ.js 28.9 kB 28.9 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 8 added / 8 removed

User & Accounts — 3.94 kB (baseline 3.94 kB) • ⚪ 0 B

Authentication, profile, and account management bundles

File Before After Δ Raw Δ Gzip Δ Brotli
assets/auth-Ckx2peL3.js (new) 3.54 kB 🔴 +3.54 kB 🔴 +1.23 kB 🔴 +1.06 kB
assets/auth-CQ5VWzPp.js (removed) 3.54 kB 🟢 -3.54 kB 🟢 -1.24 kB 🟢 -1.06 kB
assets/firebaseAuthStore-6DnRBqpJ.js (removed) 217 B 🟢 -217 B 🟢 -137 B 🟢 -125 B
assets/firebaseAuthStore-etg7t5LC.js (new) 217 B 🔴 +217 B 🔴 +137 B 🔴 +125 B
assets/auth-DzMrlFU7.js (removed) 178 B 🟢 -178 B 🟢 -142 B 🟢 -130 B
assets/auth-EqzzSt5x.js (new) 178 B 🔴 +178 B 🔴 +141 B 🔴 +129 B

Status: 3 added / 3 removed

Editors & Dialogs — 2.8 kB (baseline 2.8 kB) • ⚪ 0 B

Modals, dialogs, drawers, and in-app editors

File Before After Δ Raw Δ Gzip Δ Brotli
assets/useSubscriptionDialog-BUqRVcJI.js (removed) 2.62 kB 🟢 -2.62 kB 🟢 -1.24 kB 🟢 -1.09 kB
assets/useSubscriptionDialog-DSB50Gbn.js (new) 2.62 kB 🔴 +2.62 kB 🔴 +1.24 kB 🔴 +1.09 kB
assets/useSubscriptionDialog-9c5vmWy7.js (new) 179 B 🔴 +179 B 🔴 +110 B 🔴 +96 B
assets/useSubscriptionDialog-BTo0aX3K.js (removed) 179 B 🟢 -179 B 🟢 -110 B 🟢 -104 B

Status: 2 added / 2 removed

UI Components — 32.8 kB (baseline 32.8 kB) • ⚪ 0 B

Reusable component library chunks

File Before After Δ Raw Δ Gzip Δ Brotli
assets/SubscribeButton-B8kxGGql.js (new) 12.5 kB 🔴 +12.5 kB 🔴 +3.01 kB 🔴 +2.69 kB
assets/SubscribeButton-DRacDxAb.js (removed) 12.5 kB 🟢 -12.5 kB 🟢 -3.01 kB 🟢 -2.69 kB
assets/ComfyQueueButton-BZHnWpiz.js (new) 9.52 kB 🔴 +9.52 kB 🔴 +2.69 kB 🔴 +2.42 kB
assets/ComfyQueueButton-LBFAk5ga.js (removed) 9.52 kB 🟢 -9.52 kB 🟢 -2.69 kB 🟢 -2.42 kB
assets/CloudBadge-C0WuFloC.js (new) 1.85 kB 🔴 +1.85 kB 🔴 +728 B 🔴 +650 B
assets/CloudBadge-C321mpPS.js (removed) 1.85 kB 🟢 -1.85 kB 🟢 -726 B 🟢 -645 B
assets/cloudFeedbackTopbarButton-CkI3N6Yw.js (removed) 866 B 🟢 -866 B 🟢 -526 B 🟢 -439 B
assets/cloudFeedbackTopbarButton-DTcEun_W.js (new) 866 B 🔴 +866 B 🔴 +525 B 🔴 +447 B
assets/ComfyQueueButton-BGPvY5k6.js (removed) 181 B 🟢 -181 B 🟢 -118 B 🟢 -113 B
assets/ComfyQueueButton-CiUpxEGY.js (new) 181 B 🔴 +181 B 🔴 +118 B 🔴 +123 B
assets/Button-CKxdX0Yq.js 3.75 kB 3.75 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/UserAvatar-Bj7TTp1S.js 1.73 kB 1.73 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetButton-ftAKT8u9.js 2.41 kB 2.41 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 5 added / 5 removed

Data & Services — 3.06 MB (baseline 3.05 MB) • 🔴 +7.03 kB

Stores, services, APIs, and repositories

File Before After Δ Raw Δ Gzip Δ Brotli
assets/dialogService-BOMc-i62.js (new) 1.88 MB 🔴 +1.88 MB 🔴 +400 kB 🔴 +305 kB
assets/dialogService-Bb7g2d6M.js (removed) 1.88 MB 🟢 -1.88 MB 🟢 -398 kB 🟢 -305 kB
assets/api-B9RtHf0q.js (new) 1.15 MB 🔴 +1.15 MB 🔴 +240 kB 🔴 +186 kB
assets/api-Buf3aOHS.js (removed) 1.15 MB 🟢 -1.15 MB 🟢 -240 kB 🟢 -186 kB
assets/releaseStore-DSMt5eVN.js (removed) 8.91 kB 🟢 -8.91 kB 🟢 -2.41 kB 🟢 -2.13 kB
assets/releaseStore-gu82bbUQ.js (new) 8.91 kB 🔴 +8.91 kB 🔴 +2.41 kB 🔴 +2.12 kB
assets/keybindingService-7-9YcRXQ.js (new) 6.78 kB 🔴 +6.78 kB 🔴 +1.74 kB 🔴 +1.51 kB
assets/keybindingService-DpDVsorv.js (removed) 6.78 kB 🟢 -6.78 kB 🟢 -1.75 kB 🟢 -1.51 kB
assets/userStore-DsUHTRUA.js (new) 2.16 kB 🔴 +2.16 kB 🔴 +813 B 🔴 +727 B
assets/userStore-XWhzecQg.js (removed) 2.16 kB 🟢 -2.16 kB 🟢 -812 B 🟢 -727 B
assets/audioService-BngqG14c.js (removed) 2.03 kB 🟢 -2.03 kB 🟢 -929 B 🟢 -823 B
assets/audioService-D7w9IRF7.js (new) 2.03 kB 🔴 +2.03 kB 🔴 +931 B 🔴 +820 B
assets/releaseStore-BX7dAmkf.js (new) 140 B 🔴 +140 B 🔴 +106 B 🔴 +105 B
assets/releaseStore-Da3x-TM-.js (removed) 140 B 🟢 -140 B 🟢 -106 B 🟢 -105 B
assets/serverConfigStore-sopnD88s.js 2.64 kB 2.64 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 7 added / 7 removed

Utilities & Hooks — 18.1 kB (baseline 18.1 kB) • ⚪ 0 B

Helpers, composables, and utility bundles

File Before After Δ Raw Δ Gzip Δ Brotli
assets/useErrorHandling-Bfegpret.js (removed) 5.08 kB 🟢 -5.08 kB 🟢 -1.5 kB 🟢 -1.3 kB
assets/useErrorHandling-CWKs0VHb.js (new) 5.08 kB 🔴 +5.08 kB 🔴 +1.5 kB 🔴 +1.3 kB
assets/subscriptionCheckoutUtil-DBgZcAcl.js (removed) 1.98 kB 🟢 -1.98 kB 🟢 -859 B 🟢 -751 B
assets/subscriptionCheckoutUtil-XO4Zp-jR.js (new) 1.98 kB 🔴 +1.98 kB 🔴 +861 B 🔴 +750 B
assets/audioUtils-BYbiu90h.js (removed) 970 B 🟢 -970 B 🟢 -548 B 🟢 -486 B
assets/audioUtils-gKXjbx55.js (new) 970 B 🔴 +970 B 🔴 +548 B 🔴 +457 B
assets/useCurrentUser-B3kbz8ZL.js (new) 145 B 🔴 +145 B 🔴 +114 B 🔴 +105 B
assets/useCurrentUser-CerLyuA8.js (removed) 145 B 🟢 -145 B 🟢 -114 B 🟢 -106 B
assets/_plugin-vue_export-helper-xVPqUhAl.js 467 B 467 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/colorUtil-BTZOs5h9.js 7.2 kB 7.2 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/markdownRendererUtil-B9qvfWYq.js 1.78 kB 1.78 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/tailwindUtil-DTv34axN.js 487 B 487 B ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 4 added / 4 removed

Vendor & Third-Party — 10.4 MB (baseline 10.4 MB) • ⚪ 0 B

External libraries and shared vendor chunks

File Before After Δ Raw Δ Gzip Δ Brotli
assets/vendor-chart-Dr8GmMlH.js 408 kB 408 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-other-CpOC_out.js 3.92 MB 3.92 MB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-primevue-DvjPM_Lx.js 3.04 MB 3.04 MB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-reka-ui-BRjoKiJi.js 172 kB 172 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-three-Dqb1VEds.js 1.83 MB 1.83 MB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-tiptap-BxNhpyUI.js 650 kB 650 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-vue-7XRCqLaG.js 13.6 kB 13.6 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-xterm-CArXWFIl.js 398 kB 398 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
Other — 6.28 MB (baseline 6.28 MB) • ⚪ 0 B

Bundles that do not match a named category

File Before After Δ Raw Δ Gzip Δ Brotli
assets/core-Bk3TPpwL.js (removed) 177 kB 🟢 -177 kB 🟢 -42.8 kB 🟢 -35.8 kB
assets/core-DexBydgK.js (new) 177 kB 🔴 +177 kB 🔴 +42.8 kB 🔴 +35.8 kB
assets/Load3D-34-rF7Mk.js (removed) 55.7 kB 🟢 -55.7 kB 🟢 -9.17 kB 🟢 -7.92 kB
assets/Load3D-pNdQS4F_.js (new) 55.7 kB 🔴 +55.7 kB 🔴 +9.17 kB 🔴 +7.92 kB
assets/WidgetSelect-BEIT5x7S.js (removed) 50.5 kB 🟢 -50.5 kB 🟢 -11.1 kB 🟢 -9.68 kB
assets/WidgetSelect-CABt4BMo.js (new) 50.5 kB 🔴 +50.5 kB 🔴 +11.1 kB 🔴 +9.68 kB
assets/SubscriptionRequiredDialogContent-BmdSRMZf.js (removed) 28.7 kB 🟢 -28.7 kB 🟢 -6.78 kB 🟢 -5.91 kB
assets/SubscriptionRequiredDialogContent-CXayNvfz.js (new) 28.7 kB 🔴 +28.7 kB 🔴 +6.78 kB 🔴 +5.91 kB
assets/WidgetRecordAudio-DHt_tE_k.js (removed) 18.2 kB 🟢 -18.2 kB 🟢 -4.96 kB 🟢 -4.42 kB
assets/WidgetRecordAudio-guqrZ-WQ.js (new) 18.2 kB 🔴 +18.2 kB 🔴 +4.96 kB 🔴 +4.43 kB
assets/WidgetInputNumber-BW7mlTor.js (removed) 18.2 kB 🟢 -18.2 kB 🟢 -4.49 kB 🟢 -4 kB
assets/WidgetInputNumber-BXJTO0qL.js (new) 18.2 kB 🔴 +18.2 kB 🔴 +4.49 kB 🔴 +4.01 kB
assets/WidgetImageCrop-Cm3uaZPk.js (new) 17.1 kB 🔴 +17.1 kB 🔴 +4.13 kB 🔴 +3.62 kB
assets/WidgetImageCrop-DE4Xop3B.js (removed) 17.1 kB 🟢 -17.1 kB 🟢 -4.14 kB 🟢 -3.63 kB
assets/PanelTemplate-CrG-lQbu.js (new) 16.2 kB 🔴 +16.2 kB 🔴 +5.45 kB 🔴 +4.79 kB
assets/PanelTemplate-Dxe43aT2.js (removed) 16.2 kB 🟢 -16.2 kB 🟢 -5.45 kB 🟢 -4.79 kB
assets/AudioPreviewPlayer-BHVFGya5.js (new) 10.8 kB 🔴 +10.8 kB 🔴 +2.97 kB 🔴 +2.65 kB
assets/AudioPreviewPlayer-JqamuX_O.js (removed) 10.8 kB 🟢 -10.8 kB 🟢 -2.97 kB 🟢 -2.65 kB
assets/WidgetWithControl-3M8t1E2n.js (removed) 8.02 kB 🟢 -8.02 kB 🟢 -2.65 kB 🟢 -2.38 kB
assets/WidgetWithControl-DUcG1Zxo.js (new) 8.02 kB 🔴 +8.02 kB 🔴 +2.65 kB 🔴 +2.38 kB
assets/ValueControlPopover-BvtmENLH.js (removed) 4.86 kB 🟢 -4.86 kB 🟢 -1.55 kB 🟢 -1.37 kB
assets/ValueControlPopover-D5h5avs4.js (new) 4.86 kB 🔴 +4.86 kB 🔴 +1.55 kB 🔴 +1.37 kB
assets/GlobalToast-BftRlmVW.js (new) 3.05 kB 🔴 +3.05 kB 🔴 +1.1 kB 🔴 +940 B
assets/GlobalToast-C5vO0U0P.js (removed) 3.05 kB 🟢 -3.05 kB 🟢 -1.1 kB 🟢 -940 B
assets/SubscribeToRun-CeCvzS9Q.js (removed) 2.96 kB 🟢 -2.96 kB 🟢 -1.15 kB 🟢 -1.01 kB
assets/SubscribeToRun-DkQwkbLL.js (new) 2.96 kB 🔴 +2.96 kB 🔴 +1.15 kB 🔴 +1.01 kB
assets/cloudSessionCookie-D3GUiIh2.js (new) 2.94 kB 🔴 +2.94 kB 🔴 +934 B 🔴 +805 B
assets/cloudSessionCookie-OCqD_DxI.js (removed) 2.94 kB 🟢 -2.94 kB 🟢 -932 B 🟢 -808 B
assets/BaseViewTemplate-DHsdLGyT.js (new) 2.42 kB 🔴 +2.42 kB 🔴 +1.04 kB 🔴 +925 B
assets/BaseViewTemplate-DNGu5NFc.js (removed) 2.42 kB 🟢 -2.42 kB 🟢 -1.04 kB 🟢 -927 B
assets/CloudRunButtonWrapper-BReJy4aR.js (new) 1.79 kB 🔴 +1.79 kB 🔴 +642 B 🔴 +561 B
assets/CloudRunButtonWrapper-DwpMID0e.js (removed) 1.79 kB 🟢 -1.79 kB 🟢 -642 B 🟢 -575 B
assets/cloudBadges-COXlvTRR.js (removed) 1.08 kB 🟢 -1.08 kB 🟢 -537 B 🟢 -484 B
assets/cloudBadges-fv74vor3.js (new) 1.08 kB 🔴 +1.08 kB 🔴 +536 B 🔴 +482 B
assets/graphHasMissingNodes-9l9yW3Lg.js (removed) 1.06 kB 🟢 -1.06 kB 🟢 -459 B 🟢 -425 B
assets/graphHasMissingNodes-DMq5VTfg.js (new) 1.06 kB 🔴 +1.06 kB 🔴 +459 B 🔴 +424 B
assets/cloudSubscription-CHQDbpKC.js (removed) 976 B 🟢 -976 B 🟢 -459 B 🟢 -401 B
assets/cloudSubscription-D5qQJGXp.js (new) 976 B 🔴 +976 B 🔴 +461 B 🔴 +397 B
assets/WidgetInputNumber-Bw3qRf90.js (new) 186 B 🔴 +186 B 🔴 +119 B 🔴 +122 B
assets/WidgetInputNumber-CCfoplE1.js (removed) 186 B 🟢 -186 B 🟢 -119 B 🟢 -122 B
assets/WidgetLegacy-BmxnXkg6.js (new) 164 B 🔴 +164 B 🔴 +125 B 🔴 +113 B
assets/WidgetLegacy-mjyNvgz5.js (removed) 164 B 🟢 -164 B 🟢 -125 B 🟢 -109 B
assets/Load3D-DqnENZqV.js (new) 131 B 🔴 +131 B 🔴 +107 B 🔴 +109 B
assets/Load3D-j78a5sKB.js (removed) 131 B 🟢 -131 B 🟢 -107 B 🟢 -117 B
assets/auto-Bv9cmrEd.js 1.73 kB 1.73 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-6dIwsSNi.js 17.2 kB 17.2 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-BahwM9ZP.js 19.3 kB 19.3 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-BoJZgy7S.js 17 kB 17 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-BQtdp20P.js 20.6 kB 20.6 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-CEMgeOuO.js 18.5 kB 18.5 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-CnxND6sZ.js 18 kB 18 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-coXkrooi.js 18 kB 18 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-CZcHDaAg.js 18.8 kB 18.8 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-DDPGTXy9.js 17.9 kB 17.9 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-DsGC6118.js 17.8 kB 17.8 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-yZ2AjT4s.js 19.3 kB 19.3 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/LazyImage-BuqR6Hu5.js 14.1 kB 14.1 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-B_sPkRkB.js 121 kB 121 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-BAkXMjmM.js 141 kB 141 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-BENvLtOF.js 117 kB 117 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-BNsn8_Lr.js 120 kB 120 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-C9XUWxrh.js 105 kB 105 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-Ch4S7NKM.js 105 kB 105 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-DqG_JuMY.js 161 kB 161 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-DSqO9eB5.js 124 kB 124 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-F6Zr8qmN.js 118 kB 118 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-kF4hEjF-.js 145 kB 145 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-KWKxelma.js 134 kB 134 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/Media3DTop-DEJN4gIz.js 2.38 kB 2.38 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/MediaAudioTop-D39-6tpk.js 2 kB 2 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/MediaImageTop-CVYh1Dta.js 2.34 kB 2.34 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/MediaVideoTop-D7WAsNtO.js 2.84 kB 2.84 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/mixpanel.module-DaKz7N-R.js 143 B 143 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-42NP799-.js 358 kB 358 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-5Wl7kJtq.js 361 kB 361 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-Bfo_nHET.js 361 kB 361 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-BIaHseXE.js 334 kB 334 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-BqTE0tnV.js 437 kB 437 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-CkFt94jg.js 365 kB 365 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-COXALCSv.js 374 kB 374 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-Cuv6XdUW.js 332 kB 332 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-CyylrXT5.js 355 kB 355 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-DN_FfVrO.js 403 kB 403 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-Dxwvr4db.js 403 kB 403 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/OBJLoader2WorkerModule-DTMpvldF.js 109 kB 109 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/preservedQueryNamespaces-BsMrb3S_.js 3.23 kB 3.23 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/previousFullPath-DZ1Jt5wB.js 838 B 838 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/rolldown-runtime-CqTjxoQm.js 1.53 kB 1.53 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/Slider-Buvb2eP-.js 4.21 kB 4.21 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/widget-Dneex3J5.js 518 B 518 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetBoundingBox-BRX2wHPg.js 4.71 kB 4.71 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetBoundingBox-BttrDPHP.js 186 B 186 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetChart-D3w-Nwsc.js 2.79 kB 2.79 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetColorPicker-E9_-OJ5u.js 3.71 kB 3.71 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetGalleria-BekALFye.js 4.57 kB 4.57 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetImageCompare-BqwXGWo9.js 3.79 kB 3.79 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetInputText-BUBXlHZn.js 2.58 kB 2.58 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetLayoutField-BmL9OHU7.js 2.61 kB 2.61 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetMarkdown-BdG0Jp83.js 3.22 kB 3.22 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/widgetPropFilter-B0BM5Ibm.js 1.31 kB 1.31 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetTextarea-Dm4Ij7fB.js 3.52 kB 3.52 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetToggleSwitch-jOzkIkDw.js 3.08 kB 3.08 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 22 added / 22 removed

@viva-jinyi viva-jinyi added area:assets-sidebar claude-review Add to trigger a PR code review from Claude Code labels Jan 21, 2026
Copy link

@claude claude bot left a comment

Choose a reason for hiding this comment

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

Comprehensive PR Review

This review is generated by Claude. It may not always be accurate, as with human reviewers. If you believe that any of the comments are invalid or incorrect, please state why for each. For others, please implement the changes in one way or another.

Review Summary

PR: [feat] Add active jobs display to grid view (#8209)
Impact: 173 additions, 33 deletions across 4 files

Issue Distribution

  • Critical: 0
  • High: 1
  • Medium: 4
  • Low: 3

Category Breakdown

  • Architecture: 2 issues
  • Security: 0 issues
  • Performance: 1 issues
  • Code Quality: 5 issues

Key Findings

Architecture & Design

The refactoring to extract AssetsSidebarGridView follows good component separation patterns. However, there's code duplication in the isActiveJobState function between GridView and ListView components that should be addressed by extracting to a shared utility.

Security Considerations

No security issues identified. The components follow safe practices for UI rendering.

Performance Impact

Minor concern with removing overflow-y-auto from ListView which could affect scroll behavior with many jobs. Overall performance impact is minimal.

Integration Points

Good integration with existing useJobList composable and progress bar styling. ActiveJobCard properly integrates with the existing design system.

Positive Observations

  • Excellent component extraction following established patterns
  • Consistent use of existing composables (useProgressBarBackground, useJobList)
  • Good separation of concerns between grid and list views
  • Proper TypeScript typing throughout
  • Consistent styling with design system

References

Next Steps

  1. Address the high-priority missing test issue before merge
  2. Consider extracting duplicate isActiveJobState function
  3. Review accessibility attributes for ActiveJobCard component
  4. Consider scroll behavior implications in ListView

This is a comprehensive automated review. For architectural decisions requiring human judgment, please request additional manual review.

@github-actions github-actions bot removed the claude-review Add to trigger a PR code review from Claude Code label Jan 21, 2026
@viva-jinyi viva-jinyi requested a review from a team as a code owner January 21, 2026 06:32
Copy link
Member

@benceruleanlu benceruleanlu left a comment

Choose a reason for hiding this comment

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

Image

If there are several active jobs, they can overflow and hide all generated assets. Can that be fixed?

<ActiveJobCard v-for="job in activeJobItems" :key="job.id" :job="job" />
</div>

<!-- Assets Header -->
Copy link
Member

Choose a reason for hiding this comment

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

nit: A followup is making this dependent on the dates, per the design

Copy link
Member Author

Choose a reason for hiding this comment

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

Comment on lines 82 to 85
<div v-if="showLoadingState">
<ProgressSpinner class="absolute left-1/2 w-[50px] -translate-x-1/2" />
</div>
<div v-else-if="showEmptyState">
Copy link
Member

Choose a reason for hiding this comment

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

nit: when there are no generated assets, on the first active job, the grid view will not show the grids because of the logic in showLoadingState and showEmptyState

Copy link
Member

Choose a reason for hiding this comment

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

nit: design had slightly different ideas for the status text and progress bar designs, but that can be fixed later.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@src/components/sidebar/tabs/assets/ActiveJobCard.test.ts`:
- Around line 54-87: Update ActiveJobCard.vue to mark the progress element with
role="progressbar" and set aria-valuenow to the numeric progress (when present)
and mark the spinner element with aria-hidden="true"; then update the tests in
ActiveJobCard.test.ts (the "displays progress bar when job is running with
progress", "hides progress bar when job is pending", and "displays spinner icon
in thumbnail area" cases) to use wrapper.find('[role="progressbar"]') and assert
the aria-valuenow value (or absence when pending) and to find the spinner via
'[aria-hidden="true"]' instead of relying on Tailwind classes; locate changes
via mountComponent and createJob helpers and the ActiveJobCard component.

Comment on lines 54 to 87
it('displays progress bar when job is running with progress', () => {
const wrapper = mountComponent(
createJob({ state: 'running', progressTotalPercent: 65 })
)

const progressBar = wrapper.find('.bg-blue-500')
expect(progressBar.exists()).toBe(true)
expect(progressBar.attributes('style')).toContain('width: 65%')
})

it('hides progress bar when job is pending', () => {
const wrapper = mountComponent(
createJob({ state: 'pending', progressTotalPercent: undefined })
)

const progressBar = wrapper.find('.bg-blue-500')
expect(progressBar.exists()).toBe(false)
})

it('has proper accessibility attributes', () => {
const wrapper = mountComponent(createJob({ title: 'Generating...' }))

const container = wrapper.find('[role="status"]')
expect(container.exists()).toBe(true)
expect(container.attributes('aria-label')).toBe('Active job: Generating...')
})

it('displays spinner icon in thumbnail area', () => {
const wrapper = mountComponent(createJob())

const spinner = wrapper.find('.icon-\\[lucide--loader-circle\\]')
expect(spinner.exists()).toBe(true)
expect(spinner.classes()).toContain('animate-spin')
})
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

# Check if the test file exists and verify the code snippet
find . -name "ActiveJobCard.test.ts" -type f

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 128


🏁 Script executed:

# Look for the component file
find . -name "ActiveJobCard.vue" -type f

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 124


🏁 Script executed:

# Check test content
if [ -f "src/components/sidebar/tabs/assets/ActiveJobCard.test.ts" ]; then
  sed -n '54,87p' src/components/sidebar/tabs/assets/ActiveJobCard.test.ts
fi

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 1278


🏁 Script executed:

# Check component implementation
if [ -f "src/components/sidebar/tabs/assets/ActiveJobCard.vue" ]; then
  wc -l src/components/sidebar/tabs/assets/ActiveJobCard.vue
fi

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 125


🏁 Script executed:

# Read the component file to understand structure
cat -n src/components/sidebar/tabs/assets/ActiveJobCard.vue

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 2144


🏁 Script executed:

# Let's check what progressBarPrimaryClass actually contains
grep -n "progressBarPrimaryClass" src/components/sidebar/tabs/assets/ActiveJobCard.vue

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 196


🏁 Script executed:

# Check the composable that provides the progress bar styling
find . -name "useProgressBarBackground*" -type f

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 115


🏁 Script executed:

# Read the composable
cat -n src/composables/useProgressBarBackground.ts

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 1776


🏁 Script executed:

# Let's check the full test file to understand the mount context and any setup
head -70 src/components/sidebar/tabs/assets/ActiveJobCard.test.ts

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 1994


🏁 Script executed:

# Check if there are other test files in the same directory for context
ls -la src/components/sidebar/tabs/assets/*.test.ts

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 175


🏁 Script executed:

# Let's see how other components handle testing for progress/icons
find src/components -name "*.test.ts" -type f | head -5 | xargs grep -l "role=" 2>/dev/null | head -3

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 52


🏁 Script executed:

# Let's check how other component tests in this repo handle progress bars or loading states
rg "role=\"progressbar\"" src/components --type ts -A 2 -B 2 | head -30

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 52


🏁 Script executed:

# Check if any existing tests use accessible properties for testing animations or icons
rg "aria-hidden" tests-ui/ src/components --type ts -A 1 -B 1 | head -20

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 119


🏁 Script executed:

# Check the directory structure for tests
find . -type d -name "*test*" | head -10

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 496


🏁 Script executed:

# Look for other progress bar or loading spinner components
rg "bg-blue-500|bg-interface-panel-job-progress" src/components --type vue -A 2 -B 2 | head -30

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 97


🏁 Script executed:

# Check if the component renders the progress bar as a child element
sed -n '20,28p' src/components/sidebar/tabs/assets/ActiveJobCard.vue

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 347


🏁 Script executed:

# Let's verify what the actual inner div of the progress bar looks like when rendered
# Check if progress bar inner element currently has any role or aria attributes
grep -A 3 'progressBarPrimaryClass' src/components/sidebar/tabs/assets/ActiveJobCard.vue

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 349


🏁 Script executed:

# Check the exact structure again - looking at line 24-27
sed -n '24,27p' src/components/sidebar/tabs/assets/ActiveJobCard.vue

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 193


🏁 Script executed:

# Let's check if other test files use data-testid for selectors
rg "data-testid" src/components --type ts -B 1 -A 1 | head -20

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 1395


🏁 Script executed:

# Check the full test to see what the last test case looks like
tail -20 src/components/sidebar/tabs/assets/ActiveJobCard.test.ts

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 762


🏁 Script executed:

# Verify the mock setup more carefully
sed -n '8,16p' src/components/sidebar/tabs/assets/ActiveJobCard.test.ts

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 364


Replace class selectors with semantic ARIA attributes to avoid brittle style-dependent tests.

The tests select elements via Tailwind utility classes (bg-blue-500, animate-spin), which breaks when styling changes and conflicts with the "no style-dependent tests" guideline. Add role="progressbar" with aria-valuenow to the progress bar container and aria-hidden="true" to the spinner icon, then update tests to use these semantic properties instead.

🔧 Proposed test updates (ActiveJobCard.test.ts)
     const progressBar = wrapper.find('.bg-blue-500')
     expect(progressBar.exists()).toBe(true)
-    expect(progressBar.attributes('style')).toContain('width: 65%')
+    expect(progressBar.attributes('aria-valuenow')).toBe('65')
-    const progressBar = wrapper.find('.bg-blue-500')
+    const progressBar = wrapper.find('[role="progressbar"]')
     expect(progressBar.exists()).toBe(false)
-    const spinner = wrapper.find('.icon-\\[lucide--loader-circle\\]')
+    const spinner = wrapper.find('i[aria-hidden="true"]')
     expect(spinner.exists()).toBe(true)
-    expect(spinner.classes()).toContain('animate-spin')
🧩 Required component updates (ActiveJobCard.vue)
     <div
       v-if="hasProgressPercent(progressPercent)"
+      role="progressbar"
+      :aria-valuenow="progressPercent"
+      aria-valuemin="0"
+      aria-valuemax="100"
       class="flex-1 relative h-1 rounded-sm bg-secondary-background"
     >

     <i
+      aria-hidden="true"
       class="icon-[lucide--loader-circle] size-8 animate-spin text-muted-foreground"
     />
🤖 Prompt for AI Agents
In `@src/components/sidebar/tabs/assets/ActiveJobCard.test.ts` around lines 54 -
87, Update ActiveJobCard.vue to mark the progress element with
role="progressbar" and set aria-valuenow to the numeric progress (when present)
and mark the spinner element with aria-hidden="true"; then update the tests in
ActiveJobCard.test.ts (the "displays progress bar when job is running with
progress", "hides progress bar when job is pending", and "displays spinner icon
in thumbnail area" cases) to use wrapper.find('[role="progressbar"]') and assert
the aria-valuenow value (or absence when pending) and to find the spinner via
'[aria-hidden="true"]' instead of relying on Tailwind classes; locate changes
via mountComponent and createJob helpers and the ActiveJobCard component.

  - Add max-h-[50%] and overflow-y-auto to prevent active jobs from hiding assets
  - Fix showLoadingState/showEmptyState to check activeJobsCount in grid view
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@src/components/sidebar/tabs/AssetsSidebarGridView.vue`:
- Around line 103-108: gridStyle is intended to be immutable; add a const
assertion to its declaration by changing the gridStyle object to use a
TypeScript const assertion (gridStyle = { ... } as const) so the compiler treats
its properties as readonly literal types; update any code that relies on wider
types if necessary to accommodate the narrower types from gridStyle being
readonly.

Comment on lines +103 to +108
const gridStyle = {
display: 'grid',
gridTemplateColumns: 'repeat(auto-fill, minmax(200px, 1fr))',
padding: '0 0.5rem',
gap: '0.5rem'
}
Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Consider making gridStyle a const for clarity.

The gridStyle object is effectively immutable but declared with const already. This is fine, though using as const would make the immutability more explicit.

♻️ Optional: Add const assertion for immutability
-const gridStyle = {
+const gridStyle = {
   display: 'grid',
   gridTemplateColumns: 'repeat(auto-fill, minmax(200px, 1fr))',
   padding: '0 0.5rem',
   gap: '0.5rem'
-}
+} as const
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const gridStyle = {
display: 'grid',
gridTemplateColumns: 'repeat(auto-fill, minmax(200px, 1fr))',
padding: '0 0.5rem',
gap: '0.5rem'
}
const gridStyle = {
display: 'grid',
gridTemplateColumns: 'repeat(auto-fill, minmax(200px, 1fr))',
padding: '0 0.5rem',
gap: '0.5rem'
} as const
🤖 Prompt for AI Agents
In `@src/components/sidebar/tabs/AssetsSidebarGridView.vue` around lines 103 -
108, gridStyle is intended to be immutable; add a const assertion to its
declaration by changing the gridStyle object to use a TypeScript const assertion
(gridStyle = { ... } as const) so the compiler treats its properties as readonly
literal types; update any code that relies on wider types if necessary to
accommodate the narrower types from gridStyle being readonly.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@src/components/sidebar/tabs/assets/ActiveJobCard.test.ts`:
- Around line 29-37: The test helper createJob is written as a function
expression; convert it to a function declaration to follow coding guidelines:
replace the const createJob = (overrides: Partial<JobListItem> = {}):
JobListItem => ({ ... }) with an equivalent function createJob(overrides:
Partial<JobListItem> = {}): JobListItem { return { id: 'test-job-1', title:
'Running...', meta: 'Step 5/10', state: 'running', progressTotalPercent: 50,
progressCurrentPercent: 75, ...overrides }; } and make the same change for the
other helper(s) in this test file that use arrow expressions so they become
function declarations with identical signatures and return values.
♻️ Duplicate comments (1)
src/components/sidebar/tabs/assets/ActiveJobCard.test.ts (1)

54-56: Tests rely on style-dependent class selectors.

Using .bg-blue-500 and .animate-spin class selectors makes tests brittle - they'll break if styling changes even when behavior is correct. This was flagged in a previous review suggesting ARIA attributes instead.

Also applies to: 69-70, 76-78

Comment on lines +29 to +37
const createJob = (overrides: Partial<JobListItem> = {}): JobListItem => ({
id: 'test-job-1',
title: 'Running...',
meta: 'Step 5/10',
state: 'running',
progressTotalPercent: 50,
progressCurrentPercent: 75,
...overrides
})
Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Prefer function declarations for helpers.

Per coding guidelines, prefer function declarations over function expressions for pure functions.

♻️ Proposed refactor
-const createJob = (overrides: Partial<JobListItem> = {}): JobListItem => ({
-  id: 'test-job-1',
-  title: 'Running...',
-  meta: 'Step 5/10',
-  state: 'running',
-  progressTotalPercent: 50,
-  progressCurrentPercent: 75,
-  ...overrides
-})
+function createJob(overrides: Partial<JobListItem> = {}): JobListItem {
+  return {
+    id: 'test-job-1',
+    title: 'Running...',
+    meta: 'Step 5/10',
+    state: 'running',
+    progressTotalPercent: 50,
+    progressCurrentPercent: 75,
+    ...overrides
+  }
+}

-const mountComponent = (job: JobListItem) =>
-  mount(ActiveJobCard, {
-    props: { job },
-    global: {
-      plugins: [i18n]
-    }
-  })
+function mountComponent(job: JobListItem) {
+  return mount(ActiveJobCard, {
+    props: { job },
+    global: {
+      plugins: [i18n]
+    }
+  })
+}

Also applies to: 39-45

🤖 Prompt for AI Agents
In `@src/components/sidebar/tabs/assets/ActiveJobCard.test.ts` around lines 29 -
37, The test helper createJob is written as a function expression; convert it to
a function declaration to follow coding guidelines: replace the const createJob
= (overrides: Partial<JobListItem> = {}): JobListItem => ({ ... }) with an
equivalent function createJob(overrides: Partial<JobListItem> = {}): JobListItem
{ return { id: 'test-job-1', title: 'Running...', meta: 'Step 5/10', state:
'running', progressTotalPercent: 50, progressCurrentPercent: 75, ...overrides };
} and make the same change for the other helper(s) in this test file that use
arrow expressions so they become function declarations with identical signatures
and return values.

@viva-jinyi viva-jinyi added the New Browser Test Expectations New browser test screenshot should be set by github action label Jan 21, 2026
@github-actions
Copy link

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 Jan 21, 2026
Copy link
Member

@benceruleanlu benceruleanlu left a comment

Choose a reason for hiding this comment

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

LGTM, thanks for the great work!

Copy link
Member

Choose a reason for hiding this comment

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

nit: IDK what CR said, but I personally would tighten selectors to not fail on non‑behavioral changes

@viva-jinyi viva-jinyi merged commit e4d2bc2 into main Jan 22, 2026
28 checks passed
@viva-jinyi viva-jinyi deleted the feature/grid-view-active-job branch January 22, 2026 02:02
godwiniheuwa pushed a commit to godwiniheuwa/ComfyUI_frontend that referenced this pull request Jan 22, 2026
## Summary
Show active jobs in grid view matching the list view behavior, with
refactored component structure.

## Changes
- **ActiveJobCard**: New component for grid view job display with
progress bar
- **AssetsSidebarGridView**: Extracted grid view logic from
AssetsSidebarTab (matching ListView pattern)
- **Progress styling**: Use `useProgressBarBackground` composable for
consistent progress bar styling
- **Assets header**: Add "Generated/Imported assets" header in grid view
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:assets-sidebar area:queue area:ui General user interface and experience improvements enhancement New feature or request size:L This PR changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants