[QPOv2] Add list view to assets sidepanel#7737
Conversation
📝 WalkthroughWalkthroughAdds a list-view sidebar component that displays active jobs with per-item cancel actions and a grid of generated assets; introduces progress-bar and job-action composables, an AssetsListItem UI component, media-icon utility, storybook stories, and updates AssetsSidebarTab to toggle list vs grid mode. Changes
Sequence DiagramsequenceDiagram
participant Tab as AssetsSidebarTab
participant ListView as AssetsSidebarListView
participant JobItem as AssetsListItem (job)
participant Grid as VirtualGrid
participant AssetItem as AssetsListItem (asset)
participant JobActions as useJobActions
Tab->>ListView: render when isListView true
ListView->>JobItem: render active jobs list
JobItem->>JobActions: query canCancelJob
JobItem->>JobActions: runCancelJob (on hover action)
ListView->>Grid: render generated assets grid
Grid->>AssetItem: render each asset with icon/preview
AssetItem->>Tab: emit select-asset (on click)
AssetItem->>Tab: emit approach-end (when needed)
Possibly related PRs
✨ Finishing touches
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. Comment |
🎭 Playwright Test Results✅ All tests passed! ⏰ Completed at: 01/09/2026, 02:45:23 AM UTC 📈 Summary
📊 Test Reports by Browser
🎉 Click on the links above to view detailed test results for each browser configuration. |
🎨 Storybook Build Status✅ Build completed successfully! ⏰ Completed at: 01/09/2026, 02:40:08 AM UTC 🔗 Links🎉 Your Storybook is ready for review! |
🔧 Auto-fixes AppliedThis PR has been automatically updated to fix linting and formatting issues.
Changes made:
|
| const showLoadingState = computed( | ||
| () => | ||
| loading.value && | ||
| displayAssets.value.length === 0 && | ||
| (!isListView.value || activeJobsCount.value === 0) | ||
| ) | ||
|
|
||
| const showEmptyState = computed( | ||
| () => | ||
| !loading.value && | ||
| displayAssets.value.length === 0 && | ||
| (!isListView.value || activeJobsCount.value === 0) | ||
| ) | ||
|
|
There was a problem hiding this comment.
This change was made because now the view can show even when there are no generated assets, because running jobs were added to this view
There was a problem hiding this comment.
Pull request overview
This PR adds a list view to the media assets sidepanel as part of the QPO v2 iteration. The changes introduce a new card-based list view component that displays both active jobs with progress indicators and generated assets, providing users with a more detailed view of their asset pipeline.
Key Changes:
- New
AssetsListCardcomponent for displaying assets and jobs in list format - New
AssetsSidebarListViewcomponent integrating active jobs and assets display - New
useJobActionscomposable for managing job-specific actions - Feature flag
isQPOV2Enabledenabled to activate the new UI
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| src/platform/assets/components/AssetsListCard.vue | New reusable card component for list view with progress indicators, icons, and action slots |
| src/platform/assets/components/AssetsListCard.stories.ts | Storybook stories demonstrating the AssetsListCard component in various states |
| src/composables/queue/useJobActions.ts | New composable providing job action management (cancel) with i18n support |
| src/components/sidebar/tabs/AssetsSidebarListView.vue | Main list view component integrating active jobs and generated assets with VirtualGrid |
| src/components/sidebar/tabs/AssetsSidebarTab.vue | Updated to conditionally render list view based on feature flag and view mode |
| src/locales/en/main.json | Added "generatedAssetsHeader" translation key for the list view header |
| src/config/uiFeatureFlags.ts | Enabled QPOv2 feature flag to activate the new list view |
b2d42d4 to
8fb9eb8
Compare
|
This PR can be split into three if needed, one for the card, one for the actions, and another for the list itself. |
|
@coderabbitai full review |
✅ Actions performedFull review triggered. |
There was a problem hiding this comment.
Actionable comments posted: 2
📜 Review details
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (6)
src/components/sidebar/tabs/AssetsSidebarListView.vuesrc/components/sidebar/tabs/AssetsSidebarTab.vuesrc/composables/queue/useJobActions.tssrc/locales/en/main.jsonsrc/platform/assets/components/AssetsListCard.stories.tssrc/platform/assets/components/AssetsListCard.vue
🧰 Additional context used
📓 Path-based instructions (16)
**/*.{ts,tsx,vue,js,jsx,json,css}
📄 CodeRabbit inference engine (AGENTS.md)
Apply Prettier formatting with 2-space indentation, single quotes, no trailing semicolons, and 80-character line width
Files:
src/locales/en/main.jsonsrc/components/sidebar/tabs/AssetsSidebarListView.vuesrc/composables/queue/useJobActions.tssrc/platform/assets/components/AssetsListCard.vuesrc/components/sidebar/tabs/AssetsSidebarTab.vuesrc/platform/assets/components/AssetsListCard.stories.ts
src/**/*.vue
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
src/**/*.vue: Use the Vue 3 Composition API instead of the Options API when writing Vue components (exception: when overriding or extending PrimeVue components for compatibility)
Use setup() function for component logic
Utilize ref and reactive for reactive state
Implement computed properties with computed()
Use watch and watchEffect for side effects
Implement lifecycle hooks with onMounted, onUpdated, etc.
Utilize provide/inject for dependency injection
Use vue 3.5 style of default prop declaration
Use Tailwind CSS for styling
Implement proper props and emits definitions
Utilize Vue 3's Teleport component when needed
Use Suspense for async components
Follow Vue 3 style guide and naming conventions
Files:
src/components/sidebar/tabs/AssetsSidebarListView.vuesrc/platform/assets/components/AssetsListCard.vuesrc/components/sidebar/tabs/AssetsSidebarTab.vue
src/**/*.{vue,ts}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
src/**/*.{vue,ts}: Leverage VueUse functions for performance-enhancing styles
Implement proper error handling
Use vue-i18n in composition API for any string literals. Place new translation entries in src/locales/en/main.json
Files:
src/components/sidebar/tabs/AssetsSidebarListView.vuesrc/composables/queue/useJobActions.tssrc/platform/assets/components/AssetsListCard.vuesrc/components/sidebar/tabs/AssetsSidebarTab.vuesrc/platform/assets/components/AssetsListCard.stories.ts
src/**/*.{ts,tsx,vue}
📄 CodeRabbit inference engine (src/CLAUDE.md)
src/**/*.{ts,tsx,vue}: Sanitize HTML with DOMPurify to prevent XSS attacks
Avoid using @ts-expect-error; use proper TypeScript types instead
Use es-toolkit for utility functions instead of other utility libraries
Implement proper TypeScript types throughout the codebase
Files:
src/components/sidebar/tabs/AssetsSidebarListView.vuesrc/composables/queue/useJobActions.tssrc/platform/assets/components/AssetsListCard.vuesrc/components/sidebar/tabs/AssetsSidebarTab.vuesrc/platform/assets/components/AssetsListCard.stories.ts
src/**/{composables,components}/**/*.{ts,tsx,vue}
📄 CodeRabbit inference engine (src/CLAUDE.md)
Clean up subscriptions in state management to prevent memory leaks
Files:
src/components/sidebar/tabs/AssetsSidebarListView.vuesrc/composables/queue/useJobActions.tssrc/platform/assets/components/AssetsListCard.vuesrc/components/sidebar/tabs/AssetsSidebarTab.vuesrc/platform/assets/components/AssetsListCard.stories.ts
src/**/*.{vue,ts,tsx}
📄 CodeRabbit inference engine (src/CLAUDE.md)
Follow Vue 3 composition API style guide
Files:
src/components/sidebar/tabs/AssetsSidebarListView.vuesrc/composables/queue/useJobActions.tssrc/platform/assets/components/AssetsListCard.vuesrc/components/sidebar/tabs/AssetsSidebarTab.vuesrc/platform/assets/components/AssetsListCard.stories.ts
src/**/{components,composables}/**/*.{ts,tsx,vue}
📄 CodeRabbit inference engine (src/CLAUDE.md)
Use vue-i18n for ALL user-facing strings by adding them to
src/locales/en/main.json
Files:
src/components/sidebar/tabs/AssetsSidebarListView.vuesrc/composables/queue/useJobActions.tssrc/platform/assets/components/AssetsListCard.vuesrc/components/sidebar/tabs/AssetsSidebarTab.vuesrc/platform/assets/components/AssetsListCard.stories.ts
src/components/**/*.vue
📄 CodeRabbit inference engine (src/components/CLAUDE.md)
src/components/**/*.vue: Use setup() function in Vue 3 Composition API
Destructure props using Vue 3.5 style in Vue components
Use ref/reactive for state management in Vue 3 Composition API
Implement computed() for derived state in Vue 3 Composition API
Use provide/inject for dependency injection in Vue components
Prefer emit/@event-name for state changes over other communication patterns
Use defineExpose only for imperative operations (such as form.validate(), modal.open())
Replace PrimeVue Dropdown component with Select
Replace PrimeVue OverlayPanel component with Popover
Replace PrimeVue Calendar component with DatePicker
Replace PrimeVue InputSwitch component with ToggleSwitch
Replace PrimeVue Sidebar component with Drawer
Replace PrimeVue Chips component with AutoComplete with multiple enabled
Replace PrimeVue TabMenu component with Tabs without panels
Replace PrimeVue Steps component with Stepper without panels
Replace PrimeVue InlineMessage component with Message
Extract complex conditionals to computed properties
Implement cleanup for async operations in Vue components
Use lifecycle hooks: onMounted, onUpdated in Vue 3 Composition API
Use Teleport/Suspense when needed for component rendering
Define proper props and emits definitions in Vue components
Files:
src/components/sidebar/tabs/AssetsSidebarListView.vuesrc/components/sidebar/tabs/AssetsSidebarTab.vue
src/components/**/*.{vue,css}
📄 CodeRabbit inference engine (src/components/CLAUDE.md)
src/components/**/*.{vue,css}: Use Tailwind CSS only for styling (no custom CSS)
Use the correct tokens from style.css in the design system package
Files:
src/components/sidebar/tabs/AssetsSidebarListView.vuesrc/components/sidebar/tabs/AssetsSidebarTab.vue
src/components/**/*.{vue,ts,js}
📄 CodeRabbit inference engine (src/components/CLAUDE.md)
src/components/**/*.{vue,ts,js}: Use existing VueUse composables (such as useElementHover) instead of manually managing event listeners
Use useIntersectionObserver for visibility detection instead of custom scroll handlers
Use vue-i18n for ALL UI strings
Files:
src/components/sidebar/tabs/AssetsSidebarListView.vuesrc/components/sidebar/tabs/AssetsSidebarTab.vue
**/*.vue
📄 CodeRabbit inference engine (AGENTS.md)
**/*.vue: Use Vue 3.5+ with TypeScript in.vuefiles, exclusively using Composition API with<script setup lang="ts">syntax
Use Tailwind 4 for styling in Vue components; avoid<style>blocks
Name Vue components using PascalCase (e.g.,MenuHamburger.vue)
Use Vue 3.5 TypeScript-style default prop declaration with reactive props destructuring; do not usewithDefaultsor runtime props declaration
Prefercomputed()overrefwithwatchwhen deriving values
PreferuseModelover separately defining prop and emit for two-way binding
Usevue-i18nin composition API for string literals; place new translation entries insrc/locales/en/main.json
Usecn()utility function from@/utils/tailwindUtilfor merging Tailwind class names; do not use:class="[]"syntax
Do not use thedark:Tailwind variant; use semantic values from thestyle.csstheme instead (e.g.,bg-node-component-surface)
Do not use!importantor the!important prefix for Tailwind classes; find and correct interfering!importantclasses instead
Avoid new usage of PrimeVue components; use VueUse, shadcn/vue, or Reka UI instead
Leverage VueUse functions for performance-enhancing styles in Vue components
Implement proper props and emits definitions in Vue components
Utilize Vue 3's Teleport component when needed
Use Suspense for async components
Follow Vue 3 style guide and naming conventions
Files:
src/components/sidebar/tabs/AssetsSidebarListView.vuesrc/platform/assets/components/AssetsListCard.vuesrc/components/sidebar/tabs/AssetsSidebarTab.vue
**/*.{ts,tsx,vue}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ts,tsx,vue}: Use TypeScript exclusively; do not write new JavaScript code
Use sorted and grouped imports organized by plugin/source
Enforce ESLint rules including Vue + TypeScript rules, disallow floating promises, disallow unused imports, and restrict i18n raw text in templates
Do not useanytype oras anytype assertions; fix the underlying type issue instead
Write code that is expressive and self-documenting; avoid redundant comments and clean as you go
Keep functions short and functional; minimize nesting and follow the arrow anti-pattern
Avoid mutable state; prefer immutability and assignment at point of declaration
Use function declarations instead of function expressions when possible
Use es-toolkit for utility functions
Implement proper error handling in code
Files:
src/components/sidebar/tabs/AssetsSidebarListView.vuesrc/composables/queue/useJobActions.tssrc/platform/assets/components/AssetsListCard.vuesrc/components/sidebar/tabs/AssetsSidebarTab.vuesrc/platform/assets/components/AssetsListCard.stories.ts
src/**/*.ts
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
src/**/*.ts: Use es-toolkit for utility functions
Use TypeScript for type safety
Files:
src/composables/queue/useJobActions.tssrc/platform/assets/components/AssetsListCard.stories.ts
src/**/{services,composables}/**/*.{ts,tsx}
📄 CodeRabbit inference engine (src/CLAUDE.md)
src/**/{services,composables}/**/*.{ts,tsx}: Useapi.apiURL()for backend endpoints instead of constructing URLs directly
Useapi.fileURL()for static file access instead of constructing URLs directly
Files:
src/composables/queue/useJobActions.ts
**/**/use[A-Z]*.ts
📄 CodeRabbit inference engine (AGENTS.md)
Name composables using the pattern
useXyz.ts
Files:
src/composables/queue/useJobActions.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Minimize the surface area (exported values) of each module and composable
Files:
src/composables/queue/useJobActions.tssrc/platform/assets/components/AssetsListCard.stories.ts
🧠 Learnings (23)
📚 Learning: 2025-12-09T04:35:43.971Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 6300
File: src/locales/en/main.json:774-780
Timestamp: 2025-12-09T04:35:43.971Z
Learning: In the Comfy-Org/ComfyUI_frontend repository, locale files other than `src/locales/en/main.json` are generated automatically on every release. Developers only need to add English (en) key/values in `src/locales/en/main.json` when making PRs; manual updates to other locale files (fr, ja, ko, ru, zh, zh-TW, es, ar, tr, etc.) are not required and should not be suggested in reviews.
Applied to files:
src/locales/en/main.json
📚 Learning: 2025-11-24T19:47:34.324Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:34.324Z
Learning: Applies to src/**/{components,composables}/**/*.{ts,tsx,vue} : Use vue-i18n for ALL user-facing strings by adding them to `src/locales/en/main.json`
Applied to files:
src/locales/en/main.json
📚 Learning: 2025-12-09T03:49:52.828Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 6300
File: src/platform/updates/components/WhatsNewPopup.vue:5-13
Timestamp: 2025-12-09T03:49:52.828Z
Learning: In Vue files across the ComfyUI_frontend repo, when a button is needed, prefer the repo's common button components from src/components/button/ (IconButton.vue, TextButton.vue, IconTextButton.vue) over plain HTML <button> elements. These components wrap PrimeVue with the project’s design system styling. Use only the common button components for consistency and theming, and import them from src/components/button/ as needed.
Applied to files:
src/components/sidebar/tabs/AssetsSidebarListView.vuesrc/platform/assets/components/AssetsListCard.vuesrc/components/sidebar/tabs/AssetsSidebarTab.vue
📚 Learning: 2025-12-09T21:40:12.361Z
Learnt from: benceruleanlu
Repo: Comfy-Org/ComfyUI_frontend PR: 7297
File: src/components/actionbar/ComfyActionbar.vue:33-43
Timestamp: 2025-12-09T21:40:12.361Z
Learning: In Vue single-file components, allow inline Tailwind CSS class strings for static classes and avoid extracting them into computed properties solely for readability. Prefer keeping static class names inline for simplicity and performance. For dynamic or conditional classes, use Vue bindings (e.g., :class) to compose classes.
Applies to all Vue files in the repository (e.g., src/**/*.vue) where Tailwind utilities are used for static styling.
Applied to files:
src/components/sidebar/tabs/AssetsSidebarListView.vuesrc/platform/assets/components/AssetsListCard.vuesrc/components/sidebar/tabs/AssetsSidebarTab.vue
📚 Learning: 2025-12-16T22:26:49.463Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7537
File: src/components/ui/button/Button.vue:17-17
Timestamp: 2025-12-16T22:26:49.463Z
Learning: In Vue 3.5+ with <script setup>, when using defineProps<Props>() with partial destructuring (e.g., const { as = 'button', class: customClass = '' } = defineProps<Props>() ), props that are not destructured (e.g., variant, size) stay accessible by name in the template scope. This pattern is valid: you can destructure only a subset of props for convenience while referencing the remaining props directly in template expressions. Apply this guideline to Vue components across the codebase (all .vue files).
Applied to files:
src/components/sidebar/tabs/AssetsSidebarListView.vuesrc/platform/assets/components/AssetsListCard.vuesrc/components/sidebar/tabs/AssetsSidebarTab.vue
📚 Learning: 2025-12-22T21:36:08.369Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7649
File: src/platform/cloud/subscription/components/PricingTable.vue:185-201
Timestamp: 2025-12-22T21:36:08.369Z
Learning: In Vue components, avoid creating single-use variants for common UI components (e.g., Button and other shared components). Aim for reusable variants that cover multiple use cases. It’s acceptable to temporarily mix variant props with inline Tailwind classes when a styling need is unique to one place, but plan and consolidate into shared, reusable variants as patterns emerge across the codebase.
Applied to files:
src/components/sidebar/tabs/AssetsSidebarListView.vuesrc/platform/assets/components/AssetsListCard.vuesrc/components/sidebar/tabs/AssetsSidebarTab.vue
📚 Learning: 2025-12-11T12:25:15.470Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7358
File: src/components/dialog/content/signin/SignUpForm.vue:45-54
Timestamp: 2025-12-11T12:25:15.470Z
Learning: This repository uses CI automation to format code (pnpm format). Do not include manual formatting suggestions in code reviews for Comfy-Org/ComfyUI_frontend. If formatting issues are detected, rely on the CI formatter or re-run pnpm format. Focus reviews on correctness, readability, performance, accessibility, and maintainability rather than style formatting.
Applied to files:
src/components/sidebar/tabs/AssetsSidebarListView.vuesrc/composables/queue/useJobActions.tssrc/platform/assets/components/AssetsListCard.vuesrc/components/sidebar/tabs/AssetsSidebarTab.vuesrc/platform/assets/components/AssetsListCard.stories.ts
📚 Learning: 2025-12-18T02:07:38.870Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7598
File: src/components/sidebar/tabs/AssetsSidebarTab.vue:131-131
Timestamp: 2025-12-18T02:07:38.870Z
Learning: Tailwind CSS v4 safe utilities (e.g., items-center-safe, justify-*-safe, place-*-safe) are allowed in Vue components under src/ and in story files. Do not flag these specific safe variants as invalid when reviewing code in src/**/*.vue or related stories.
Applied to files:
src/components/sidebar/tabs/AssetsSidebarListView.vuesrc/platform/assets/components/AssetsListCard.vuesrc/components/sidebar/tabs/AssetsSidebarTab.vue
📚 Learning: 2025-12-18T21:15:46.862Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7603
File: src/components/queue/QueueOverlayHeader.vue:49-59
Timestamp: 2025-12-18T21:15:46.862Z
Learning: In the ComfyUI_frontend repository, for Vue components, do not add aria-label to buttons that have visible text content (e.g., buttons containing <span> text). The visible text provides the accessible name. Use aria-label only for elements without visible labels (e.g., icon-only buttons). If a button has no visible label, provide a clear aria-label or associate with an aria-labelledby describing its action.
Applied to files:
src/components/sidebar/tabs/AssetsSidebarListView.vuesrc/platform/assets/components/AssetsListCard.vuesrc/components/sidebar/tabs/AssetsSidebarTab.vue
📚 Learning: 2025-12-21T01:06:02.786Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7649
File: src/components/graph/selectionToolbox/ColorPickerButton.vue:15-18
Timestamp: 2025-12-21T01:06:02.786Z
Learning: In Comfy-Org/ComfyUI_frontend, in Vue component files, when a filled icon is required (e.g., 'pi pi-circle-fill'), you may mix PrimeIcons with Lucide icons since Lucide lacks filled variants. This mixed usage is acceptable when one icon library does not provide an equivalent filled icon. Apply consistently across Vue components in the src directory where icons are used, and document the rationale when a mixed approach is chosen.
Applied to files:
src/components/sidebar/tabs/AssetsSidebarListView.vuesrc/platform/assets/components/AssetsListCard.vuesrc/components/sidebar/tabs/AssetsSidebarTab.vue
📚 Learning: 2025-12-18T16:03:02.066Z
Learnt from: henrikvilhelmberglund
Repo: Comfy-Org/ComfyUI_frontend PR: 7617
File: src/components/actionbar/ComfyActionbar.vue:301-308
Timestamp: 2025-12-18T16:03:02.066Z
Learning: In the ComfyUI frontend queue system, useQueuePendingTaskCountStore().count indicates the number of tasks in the queue, where count = 1 means a single active/running task and count > 1 means there are pending tasks in addition to the active task. Therefore, in src/components/actionbar/ComfyActionbar.vue, enable the 'Clear Pending Tasks' button only when count > 1 to avoid clearing the currently running task. The active task should be canceled using the 'Cancel current run' button instead. This rule should be enforced via a conditional check on the queue count, with appropriate disabled/aria-disabled states for accessibility, and tests should verify behavior for count = 1 and count > 1.
Applied to files:
src/components/sidebar/tabs/AssetsSidebarListView.vuesrc/components/sidebar/tabs/AssetsSidebarTab.vue
📚 Learning: 2025-12-09T03:39:54.501Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7169
File: src/platform/remote/comfyui/jobs/jobTypes.ts:1-107
Timestamp: 2025-12-09T03:39:54.501Z
Learning: In the ComfyUI_frontend project, Zod is on v3.x. Do not suggest Zod v4 standalone validators (z.uuid, z.ulid, z.cuid2, z.nanoid) until an upgrade to Zod 4 is performed. When reviewing TypeScript files (e.g., src/platform/remote/comfyui/jobs/jobTypes.ts) validate against Zod 3 capabilities and avoid introducing v4-specific features; flag any proposal to upgrade or incorporate v4-only validators and propose staying with compatible 3.x patterns.
Applied to files:
src/composables/queue/useJobActions.tssrc/platform/assets/components/AssetsListCard.stories.ts
📚 Learning: 2025-12-13T11:03:11.264Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7416
File: src/stores/imagePreviewStore.ts:5-7
Timestamp: 2025-12-13T11:03:11.264Z
Learning: In the ComfyUI_frontend repository, lint rules require keeping 'import type' statements separate from non-type imports, even if importing from the same module. Do not suggest consolidating them into a single import statement. Ensure type imports remain on their own line (import type { ... } from 'module') and regular imports stay on separate lines.
Applied to files:
src/composables/queue/useJobActions.tssrc/platform/assets/components/AssetsListCard.stories.ts
📚 Learning: 2025-12-17T00:40:09.635Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7537
File: src/components/ui/button/Button.stories.ts:45-55
Timestamp: 2025-12-17T00:40:09.635Z
Learning: Prefer pure function declarations over function expressions (e.g., use function foo() { ... } instead of const foo = () => { ... }) for pure functions in the repository. Function declarations are more functional-leaning, offer better hoisting clarity, and can improve readability and tooling consistency. Apply this guideline across TypeScript files in Comfy-Org/ComfyUI_frontend, including story and UI component code, except where a function expression is semantically required (e.g., callbacks, higher-order functions with closures).
Applied to files:
src/composables/queue/useJobActions.tssrc/platform/assets/components/AssetsListCard.stories.ts
📚 Learning: 2025-12-30T22:22:33.836Z
Learnt from: kaili-yang
Repo: Comfy-Org/ComfyUI_frontend PR: 7805
File: src/composables/useCoreCommands.ts:439-439
Timestamp: 2025-12-30T22:22:33.836Z
Learning: When accessing reactive properties from Pinia stores in TypeScript files, avoid using .value on direct property access (e.g., useStore().isOverlayExpanded). Pinia auto-wraps refs when accessed directly, returning the primitive value. The .value accessor is only needed when destructuring store properties or when using storeToRefs().
Applied to files:
src/composables/queue/useJobActions.tssrc/platform/assets/components/AssetsListCard.stories.ts
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Define proper props and emits definitions in Vue components
Applied to files:
src/platform/assets/components/AssetsListCard.vue
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.vue : Implement proper props and emits definitions in Vue components
Applied to files:
src/platform/assets/components/AssetsListCard.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Implement proper props and emits definitions
Applied to files:
src/platform/assets/components/AssetsListCard.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.{vue,css} : Use the correct tokens from style.css in the design system package
Applied to files:
src/platform/assets/components/AssetsListCard.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue TabMenu component with Tabs without panels
Applied to files:
src/components/sidebar/tabs/AssetsSidebarTab.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue Sidebar component with Drawer
Applied to files:
src/components/sidebar/tabs/AssetsSidebarTab.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Utilize Vue 3's Teleport component when needed
Applied to files:
src/components/sidebar/tabs/AssetsSidebarTab.vue
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.vue : Utilize Vue 3's Teleport component when needed
Applied to files:
src/components/sidebar/tabs/AssetsSidebarTab.vue
🧬 Code graph analysis (1)
src/platform/assets/components/AssetsListCard.stories.ts (1)
src/components/input/SingleSelect.stories.ts (1)
Story(40-40)
🔇 Additional comments (19)
src/locales/en/main.json (1)
687-687: LGTM - Translation key properly added.The new translation key
generatedAssetsHeaderis correctly placed under thesideToolbarscope and follows the existing naming conventions. It's used in the new list view component to label the generated assets section.src/composables/queue/useJobActions.ts (3)
1-8: LGTM - Proper import structure.Imports follow the repository conventions with type imports separated from regular imports.
18-37: Well-structured composable implementation.The composable properly:
- Uses i18n for internationalized labels
- Wraps actions with error handling via
useErrorHandling- Maps job states to available actions using a computed property
- Provides a clear action structure with icon, label, and variant
39-41: Clarify the intent with theshowCleartype definition.The condition
job.showClear === false ? [] : (jobActionSets.value[job.state] ?? [])is correct, but theJobListItemtype definesshowClear?: boolean(optional), while in practice it's always explicitly set totrueorfalseviaqueueDisplay.ts. The type definition should be non-optional (showClear: boolean) to accurately reflect actual usage and prevent future confusion.src/platform/assets/components/AssetsListCard.stories.ts (3)
1-21: LGTM - Proper Storybook setup.The story file follows Storybook conventions with:
- Correct TypeScript typing with
MetaandStoryObj- Appropriate decorators for styling context
- Centered layout for component display
23-51: Well-structured render function using function declaration.The
renderActiveJobfunction properly uses a function declaration (as preferred in the repository) and demonstrates the component's active state with all relevant slots populated.Based on learnings, function declarations are preferred for pure functions in this repository.
72-99: Good story coverage for different component states.The three stories (
ActiveJob,FailedJob,GeneratedAsset) effectively demonstrate the component's different visual states and prop combinations, providing useful documentation and testing scenarios.src/platform/assets/components/AssetsListCard.vue (2)
75-97: LGTM - Proper props definition with partial destructuring.The component correctly uses Vue 3.5 style with partial destructuring of props. As per repository guidelines, props that are not destructured remain accessible by name in the template scope.
99-101: LGTM - Simple and effective helper function.The
clampPercentfunction correctly constrains percentage values to the [0, 100] range, preventing visual glitches from invalid progress values.src/components/sidebar/tabs/AssetsSidebarTab.vue (4)
208-208: LGTM - Proper import of new list view component.The import follows the repository's conventions and integrates the new AssetsSidebarListView component.
239-239: LGTM - Clear computed for list view mode.The
isListViewcomputed properly gates the list view based on the QPOV2 feature flag and the current view mode.
99-105: LGTM - Conditional rendering for list view.The component properly switches between list and grid views based on
isListView, with event handlers correctly wired to propagateselect-assetandapproach-endevents.
351-363: The code logic is correct and intentional. The condition(!isListView.value || activeJobsCount.value === 0)works as designed:
- Grid view:
!isListView.valueistrue, so the loading/empty state always shows when assets are empty, regardless of active job count- List view with active jobs: When
activeJobsCount > 0, the condition becomesfalse, which hides the loading/empty state to allow the active jobs list to display- List view without active jobs: The loading/empty state shows normally
The edge case mentioned (loading true, empty assets, activeJobsCount > 0 in grid view) does not cause a problem—the loading spinner correctly displays. The design intentionally treats grid and list views differently: the list view has special handling for active jobs, while the grid view shows standard loading/empty states.
src/components/sidebar/tabs/AssetsSidebarListView.vue (6)
101-109: LGTM - Proper props and emits definitions.The component correctly defines props using TypeScript and emits with proper typing, following Vue 3 and repository conventions.
3-36: Well-structured active jobs rendering with hover actions.The implementation properly:
- Renders active jobs with AssetsListCard
- Shows actions only on hover using
hoveredJobIdstate- Uses
@click.stop(line 18) to prevent event bubbling- Provides accessible labels for action buttons
The hover-to-reveal actions pattern improves UI cleanliness while maintaining functionality.
38-47: LGTM - Conditional header for generated assets.The header correctly uses the new translation key and only appears when assets exist, with appropriate spacing when active jobs are also present.
49-74: LGTM - VirtualGrid integration with proper accessibility.The VirtualGrid implementation:
- Uses proper aria-label with dynamic content (lines 59-64)
- Includes role and tabindex for keyboard navigation
- Emits approach-end for pagination
- Applies selection styling conditionally
Following repository guidelines, the button has an aria-label because it's effectively icon-only (the visual content is in slots).
145-173: Well-organized asset display utilities.The helper functions for asset rendering are well-structured:
getAssetPrimaryText: Uses truncateFilename for consistent displaygetAssetSecondaryText: Prioritizes execution time, then duration, then file sizegetAssetIconName: Maps media types to appropriate iconsThe fallback logic in
getAssetSecondaryTextensures graceful handling of missing metadata.
207-209: LGTM - Proper fire-and-forget async handling.The use of
voidkeyword correctly indicates intentional fire-and-forget for the async action execution, with error handling delegated torunJobAction.
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 Fix all issues with AI agents
In @src/components/sidebar/tabs/AssetsSidebarListView.vue:
- Around line 146-150: Extract the isActiveJobState function into a shared
queueDisplay utility alongside the existing iconForJobState so multiple
components can reuse it; create a new exported function isActiveJobState(state:
JobState) that returns true for 'pending'|'initialization'|'running', replace
the inline function in AssetsSidebarListView.vue with an import from the shared
module, and update any other components that duplicate this logic to import and
use the shared isActiveJobState instead.
- Around line 32-41: The action buttons currently call runCancelJob(job)
unconditionally, so replace that with a dispatcher that uses the action.key from
getJobActions(job); add a handler (e.g., handleJobAction) that accepts (key,
job) and switches on key (call runCancelJob(job) when key === 'cancel'), then
change the @click to call handleJobAction(action.key, job) so future actions are
routed correctly.
In @src/composables/queue/useJobActions.ts:
- Around line 20-33: getJobActionSets currently allocates new action objects on
each call; replace it with a computed memoized value so the cancel action (which
depends on t()) is only recreated when its dependencies change. Implement a
const jobActionSets = computed<Partial<Record<JobState, JobAction[]>>>(() => {
const cancelAction: JobAction = { key: 'cancel', icon: 'icon-[lucide--x]',
label: t('sideToolbar.queueProgressOverlay.cancelJobTooltip'), variant:
'destructive' }; return { pending: [cancelAction], initialization:
[cancelAction], running: [cancelAction] }; }); and use jobActionSets.value where
getJobActionSets() was used; ensure the computed imports/reactivity are
available and that t() is referenced inside the computed so translations update
reactively.
In @src/platform/assets/components/AssetsListItem.vue:
- Around line 21-29: Remove the non-interactive wrapper div's aria-label usage:
stop binding iconAriaLabel to the outer div (the element using cn(...) and
iconWrapperClass) so it does not output aria-label on a plain <div>; instead
ensure the actual icon element (the SVG/Img rendered where aria-hidden is
already set) has aria-hidden="true" and keep any descriptive text in nearby
visible content, leaving iconAriaLabel unused on the wrapper or only applied to
an interactive control if/when the wrapper becomes interactive.
📜 Review details
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (4)
src/components/sidebar/tabs/AssetsSidebarListView.vuesrc/composables/queue/useJobActions.tssrc/composables/queue/useJobMenu.tssrc/platform/assets/components/AssetsListItem.vue
🧰 Additional context used
📓 Path-based instructions (16)
src/**/*.{vue,ts}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
src/**/*.{vue,ts}: Leverage VueUse functions for performance-enhancing styles
Implement proper error handling
Use vue-i18n in composition API for any string literals. Place new translation entries in src/locales/en/main.json
Files:
src/composables/queue/useJobMenu.tssrc/composables/queue/useJobActions.tssrc/platform/assets/components/AssetsListItem.vuesrc/components/sidebar/tabs/AssetsSidebarListView.vue
src/**/*.ts
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
src/**/*.ts: Use es-toolkit for utility functions
Use TypeScript for type safety
Files:
src/composables/queue/useJobMenu.tssrc/composables/queue/useJobActions.ts
src/**/{services,composables}/**/*.{ts,tsx}
📄 CodeRabbit inference engine (src/CLAUDE.md)
src/**/{services,composables}/**/*.{ts,tsx}: Useapi.apiURL()for backend endpoints instead of constructing URLs directly
Useapi.fileURL()for static file access instead of constructing URLs directly
Files:
src/composables/queue/useJobMenu.tssrc/composables/queue/useJobActions.ts
src/**/*.{ts,tsx,vue}
📄 CodeRabbit inference engine (src/CLAUDE.md)
src/**/*.{ts,tsx,vue}: Sanitize HTML with DOMPurify to prevent XSS attacks
Avoid using @ts-expect-error; use proper TypeScript types instead
Use es-toolkit for utility functions instead of other utility libraries
Implement proper TypeScript types throughout the codebase
Files:
src/composables/queue/useJobMenu.tssrc/composables/queue/useJobActions.tssrc/platform/assets/components/AssetsListItem.vuesrc/components/sidebar/tabs/AssetsSidebarListView.vue
src/**/{composables,components}/**/*.{ts,tsx,vue}
📄 CodeRabbit inference engine (src/CLAUDE.md)
Clean up subscriptions in state management to prevent memory leaks
Files:
src/composables/queue/useJobMenu.tssrc/composables/queue/useJobActions.tssrc/platform/assets/components/AssetsListItem.vuesrc/components/sidebar/tabs/AssetsSidebarListView.vue
src/**/*.{vue,ts,tsx}
📄 CodeRabbit inference engine (src/CLAUDE.md)
Follow Vue 3 composition API style guide
Files:
src/composables/queue/useJobMenu.tssrc/composables/queue/useJobActions.tssrc/platform/assets/components/AssetsListItem.vuesrc/components/sidebar/tabs/AssetsSidebarListView.vue
src/**/{components,composables}/**/*.{ts,tsx,vue}
📄 CodeRabbit inference engine (src/CLAUDE.md)
Use vue-i18n for ALL user-facing strings by adding them to
src/locales/en/main.json
Files:
src/composables/queue/useJobMenu.tssrc/composables/queue/useJobActions.tssrc/platform/assets/components/AssetsListItem.vuesrc/components/sidebar/tabs/AssetsSidebarListView.vue
**/*.{ts,tsx,vue}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ts,tsx,vue}: Use TypeScript exclusively; do not write new JavaScript code
Use sorted and grouped imports organized by plugin/source
Enforce ESLint rules including Vue + TypeScript rules, disallow floating promises, disallow unused imports, and restrict i18n raw text in templates
Do not useanytype oras anytype assertions; fix the underlying type issue instead
Write code that is expressive and self-documenting; avoid redundant comments and clean as you go
Keep functions short and functional; minimize nesting and follow the arrow anti-pattern
Avoid mutable state; prefer immutability and assignment at point of declaration
Use function declarations instead of function expressions when possible
Use es-toolkit for utility functions
Implement proper error handling in code
Files:
src/composables/queue/useJobMenu.tssrc/composables/queue/useJobActions.tssrc/platform/assets/components/AssetsListItem.vuesrc/components/sidebar/tabs/AssetsSidebarListView.vue
**/**/use[A-Z]*.ts
📄 CodeRabbit inference engine (AGENTS.md)
Name composables using the pattern
useXyz.ts
Files:
src/composables/queue/useJobMenu.tssrc/composables/queue/useJobActions.ts
**/*.{ts,tsx,vue,js,jsx,json,css}
📄 CodeRabbit inference engine (AGENTS.md)
Apply Prettier formatting with 2-space indentation, single quotes, no trailing semicolons, and 80-character line width
Files:
src/composables/queue/useJobMenu.tssrc/composables/queue/useJobActions.tssrc/platform/assets/components/AssetsListItem.vuesrc/components/sidebar/tabs/AssetsSidebarListView.vue
**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Minimize the surface area (exported values) of each module and composable
Files:
src/composables/queue/useJobMenu.tssrc/composables/queue/useJobActions.ts
src/**/*.vue
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
src/**/*.vue: Use the Vue 3 Composition API instead of the Options API when writing Vue components (exception: when overriding or extending PrimeVue components for compatibility)
Use setup() function for component logic
Utilize ref and reactive for reactive state
Implement computed properties with computed()
Use watch and watchEffect for side effects
Implement lifecycle hooks with onMounted, onUpdated, etc.
Utilize provide/inject for dependency injection
Use vue 3.5 style of default prop declaration
Use Tailwind CSS for styling
Implement proper props and emits definitions
Utilize Vue 3's Teleport component when needed
Use Suspense for async components
Follow Vue 3 style guide and naming conventions
Files:
src/platform/assets/components/AssetsListItem.vuesrc/components/sidebar/tabs/AssetsSidebarListView.vue
**/*.vue
📄 CodeRabbit inference engine (AGENTS.md)
**/*.vue: Use Vue 3.5+ with TypeScript in.vuefiles, exclusively using Composition API with<script setup lang="ts">syntax
Use Tailwind 4 for styling in Vue components; avoid<style>blocks
Name Vue components using PascalCase (e.g.,MenuHamburger.vue)
Use Vue 3.5 TypeScript-style default prop declaration with reactive props destructuring; do not usewithDefaultsor runtime props declaration
Prefercomputed()overrefwithwatchwhen deriving values
PreferuseModelover separately defining prop and emit for two-way binding
Usevue-i18nin composition API for string literals; place new translation entries insrc/locales/en/main.json
Usecn()utility function from@/utils/tailwindUtilfor merging Tailwind class names; do not use:class="[]"syntax
Do not use thedark:Tailwind variant; use semantic values from thestyle.csstheme instead (e.g.,bg-node-component-surface)
Do not use!importantor the!important prefix for Tailwind classes; find and correct interfering!importantclasses instead
Avoid new usage of PrimeVue components; use VueUse, shadcn/vue, or Reka UI instead
Leverage VueUse functions for performance-enhancing styles in Vue components
Implement proper props and emits definitions in Vue components
Utilize Vue 3's Teleport component when needed
Use Suspense for async components
Follow Vue 3 style guide and naming conventions
Files:
src/platform/assets/components/AssetsListItem.vuesrc/components/sidebar/tabs/AssetsSidebarListView.vue
src/components/**/*.vue
📄 CodeRabbit inference engine (src/components/CLAUDE.md)
src/components/**/*.vue: Use setup() function in Vue 3 Composition API
Destructure props using Vue 3.5 style in Vue components
Use ref/reactive for state management in Vue 3 Composition API
Implement computed() for derived state in Vue 3 Composition API
Use provide/inject for dependency injection in Vue components
Prefer emit/@event-name for state changes over other communication patterns
Use defineExpose only for imperative operations (such as form.validate(), modal.open())
Replace PrimeVue Dropdown component with Select
Replace PrimeVue OverlayPanel component with Popover
Replace PrimeVue Calendar component with DatePicker
Replace PrimeVue InputSwitch component with ToggleSwitch
Replace PrimeVue Sidebar component with Drawer
Replace PrimeVue Chips component with AutoComplete with multiple enabled
Replace PrimeVue TabMenu component with Tabs without panels
Replace PrimeVue Steps component with Stepper without panels
Replace PrimeVue InlineMessage component with Message
Extract complex conditionals to computed properties
Implement cleanup for async operations in Vue components
Use lifecycle hooks: onMounted, onUpdated in Vue 3 Composition API
Use Teleport/Suspense when needed for component rendering
Define proper props and emits definitions in Vue components
Files:
src/components/sidebar/tabs/AssetsSidebarListView.vue
src/components/**/*.{vue,css}
📄 CodeRabbit inference engine (src/components/CLAUDE.md)
src/components/**/*.{vue,css}: Use Tailwind CSS only for styling (no custom CSS)
Use the correct tokens from style.css in the design system package
Files:
src/components/sidebar/tabs/AssetsSidebarListView.vue
src/components/**/*.{vue,ts,js}
📄 CodeRabbit inference engine (src/components/CLAUDE.md)
src/components/**/*.{vue,ts,js}: Use existing VueUse composables (such as useElementHover) instead of manually managing event listeners
Use useIntersectionObserver for visibility detection instead of custom scroll handlers
Use vue-i18n for ALL UI strings
Files:
src/components/sidebar/tabs/AssetsSidebarListView.vue
🧠 Learnings (31)
📚 Learning: 2025-12-09T03:39:54.501Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7169
File: src/platform/remote/comfyui/jobs/jobTypes.ts:1-107
Timestamp: 2025-12-09T03:39:54.501Z
Learning: In the ComfyUI_frontend project, Zod is on v3.x. Do not suggest Zod v4 standalone validators (z.uuid, z.ulid, z.cuid2, z.nanoid) until an upgrade to Zod 4 is performed. When reviewing TypeScript files (e.g., src/platform/remote/comfyui/jobs/jobTypes.ts) validate against Zod 3 capabilities and avoid introducing v4-specific features; flag any proposal to upgrade or incorporate v4-only validators and propose staying with compatible 3.x patterns.
Applied to files:
src/composables/queue/useJobMenu.tssrc/composables/queue/useJobActions.ts
📚 Learning: 2025-12-13T11:03:11.264Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7416
File: src/stores/imagePreviewStore.ts:5-7
Timestamp: 2025-12-13T11:03:11.264Z
Learning: In the ComfyUI_frontend repository, lint rules require keeping 'import type' statements separate from non-type imports, even if importing from the same module. Do not suggest consolidating them into a single import statement. Ensure type imports remain on their own line (import type { ... } from 'module') and regular imports stay on separate lines.
Applied to files:
src/composables/queue/useJobMenu.tssrc/composables/queue/useJobActions.ts
📚 Learning: 2025-12-17T00:40:09.635Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7537
File: src/components/ui/button/Button.stories.ts:45-55
Timestamp: 2025-12-17T00:40:09.635Z
Learning: Prefer pure function declarations over function expressions (e.g., use function foo() { ... } instead of const foo = () => { ... }) for pure functions in the repository. Function declarations are more functional-leaning, offer better hoisting clarity, and can improve readability and tooling consistency. Apply this guideline across TypeScript files in Comfy-Org/ComfyUI_frontend, including story and UI component code, except where a function expression is semantically required (e.g., callbacks, higher-order functions with closures).
Applied to files:
src/composables/queue/useJobMenu.tssrc/composables/queue/useJobActions.ts
📚 Learning: 2025-12-30T22:22:33.836Z
Learnt from: kaili-yang
Repo: Comfy-Org/ComfyUI_frontend PR: 7805
File: src/composables/useCoreCommands.ts:439-439
Timestamp: 2025-12-30T22:22:33.836Z
Learning: When accessing reactive properties from Pinia stores in TypeScript files, avoid using .value on direct property access (e.g., useStore().isOverlayExpanded). Pinia auto-wraps refs when accessed directly, returning the primitive value. The .value accessor is only needed when destructuring store properties or when using storeToRefs().
Applied to files:
src/composables/queue/useJobMenu.tssrc/composables/queue/useJobActions.ts
📚 Learning: 2025-12-11T12:25:15.470Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7358
File: src/components/dialog/content/signin/SignUpForm.vue:45-54
Timestamp: 2025-12-11T12:25:15.470Z
Learning: This repository uses CI automation to format code (pnpm format). Do not include manual formatting suggestions in code reviews for Comfy-Org/ComfyUI_frontend. If formatting issues are detected, rely on the CI formatter or re-run pnpm format. Focus reviews on correctness, readability, performance, accessibility, and maintainability rather than style formatting.
Applied to files:
src/composables/queue/useJobMenu.tssrc/composables/queue/useJobActions.tssrc/platform/assets/components/AssetsListItem.vuesrc/components/sidebar/tabs/AssetsSidebarListView.vue
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/**/use[A-Z]*.ts : Name composables using the pattern `useXyz.ts`
Applied to files:
src/composables/queue/useJobActions.ts
📚 Learning: 2025-12-18T21:15:46.862Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7603
File: src/components/queue/QueueOverlayHeader.vue:49-59
Timestamp: 2025-12-18T21:15:46.862Z
Learning: In the ComfyUI_frontend repository, for Vue components, do not add aria-label to buttons that have visible text content (e.g., buttons containing <span> text). The visible text provides the accessible name. Use aria-label only for elements without visible labels (e.g., icon-only buttons). If a button has no visible label, provide a clear aria-label or associate with an aria-labelledby describing its action.
Applied to files:
src/platform/assets/components/AssetsListItem.vuesrc/components/sidebar/tabs/AssetsSidebarListView.vue
📚 Learning: 2025-11-24T19:47:34.324Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:34.324Z
Learning: Applies to src/**/*.{vue,ts,tsx} : Follow Vue 3 composition API style guide
Applied to files:
src/platform/assets/components/AssetsListItem.vue
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.vue : Implement proper props and emits definitions in Vue components
Applied to files:
src/platform/assets/components/AssetsListItem.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Define proper props and emits definitions in Vue components
Applied to files:
src/platform/assets/components/AssetsListItem.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Implement proper props and emits definitions
Applied to files:
src/platform/assets/components/AssetsListItem.vue
📚 Learning: 2025-12-09T03:49:52.828Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 6300
File: src/platform/updates/components/WhatsNewPopup.vue:5-13
Timestamp: 2025-12-09T03:49:52.828Z
Learning: In Vue files across the ComfyUI_frontend repo, when a button is needed, prefer the repo's common button components from src/components/button/ (IconButton.vue, TextButton.vue, IconTextButton.vue) over plain HTML <button> elements. These components wrap PrimeVue with the project’s design system styling. Use only the common button components for consistency and theming, and import them from src/components/button/ as needed.
Applied to files:
src/platform/assets/components/AssetsListItem.vuesrc/components/sidebar/tabs/AssetsSidebarListView.vue
📚 Learning: 2025-12-09T21:40:12.361Z
Learnt from: benceruleanlu
Repo: Comfy-Org/ComfyUI_frontend PR: 7297
File: src/components/actionbar/ComfyActionbar.vue:33-43
Timestamp: 2025-12-09T21:40:12.361Z
Learning: In Vue single-file components, allow inline Tailwind CSS class strings for static classes and avoid extracting them into computed properties solely for readability. Prefer keeping static class names inline for simplicity and performance. For dynamic or conditional classes, use Vue bindings (e.g., :class) to compose classes.
Applies to all Vue files in the repository (e.g., src/**/*.vue) where Tailwind utilities are used for static styling.
Applied to files:
src/platform/assets/components/AssetsListItem.vuesrc/components/sidebar/tabs/AssetsSidebarListView.vue
📚 Learning: 2025-12-16T22:26:49.463Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7537
File: src/components/ui/button/Button.vue:17-17
Timestamp: 2025-12-16T22:26:49.463Z
Learning: In Vue 3.5+ with <script setup>, when using defineProps<Props>() with partial destructuring (e.g., const { as = 'button', class: customClass = '' } = defineProps<Props>() ), props that are not destructured (e.g., variant, size) stay accessible by name in the template scope. This pattern is valid: you can destructure only a subset of props for convenience while referencing the remaining props directly in template expressions. Apply this guideline to Vue components across the codebase (all .vue files).
Applied to files:
src/platform/assets/components/AssetsListItem.vuesrc/components/sidebar/tabs/AssetsSidebarListView.vue
📚 Learning: 2025-12-22T21:36:08.369Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7649
File: src/platform/cloud/subscription/components/PricingTable.vue:185-201
Timestamp: 2025-12-22T21:36:08.369Z
Learning: In Vue components, avoid creating single-use variants for common UI components (e.g., Button and other shared components). Aim for reusable variants that cover multiple use cases. It’s acceptable to temporarily mix variant props with inline Tailwind classes when a styling need is unique to one place, but plan and consolidate into shared, reusable variants as patterns emerge across the codebase.
Applied to files:
src/platform/assets/components/AssetsListItem.vuesrc/components/sidebar/tabs/AssetsSidebarListView.vue
📚 Learning: 2025-12-18T02:07:38.870Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7598
File: src/components/sidebar/tabs/AssetsSidebarTab.vue:131-131
Timestamp: 2025-12-18T02:07:38.870Z
Learning: Tailwind CSS v4 safe utilities (e.g., items-center-safe, justify-*-safe, place-*-safe) are allowed in Vue components under src/ and in story files. Do not flag these specific safe variants as invalid when reviewing code in src/**/*.vue or related stories.
Applied to files:
src/platform/assets/components/AssetsListItem.vuesrc/components/sidebar/tabs/AssetsSidebarListView.vue
📚 Learning: 2025-12-21T01:06:02.786Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7649
File: src/components/graph/selectionToolbox/ColorPickerButton.vue:15-18
Timestamp: 2025-12-21T01:06:02.786Z
Learning: In Comfy-Org/ComfyUI_frontend, in Vue component files, when a filled icon is required (e.g., 'pi pi-circle-fill'), you may mix PrimeIcons with Lucide icons since Lucide lacks filled variants. This mixed usage is acceptable when one icon library does not provide an equivalent filled icon. Apply consistently across Vue components in the src directory where icons are used, and document the rationale when a mixed approach is chosen.
Applied to files:
src/platform/assets/components/AssetsListItem.vuesrc/components/sidebar/tabs/AssetsSidebarListView.vue
📚 Learning: 2025-12-18T16:03:02.066Z
Learnt from: henrikvilhelmberglund
Repo: Comfy-Org/ComfyUI_frontend PR: 7617
File: src/components/actionbar/ComfyActionbar.vue:301-308
Timestamp: 2025-12-18T16:03:02.066Z
Learning: In the ComfyUI frontend queue system, useQueuePendingTaskCountStore().count indicates the number of tasks in the queue, where count = 1 means a single active/running task and count > 1 means there are pending tasks in addition to the active task. Therefore, in src/components/actionbar/ComfyActionbar.vue, enable the 'Clear Pending Tasks' button only when count > 1 to avoid clearing the currently running task. The active task should be canceled using the 'Cancel current run' button instead. This rule should be enforced via a conditional check on the queue count, with appropriate disabled/aria-disabled states for accessibility, and tests should verify behavior for count = 1 and count > 1.
Applied to files:
src/components/sidebar/tabs/AssetsSidebarListView.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.{vue,ts,js} : Use existing VueUse composables (such as useElementHover) instead of manually managing event listeners
Applied to files:
src/components/sidebar/tabs/AssetsSidebarListView.vue
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.vue : Leverage VueUse functions for performance-enhancing styles in Vue components
Applied to files:
src/components/sidebar/tabs/AssetsSidebarListView.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.{vue,ts} : Leverage VueUse functions for performance-enhancing styles
Applied to files:
src/components/sidebar/tabs/AssetsSidebarListView.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.{vue,ts,js} : Use useIntersectionObserver for visibility detection instead of custom scroll handlers
Applied to files:
src/components/sidebar/tabs/AssetsSidebarListView.vue
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.vue : Utilize Vue 3's Teleport component when needed
Applied to files:
src/components/sidebar/tabs/AssetsSidebarListView.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Utilize ref and reactive for reactive state
Applied to files:
src/components/sidebar/tabs/AssetsSidebarListView.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Utilize Vue 3's Teleport component when needed
Applied to files:
src/components/sidebar/tabs/AssetsSidebarListView.vue
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.vue : Avoid new usage of PrimeVue components; use VueUse, shadcn/vue, or Reka UI instead
Applied to files:
src/components/sidebar/tabs/AssetsSidebarListView.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Use ref/reactive for state management in Vue 3 Composition API
Applied to files:
src/components/sidebar/tabs/AssetsSidebarListView.vue
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.vue : Prefer `computed()` over `ref` with `watch` when deriving values
Applied to files:
src/components/sidebar/tabs/AssetsSidebarListView.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Implement lifecycle hooks with onMounted, onUpdated, etc.
Applied to files:
src/components/sidebar/tabs/AssetsSidebarListView.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Prefer emit/event-name for state changes over other communication patterns
Applied to files:
src/components/sidebar/tabs/AssetsSidebarListView.vue
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.vue : Use `cn()` utility function from `@/utils/tailwindUtil` for merging Tailwind class names; do not use `:class="[]"` syntax
Applied to files:
src/components/sidebar/tabs/AssetsSidebarListView.vue
🧬 Code graph analysis (2)
src/composables/queue/useJobMenu.ts (3)
src/composables/queue/useJobList.ts (1)
JobListItem(33-47)src/schemas/apiSchema.ts (1)
ExecutionErrorWsMessage(162-162)src/base/common/downloadUtil.ts (1)
downloadFile(31-48)
src/composables/queue/useJobActions.ts (3)
src/composables/useErrorHandling.ts (1)
useErrorHandling(52-112)src/composables/queue/useJobMenu.ts (1)
useJobMenu(43-359)src/types/queue.ts (1)
JobState(4-9)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: lint-and-format
- GitHub Check: test
- GitHub Check: collect
🔇 Additional comments (7)
src/composables/queue/useJobActions.ts (1)
35-45: LGTM!The
getJobActionscorrectly checksshowClear === falseto guard against undefined values, andrunCancelJobproperly wraps the cancel operation with centralized error handling.src/composables/queue/useJobMenu.ts (3)
55-56: LGTM!The
resolveItemhelper cleanly unifies item resolution, supporting both explicit item parameters and fallback tocurrentMenuItem(). This enables external callers (likeuseJobActions) to invoke actions directly with a job reference.
74-83: Clean null-safe cancellation flow.The
cancelJobfunction properly resolves the item, guards against null, and handles state-specific cancellation (interrupt for running/initialization, delete for pending). ThequeueStore.update()ensures UI consistency after cancellation.
238-242: Good deferred resolution pattern for menu click handlers.The
onInspectAssetcallback correctly resolves the current item at click time viaresolveItem(), ensuring the callback receives the actual current item when invoked rather than a stale reference captured during menu construction.src/platform/assets/components/AssetsListItem.vue (1)
84-106: Props definition follows Vue 3.5 style correctly.The component uses proper Vue 3.5 TypeScript-style prop declaration with reactive props destructuring and defaults (
previewAlt = ''). The composable integration withuseProgressBarBackgroundis clean.src/components/sidebar/tabs/AssetsSidebarListView.vue (2)
156-172: LGTM!The
getAssetSecondaryTextfunction implements a clean fallback chain for displaying asset metadata: execution time → duration → file size → empty string. This provides meaningful secondary information based on available data.
193-200: LGTM!The
getJobIconClassfunction correctly addsanimate-spinfor pending jobs without a preview image, providing visual feedback that the job is queued. The conditional logic properly checks for the absence oficonImageUrlbefore applying the animation.
AustinMroz
left a comment
There was a problem hiding this comment.
Changes look good to me.
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 Fix all issues with AI agents
In @src/components/sidebar/tabs/AssetsSidebarListView.vue:
- Around line 141-145: The isActiveJobState function in
AssetsSidebarListView.vue duplicates the active-state logic defined as
cancellableStates in useJobActions.ts; remove the local function and instead
import and reuse the shared logic by either exporting a helper
(isActiveJobState) or a shared constant (cancellableStates) from
useJobActions.ts, or call the existing canCancelJob/cancellableStates-based
function there; update AssetsSidebarListView.vue to import and use that exported
helper/constant so both components share the same source of truth.
- Around line 188-195: getJobIconClass currently builds an array to possibly
push a single class then joins it; simplify by returning the conditional class
directly: check whether job.iconImageUrl is falsy and the resolved iconName
(job.iconName ?? iconForJobState(job.state)) equals iconForJobState('pending'),
and if so return 'animate-spin', otherwise return undefined; update references
to getJobIconClass, job.iconName, job.iconImageUrl, iconForJobState and
job.state accordingly.
- Around line 116-119: Replace the manual hover tracking by removing the
hoveredJobId ref and the onJobEnter/onJobLeave handlers and instead use VueUse's
useElementHover: create a hover composable per job item (via useElementHover)
and bind its returned isHovered reactive to the template element ref for each
job in the list; update usages of hoveredJobId (e.g., any class or conditional
rendering) to use the per-item isHovered value and remove related event
listeners so hover state is derived from useElementHover.
In @src/composables/queue/useJobActions.ts:
- Around line 25-28: Replace the mutable array and arrow function with immutable
const assertion and a function declaration: change cancellableStates to a
readonly tuple using a const assertion (cancellableStates =
['pending','initialization','running'] as const) and refactor the arrow function
canCancelJob into a normal function declaration function canCancelJob(job:
JobListItem): boolean { return job.showClear !== false && (cancellableStates as
readonly JobState[]).includes(job.state); } so the list is immutable and the
pure predicate is a declared function for readability and hoisting.
📜 Review details
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (3)
src/components/sidebar/tabs/AssetsSidebarListView.vuesrc/composables/queue/useJobActions.tssrc/platform/assets/utils/mediaIconUtil.ts
🧰 Additional context used
📓 Path-based instructions (17)
src/**/*.{vue,ts}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
src/**/*.{vue,ts}: Leverage VueUse functions for performance-enhancing styles
Implement proper error handling
Use vue-i18n in composition API for any string literals. Place new translation entries in src/locales/en/main.json
Files:
src/platform/assets/utils/mediaIconUtil.tssrc/composables/queue/useJobActions.tssrc/components/sidebar/tabs/AssetsSidebarListView.vue
src/**/*.ts
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
src/**/*.ts: Use es-toolkit for utility functions
Use TypeScript for type safety
Files:
src/platform/assets/utils/mediaIconUtil.tssrc/composables/queue/useJobActions.ts
src/**/*.{ts,tsx,vue}
📄 CodeRabbit inference engine (src/CLAUDE.md)
src/**/*.{ts,tsx,vue}: Sanitize HTML with DOMPurify to prevent XSS attacks
Avoid using @ts-expect-error; use proper TypeScript types instead
Use es-toolkit for utility functions instead of other utility libraries
Implement proper TypeScript types throughout the codebase
src/**/*.{ts,tsx,vue}: TypeScript files must use exclusive TypeScript; no new JavaScript files
Use VueUse functions for performance-enhancing styles
Use es-toolkit for utility functions
Implement proper error handling in Vue components and async code
Files:
src/platform/assets/utils/mediaIconUtil.tssrc/composables/queue/useJobActions.tssrc/components/sidebar/tabs/AssetsSidebarListView.vue
src/**/*.{vue,ts,tsx}
📄 CodeRabbit inference engine (src/CLAUDE.md)
Follow Vue 3 composition API style guide
Files:
src/platform/assets/utils/mediaIconUtil.tssrc/composables/queue/useJobActions.tssrc/components/sidebar/tabs/AssetsSidebarListView.vue
**/*.{ts,tsx,vue}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ts,tsx,vue}: Use separateimport typestatements; avoid inline type imports mixed with value imports
ESLint rules must enforce Vue + TypeScript rules, no floating promises, no unused imports, and i18n raw text restrictions in templates
Never useanytype oras anytype assertions; use proper TypeScript types
Keep functions short and functional; minimize nesting with early returns and reduce arrow anti-patterns
Avoid mutable state; prefer immutability and assignment at point of declaration
Favor pure functions over function expressions; use function declarations when possible
Write expressive, self-documenting code; minimize unnecessary comments and avoid redundant comments
Ask 'is there a simpler way?' when writing code; use refactoring to make complex code simpler
Watch out for Code Smells and refactor to avoid them
Files:
src/platform/assets/utils/mediaIconUtil.tssrc/composables/queue/useJobActions.tssrc/components/sidebar/tabs/AssetsSidebarListView.vue
**/*.{ts,tsx,vue,js,jsx,json,css,md}
📄 CodeRabbit inference engine (AGENTS.md)
Format code with Prettier using 2-space indent, single quotes, no trailing semicolons, 80-character width
Files:
src/platform/assets/utils/mediaIconUtil.tssrc/composables/queue/useJobActions.tssrc/components/sidebar/tabs/AssetsSidebarListView.vue
{src/**/*.{ts,tsx,vue},**/*.test.ts}
📄 CodeRabbit inference engine (AGENTS.md)
Use vue-i18n in Composition API for string literals; place translation entries in src/locales/en/main.json and use i18n plurals system
Files:
src/platform/assets/utils/mediaIconUtil.tssrc/composables/queue/useJobActions.tssrc/components/sidebar/tabs/AssetsSidebarListView.vue
src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Minimize surface area (exported values) of each module and composable
Files:
src/platform/assets/utils/mediaIconUtil.tssrc/composables/queue/useJobActions.ts
src/**/{services,composables}/**/*.{ts,tsx}
📄 CodeRabbit inference engine (src/CLAUDE.md)
src/**/{services,composables}/**/*.{ts,tsx}: Useapi.apiURL()for backend endpoints instead of constructing URLs directly
Useapi.fileURL()for static file access instead of constructing URLs directly
Files:
src/composables/queue/useJobActions.ts
src/**/{composables,components}/**/*.{ts,tsx,vue}
📄 CodeRabbit inference engine (src/CLAUDE.md)
Clean up subscriptions in state management to prevent memory leaks
Files:
src/composables/queue/useJobActions.tssrc/components/sidebar/tabs/AssetsSidebarListView.vue
src/**/{components,composables}/**/*.{ts,tsx,vue}
📄 CodeRabbit inference engine (src/CLAUDE.md)
Use vue-i18n for ALL user-facing strings by adding them to
src/locales/en/main.json
Files:
src/composables/queue/useJobActions.tssrc/components/sidebar/tabs/AssetsSidebarListView.vue
src/composables/**/*.ts
📄 CodeRabbit inference engine (AGENTS.md)
Composables must follow the naming convention useXyz.ts
Files:
src/composables/queue/useJobActions.ts
src/**/*.vue
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
src/**/*.vue: Use the Vue 3 Composition API instead of the Options API when writing Vue components (exception: when overriding or extending PrimeVue components for compatibility)
Use setup() function for component logic
Utilize ref and reactive for reactive state
Implement computed properties with computed()
Use watch and watchEffect for side effects
Implement lifecycle hooks with onMounted, onUpdated, etc.
Utilize provide/inject for dependency injection
Use vue 3.5 style of default prop declaration
Use Tailwind CSS for styling
Implement proper props and emits definitions
Utilize Vue 3's Teleport component when needed
Use Suspense for async components
Follow Vue 3 style guide and naming conventions
Files:
src/components/sidebar/tabs/AssetsSidebarListView.vue
src/components/**/*.vue
📄 CodeRabbit inference engine (src/components/CLAUDE.md)
src/components/**/*.vue: Use setup() function in Vue 3 Composition API
Destructure props using Vue 3.5 style in Vue components
Use ref/reactive for state management in Vue 3 Composition API
Implement computed() for derived state in Vue 3 Composition API
Use provide/inject for dependency injection in Vue components
Prefer emit/@event-name for state changes over other communication patterns
Use defineExpose only for imperative operations (such as form.validate(), modal.open())
Replace PrimeVue Dropdown component with Select
Replace PrimeVue OverlayPanel component with Popover
Replace PrimeVue Calendar component with DatePicker
Replace PrimeVue InputSwitch component with ToggleSwitch
Replace PrimeVue Sidebar component with Drawer
Replace PrimeVue Chips component with AutoComplete with multiple enabled
Replace PrimeVue TabMenu component with Tabs without panels
Replace PrimeVue Steps component with Stepper without panels
Replace PrimeVue InlineMessage component with Message
Extract complex conditionals to computed properties
Implement cleanup for async operations in Vue components
Use lifecycle hooks: onMounted, onUpdated in Vue 3 Composition API
Use Teleport/Suspense when needed for component rendering
Define proper props and emits definitions in Vue componentsVue components must be named in PascalCase (e.g., MenuHamburger.vue)
Files:
src/components/sidebar/tabs/AssetsSidebarListView.vue
src/components/**/*.{vue,css}
📄 CodeRabbit inference engine (src/components/CLAUDE.md)
src/components/**/*.{vue,css}: Use Tailwind CSS only for styling (no custom CSS)
Use the correct tokens from style.css in the design system package
Files:
src/components/sidebar/tabs/AssetsSidebarListView.vue
src/components/**/*.{vue,ts,js}
📄 CodeRabbit inference engine (src/components/CLAUDE.md)
src/components/**/*.{vue,ts,js}: Use existing VueUse composables (such as useElementHover) instead of manually managing event listeners
Use useIntersectionObserver for visibility detection instead of custom scroll handlers
Use vue-i18n for ALL UI strings
Files:
src/components/sidebar/tabs/AssetsSidebarListView.vue
**/*.vue
📄 CodeRabbit inference engine (AGENTS.md)
**/*.vue: Vue 3.5+ components must use TypeScript with Composition API and <script setup lang="ts">
Use Tailwind 4 for styling; avoid <style> blocks in Vue components
Avoid new usage of PrimeVue components
Never usedark:Tailwind variant; use semantic values from style.css theme (e.g., bg-node-component-surface)
Use cn() utility from '@/utils/tailwindUtil' for merging class names; never use :class="[]"
Never use !important or ! prefix for Tailwind classes; find and fix interfering !important classes instead
Use default prop declaration with destructuring in Vue 3.5 TypeScript style; avoid withDefaults and runtime props
Prefer useModel over separate prop and emit definitions in Vue components
Be judicious with addition of new refs and state in Vue; use props directly, computed instead of watch, useModel instead of prop+emit when appropriate
Use provide/inject for dependency injection only when appropriate; prefer Store or shared composable for simplicity
Utilize Vue 3 Teleport component when needed for portal-style rendering
Use Suspense for async components in Vue 3
Files:
src/components/sidebar/tabs/AssetsSidebarListView.vue
🧠 Learnings (37)
📚 Learning: 2025-12-09T03:39:54.501Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7169
File: src/platform/remote/comfyui/jobs/jobTypes.ts:1-107
Timestamp: 2025-12-09T03:39:54.501Z
Learning: In the ComfyUI_frontend project, Zod is on v3.x. Do not suggest Zod v4 standalone validators (z.uuid, z.ulid, z.cuid2, z.nanoid) until an upgrade to Zod 4 is performed. When reviewing TypeScript files (e.g., src/platform/remote/comfyui/jobs/jobTypes.ts) validate against Zod 3 capabilities and avoid introducing v4-specific features; flag any proposal to upgrade or incorporate v4-only validators and propose staying with compatible 3.x patterns.
Applied to files:
src/platform/assets/utils/mediaIconUtil.tssrc/composables/queue/useJobActions.ts
📚 Learning: 2025-12-13T11:03:11.264Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7416
File: src/stores/imagePreviewStore.ts:5-7
Timestamp: 2025-12-13T11:03:11.264Z
Learning: In the ComfyUI_frontend repository, lint rules require keeping 'import type' statements separate from non-type imports, even if importing from the same module. Do not suggest consolidating them into a single import statement. Ensure type imports remain on their own line (import type { ... } from 'module') and regular imports stay on separate lines.
Applied to files:
src/platform/assets/utils/mediaIconUtil.tssrc/composables/queue/useJobActions.ts
📚 Learning: 2025-12-17T00:40:09.635Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7537
File: src/components/ui/button/Button.stories.ts:45-55
Timestamp: 2025-12-17T00:40:09.635Z
Learning: Prefer pure function declarations over function expressions (e.g., use function foo() { ... } instead of const foo = () => { ... }) for pure functions in the repository. Function declarations are more functional-leaning, offer better hoisting clarity, and can improve readability and tooling consistency. Apply this guideline across TypeScript files in Comfy-Org/ComfyUI_frontend, including story and UI component code, except where a function expression is semantically required (e.g., callbacks, higher-order functions with closures).
Applied to files:
src/platform/assets/utils/mediaIconUtil.tssrc/composables/queue/useJobActions.ts
📚 Learning: 2025-12-30T22:22:33.836Z
Learnt from: kaili-yang
Repo: Comfy-Org/ComfyUI_frontend PR: 7805
File: src/composables/useCoreCommands.ts:439-439
Timestamp: 2025-12-30T22:22:33.836Z
Learning: When accessing reactive properties from Pinia stores in TypeScript files, avoid using .value on direct property access (e.g., useStore().isOverlayExpanded). Pinia auto-wraps refs when accessed directly, returning the primitive value. The .value accessor is only needed when destructuring store properties or when using storeToRefs().
Applied to files:
src/platform/assets/utils/mediaIconUtil.tssrc/composables/queue/useJobActions.ts
📚 Learning: 2025-12-11T12:25:15.470Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7358
File: src/components/dialog/content/signin/SignUpForm.vue:45-54
Timestamp: 2025-12-11T12:25:15.470Z
Learning: This repository uses CI automation to format code (pnpm format). Do not include manual formatting suggestions in code reviews for Comfy-Org/ComfyUI_frontend. If formatting issues are detected, rely on the CI formatter or re-run pnpm format. Focus reviews on correctness, readability, performance, accessibility, and maintainability rather than style formatting.
Applied to files:
src/platform/assets/utils/mediaIconUtil.tssrc/composables/queue/useJobActions.tssrc/components/sidebar/tabs/AssetsSidebarListView.vue
📚 Learning: 2026-01-08T22:30:03.686Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-08T22:30:03.686Z
Learning: Applies to src/composables/**/*.ts : Composables must follow the naming convention useXyz.ts
Applied to files:
src/composables/queue/useJobActions.ts
📚 Learning: 2026-01-08T22:30:03.686Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-08T22:30:03.686Z
Learning: Applies to **/*.{ts,tsx,vue} : Keep functions short and functional; minimize nesting with early returns and reduce arrow anti-patterns
Applied to files:
src/composables/queue/useJobActions.ts
📚 Learning: 2026-01-08T22:30:03.686Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-08T22:30:03.686Z
Learning: Applies to **/*.{ts,tsx,vue} : Ask 'is there a simpler way?' when writing code; use refactoring to make complex code simpler
Applied to files:
src/composables/queue/useJobActions.ts
📚 Learning: 2025-11-24T19:47:34.324Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:34.324Z
Learning: Applies to src/**/{composables,components}/**/*.{ts,tsx,vue} : Clean up subscriptions in state management to prevent memory leaks
Applied to files:
src/composables/queue/useJobActions.ts
📚 Learning: 2025-12-18T16:03:09.642Z
Learnt from: henrikvilhelmberglund
Repo: Comfy-Org/ComfyUI_frontend PR: 7617
File: src/components/actionbar/ComfyActionbar.vue:301-308
Timestamp: 2025-12-18T16:03:09.642Z
Learning: In the ComfyUI frontend queue system (src/stores/queueStore.ts), the `useQueuePendingTaskCountStore().count` includes the currently executing task. When count = 1, there is only the active/running task with no pending tasks. When count > 1, there is an active task plus pending tasks waiting in the queue. The "Clear Pending Tasks" button should only be enabled when count > 1 to avoid clearing the currently running task, which should be handled by the "Cancel current run" button instead.
Applied to files:
src/composables/queue/useJobActions.ts
📚 Learning: 2026-01-08T22:30:03.686Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-08T22:30:03.686Z
Learning: Applies to **/*.{ts,tsx,vue} : Avoid mutable state; prefer immutability and assignment at point of declaration
Applied to files:
src/composables/queue/useJobActions.ts
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue Sidebar component with Drawer
Applied to files:
src/components/sidebar/tabs/AssetsSidebarListView.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.{vue,ts,js} : Use existing VueUse composables (such as useElementHover) instead of manually managing event listeners
Applied to files:
src/components/sidebar/tabs/AssetsSidebarListView.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.{vue,ts} : Leverage VueUse functions for performance-enhancing styles
Applied to files:
src/components/sidebar/tabs/AssetsSidebarListView.vue
📚 Learning: 2026-01-08T22:30:03.686Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-08T22:30:03.686Z
Learning: Applies to src/**/*.{ts,tsx,vue} : Use VueUse functions for performance-enhancing styles
Applied to files:
src/components/sidebar/tabs/AssetsSidebarListView.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.{vue,ts,js} : Use useIntersectionObserver for visibility detection instead of custom scroll handlers
Applied to files:
src/components/sidebar/tabs/AssetsSidebarListView.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Utilize ref and reactive for reactive state
Applied to files:
src/components/sidebar/tabs/AssetsSidebarListView.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Utilize Vue 3's Teleport component when needed
Applied to files:
src/components/sidebar/tabs/AssetsSidebarListView.vue
📚 Learning: 2026-01-08T22:30:03.686Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-08T22:30:03.686Z
Learning: Applies to **/*.vue : Utilize Vue 3 Teleport component when needed for portal-style rendering
Applied to files:
src/components/sidebar/tabs/AssetsSidebarListView.vue
📚 Learning: 2025-12-18T16:03:02.066Z
Learnt from: henrikvilhelmberglund
Repo: Comfy-Org/ComfyUI_frontend PR: 7617
File: src/components/actionbar/ComfyActionbar.vue:301-308
Timestamp: 2025-12-18T16:03:02.066Z
Learning: In the ComfyUI frontend queue system, useQueuePendingTaskCountStore().count indicates the number of tasks in the queue, where count = 1 means a single active/running task and count > 1 means there are pending tasks in addition to the active task. Therefore, in src/components/actionbar/ComfyActionbar.vue, enable the 'Clear Pending Tasks' button only when count > 1 to avoid clearing the currently running task. The active task should be canceled using the 'Cancel current run' button instead. This rule should be enforced via a conditional check on the queue count, with appropriate disabled/aria-disabled states for accessibility, and tests should verify behavior for count = 1 and count > 1.
Applied to files:
src/components/sidebar/tabs/AssetsSidebarListView.vue
📚 Learning: 2026-01-08T22:30:03.686Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-08T22:30:03.686Z
Learning: Applies to **/*.vue : Be judicious with addition of new refs and state in Vue; use props directly, computed instead of watch, useModel instead of prop+emit when appropriate
Applied to files:
src/components/sidebar/tabs/AssetsSidebarListView.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Use ref/reactive for state management in Vue 3 Composition API
Applied to files:
src/components/sidebar/tabs/AssetsSidebarListView.vue
📚 Learning: 2026-01-08T22:30:03.686Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-08T22:30:03.686Z
Learning: Applies to **/*.{ts,tsx,vue} : Watch out for Code Smells and refactor to avoid them
Applied to files:
src/components/sidebar/tabs/AssetsSidebarListView.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Prefer emit/event-name for state changes over other communication patterns
Applied to files:
src/components/sidebar/tabs/AssetsSidebarListView.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Implement lifecycle hooks with onMounted, onUpdated, etc.
Applied to files:
src/components/sidebar/tabs/AssetsSidebarListView.vue
📚 Learning: 2025-12-09T21:40:12.361Z
Learnt from: benceruleanlu
Repo: Comfy-Org/ComfyUI_frontend PR: 7297
File: src/components/actionbar/ComfyActionbar.vue:33-43
Timestamp: 2025-12-09T21:40:12.361Z
Learning: In Vue single-file components, allow inline Tailwind CSS class strings for static classes and avoid extracting them into computed properties solely for readability. Prefer keeping static class names inline for simplicity and performance. For dynamic or conditional classes, use Vue bindings (e.g., :class) to compose classes.
Applies to all Vue files in the repository (e.g., src/**/*.vue) where Tailwind utilities are used for static styling.
Applied to files:
src/components/sidebar/tabs/AssetsSidebarListView.vue
📚 Learning: 2026-01-08T22:30:03.686Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-08T22:30:03.686Z
Learning: Applies to **/*.vue : Use cn() utility from '@/utils/tailwindUtil' for merging class names; never use :class="[]"
Applied to files:
src/components/sidebar/tabs/AssetsSidebarListView.vue
📚 Learning: 2026-01-08T02:26:18.357Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7893
File: src/components/button/IconGroup.vue:5-6
Timestamp: 2026-01-08T02:26:18.357Z
Learning: In components that use the cn utility from '@/utils/tailwindUtil' with tailwind-merge, rely on the behavior that conflicting Tailwind classes are resolved by keeping the last one. For example, cn('base-classes bg-default', propClass) will have any conflicting background class from propClass override bg-default. This additive pattern is intentional and aligns with the shadcn-ui convention; ensure you document or review expectations accordingly in Vue components.
Applied to files:
src/components/sidebar/tabs/AssetsSidebarListView.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Use the Vue 3 Composition API instead of the Options API when writing Vue components (exception: when overriding or extending PrimeVue components for compatibility)
Applied to files:
src/components/sidebar/tabs/AssetsSidebarListView.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Use lifecycle hooks: onMounted, onUpdated in Vue 3 Composition API
Applied to files:
src/components/sidebar/tabs/AssetsSidebarListView.vue
📚 Learning: 2025-11-24T19:47:34.324Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:34.324Z
Learning: Applies to src/**/*.{vue,ts,tsx} : Follow Vue 3 composition API style guide
Applied to files:
src/components/sidebar/tabs/AssetsSidebarListView.vue
📚 Learning: 2025-12-09T03:49:52.828Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 6300
File: src/platform/updates/components/WhatsNewPopup.vue:5-13
Timestamp: 2025-12-09T03:49:52.828Z
Learning: In Vue files across the ComfyUI_frontend repo, when a button is needed, prefer the repo's common button components from src/components/button/ (IconButton.vue, TextButton.vue, IconTextButton.vue) over plain HTML <button> elements. These components wrap PrimeVue with the project’s design system styling. Use only the common button components for consistency and theming, and import them from src/components/button/ as needed.
Applied to files:
src/components/sidebar/tabs/AssetsSidebarListView.vue
📚 Learning: 2025-12-16T22:26:49.463Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7537
File: src/components/ui/button/Button.vue:17-17
Timestamp: 2025-12-16T22:26:49.463Z
Learning: In Vue 3.5+ with <script setup>, when using defineProps<Props>() with partial destructuring (e.g., const { as = 'button', class: customClass = '' } = defineProps<Props>() ), props that are not destructured (e.g., variant, size) stay accessible by name in the template scope. This pattern is valid: you can destructure only a subset of props for convenience while referencing the remaining props directly in template expressions. Apply this guideline to Vue components across the codebase (all .vue files).
Applied to files:
src/components/sidebar/tabs/AssetsSidebarListView.vue
📚 Learning: 2025-12-22T21:36:08.369Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7649
File: src/platform/cloud/subscription/components/PricingTable.vue:185-201
Timestamp: 2025-12-22T21:36:08.369Z
Learning: In Vue components, avoid creating single-use variants for common UI components (e.g., Button and other shared components). Aim for reusable variants that cover multiple use cases. It’s acceptable to temporarily mix variant props with inline Tailwind classes when a styling need is unique to one place, but plan and consolidate into shared, reusable variants as patterns emerge across the codebase.
Applied to files:
src/components/sidebar/tabs/AssetsSidebarListView.vue
📚 Learning: 2025-12-18T02:07:38.870Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7598
File: src/components/sidebar/tabs/AssetsSidebarTab.vue:131-131
Timestamp: 2025-12-18T02:07:38.870Z
Learning: Tailwind CSS v4 safe utilities (e.g., items-center-safe, justify-*-safe, place-*-safe) are allowed in Vue components under src/ and in story files. Do not flag these specific safe variants as invalid when reviewing code in src/**/*.vue or related stories.
Applied to files:
src/components/sidebar/tabs/AssetsSidebarListView.vue
📚 Learning: 2025-12-18T21:15:46.862Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7603
File: src/components/queue/QueueOverlayHeader.vue:49-59
Timestamp: 2025-12-18T21:15:46.862Z
Learning: In the ComfyUI_frontend repository, for Vue components, do not add aria-label to buttons that have visible text content (e.g., buttons containing <span> text). The visible text provides the accessible name. Use aria-label only for elements without visible labels (e.g., icon-only buttons). If a button has no visible label, provide a clear aria-label or associate with an aria-labelledby describing its action.
Applied to files:
src/components/sidebar/tabs/AssetsSidebarListView.vue
📚 Learning: 2025-12-21T01:06:02.786Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7649
File: src/components/graph/selectionToolbox/ColorPickerButton.vue:15-18
Timestamp: 2025-12-21T01:06:02.786Z
Learning: In Comfy-Org/ComfyUI_frontend, in Vue component files, when a filled icon is required (e.g., 'pi pi-circle-fill'), you may mix PrimeIcons with Lucide icons since Lucide lacks filled variants. This mixed usage is acceptable when one icon library does not provide an equivalent filled icon. Apply consistently across Vue components in the src directory where icons are used, and document the rationale when a mixed approach is chosen.
Applied to files:
src/components/sidebar/tabs/AssetsSidebarListView.vue
🧬 Code graph analysis (2)
src/platform/assets/utils/mediaIconUtil.ts (1)
src/platform/assets/schemas/mediaAssetSchema.ts (1)
MediaKind(7-7)
src/composables/queue/useJobActions.ts (3)
src/composables/useErrorHandling.ts (1)
useErrorHandling(52-112)src/composables/queue/useJobMenu.ts (1)
useJobMenu(43-359)src/types/queue.ts (1)
JobState(4-9)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
- GitHub Check: setup
- GitHub Check: lint-and-format
- GitHub Check: test
- GitHub Check: collect
🔇 Additional comments (6)
src/platform/assets/utils/mediaIconUtil.ts (1)
1-14: LGTM!The utility function is well-structured, type-safe, and follows functional programming principles. The icon mapping is clear and uses proper Lucide icon classes.
src/composables/queue/useJobActions.ts (2)
8-23: LGTM!The JobAction type and cancelAction definition are well-structured. The use of i18n for the label follows best practices.
30-38: LGTM!The error handling wrapper and composable return structure are correctly implemented, providing a clean public API for job actions.
src/components/sidebar/tabs/AssetsSidebarListView.vue (3)
1-39: LGTM!The active jobs template section is well-structured with proper accessibility attributes, semantic styling, and correct Vue 3 patterns. The use of
@click.stopappropriately prevents event bubbling.
41-81: LGTM!The generated assets section demonstrates excellent accessibility practices with proper ARIA labels, keyboard navigation support, and semantic markup. The i18n integration and event emission patterns are correct.
147-176: LGTM!The asset helper functions follow best practices with function declarations, proper use of the
cn()utility, and clear fallback logic ingetAssetSecondaryText.
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Fix all issues with AI agents
In @src/components/sidebar/tabs/AssetsSidebarListView.vue:
- Around line 148-152: isActiveJobState duplicates the cancellableStates list
from useJobActions.ts; centralize the definition to avoid divergence by
exporting a shared constant (e.g., ACTIVE_JOB_STATES) and using it in both
places. Update useJobActions.ts to export the constant (or move it to a shared
file like src/types/queue.ts or src/constants/queue.ts), then replace the local
cancellableStates/reference in useJobActions and replace isActiveJobState in
AssetsSidebarListView.vue to check membership against the exported
ACTIVE_JOB_STATES (or import from useJobActions if you choose that location).
Ensure types remain JobState[] and adjust imports accordingly.
- Around line 141-146: The listGridStyle object is static and should be declared
once at module scope instead of inside the component; move the const
listGridStyle declaration out of the component definition to the top-level of
AssetsSidebarListView.vue (above the export default), keep the exact object
shape and leave all usages inside the component intact, and remove the
in-component declaration so instances no longer recreate it on each render.
In @src/composables/queue/useJobActions.ts:
- Around line 23-29: Move the purely static array cancellableStates out of the
composable and define it as a module-level constant named cancellableStates:
JobState[] = ['pending','initialization','running'] to avoid recreating it on
each invocation; for cancelAction (symbol cancelAction) since it depends on t()
from useI18n(), either keep it inside the composable or convert it to a small
factory function (e.g., createCancelAction(t): JobAction) that builds and
returns the object so the static shape is defined outside while still allowing
localization to be injected.
📜 Review details
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (2)
src/components/sidebar/tabs/AssetsSidebarListView.vuesrc/composables/queue/useJobActions.ts
🧰 Additional context used
📓 Path-based instructions (13)
src/**/*.{vue,ts}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
src/**/*.{vue,ts}: Leverage VueUse functions for performance-enhancing styles
Implement proper error handling
Use vue-i18n in composition API for any string literals. Place new translation entries in src/locales/en/main.jsonLeverage VueUse functions for performance-enhancing utilities
Files:
src/composables/queue/useJobActions.tssrc/components/sidebar/tabs/AssetsSidebarListView.vue
src/**/*.ts
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
src/**/*.ts: Use es-toolkit for utility functions
Use TypeScript for type safety
src/**/*.ts: Minimize the surface area (exported values) of each module and composable
Use es-toolkit for utility functions
Files:
src/composables/queue/useJobActions.ts
src/**/{services,composables}/**/*.{ts,tsx}
📄 CodeRabbit inference engine (src/CLAUDE.md)
src/**/{services,composables}/**/*.{ts,tsx}: Useapi.apiURL()for backend endpoints instead of constructing URLs directly
Useapi.fileURL()for static file access instead of constructing URLs directly
Files:
src/composables/queue/useJobActions.ts
src/**/*.{ts,tsx,vue}
📄 CodeRabbit inference engine (src/CLAUDE.md)
src/**/*.{ts,tsx,vue}: Sanitize HTML with DOMPurify to prevent XSS attacks
Avoid using @ts-expect-error; use proper TypeScript types instead
Use es-toolkit for utility functions instead of other utility libraries
Implement proper TypeScript types throughout the codebase
src/**/*.{ts,tsx,vue}: Use separateimport typestatements; do not mix inlinetypeimports in the same statement
Sort and group imports by plugin; runpnpm formatbefore committing
Derive component types usingvue-component-type-helpers(ComponentProps,ComponentSlots) instead of separate type files
Code should be well-designed with clear names for everything; write code that is expressive and self-documenting
Avoid redundant comments and clean up code as you go; comments should explain why, not what
Ask if there is a simpler way to implement functionality; refactor complex code to simplify it
Minimize nesting depth (e.g.,if () { ... }orfor () { ... }); watch for arrow anti-pattern
Watch out for code smells and refactor to avoid them
Never useanytype; use proper TypeScript types
Never useas anytype assertions; fix the underlying type issue instead
Indent with 2 spaces; use single quotes; no trailing semicolons; max line width 80 (per .prettierrc)
Complex type definitions used in multiple related places should be extracted and named for reuse
Implement proper error handling
Files:
src/composables/queue/useJobActions.tssrc/components/sidebar/tabs/AssetsSidebarListView.vue
src/**/{composables,components}/**/*.{ts,tsx,vue}
📄 CodeRabbit inference engine (src/CLAUDE.md)
Clean up subscriptions in state management to prevent memory leaks
Files:
src/composables/queue/useJobActions.tssrc/components/sidebar/tabs/AssetsSidebarListView.vue
src/**/*.{vue,ts,tsx}
📄 CodeRabbit inference engine (src/CLAUDE.md)
Follow Vue 3 composition API style guide
Files:
src/composables/queue/useJobActions.tssrc/components/sidebar/tabs/AssetsSidebarListView.vue
src/**/{components,composables}/**/*.{ts,tsx,vue}
📄 CodeRabbit inference engine (src/CLAUDE.md)
Use vue-i18n for ALL user-facing strings by adding them to
src/locales/en/main.json
Files:
src/composables/queue/useJobActions.tssrc/components/sidebar/tabs/AssetsSidebarListView.vue
src/composables/**/*.ts
📄 CodeRabbit inference engine (AGENTS.md)
Name composables using the
useXyz.tspattern
Files:
src/composables/queue/useJobActions.ts
src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
src/**/*.{ts,tsx}: Keep functions short and functional; use function declarations instead of function expressions when possible
Avoid mutable state; prefer immutability and assignment at point of declaration
Favor pure functions, especially testable ones
Files:
src/composables/queue/useJobActions.ts
src/**/*.vue
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
src/**/*.vue: Use the Vue 3 Composition API instead of the Options API when writing Vue components (exception: when overriding or extending PrimeVue components for compatibility)
Use setup() function for component logic
Utilize ref and reactive for reactive state
Implement computed properties with computed()
Use watch and watchEffect for side effects
Implement lifecycle hooks with onMounted, onUpdated, etc.
Utilize provide/inject for dependency injection
Use vue 3.5 style of default prop declaration
Use Tailwind CSS for styling
Implement proper props and emits definitions
Utilize Vue 3's Teleport component when needed
Use Suspense for async components
Follow Vue 3 style guide and naming conventions
src/**/*.vue: Use Vue 3 Single File Components (SFCs) with Composition API only; never use Options API
Use<script setup lang="ts">syntax for component logic
Use Tailwind 4 utility classes for styling; avoid<style>blocks in Vue components
Do not use thedark:Tailwind variant; use semantic values fromstyle.csstheme instead (e.g.,bg-node-component-surface)
Usecn()utility from@/utils/tailwindUtilfor merging class names; never use:class="[]"syntax
Never use!importantor the!prefix for Tailwind classes; find and fix interfering classes instead
Use Tailwind fraction utilities instead of arbitrary percentages (e.g.,w-4/5instead ofw-[80%],w-1/2instead ofw-[50%])
Use Vue 3.5 TypeScript style default prop declaration with destructuring; avoidwithDefaultsand runtime props
UsedefineModelfor v-model bindings instead of separately defining props and emits
Prefer reactive props destructuring overconst props = defineProps<...>
Define slots via template usage, notdefineSlots
Use same-name shorthand for slot prop bindings (e.g.,:isExpandedinstead of:is-expanded="isExpanded")
Usereffor reactive state,computed()for computed properties, andwatch/watchEffectfor side effects
Avoid usingrefandwatcht...
Files:
src/components/sidebar/tabs/AssetsSidebarListView.vue
src/components/**/*.vue
📄 CodeRabbit inference engine (src/components/CLAUDE.md)
src/components/**/*.vue: Use setup() function in Vue 3 Composition API
Destructure props using Vue 3.5 style in Vue components
Use ref/reactive for state management in Vue 3 Composition API
Implement computed() for derived state in Vue 3 Composition API
Use provide/inject for dependency injection in Vue components
Prefer emit/@event-name for state changes over other communication patterns
Use defineExpose only for imperative operations (such as form.validate(), modal.open())
Replace PrimeVue Dropdown component with Select
Replace PrimeVue OverlayPanel component with Popover
Replace PrimeVue Calendar component with DatePicker
Replace PrimeVue InputSwitch component with ToggleSwitch
Replace PrimeVue Sidebar component with Drawer
Replace PrimeVue Chips component with AutoComplete with multiple enabled
Replace PrimeVue TabMenu component with Tabs without panels
Replace PrimeVue Steps component with Stepper without panels
Replace PrimeVue InlineMessage component with Message
Extract complex conditionals to computed properties
Implement cleanup for async operations in Vue components
Use lifecycle hooks: onMounted, onUpdated in Vue 3 Composition API
Use Teleport/Suspense when needed for component rendering
Define proper props and emits definitions in Vue componentsName Vue components in PascalCase (e.g., MenuHamburger.vue)
Files:
src/components/sidebar/tabs/AssetsSidebarListView.vue
src/components/**/*.{vue,css}
📄 CodeRabbit inference engine (src/components/CLAUDE.md)
src/components/**/*.{vue,css}: Use Tailwind CSS only for styling (no custom CSS)
Use the correct tokens from style.css in the design system package
Files:
src/components/sidebar/tabs/AssetsSidebarListView.vue
src/components/**/*.{vue,ts,js}
📄 CodeRabbit inference engine (src/components/CLAUDE.md)
src/components/**/*.{vue,ts,js}: Use existing VueUse composables (such as useElementHover) instead of manually managing event listeners
Use useIntersectionObserver for visibility detection instead of custom scroll handlers
Use vue-i18n for ALL UI strings
Files:
src/components/sidebar/tabs/AssetsSidebarListView.vue
🧠 Learnings (36)
📚 Learning: 2026-01-09T00:50:57.103Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-09T00:50:57.103Z
Learning: Applies to src/composables/**/*.ts : Name composables using the `useXyz.ts` pattern
Applied to files:
src/composables/queue/useJobActions.ts
📚 Learning: 2025-11-24T19:47:34.324Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:34.324Z
Learning: Applies to src/**/{composables,components}/**/*.{ts,tsx,vue} : Clean up subscriptions in state management to prevent memory leaks
Applied to files:
src/composables/queue/useJobActions.ts
📚 Learning: 2025-12-18T16:03:09.642Z
Learnt from: henrikvilhelmberglund
Repo: Comfy-Org/ComfyUI_frontend PR: 7617
File: src/components/actionbar/ComfyActionbar.vue:301-308
Timestamp: 2025-12-18T16:03:09.642Z
Learning: In the ComfyUI frontend queue system (src/stores/queueStore.ts), the `useQueuePendingTaskCountStore().count` includes the currently executing task. When count = 1, there is only the active/running task with no pending tasks. When count > 1, there is an active task plus pending tasks waiting in the queue. The "Clear Pending Tasks" button should only be enabled when count > 1 to avoid clearing the currently running task, which should be handled by the "Cancel current run" button instead.
Applied to files:
src/composables/queue/useJobActions.ts
📚 Learning: 2026-01-09T00:50:57.103Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-09T00:50:57.103Z
Learning: Applies to src/**/*.{ts,tsx,vue} : Ask if there is a simpler way to implement functionality; refactor complex code to simplify it
Applied to files:
src/composables/queue/useJobActions.tssrc/components/sidebar/tabs/AssetsSidebarListView.vue
📚 Learning: 2026-01-09T00:50:57.103Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-09T00:50:57.103Z
Learning: Applies to src/**/*.{ts,tsx} : Avoid mutable state; prefer immutability and assignment at point of declaration
Applied to files:
src/composables/queue/useJobActions.ts
📚 Learning: 2026-01-09T00:50:57.103Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-09T00:50:57.103Z
Learning: Applies to src/**/*.{ts,tsx} : Favor pure functions, especially testable ones
Applied to files:
src/composables/queue/useJobActions.ts
📚 Learning: 2026-01-09T00:50:57.103Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-09T00:50:57.103Z
Learning: Applies to src/**/*.{ts,tsx} : Keep functions short and functional; use function declarations instead of function expressions when possible
Applied to files:
src/composables/queue/useJobActions.ts
📚 Learning: 2025-12-09T03:39:54.501Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7169
File: src/platform/remote/comfyui/jobs/jobTypes.ts:1-107
Timestamp: 2025-12-09T03:39:54.501Z
Learning: In the ComfyUI_frontend project, Zod is on v3.x. Do not suggest Zod v4 standalone validators (z.uuid, z.ulid, z.cuid2, z.nanoid) until an upgrade to Zod 4 is performed. When reviewing TypeScript files (e.g., src/platform/remote/comfyui/jobs/jobTypes.ts) validate against Zod 3 capabilities and avoid introducing v4-specific features; flag any proposal to upgrade or incorporate v4-only validators and propose staying with compatible 3.x patterns.
Applied to files:
src/composables/queue/useJobActions.ts
📚 Learning: 2025-12-13T11:03:11.264Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7416
File: src/stores/imagePreviewStore.ts:5-7
Timestamp: 2025-12-13T11:03:11.264Z
Learning: In the ComfyUI_frontend repository, lint rules require keeping 'import type' statements separate from non-type imports, even if importing from the same module. Do not suggest consolidating them into a single import statement. Ensure type imports remain on their own line (import type { ... } from 'module') and regular imports stay on separate lines.
Applied to files:
src/composables/queue/useJobActions.ts
📚 Learning: 2025-12-17T00:40:09.635Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7537
File: src/components/ui/button/Button.stories.ts:45-55
Timestamp: 2025-12-17T00:40:09.635Z
Learning: Prefer pure function declarations over function expressions (e.g., use function foo() { ... } instead of const foo = () => { ... }) for pure functions in the repository. Function declarations are more functional-leaning, offer better hoisting clarity, and can improve readability and tooling consistency. Apply this guideline across TypeScript files in Comfy-Org/ComfyUI_frontend, including story and UI component code, except where a function expression is semantically required (e.g., callbacks, higher-order functions with closures).
Applied to files:
src/composables/queue/useJobActions.ts
📚 Learning: 2025-12-30T22:22:33.836Z
Learnt from: kaili-yang
Repo: Comfy-Org/ComfyUI_frontend PR: 7805
File: src/composables/useCoreCommands.ts:439-439
Timestamp: 2025-12-30T22:22:33.836Z
Learning: When accessing reactive properties from Pinia stores in TypeScript files, avoid using .value on direct property access (e.g., useStore().isOverlayExpanded). Pinia auto-wraps refs when accessed directly, returning the primitive value. The .value accessor is only needed when destructuring store properties or when using storeToRefs().
Applied to files:
src/composables/queue/useJobActions.ts
📚 Learning: 2025-12-11T12:25:15.470Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7358
File: src/components/dialog/content/signin/SignUpForm.vue:45-54
Timestamp: 2025-12-11T12:25:15.470Z
Learning: This repository uses CI automation to format code (pnpm format). Do not include manual formatting suggestions in code reviews for Comfy-Org/ComfyUI_frontend. If formatting issues are detected, rely on the CI formatter or re-run pnpm format. Focus reviews on correctness, readability, performance, accessibility, and maintainability rather than style formatting.
Applied to files:
src/composables/queue/useJobActions.tssrc/components/sidebar/tabs/AssetsSidebarListView.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue Sidebar component with Drawer
Applied to files:
src/components/sidebar/tabs/AssetsSidebarListView.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.{vue,ts,js} : Use existing VueUse composables (such as useElementHover) instead of manually managing event listeners
Applied to files:
src/components/sidebar/tabs/AssetsSidebarListView.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.{vue,ts} : Leverage VueUse functions for performance-enhancing styles
Applied to files:
src/components/sidebar/tabs/AssetsSidebarListView.vue
📚 Learning: 2026-01-09T00:50:57.103Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-09T00:50:57.103Z
Learning: Applies to src/**/*.{vue,ts} : Leverage VueUse functions for performance-enhancing utilities
Applied to files:
src/components/sidebar/tabs/AssetsSidebarListView.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.{vue,ts,js} : Use useIntersectionObserver for visibility detection instead of custom scroll handlers
Applied to files:
src/components/sidebar/tabs/AssetsSidebarListView.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Utilize ref and reactive for reactive state
Applied to files:
src/components/sidebar/tabs/AssetsSidebarListView.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Utilize Vue 3's Teleport component when needed
Applied to files:
src/components/sidebar/tabs/AssetsSidebarListView.vue
📚 Learning: 2026-01-09T00:50:57.103Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-09T00:50:57.103Z
Learning: Applies to src/**/*.vue : Use `ref` for reactive state, `computed()` for computed properties, and `watch`/`watchEffect` for side effects
Applied to files:
src/components/sidebar/tabs/AssetsSidebarListView.vue
📚 Learning: 2025-12-18T16:03:02.066Z
Learnt from: henrikvilhelmberglund
Repo: Comfy-Org/ComfyUI_frontend PR: 7617
File: src/components/actionbar/ComfyActionbar.vue:301-308
Timestamp: 2025-12-18T16:03:02.066Z
Learning: In the ComfyUI frontend queue system, useQueuePendingTaskCountStore().count indicates the number of tasks in the queue, where count = 1 means a single active/running task and count > 1 means there are pending tasks in addition to the active task. Therefore, in src/components/actionbar/ComfyActionbar.vue, enable the 'Clear Pending Tasks' button only when count > 1 to avoid clearing the currently running task. The active task should be canceled using the 'Cancel current run' button instead. This rule should be enforced via a conditional check on the queue count, with appropriate disabled/aria-disabled states for accessibility, and tests should verify behavior for count = 1 and count > 1.
Applied to files:
src/components/sidebar/tabs/AssetsSidebarListView.vue
📚 Learning: 2026-01-09T00:50:57.103Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-09T00:50:57.103Z
Learning: Follow Vue 3 style guide and naming conventions
Applied to files:
src/components/sidebar/tabs/AssetsSidebarListView.vue
📚 Learning: 2026-01-09T00:50:57.103Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-09T00:50:57.103Z
Learning: Applies to src/**/*.vue : Avoid using `ref` and `watch` together if a `computed` would work instead
Applied to files:
src/components/sidebar/tabs/AssetsSidebarListView.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Use ref/reactive for state management in Vue 3 Composition API
Applied to files:
src/components/sidebar/tabs/AssetsSidebarListView.vue
📚 Learning: 2026-01-09T00:50:57.103Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-09T00:50:57.103Z
Learning: Applies to src/**/*.vue : Be judicious with state additions: prefer props, avoid `computed` for simple values, use `computed` instead of `watch` for derived values
Applied to files:
src/components/sidebar/tabs/AssetsSidebarListView.vue
📚 Learning: 2026-01-09T00:50:57.103Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-09T00:50:57.103Z
Learning: Applies to src/**/*.{ts,tsx,vue} : Watch out for code smells and refactor to avoid them
Applied to files:
src/components/sidebar/tabs/AssetsSidebarListView.vue
📚 Learning: 2025-12-09T21:40:12.361Z
Learnt from: benceruleanlu
Repo: Comfy-Org/ComfyUI_frontend PR: 7297
File: src/components/actionbar/ComfyActionbar.vue:33-43
Timestamp: 2025-12-09T21:40:12.361Z
Learning: In Vue single-file components, allow inline Tailwind CSS class strings for static classes and avoid extracting them into computed properties solely for readability. Prefer keeping static class names inline for simplicity and performance. For dynamic or conditional classes, use Vue bindings (e.g., :class) to compose classes.
Applies to all Vue files in the repository (e.g., src/**/*.vue) where Tailwind utilities are used for static styling.
Applied to files:
src/components/sidebar/tabs/AssetsSidebarListView.vue
📚 Learning: 2026-01-09T00:50:57.103Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-09T00:50:57.103Z
Learning: Applies to src/**/*.vue : Use `cn()` utility from `@/utils/tailwindUtil` for merging class names; never use `:class="[]"` syntax
Applied to files:
src/components/sidebar/tabs/AssetsSidebarListView.vue
📚 Learning: 2026-01-08T02:26:18.357Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7893
File: src/components/button/IconGroup.vue:5-6
Timestamp: 2026-01-08T02:26:18.357Z
Learning: In components that use the cn utility from '@/utils/tailwindUtil' with tailwind-merge, rely on the behavior that conflicting Tailwind classes are resolved by keeping the last one. For example, cn('base-classes bg-default', propClass) will have any conflicting background class from propClass override bg-default. This additive pattern is intentional and aligns with the shadcn-ui convention; ensure you document or review expectations accordingly in Vue components.
Applied to files:
src/components/sidebar/tabs/AssetsSidebarListView.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Use the Vue 3 Composition API instead of the Options API when writing Vue components (exception: when overriding or extending PrimeVue components for compatibility)
Applied to files:
src/components/sidebar/tabs/AssetsSidebarListView.vue
📚 Learning: 2025-12-09T03:49:52.828Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 6300
File: src/platform/updates/components/WhatsNewPopup.vue:5-13
Timestamp: 2025-12-09T03:49:52.828Z
Learning: In Vue files across the ComfyUI_frontend repo, when a button is needed, prefer the repo's common button components from src/components/button/ (IconButton.vue, TextButton.vue, IconTextButton.vue) over plain HTML <button> elements. These components wrap PrimeVue with the project’s design system styling. Use only the common button components for consistency and theming, and import them from src/components/button/ as needed.
Applied to files:
src/components/sidebar/tabs/AssetsSidebarListView.vue
📚 Learning: 2025-12-16T22:26:49.463Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7537
File: src/components/ui/button/Button.vue:17-17
Timestamp: 2025-12-16T22:26:49.463Z
Learning: In Vue 3.5+ with <script setup>, when using defineProps<Props>() with partial destructuring (e.g., const { as = 'button', class: customClass = '' } = defineProps<Props>() ), props that are not destructured (e.g., variant, size) stay accessible by name in the template scope. This pattern is valid: you can destructure only a subset of props for convenience while referencing the remaining props directly in template expressions. Apply this guideline to Vue components across the codebase (all .vue files).
Applied to files:
src/components/sidebar/tabs/AssetsSidebarListView.vue
📚 Learning: 2025-12-22T21:36:08.369Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7649
File: src/platform/cloud/subscription/components/PricingTable.vue:185-201
Timestamp: 2025-12-22T21:36:08.369Z
Learning: In Vue components, avoid creating single-use variants for common UI components (e.g., Button and other shared components). Aim for reusable variants that cover multiple use cases. It’s acceptable to temporarily mix variant props with inline Tailwind classes when a styling need is unique to one place, but plan and consolidate into shared, reusable variants as patterns emerge across the codebase.
Applied to files:
src/components/sidebar/tabs/AssetsSidebarListView.vue
📚 Learning: 2025-12-18T02:07:38.870Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7598
File: src/components/sidebar/tabs/AssetsSidebarTab.vue:131-131
Timestamp: 2025-12-18T02:07:38.870Z
Learning: Tailwind CSS v4 safe utilities (e.g., items-center-safe, justify-*-safe, place-*-safe) are allowed in Vue components under src/ and in story files. Do not flag these specific safe variants as invalid when reviewing code in src/**/*.vue or related stories.
Applied to files:
src/components/sidebar/tabs/AssetsSidebarListView.vue
📚 Learning: 2025-12-18T21:15:46.862Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7603
File: src/components/queue/QueueOverlayHeader.vue:49-59
Timestamp: 2025-12-18T21:15:46.862Z
Learning: In the ComfyUI_frontend repository, for Vue components, do not add aria-label to buttons that have visible text content (e.g., buttons containing <span> text). The visible text provides the accessible name. Use aria-label only for elements without visible labels (e.g., icon-only buttons). If a button has no visible label, provide a clear aria-label or associate with an aria-labelledby describing its action.
Applied to files:
src/components/sidebar/tabs/AssetsSidebarListView.vue
📚 Learning: 2025-12-21T01:06:02.786Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7649
File: src/components/graph/selectionToolbox/ColorPickerButton.vue:15-18
Timestamp: 2025-12-21T01:06:02.786Z
Learning: In Comfy-Org/ComfyUI_frontend, in Vue component files, when a filled icon is required (e.g., 'pi pi-circle-fill'), you may mix PrimeIcons with Lucide icons since Lucide lacks filled variants. This mixed usage is acceptable when one icon library does not provide an equivalent filled icon. Apply consistently across Vue components in the src directory where icons are used, and document the rationale when a mixed approach is chosen.
Applied to files:
src/components/sidebar/tabs/AssetsSidebarListView.vue
🧬 Code graph analysis (1)
src/composables/queue/useJobActions.ts (3)
src/composables/useErrorHandling.ts (1)
useErrorHandling(52-112)src/composables/queue/useJobMenu.ts (1)
useJobMenu(43-359)src/types/queue.ts (1)
JobState(4-9)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
- GitHub Check: deploy-and-comment
- GitHub Check: lint-and-format
- GitHub Check: setup
- GitHub Check: collect
- GitHub Check: test
🔇 Additional comments (2)
src/composables/queue/useJobActions.ts (1)
16-59: Well-structured composable with proper reactive patterns.The composable correctly:
- Accepts a reactive job parameter via
MaybeRefOrGetter- Converts it to a computed ref for consistent reactivity
- Derives cancellability state reactively
- Wraps the cancel action with centralized error handling
- Returns a clean interface with both state and actions
src/components/sidebar/tabs/AssetsSidebarListView.vue (1)
84-203: Well-structured component with good reactive patterns and accessibility.The component demonstrates several strengths:
- Proper Vue 3 Composition API usage with
<script setup lang="ts">- Clean props/emits interface with proper TypeScript typing
- Good accessibility with aria-label, role, and tabindex attributes
- Effective use of VirtualGrid for rendering large asset lists efficiently
- Pure, testable helper functions for asset display logic
- Proper i18n integration for user-facing strings
- Reactive hover state management with
hoveredJobIdfeeding intouseJobActionsThe architecture cleanly separates active jobs (with cancel actions) from generated assets, with appropriate visual hierarchy.
| function isActiveJobState(state: JobState): boolean { | ||
| return ( | ||
| state === 'pending' || state === 'initialization' || state === 'running' | ||
| ) | ||
| } |
There was a problem hiding this comment.
🛠️ Refactor suggestion | 🟠 Major
Eliminate code duplication with useJobActions.
The isActiveJobState function duplicates the cancellableStates logic from useJobActions.ts (line 29). Both define the same three states: pending, initialization, and running. If the definition of active/cancellable states changes, both locations would need updates.
♻️ Proposed refactor
Option 1: Export a shared constant from a common location
Create or use an existing constants file (e.g., src/types/queue.ts or src/constants/queue.ts):
// src/types/queue.ts or src/constants/queue.ts
export const ACTIVE_JOB_STATES: JobState[] = [
'pending',
'initialization',
'running'
] as constThen import and use in both files:
In useJobActions.ts:
+import { ACTIVE_JOB_STATES } from '@/types/queue'
+
export function useJobActions(
job: MaybeRefOrGetter<JobListItem | null | undefined>
) {
// ...
return (
currentJob.showClear !== false &&
- cancellableStates.includes(currentJob.state)
+ ACTIVE_JOB_STATES.includes(currentJob.state)
)
}In AssetsSidebarListView.vue:
+import { ACTIVE_JOB_STATES } from '@/types/queue'
+
function isActiveJobState(state: JobState): boolean {
- return (
- state === 'pending' || state === 'initialization' || state === 'running'
- )
+ return ACTIVE_JOB_STATES.includes(state)
}Option 2: Import directly from useJobActions (if you export the constant)
This centralizes the definition in the composable that owns the logic.
This refactor improves maintainability by ensuring the definition of active/cancellable job states is managed in one place.
Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In @src/components/sidebar/tabs/AssetsSidebarListView.vue around lines 148 -
152, isActiveJobState duplicates the cancellableStates list from
useJobActions.ts; centralize the definition to avoid divergence by exporting a
shared constant (e.g., ACTIVE_JOB_STATES) and using it in both places. Update
useJobActions.ts to export the constant (or move it to a shared file like
src/types/queue.ts or src/constants/queue.ts), then replace the local
cancellableStates/reference in useJobActions and replace isActiveJobState in
AssetsSidebarListView.vue to check membership against the exported
ACTIVE_JOB_STATES (or import from useJobActions if you choose that location).
Ensure types remain JobState[] and adjust imports accordingly.
There was a problem hiding this comment.
@coderabbitai make a tracking issue for this in the future
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Create a GitHub issue to track the code duplication refactoring
gh issue create \
--repo "Comfy-Org/ComfyUI_frontend" \
--title "Refactor: Eliminate code duplication between isActiveJobState and cancellableStates" \
--body "## Context
Code duplication exists between:
- \`isActiveJobState\` function in \`src/components/sidebar/tabs/AssetsSidebarListView.vue\` (lines 148-152)
- \`cancellableStates\` in \`src/composables/queue/useJobActions.ts\` (line 29)
Both define the same three job states: \`pending\`, \`initialization\`, and \`running\`.
## Problem
If the definition of active/cancellable states changes, both locations would need updates, creating a maintenance burden and risk of divergence.
## Proposed Solution
Centralize the definition by:
1. Creating a shared constant (e.g., \`ACTIVE_JOB_STATES\`) in a common location like \`src/types/queue.ts\` or \`src/constants/queue.ts\`
2. Updating both files to import and use the shared constant
3. Replacing the local \`cancellableStates\` set and \`isActiveJobState\` function with references to the shared constant
## References
- Related PR: #7737
- Review comment: https://github.com/Comfy-Org/ComfyUI_frontend/pull/7737#discussion_r2674607316
- Requested by: @christian-byrne" \
--assignee "christian-byrne"
Length of output: 57
@christian-byrne I've created issue #7947 to track this refactoring. The issue documents the code duplication between isActiveJobState and cancellableStates, explains the maintenance risk, and proposes centralizing the definition in a shared constant. It's been assigned to you and includes references back to this PR and review comment.
🧠 Learnings used
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue Sidebar component with Drawer
| const cancelAction: JobAction = { | ||
| icon: 'icon-[lucide--x]', | ||
| label: t('sideToolbar.queueProgressOverlay.cancelJobTooltip'), | ||
| variant: 'destructive' | ||
| } | ||
|
|
||
| const cancellableStates: JobState[] = ['pending', 'initialization', 'running'] |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Move static data outside the function for better performance.
Both cancelAction (lines 23-27) and cancellableStates (line 29) are static data that get recreated on every composable invocation. Moving them outside as constants would improve performance and align with immutability preferences.
♻️ Proposed refactor
+const CANCELLABLE_STATES: JobState[] = [
+ 'pending',
+ 'initialization',
+ 'running'
+]
+
export function useJobActions(
job: MaybeRefOrGetter<JobListItem | null | undefined>
) {
const { t } = useI18n()
const { wrapWithErrorHandlingAsync } = useErrorHandling()
const { cancelJob } = useJobMenu()
- const cancelAction: JobAction = {
+ const cancelAction: JobAction = {
icon: 'icon-[lucide--x]',
label: t('sideToolbar.queueProgressOverlay.cancelJobTooltip'),
variant: 'destructive'
}
- const cancellableStates: JobState[] = ['pending', 'initialization', 'running']
-
const jobRef = computed(() => toValue(job) ?? null)
const canCancelJob = computed(() => {
const currentJob = jobRef.value
if (!currentJob) {
return false
}
return (
currentJob.showClear !== false &&
- cancellableStates.includes(currentJob.state)
+ CANCELLABLE_STATES.includes(currentJob.state)
)
})Note: cancelAction could also be moved outside, but since it uses t() from useI18n(), it would need to be initialized differently (e.g., as a factory or kept as-is). The current implementation is acceptable if i18n reactivity is desired.
Based on coding guidelines emphasizing immutability and minimal mutable state.
Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In @src/composables/queue/useJobActions.ts around lines 23 - 29, Move the purely
static array cancellableStates out of the composable and define it as a
module-level constant named cancellableStates: JobState[] =
['pending','initialization','running'] to avoid recreating it on each
invocation; for cancelAction (symbol cancelAction) since it depends on t() from
useI18n(), either keep it inside the composable or convert it to a small factory
function (e.g., createCancelAction(t): JobAction) that builds and returns the
object so the static shape is defined outside while still allowing localization
to be injected.
There was a problem hiding this comment.
@coderabbitai make a tracking issue for this in the future
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Create a GitHub issue for the refactoring task
gh issue create \
--title "Refactor: Move static data outside useJobActions composable" \
--body "## Context
This refactoring was suggested during review of PR #7737.
## File
\`src/composables/queue/useJobActions.ts\`
## Suggestion
Move static data outside the composable function for better performance:
1. **\`cancellableStates\`** (lines 29): This static array is recreated on every composable invocation. Should be moved to module-level as a constant:
\`\`\`typescript
const CANCELLABLE_STATES: JobState[] = ['pending', 'initialization', 'running']
\`\`\`
2. **\`cancelAction\`** (lines 23-27): Consider moving outside or converting to a factory function, though it depends on \`t()\` from \`useI18n()\` so may need special handling for i18n reactivity.
## Benefits
- Improved performance by avoiding recreation on each invocation
- Better aligns with immutability preferences
- Reduces memory allocation
## References
- PR: https://github.com/Comfy-Org/ComfyUI_frontend/pull/7737
- Review comment: https://github.com/Comfy-Org/ComfyUI_frontend/pull/7737#discussion_r2674607319
Based on coding guidelines emphasizing immutability and minimal mutable state." \
--assignee christian-byrne
Length of output: 57
@christian-byrne, I've created tracking issue #7946 for the refactoring suggestion about moving static data outside the useJobActions composable.
The issue has been assigned to you and includes the context, specific refactoring details, benefits, and backlinks to this PR and review comment.
| function isActiveJobState(state: JobState): boolean { | ||
| return ( | ||
| state === 'pending' || state === 'initialization' || state === 'running' | ||
| ) | ||
| } |
There was a problem hiding this comment.
@coderabbitai make a tracking issue for this in the future
| const cancelAction: JobAction = { | ||
| icon: 'icon-[lucide--x]', | ||
| label: t('sideToolbar.queueProgressOverlay.cancelJobTooltip'), | ||
| variant: 'destructive' | ||
| } | ||
|
|
||
| const cancellableStates: JobState[] = ['pending', 'initialization', 'running'] |
There was a problem hiding this comment.
@coderabbitai make a tracking issue for this in the future
Add stories for the media assets sidebar tab for easier prototyping. Includes mocks for storybook. Because some functions in the mocks are only used in the storybook main.ts resolve, knip flags them as unused because it doesn't check that path. So knipIgnoreUnusedButUsedByStorybook was added. Part of the QPO v2 iteration, figma design can be found [here](https://www.figma.com/design/LVilZgHGk5RwWOkVN6yCEK/Queue-Progress-Modal?node-id=3330-37286&m=dev). This will be implemented in a series of stacked PRs that can be reviewed and merged individually. main <-- #7737, #7743, #7745 ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-7743-QPOv2-Add-stories-for-list-view-and-general-job-card-2d26d73d365081bca59afa925fb232d7) by [Unito](https://www.unito.io) --------- Co-authored-by: GitHub Action <action@github.com>
This adds the list view to the media assets sidepanel, while also adding the active jobs to be displayed right now.
The design for this is actually changing, which is why it is in draft right now. There are technical limitations of the virtual grid that doesn't make it easy for both the active jobs and generated assets to exist on the same container. Currently WIP right now.
Part of the QPO v2 iteration, figma design can be found here. This will be implemented in a series of stacked PRs that can be reviewed and merged individually.
main <-- #7737, #7743, #7745
┆Issue is synchronized with this Notion page by Unito