## Summary
Refactors `BaseModalLayout` from a flexbox-based layout to CSS Grid,
enabling smoother panel transitions and improved layout control.
## Changes
### Layout Restructure
- **Flexbox → CSS Grid**: Replaced nested flexbox with a 3-column CSS
Grid (`nav | main | aside`)
- **Smooth panel transitions**: Panel show/hide now animates via
`grid-template-columns` instead of Vue `<Transition>` with `translateX`
- **Removed transition CSS**: Deleted `.slide-panel-*` and `.fade-*`
transition styles (no longer needed with grid approach)
### Right Panel Improvements
- **Dedicated header**: Added header with close button, right panel
toggle, and customizable title slot (`rightPanelHeaderTitle`,
`rightPanelHeaderActions`)
- **New prop**: Added `rightPanelTitle` prop for simple text title in
right panel header
### UX & Accessibility
- **ESC key handling**: Pressing Escape closes the right panel (if open)
before closing the dialog
- **Accessibility**: Added `aria-label` attributes to all panel toggle
and close buttons
- **i18n**: Added translation keys: `showLeftPanel`, `hideLeftPanel`,
`showRightPanel`, `hideRightPanel`, `closeDialog`
---------
Co-authored-by: Amp <amp@ampcode.com>
## Summary
Adds optional badge support to the `NavItem` component and `NavItemData`
interface, enabling navigation items in the left sidebar of the Asset
Browser Modal to display counts or status indicators.
## Changes
- **`src/types/navTypes.ts`**: Added optional `badge?: string | number`
property to `NavItemData` interface
- **`src/components/widget/nav/NavItem.vue`**: Added `StatusBadge`
rendering when `badge` prop is provided
- **`src/components/widget/panel/LeftSidePanel.vue`**: Wired `badge`
prop from `NavItemData` to `NavItem` for both grouped and ungrouped
items
## Usage
```ts
const navItem: NavItemData = {
id: 'assets',
label: 'Assets',
icon: 'pi pi-folder',
badge: 5 // Optional - displays count badge
}
```
## Related
- Builds on #8170 which added queue badge functionality
┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-8207-feat-add-badge-support-to-NavItem-component-2ef6d73d365081669f86fe2fc618e87f)
by [Unito](https://www.unito.io)
## Summary
Simplifies the Manager dialog by consolidating components and using
BaseModalLayout with v-model support for right panel state.
## Changes
- **Consolidation**: Merged ManagerDialogContent, ManagerHeader,
ManagerNavSidebar, RegistrySearchBar, and SearchFilterDropdown into
single ManagerDialog component
- **Right panel**: Added v-model:rightPanelOpen to BaseModalLayout for
external panel state control; clicking a node card now auto-opens the
info panel
- **Cleanup**: Removed unused useResponsiveCollapse composable, TabItem
and SearchOption types
- **UI tweaks**: Moved action buttons (Install All/Update All) from
header-right-area to contentFilter area
[manager-capture.webm](https://github.com/user-attachments/assets/2dd6092a-965d-4885-8ba6-6a2cc51f024a)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-8041-refactor-Manager-dialog-simplification-2e86d73d3650815ba699e49a2748b682)
by [Unito](https://www.unito.io)
---------
Co-authored-by: GitHub Action <action@github.com>
Co-authored-by: github-actions <github-actions@github.com>
## Problem
The `AssetBrowserModal` triggers hundreds of network requests when
opened because `AssetGrid.vue` renders all asset cards immediately using
a simple `v-for` loop. Each `AssetCard` loads its thumbnail image,
causing a flood of simultaneous requests.
## Solution
Replace the simple `v-for` with the existing `VirtualGrid` component
(already used in `AssetsSidebarTab.vue` and `ManagerDialogContent.vue`)
to only render visible items plus a small buffer.
## Changes
- **`AssetGrid.vue`**: Use `VirtualGrid` with computed `assetsWithKey`
that adds the required `key` property from `asset.id`
- **`BaseModalLayout.vue`**: Add `flex-1` to content container for
proper height calculation (required for `VirtualGrid` to work)
## Testing
- All 130 asset-related tests pass
- TypeScript and lint checks pass
┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-7919-perf-AssetBrowserModal-virtualize-asset-grid-to-reduce-network-requests-2e36d73d365081a1be18d0eb33b7ef8a)
by [Unito](https://www.unito.io)
Co-authored-by: Amp <amp@ampcode.com>
## Summary
Fix button sizing inconsistencies in modal dialogs and the asset
browser.
## Changes
- **What**: Fix Import button using responsive size (`lg`/`icon` based
on breakpoint) and ensure Modal Close button has explicit `w-10` width
for consistent sizing.
## Review Focus
Button sizing consistency across the modal UI.
┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-7920-fix-Button-sizing-in-modals-and-asset-browser-2e36d73d365081fc997af8be1e928049)
by [Unito](https://www.unito.io)
## Summary
Catch more user visible (or audible) text that isn't
internationalizable.
## Changes
- **What**: Linter now checks other attributes for raw text.
## Review Focus
What other properties have leaked English text to non-English locales
that aren't in here?
## Summary
This PR fixes all @intlify/vue-i18n/no-raw-text linting errors
identified in #5625 by replacing raw text strings with proper i18n
translation function calls.
## Changes
Fixed i18n linting errors in the following files:
- `src/components/widget/SampleModelSelector.vue` - "Upload Model" →
`$t('g.upload')`
- `src/components/topbar/CurrentUserButton.vue` - "user profile" →
`$t('g.currentUser')`
- `src/components/sidebar/tabs/nodeLibrary/NodeHelpPage.vue` - "Loading
help" → `$t('g.loading')`
- `src/components/sidebar/SidebarShortcutsToggleButton.vue` -
"shortcuts.shortcuts" → `$t('shortcuts.shortcuts')`
- `src/components/sidebar/SidebarLogoutIcon.vue` - "sideToolbar.logout"
→ `$t('sideToolbar.logout')`
- `src/components/sidebar/SidebarHelpCenterIcon.vue` - "menu.help" →
`$t('menu.help')`
- `src/components/sidebar/SidebarBottomPanelToggleButton.vue` -
"sideToolbar.labels.console" → `$t('sideToolbar.labels.console')`
- `src/components/load3d/controls/viewer/ViewerCameraControls.vue` -
"fov" → `t('load3d.fov')`
- `src/components/helpcenter/HelpCenterMenuContent.vue` - "Help Center
Menu" and "Recent releases" → `$t()` calls
All raw text strings have been replaced with appropriate i18n
translation keys that already exist in `src/locales/en/main.json`.
## Related Issue
Fixes errors reported in CI job:
https://github.com/Comfy-Org/ComfyUI_frontend/actions/runs/18705105609/job/53341658467?pr=5625
This PR aims to help #5625 pass CI/CD checks.
## Test Plan
- All i18n linting errors should be resolved
- No functionality changes - only proper use of i18n system
- Existing translation keys are used from the locale files
┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-6280-bugfix-fix-intlify-vue-i18n-no-raw-text-linting-errors-2976d73d365081369b43de01486fb409)
by [Unito](https://www.unito.io)
---------
Co-authored-by: GitHub Action <action@github.com>
## Summary
Implements a comprehensive media asset card component system for the
Asset Manager sidebar, enabling display and interaction with various
media types (images, videos, audio, and 3D models).
## Changes
### New Components
- **MediaAssetCard**: Main card component for displaying media assets
- **Media type-specific components**: Specialized display logic for each
media type
- MediaImageTop/Bottom
- MediaVideoTop/Bottom
- MediaAudioTop/Bottom
- Media3DTop/Bottom
- **MediaAssetActions**: Top-left action buttons (delete, download, more
options)
- **MediaAssetMoreMenu**: Dropdown menu for additional actions
- **SquareChip**: Chip component for displaying duration and file format
with dark/light variants
- **MediaAssetButtonDivider**: Visual separator for button groups
### Features
- **Video playback**: Autoplay with native video controls
- Dynamic duration chip positioning based on control visibility
- Hides overlays when video is playing
- **Audio playback**: Audio icon with HTML5 audio element
- Duration chip with consistent positioning
- **3D model support**: Icon display for 3D assets
- **Selection state**: Proper hover and selected state handling with CSS
priority fixes
### Architecture Improvements
- **Domain-Driven Design structure**: Organized under
`src/platform/mediaAsset/` following DDD principles
- **Provide/Inject pattern**: Eliminates props drilling with
MediaAssetKey InjectionKey
- **Composable pattern**: `useMediaAssetActions` manages all action
handlers
- **Type safety**: Comprehensive TypeScript types for media assets and
actions
### UI/UX Enhancements
- **CardTop component**: Added custom class props for slot positioning
- **SquareChip component**: Backdrop blur effects with variant system
- **Lazy loading**: Image optimization with LazyImage component
- **Responsive states**: Loading, selected, and hover states
### Utilities
- **formatDuration**: Converts milliseconds to human-readable format
(45s, 1m 23s, 1h 2m)
## Testing
- Comprehensive Storybook stories for all media types
- Grid layout examples
- Loading and selected state demonstrations
## File Structure
```
src/platform/assets/
├── components/
│ ├── MediaAssetCard.vue
│ ├── MediaAssetCard.stories.ts
│ ├── MediaAssetActions.vue
│ ├── MediaAssetMoreMenu.vue
│ ├── MediaAssetButtonDivider.vue
│ ├── MediaImageTop.vue
│ ├── MediaImageBottom.vue
│ ├── MediaVideoTop.vue
│ ├── MediaVideoBottom.vue
│ ├── MediaAudioTop.vue
│ ├── MediaAudioBottom.vue
│ ├── Media3DTop.vue
│ └── Media3DBottom.vue
├── composables/
│ └── useMediaAssetActions.ts
└── schemas/
└── mediaAssetSchema.ts
```
## Screenshots
[media_asset_record.webm](https://github.com/user-attachments/assets/d13b5cc0-a262-4850-bb81-ca1daa0dd969)
---------
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: GitHub Action <action@github.com>
Co-authored-by: github-actions <github-actions@github.com>
This pull request introduces improvements to the workflow template
selector and search box components, focusing on better user experience
and more accurate terminology. The most significant changes include
adding debounced search input handling, updating sorting option labels,
and refining UI styling for consistency.
**Search functionality improvements:**
* Refactored `SearchBox.vue` to use an internal search query state and a
debounced update mechanism, reducing unnecessary parent updates and
improving responsiveness. The parent model is updated only after the
user stops typing for 300ms. (`src/components/input/SearchBox.vue`)
[[1]](diffhunk://#diff-08f3b0c51fbfe63171509b9944bf7558228f6c2596a1ef5338e88ab64585791bL6-R6)
[[2]](diffhunk://#diff-08f3b0c51fbfe63171509b9944bf7558228f6c2596a1ef5338e88ab64585791bR39-R62)
* Updated the search box in `WorkflowTemplateSelectorDialog.vue` to use
the new debounced search model and increased its size for better
visibility.
(`src/components/custom/widget/WorkflowTemplateSelectorDialog.vue`)
**Sorting and terminology updates:**
* Changed sorting option labels to use more precise terminology, such as
"VRAM Usage (Low to High)" and added new locale strings for sorting
options.
(`src/components/custom/widget/WorkflowTemplateSelectorDialog.vue`,
`src/locales/en/main.json`)
[[1]](diffhunk://#diff-2c860bdc48e907b1b85dbef846599d8376dd02cff90f49e490eebe61371fecedL623-R623)
[[2]](diffhunk://#diff-bbf3da78aeff5b4d868a17a6960d109cb0627316cda2f9b5fa7c08e9abd93be6L1032-R1035)
**UI and styling adjustments:**
* Adjusted the width of the sorting dropdown for better alignment and
consistency.
(`src/components/custom/widget/WorkflowTemplateSelectorDialog.vue`)
* Updated active navigation item background color for improved visual
clarity. (`src/components/widget/nav/NavItem.vue`)
┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-5975-Workflow-templates-review-2866d73d365081419257f9df2bab9c5b)
by [Unito](https://www.unito.io)
https://github.com/user-attachments/assets/4f72d515-f114-4cd4-8a76-6abbe906e5bb
This pull request refactors and simplifies the template workflow card
components and related UI in the codebase. The main changes focus on
removing unused or redundant components, improving visual and
interaction consistency, and enhancing error handling for images. Below
are the most important changes grouped by theme:
**Template Workflow Card Refactor and Cleanup**
* Removed the `TemplateWorkflowCard.vue` component and its associated
test file `TemplateWorkflowCard.spec.ts`, as well as the
`TemplateWorkflowCardSkeleton.vue` and `TemplateWorkflowList.vue`
components, indicating a shift away from the previous card-based
template workflow UI.
[[1]](diffhunk://#diff-49569af0404058e8257f3cc0716b066517ce7397dd58744b02aa0d0c61f2a815L1-L139)
[[2]](diffhunk://#diff-9fa6fc1470371f0b520d4deda4129fb313b1bea69888a376556f4bd824f9d751L1-L263)
[[3]](diffhunk://#diff-bc35b6f77d1cee6e86b05d0da80b7bd40013c7a6a97a89706d3bc52573e1c574L1-L30)
[[4]](diffhunk://#diff-48171f792b22022526fca411d3c3a366d48b675dab77943a20846ae079cbaf3bL1-L68)
* Removed the `TemplateSearchBar.vue` component, suggesting a redesign
or replacement of the search/filter UI for templates.
**UI and Interaction Improvements**
* Improved the `CardBottom.vue` component by making its height
configurable via a `fullHeight` prop, enhancing layout flexibility.
* Updated the `CardContainer.vue` component to add hover effects
(background, border, shadow, and padding) and support a new `none`
aspect ratio for more flexible card layouts.
**Image and Input Enhancements**
* Enhanced the `LazyImage.vue` component to display a default
placeholder image when an image fails to load, improving error handling
and user experience.
* Improved the `SearchBox.vue` component by making the input focusable
when clicking anywhere on the wrapper, and added a template ref for
better accessibility and usability.
[[1]](diffhunk://#diff-08f3b0c51fbfe63171509b9944bf7558228f6c2596a1ef5338e88ab64585791bL2-R5)
[[2]](diffhunk://#diff-08f3b0c51fbfe63171509b9944bf7558228f6c2596a1ef5338e88ab64585791bL16-R17)
[[3]](diffhunk://#diff-08f3b0c51fbfe63171509b9944bf7558228f6c2596a1ef5338e88ab64585791bR33-R39)
**Minor UI Tweaks**
* Adjusted label styling in `SingleSelect.vue` to remove unnecessary
overflow handling, simplifying the visual layout.
---------
Co-authored-by: Benjamin Lu <benceruleanlu@proton.me>
Co-authored-by: Alexander Brown <drjkl@comfy.org>
Co-authored-by: github-actions <github-actions@github.com>
Co-authored-by: Christian Byrne <cbyrne@comfy.org>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: snomiao <snomiao@gmail.com>
Co-authored-by: GitHub Action <action@github.com>
Co-authored-by: filtered <176114999+webfiltered@users.noreply.github.com>
Co-authored-by: Comfy Org PR Bot <snomiao+comfy-pr@gmail.com>
Co-authored-by: Jin Yi <jin12cc@gmail.com>
* feat: add dynamic icon support for NavItem components
- Created NavIcon component with switch-case based icon rendering
- Added iconName prop to NavItem and NavItemData interface
- Updated LeftSidePanel to pass icon names to nav items
- Added sample icons to SampleModelSelector navigation (download, tag, layers, grid)
- Uses i-lucide syntax without imports for better tree-shaking
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* test: add Storybook stories for navigation components
- Add NavIcon.stories.ts with interactive icon selector and all icons gallery
- Add NavItem.stories.ts with text customization and interactive list examples
- Add LeftSidePanel.stories.ts with various navigation configurations
- Remove old Navigation.stories.ts (replaced with component-specific stories)
- Configure slot visibility and hide update:modelValue event in controls
* refactor: simplify NavIcon component and improve type definitions
* fix: add icon size specification for Lucide icons in Storybook
* feature: NavItem story modified
* fix: disable knip unresolved imports rule for virtual icon modules
Add unresolved: 'off' to knip configuration to ignore virtual module imports
from unplugin-icons (~icons/*). These are generated at build time and cannot
be resolved statically.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* chore: v-if condition added
* chore: knip ignoreUnresolved added based on knip issue PR
* refactor: navItem types added & deleting any type on storybook files
---------
Co-authored-by: Claude <noreply@anthropic.com>
* temp: move tailwind calls out of the layer
* temp: ts tailwind config
* upgrade: Tailwind v4
This got a little out of hand.
Had to add a relative reference to the stylesheet in any component that uses @apply instead of the utility classes directly.
* upgrade: bg-opacity is now a modifier
* fix: Classic menu buttons assume a border
* Update test expectations [skip ci]
* fix: New preflight removal pattern
* fix: Skeletons don't have skin
* Update test expectations [skip ci]
* fix: Missing @reference
* [auto-fix] Apply ESLint and Prettier fixes
---------
Co-authored-by: github-actions <github-actions@github.com>
Co-authored-by: GitHub Action <action@github.com>
* [feat] Add enhanced filter UI components with search and clear functionality
- Add SearchBox, clear all button, and item count to MultiSelect header
- Add 'fit-content' size option to button types for flexible sizing
- Update SingleSelect and ModelSelector components for consistency
- Add localization strings for item selection and clear all functionality
Co-Authored-By: Claude <noreply@anthropic.com>
* Update locales [skip ci]
---------
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: github-actions <github-actions@github.com>