## Summary
Refactors asset download state management and fixes asset deletion UI
issues.
## Changes
### assetDownloadStore simplification
- Replace `pendingModelTypes` Map with `modelType` stored directly on
`AssetDownload`
- Replace `completedDownloads` array with single `lastCompletedDownload`
ref
- `trackDownload()` now creates a placeholder entry immediately
- Use VueUse `whenever` instead of `watch` for cleaner null handling
### Asset refresh on download completion
- Refresh all relevant caches when a download completes:
- Node type caches (e.g., "CheckpointLoaderSimple")
- Tag caches (e.g., "tag:checkpoints")
- "All Models" cache ("tag:models")
### Asset deletion fix
- Remove local `deletedLocal` state that caused blank grid cells
- Emit `deleted` event from AssetCard → AssetGrid → AssetBrowserModal
- Trigger store refresh on deletion to properly remove the asset from
the grid
## Testing
- Added test for out-of-order websocket message handling
- All existing tests pass
┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-7974-refactor-simplify-asset-download-state-and-fix-deletion-UI-2e76d73d365081c69bcde9150a0d460c)
by [Unito](https://www.unito.io)
---------
Co-authored-by: Amp <amp@ampcode.com>
## Summary
Addresses UI/UX feedback on the Upload Model Dialog (BYOM feature).
## Changes
1. **Standardize link styling** - Use consistent `text-muted-foreground
underline` for all links in both URL input variants
2. **Increase warning/example text font size** - Changed from 12px
(`text-xs`) to 14px (`text-sm`) for better readability
3. **Fix padding inconsistency** - Aligned padding between model name
box and SingleSelect dropdown; moved "Not sure?" help text inline with
the label
4. **Add "Upload Another" button** - Allows users to upload multiple
models without closing and reopening the dialog
## Testing
- Verified link styling consistency across both Civitai and generic URL
input components
- Confirmed padding alignment in confirmation step
- Tested Upload Another button resets wizard to step 1
┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-7969-fix-upload-model-UI-UX-improvements-for-Upload-Model-Dialog-2e66d73d3650815c8184cedb3d02672d)
by [Unito](https://www.unito.io)
## Summary
Truncate long filenames in the model upload wizard to prevent dialog
overflow.
## Changes
- **UploadModelConfirmation**: Added `min-w-0 flex-1 truncate` to model
filename display
- **UploadModelProgress**: Added truncation to both processing and
success state filename displays
## Testing
1. Import a model with a very long filename
2. Verify the filename truncates with ellipsis instead of expanding the
dialog
┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-7939-fix-UploadModel-truncate-long-filenames-in-wizard-2e46d73d365081a0a60bd6326129b9a4)
by [Unito](https://www.unito.io)
## Summary
Polishing improvements for the model upload (BYOM) experience.
## Changes
- **HoneyToast z-index**: Increased from `z-50` to `z-9999` so the
ModelImportProgressDialog appears above modal backdrops
- **VideoHelpDialog**: Removed pixel-based max-width constraint, now
uses `90vw` to fill more of the viewport
- **UploadModelDialog responsive layout**: Added `max-height: 90vh` and
scrollable content area to prevent footer buttons from underflowing on
small screens
- **URL validity indicator**: Added green checkmark icon inside the URL
input when a valid Civitai or HuggingFace URL is entered
## Testing
- Open the model upload dialog and verify buttons remain accessible on
small viewport heights
- Enter a valid Civitai/HuggingFace URL and confirm the green checkmark
appears
- Open the help video and verify it uses more of the viewport
- Start a model download and verify the progress toast appears above any
open modals
┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-7938-fix-Model-upload-UI-improvements-2e46d73d365081a292f5fda70c6db0f5)
by [Unito](https://www.unito.io)
---------
Co-authored-by: Amp <amp@ampcode.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.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
Add HoneyToast, a persistent bottom-anchored notification component for
long-running task progress, and migrate existing progress dialogs to use
it.
## Changes
- **What**:
- New `HoneyToast` component with slot-based API, Teleport, transitions,
and accessibility
- Migrated `ModelImportProgressDialog` to use HoneyToast
- Created `ManagerProgressToast` combining the old Header/Content/Footer
components
- Deleted deprecated `ManagerProgressDialogContent`,
`ManagerProgressHeader`, `ManagerProgressFooter`, and
`useManagerProgressDialogStore`
- Removed no-op
`showManagerProgressDialog`/`toggleManagerProgressDialog` functions
- Added Storybook stories for HoneyToast and ProgressToastItem
## Review Focus
- HoneyToast component design and slot API
- ManagerProgressToast self-contained state management (auto-shows when
`comfyManagerStore.taskLogs.length > 0`)
- Accessibility attributes on the toast component
┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-7902-feat-add-HoneyToast-component-for-persistent-progress-notifications-2e26d73d365081c78ae6edc5accb326e)
by [Unito](https://www.unito.io)
---------
Co-authored-by: Amp <amp@ampcode.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: sno <snomiao@gmail.com>
Co-authored-by: github-actions <github-actions@github.com>
Co-authored-by: GitHub Action <action@github.com>
## Summary
Add a progress dialog for model downloads that appears when downloads
are active.
## Changes
- Add `ModelImportProgressDialog` component for showing download
progress
- Add `ProgressToastItem` component for individual download job display
- Add `StatusBadge` component for status indicators
- Extend `assetDownloadStore` with:
- `finishedDownloads` computed for completed/failed jobs
- `hasDownloads` computed for dialog visibility
- `clearFinishedDownloads()` to dismiss finished downloads
- Dialog visibility driven by store state
- Closing dialog clears finished downloads
- Filter dropdown to show all/completed/failed downloads
- Expandable/collapsible UI with animated transitions
- Update AGENTS.md with import type convention and pluralization note
## Testing
- Start a model download and verify the dialog appears
- Verify expand/collapse animation works
- Verify filter dropdown works
- Verify closing the dialog clears finished downloads
- Verify dialog hides when no downloads remain
┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-7897-feat-add-model-download-progress-dialog-2e26d73d36508116960eff6fbe7dc392)
by [Unito](https://www.unito.io)
---------
Co-authored-by: Amp <amp@ampcode.com>
## Summary
Implements stale-while-revalidate pattern for AssetBrowserModal to show
cached assets immediately while refreshing in background.
## Changes
### AssetBrowserModal.vue
- Reads assets directly from store cache via computed properties
- Shows loading spinner only when loading AND no cached data exists
- Simplified refresh logic: single `refreshAssets()` call on mount
### assetsStore.ts
- Added `updateModelsForTag(tag)` for tag-based fetching
- Added `updateModelsForKey()` internal helper to unify node type and
tag fetching
- Cache key convention: node types as-is, tags prefixed with `tag:`
- Added `isEqual` check before cache updates to prevent unnecessary
re-renders
### useModelUpload.ts
- Simplified signature from `UseAsyncStateReturn<...>['execute']` to `()
=> Promise<unknown> | void`
## UX Improvement
| Scenario | Before | After |
|----------|--------|-------|
| First open | Spinner → Assets | Spinner → Assets |
| Re-open same type | Spinner → Assets | Instant + silent refresh |
| Re-open after download | Spinner → Assets | Cached + auto-update |
┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-7880-feat-Stale-while-revalidate-pattern-for-AssetBrowserModal-2e16d73d365081ba93f4d6e0415ebfae)
by [Unito](https://www.unito.io)
---------
Co-authored-by: Amp <amp@ampcode.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
## Summary
- Define `touch:` Tailwind variant using `@media (hover: none)` to
target touch devices
- Add `touch:opacity-100` to `TreeExplorerTreeNode` for node action
buttons
- Add `useMediaQuery('(hover: none)')` to `MediaAssetCard` for action
overlay visibility
## Problem
On touch devices, sidebar buttons that appear on hover are inaccessible
because:
1. The `touch:` Tailwind variant was used but never defined (classes
silently ignored)
2. `TreeExplorerTreeNode` had no touch support for action buttons
3. `MediaAssetCard` used JS-based `useElementHover` which doesn't work
on touch
## Screenshots (Touch Device Emulation)
### Before (main branch)
- No "Generated"/"Imported" tabs visible in header
- Only duration chips shown on cards, no action buttons (zoom, menu)

### After (with fix)
- "Generated"/"Imported" tabs visible in header
- Action buttons (zoom, menu) visible on left of cards
- Duration chips moved to right side

## Test plan
- [ ] On touch device: verify Media Assets sidebar
"Imported"/"Generated" tabs are visible
- [ ] On touch device: verify Node Library filter buttons are visible
- [ ] On touch device: verify tree node action buttons (bookmark, help)
are visible
- [ ] On touch device: verify media asset card zoom/menu buttons are
visible
- [ ] On desktop with mouse: verify hover behavior still works as
expected
## Summary
Replace single `asset_update_options_enabled` feature flag with two
granular flags:
- `asset_deletion_enabled`: controls delete button visibility
- `asset_rename_enabled`: controls rename button visibility
The context menu only shows when at least one flag is enabled.
## Changes
- Updated `ServerFeatureFlag` enum with new flag names
- Updated `RemoteConfig` type with new properties
- Updated `AssetCard.vue` to conditionally show rename/delete buttons
based on their respective flags
┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-7864-feat-split-asset_update_options_enabled-into-separate-deletion-and-rename-flags-2e06d73d365081f9ac0afa12b87bd988)
by [Unito](https://www.unito.io)
---------
Co-authored-by: Amp <amp@ampcode.com>
## Summary
- Adds asynchronous model upload support with HTTP 202 responses
- Implements WebSocket-based real-time download progress tracking via
`asset_download` events
- Creates `assetDownloadStore` for centralized download state management
and toast notifications
- Updates upload wizard UI to show "processing" state when downloads
continue in background
## Changes
- **Core**: New `assetDownloadStore` for managing async downloads with
WebSocket events
- **API**: Support for HTTP 202 async upload responses with task
tracking
- **UI**: Upload wizard now shows "processing" state and allows closing
dialog during download
- **Progress**: Periodic toast notifications (every 5s) during active
downloads with completion/error toasts
- **Schema**: Updated task statuses (`created`, `running`, `completed`,
`failed`) and WebSocket message types
## Review Focus
- WebSocket event handling and download state management in
`assetDownloadStore`
- Upload flow UX - users can now close the dialog and download continues
in background
- Toast notification frequency and timing
- Schema alignment with backend async upload API
Fixes#7748
┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-7746-feat-Add-async-model-upload-with-WebSocket-progress-tracking-2d36d73d3650811cb79ae06f470dcded)
by [Unito](https://www.unito.io)
---------
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: GitHub Action <action@github.com>
## Summary
Migrates all unit tests from `tests-ui/` to colocate with their source
files in `src/`, improving discoverability and maintainability.
## Changes
- **What**: Relocated all unit tests to be adjacent to the code they
test, following the `<source>.test.ts` naming convention
- **Config**: Updated `vitest.config.ts` to remove `tests-ui` include
pattern and `@tests-ui` alias
- **Docs**: Moved testing documentation to `docs/testing/` with updated
paths and patterns
## Review Focus
- Migration patterns documented in
`temp/plans/migrate-tests-ui-to-src.md`
- Tests use `@/` path aliases instead of relative imports
- Shared fixtures placed in `__fixtures__/` directories
┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-7811-chore-migrate-tests-from-tests-ui-to-colocate-with-source-files-2da6d73d36508147a4cce85365dee614)
by [Unito](https://www.unito.io)
---------
Co-authored-by: Amp <amp@ampcode.com>
Co-authored-by: GitHub Action <action@github.com>
## Summary
Filters out the "nlf" (no-license-file) model type from the Upload Model
wizard's model type dropdown, preventing users from selecting this
internal category.
## Changes
- **What**: Added DISALLOWED_MODEL_TYPES constant and filter in
useModelTypes composable
- **Scope**: Only affects Upload Model flow (used by UploadModelDialog
and UploadModelConfirmation)
## Test plan
- [ ] Open Upload Model dialog and verify "nlf" does not appear in model
type dropdown
- [ ] Verify other model types still appear correctly
- [ ] Verify dropdown still functions as expected
🤖 Generated with [Claude Code](https://claude.com/claude-code)
┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-7793-feat-Filter-out-nlf-model-type-from-Upload-Model-flow-2d86d73d3650811f88e1fcc8dd7040cd)
by [Unito](https://www.unito.io)
Co-authored-by: Claude <noreply@anthropic.com>
Use useI18n for media asset action translations and fix missing
translation string.
## What changed
- Switch the media asset actions composable to use `useI18n()` instead
of the global `t`.
- Use the existing `mediaAsset.selection.downloadsStarted` key for the
single-download toast to avoid missing strings.
## Why
- Aligns translation usage with the composition API and avoids
referencing a non-existent key.
- Reuses existing translation keys without adding new strings.
## Evidence
- Tests: `pnpm lint:fix`, `pnpm typecheck`, `pnpm knip`
## References
- N/A
┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-7744-Use-useI18n-in-media-asset-actions-2d26d73d365081f79cd1c5af105fc59b)
by [Unito](https://www.unito.io)
## Summary
Adds HuggingFace as a model import source alongside CivitAI, with
improved UX for model type selection and UTF-8 filename support.
## Changes
- **Import Sources**: Implemented extensible import source handler
pattern supporting both CivitAI and HuggingFace
- **UTF-8 Support**: Decode URL-encoded filenames to properly display
international characters (e.g., Chinese)
- **UX**: Sort model types alphabetically for easier selection
- **Feature Flag**: Added `huggingfaceModelImportEnabled` flag for
gradual rollout
- **i18n**: Use proper template parameters for localized error messages
## Technical Details
- Created `ImportSourceHandler` interface for extensibility
- Refactored existing CivitAI logic into handler pattern
- Added URL validation per source
- Filename decoding handles malformed URLs gracefully
┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-7540-feat-Add-HuggingFace-model-import-support-2cb6d73d3650818f966cca89244e8c36)
by [Unito](https://www.unito.io)
---------
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: GitHub Action <action@github.com>
## Summary
Setup the variants and migrate existing uses of
TextButton/TextIconButton/IconButton to a single Button component.
Still a work in progress.
## Changes
- **What**: Add a new Button
- **What**: Migrate old buttons
- **What**: Delete old buttons
- **Dependencies**: CVA, upgrade Storybook
## Review Focus
<!-- Critical design decisions or edge cases that need attention -->
<!-- If this PR fixes an issue, uncomment and update the line below -->
<!-- Fixes #ISSUE_NUMBER -->
## Screenshots (if applicable)
<!-- Add screenshots or video recording to help explain your changes -->
┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-7537-WIP-Component-Button-migration-2cb6d73d36508156a81bfc7bbddb36e9)
by [Unito](https://www.unito.io)
---------
Co-authored-by: GitHub Action <action@github.com>
## Summary
Stores and displays base64-encoded preview images from Civitai during
the model upload flow, uploading the preview as a separate asset linked
to the model.
## Changes
- **Schema**: Added `preview_image` field to `AssetMetadata` schema
- **Service**: Added `uploadAssetFromBase64` method to convert base64
data to blob and upload via FormData
- **Upload Flow**: Modified wizard to first upload preview image as
asset, then link it to model via `preview_id`
- **UI**: Display 56x56px preview thumbnail alongside model filename in
confirmation and success steps
## Review Focus
- Base64 to blob conversion and FormData upload implementation
- Sequential upload flow (preview first, then model with preview_id
reference)
┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-7274-feat-display-and-upload-Civitai-preview-images-in-model-upload-flow-2c46d73d365081ff9b74c1791d23f6dd)
by [Unito](https://www.unito.io)
---------
Co-authored-by: Claude <noreply@anthropic.com>
## Summary
Adds a dropdown filter to the model browser that allows users to filter
assets by ownership (All, My models, Public models), based on the
`is_immutable` property.
## Changes
- **Filter UI**: Added ownership dropdown in
[AssetFilterBar.vue](src/platform/assets/components/AssetFilterBar.vue#L30-L38)
that only appears when user has uploaded models
- **Filter Logic**: Implemented `filterByOwnership` function in
[useAssetBrowser.ts](src/platform/assets/composables/useAssetBrowser.ts#L38-L45)
to filter by `is_immutable` property
- **i18n**: Added translation strings for ownership filter options
- **Tests**: Added comprehensive tests for ownership filtering in both
composable and component test files
## Review Focus
- The ownership filter visibility logic correctly checks for mutable
assets (`!is_immutable`)
- Default filter value is 'all' to show all models initially
- Filter integrates cleanly with existing file format and base model
filters
🤖 Generated with [Claude Code](https://claude.com/claude-code)
┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-7201-feat-Add-ownership-filter-to-model-browser-2c16d73d365081f280f6d1e42e5400af)
by [Unito](https://www.unito.io)
---------
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: GitHub Action <action@github.com>
## Summary
Unify the current sidebar tabs, structurally and aesthetically.
## Changes
- Removes the Assets only Layout
- Standardizes the title styling and spacing across the tabs.
## Review Focus
<!-- Critical design decisions or edge cases that need attention -->
<!-- If this PR fixes an issue, uncomment and update the line below -->
<!-- Fixes #ISSUE_NUMBER -->
## Screenshots (if applicable)
<!-- Add screenshots or video recording to help explain your changes -->
┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-7215-WIP-Sidebar-Tabs-component-and-style-alignment-2c26d73d3650817193bfd752e0d0bbde)
by [Unito](https://www.unito.io)
## Summary
Fixes Vue Nodes 2.0 dropdowns not displaying the selected model when
created from the Asset Browser.
## Root Cause
Widget values were set AFTER the node was added to the graph, causing
Vue's reactivity system to capture stale initial values.
## Solution
Set widget value BEFORE adding node to graph in
`createModelNodeFromAsset.ts`.
## Changes
- **1 file changed**: `createModelNodeFromAsset.ts`
- **4 lines added, 1 removed**: Move widget value assignment before
graph.add()
This ensures Vue's reactivity system captures the correct initial widget
value when the node is created.
Co-authored-by: Claude <noreply@anthropic.com>
## Summary
Model selection dropdowns now automatically refresh after uploading a
new model, ensuring users see newly uploaded models immediately.
## Changes
- **Cache Orchestration**: Upload wizard now refreshes model caches by
coordinating between `modelToNodeStore` and `assetsStore`
- **Smart Refetching**: Only refreshes node types that use the uploaded
model category (e.g., uploading a checkpoint refreshes
`CheckpointLoaderSimple` but not `LoraLoader`)
- **Clean Architecture**: Stores remain decoupled - the upload wizard
composable orchestrates the refresh logic
## Technical Details
After successful upload, `useUploadModelWizard`:
1. Gets all node providers for the model type from `modelToNodeStore`
2. Calls `assetsStore.updateModelsForNodeType()` for each affected node
type
3. Model dropdowns reactively update via Pinia store watchers
## Review Focus
- Orchestration pattern in upload wizard keeps stores decoupled
- Efficient cache invalidation - only refreshes affected node types
---------
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Alexander Brown <drjkl@comfy.org>
## Summary
Adds an interactive video tutorial dialog to help users find CivitAI
model URLs during the Upload Model wizard.
## Changes
- **New Component**: Created reusable `VideoHelpDialog.vue` component
- Full-width video player with floating close button
- Configurable props: `videoUrl`, `loop`, `showControls`
- Custom ESC key handling to prevent parent dialog from closing
- Click backdrop to dismiss
- 70% dark backdrop for better video focus
- **Upload Model Flow**: Integrated video help button in step 1 footer
- "How do I find this?" button opens tutorial video
- Video demonstrates finding model URLs on CivitAI
- PostHog tracking attribute maintained (`upload-model-step1-help-link`)
## Review Focus
- ESC key event handling uses capture phase to prevent propagation to
parent dialogs
- Component follows existing patterns from `MediaVideoTop.vue` and
`BaseModalLayout.vue`
- Video player accessibility (ARIA labels, keyboard navigation)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-7177-feat-Add-video-help-dialog-to-Upload-Model-flow-2c06d73d36508148963ad9ee60038ea3)
by [Unito](https://www.unito.io)
---------
Co-authored-by: Claude <noreply@anthropic.com>
## Summary
Adds step-specific `data-attr` attributes throughout the Upload Model
wizard to enable PostHog analytics tracking and action creation,
following PostHog's recommended best practices for element labeling.
## Changes
- **What**: Added `data-attr` attributes to all key interactive elements
in the Upload Model flow (buttons, inputs, selectors)
- **Step-based naming**: Attributes include step numbers for funnel
analysis (e.g., `upload-model-step1-continue-button`)
- **Coverage**: Entry button, URL input, help link, navigation buttons
(cancel/back/continue/confirm/finish), and model type selector
## Benefits
- Enables creation of stable PostHog actions using CSS selectors like
`[data-attr="upload-model-step2-confirm-button"]`
- Allows funnel analysis to track user progression through the 3-step
upload wizard
- Identifies drop-off points and help-seeking behavior
- Follows PostHog best practice of using data attributes over CSS
classes (especially important with Tailwind)
## Review Focus
- Naming consistency and clarity of data-attr values
- Completeness of coverage across the upload flow
🤖 Generated with [Claude Code](https://claude.com/claude-code)
┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-7173-feat-Add-PostHog-data-attr-attributes-to-Upload-Model-flow-2c06d73d365081699861d3d910250e32)
by [Unito](https://www.unito.io)
Co-authored-by: Claude <noreply@anthropic.com>
## Summary
Adds a dedicated upgrade modal that appears when users without private
models access try to upload models, providing a clear path to upgrade
their subscription.
## Changes
- **New upgrade modal**: Created `UploadModelUpgradeModal` with
dedicated body, header, and footer components
- **Conditional rendering**: Modified `AssetBrowserModal` to show
upgrade modal when `privateModelsEnabled` flag is false
- **Subscription integration**: Connected upgrade flow to existing
subscription system via `showSubscriptionDialog()`
- **Localization**: Added localization keys for upgrade messaging
## Review Focus
- Conditional logic in `AssetBrowserModal.handleUploadClick()` based on
feature flags
- Component naming consistency (all upgrade-related components prefixed
with `UploadModelUpgrade`)
- Footer component refactoring maintains existing upload wizard behavior
🤖 Generated with [Claude Code](https://claude.com/claude-code)
┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-7124-feat-add-upgrade-modal-for-model-upload-when-private-models-disabled-2be6d73d36508147b72eea8a1d6ab772)
by [Unito](https://www.unito.io)
---------
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Alexander Brown <drjkl@comfy.org>
## Summary
- Add right-click context menu functionality to MediaAssetCard
- Separate context menu into its own component
(MediaAssetContextMenu.vue)
- Ensure only one context menu is visible at a time within the same tab
## Changes
- Add `MediaAssetContextMenu.vue` - new component for context menu
- Update `MediaAssetCard.vue` - show context menu on right-click and
more button click
- Delete `MediaAssetMoreMenu.vue` - consolidated into context menu
- Delete `MediaAssetButtonDivider.vue` - unused
- Update `AssetsSidebarTab.vue` - add context menu state management
- Refactor `useMediaAssetActions.ts`
## Screenshot
[screen-capture.webm](https://github.com/user-attachments/assets/6fe414ef-b134-4fbe-98aa-6437bb354b41)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude <noreply@anthropic.com>
## 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
Fixed an issue where users had to click twice to continue after pasting
a URL in the upload model dialog - once to blur the input, then again to
click the button.
## Changes
- **What**: Replaced `UrlInput` with plain `InputText` in
`UploadModelUrlInput` to emit value immediately on input instead of only
on blur
- **Cleanup**: Moved URL cleaning/normalization to the `fetchMetadata`
handler, removed unused `disableValidation` prop from `UrlInput`
component
## Review Focus
- URL normalization logic in `useUploadModelWizard.ts`
🤖 Generated with [Claude Code](https://claude.com/claude-code)
┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-6801-bugfix-Fix-double-click-required-after-pasting-URL-in-upload-model-dialog-2b26d73d3650811881aed0cc064efcc7)
by [Unito](https://www.unito.io)
---------
Co-authored-by: Claude <noreply@anthropic.com>