Skip to content

Conversation

@viva-jinyi
Copy link
Member

@viva-jinyi viva-jinyi commented Oct 17, 2025

📋 Overview

Implemented a new Media Assets sidebar tab in ComfyUI for managing user-uploaded input files and generated output files. This feature supports both local and cloud environments and is currently enabled only in development mode.

🎯 Key Features

1. Media Assets Sidebar Tab

  • Imported / Generated files separated by tabs
  • Visual display with file preview cards
  • Gallery view support (navigable with arrow keys)

2. Environment-Specific Implementation

  • useInternalMediaAssets: For local environment
    • Fetches file list via /files API
    • Retrieves generation task execution time via /history API
    • Processes history data using the same logic as QueueSidebarTab
  • useCloudMediaAssets: For cloud environment
    • File retrieval through assetService
    • History data processing using TaskItemImpl
    • Auto-truncation of long filenames over 20 characters (e.g., very_long_filename_here.pngvery_long_...here.png)

3. Execution Time Display

  • Shows task execution time on generated image cards (e.g., "2.3s")
  • Calculated from History API's execution_start and execution_success messages
  • Displayed at MediaAssetCard's duration chip location

4. Gallery Feature

  • Full-screen gallery mode on image click
  • Navigate between images with keyboard arrows
  • Exit gallery with ESC key
  • Reuses ResultGallery component from QueueSidebarTab

5. Development Mode Only

  • Excluded from production builds using import.meta.env.DEV condition
  • Feature in development, scheduled for official release after stabilization

🛠️ Technical Changes

New Files Added

  • src/components/sidebar/tabs/AssetsSidebarTab.vue - Main sidebar tab component
  • src/composables/sidebarTabs/useAssetsSidebarTab.ts - Sidebar tab definition
  • src/composables/useInternalMediaAssets.ts - Local environment implementation
  • src/composables/useCloudMediaAssets.ts - Cloud environment implementation
  • packages/design-system/src/icons/image-ai-edit.svg - Icon addition

Modified Files

  • src/stores/workspace/sidebarTabStore.ts - Added dev mode only tab display logic
  • src/platform/assets/components/MediaAssetCard.vue - Added execution time display, zoom event
  • src/platform/assets/components/MediaImageTop.vue - Added image dimension detection
  • packages/shared-frontend-utils/src/formatUtil.ts - Added media type determination utility functions
  • src/locales/en/main.json - Added translation keys
media_asset_OSS_cloud.webm

@github-actions
Copy link

github-actions bot commented Oct 17, 2025

🎭 Playwright Test Results

⚠️ Tests passed with flaky tests

⏰ Completed at: 10/29/2025, 03:41:36 AM UTC

📈 Summary

  • Total Tests: 499
  • Passed: 466 ✅
  • Failed: 0
  • Flaky: 3 ⚠️
  • Skipped: 30 ⏭️

📊 Test Reports by Browser

  • chromium: View Report • ✅ 457 / ❌ 0 / ⚠️ 3 / ⏭️ 30
  • chromium-2x: View Report • ✅ 2 / ❌ 0 / ⚠️ 0 / ⏭️ 0
  • chromium-0.5x: View Report • ✅ 1 / ❌ 0 / ⚠️ 0 / ⏭️ 0
  • mobile-chrome: View Report • ✅ 6 / ❌ 0 / ⚠️ 0 / ⏭️ 0

🎉 Click on the links above to view detailed test results for each browser configuration.

@github-actions
Copy link

github-actions bot commented Oct 17, 2025

🎨 Storybook Build Status

Build completed successfully!

⏰ Completed at: 10/29/2025, 03:27:59 AM UTC

🔗 Links


🎉 Your Storybook is ready for review!

Copy link
Contributor

@christian-byrne christian-byrne left a comment

Choose a reason for hiding this comment

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

Can we put the composables in the platform/assets folder and then re-arrange so it's like:

useMediaAssets/
    useAssetsApi.ts
    useInternalFilesApi.ts
    index.ts

then inside the index.ts file you can put:

import { isCloud } from '@/platform/distribution/types'

if (isCloud) { export { useAssetsApi as useMediaAssets } from './useAssetsApi' } 
else { export { useInternalFilesApi as useMediaAssets } from './useInternalFilesApi' }

Then we should also define an interface or abstract class

interface IAssetsProvider {
   loading: ref<boolean>
   error: ref<null | string>
   fetchMediaList: () => UninifedType
}

This way, no other parts of the codebase need to understand the difference in implementations for assets - everything is abstracted behind the UnifiedType and AssetsProvider concepts. This makes refactoring, reasoning about the code, and especially dealing with types considerably easier and more maintainable.

The additional benefit is that for OSS build, the entire useAssetsApi.ts file actually gets tree-shaken.

@viva-jinyi viva-jinyi force-pushed the feature/media-asset-sidebar-tab branch from 172b3c3 to be16171 Compare October 20, 2025 06:25
@github-actions
Copy link

github-actions bot commented Oct 20, 2025

Bundle Size Report

Summary

  • Raw size: 12.3 MB baseline 12.3 MB — 🔴 +6.34 kB
  • Gzip: 2.49 MB baseline 2.48 MB — 🔴 +1.38 kB
  • Brotli: 1.96 MB baseline 1.96 MB — 🔴 +1.25 kB
  • Bundles: 56 current • 56 baseline • 16 added / 16 removed

Category Glance
App Entry Points 🔴 +6 kB (3.31 MB) · Graph Workspace 🔴 +335 B (716 kB) · Vendor & Third-Party ⚪ 0 B (5.36 MB) · Other ⚪ 0 B (2.55 MB) · Panels & Settings ⚪ 0 B (294 kB) · UI Components ⚪ 0 B (12.3 kB) · + 3 more

Per-category breakdown
App Entry Points — 3.31 MB (baseline 3.3 MB) • 🔴 +6 kB

Main entry bundles and manifests

File Before After Δ Raw Δ Gzip Δ Brotli
assets/index-HUYWA4AS.js (new) 2.69 MB 🔴 +2.69 MB 🔴 +560 kB 🔴 +424 kB
assets/index-BpjYeeYv.js (removed) 2.69 MB 🟢 -2.69 MB 🟢 -559 kB 🟢 -423 kB
assets/index-qu9Yk7AI.js (new) 617 kB 🔴 +617 kB 🔴 +114 kB 🔴 +90.4 kB
assets/index-CuJ7SyqP.js (removed) 617 kB 🟢 -617 kB 🟢 -114 kB 🟢 -90.3 kB

Status: 2 added / 2 removed

Graph Workspace — 716 kB (baseline 715 kB) • 🔴 +335 B

Graph editor runtime, canvas, workflow orchestration

File Before After Δ Raw Δ Gzip Δ Brotli
assets/GraphView-BLyaYAr1.js (new) 716 kB 🔴 +716 kB 🔴 +140 kB 🔴 +108 kB
assets/GraphView-CFwjupib.js (removed) 715 kB 🟢 -715 kB 🟢 -140 kB 🟢 -108 kB

Status: 1 added / 1 removed

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

Top-level views, pages, and routed surfaces

File Before After Δ Raw Δ Gzip Δ Brotli
assets/UserSelectView-b0H7SpDs.js (removed) 8.15 kB 🟢 -8.15 kB 🟢 -2.47 kB 🟢 -2.16 kB
assets/UserSelectView-BZoOD1Kw.js (new) 8.15 kB 🔴 +8.15 kB 🔴 +2.47 kB 🔴 +2.15 kB

Status: 1 added / 1 removed

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

Configuration panels, inspectors, and settings screens

File Before After Δ Raw Δ Gzip Δ Brotli
assets/CreditsPanel-5zMX_tN2.js (removed) 22.1 kB 🟢 -22.1 kB 🟢 -5.28 kB 🟢 -4.6 kB
assets/CreditsPanel-BxfGGvRM.js (new) 22.1 kB 🔴 +22.1 kB 🔴 +5.28 kB 🔴 +4.62 kB
assets/KeybindingPanel-JAXQQtt3.js (new) 15.2 kB 🔴 +15.2 kB 🔴 +3.77 kB 🔴 +3.31 kB
assets/KeybindingPanel-rCY2gzrI.js (removed) 15.2 kB 🟢 -15.2 kB 🟢 -3.76 kB 🟢 -3.3 kB
assets/ExtensionPanel-DsMt3uMq.js (removed) 12.1 kB 🟢 -12.1 kB 🟢 -2.83 kB 🟢 -2.48 kB
assets/ExtensionPanel-HxbGVlBD.js (new) 12.1 kB 🔴 +12.1 kB 🔴 +2.83 kB 🔴 +2.47 kB
assets/AboutPanel-CzP2yMQC.js (removed) 10.3 kB 🟢 -10.3 kB 🟢 -2.66 kB 🟢 -2.35 kB
assets/AboutPanel-DBG5Y-iE.js (new) 10.3 kB 🔴 +10.3 kB 🔴 +2.66 kB 🔴 +2.33 kB
assets/ServerConfigPanel-DWI18TNS.js (new) 8.2 kB 🔴 +8.2 kB 🔴 +2.17 kB 🔴 +1.9 kB
assets/ServerConfigPanel-r63bjy81.js (removed) 8.2 kB 🟢 -8.2 kB 🟢 -2.16 kB 🟢 -1.9 kB
assets/UserPanel-D2jjXY0g.js (removed) 7.91 kB 🟢 -7.91 kB 🟢 -2.06 kB 🟢 -1.79 kB
assets/UserPanel-DHIoGCK2.js (new) 7.91 kB 🔴 +7.91 kB 🔴 +2.06 kB 🔴 +1.8 kB
assets/settings-B-df0dZe.js 20.7 kB 20.7 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-CI6OKvJn.js 22.9 kB 22.9 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-CXGVj_nD.js 24.5 kB 24.5 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-DfQ6dSJj.js 31.6 kB 31.6 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-DJ2QgDzm.js 25.2 kB 25.2 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-DRNLPMG6.js 23.7 kB 23.7 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-DVVycxDc.js 19.9 kB 19.9 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-G6Dybj1b.js 24.1 kB 24.1 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-M6_GZccG.js 26 kB 26 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 6 added / 6 removed

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

Reusable component library chunks

File Before After Δ Raw Δ Gzip Δ Brotli
assets/ComfyQueueButton-CdDHTipf.js (new) 11.1 kB 🔴 +11.1 kB 🔴 +2.76 kB 🔴 +2.43 kB
assets/ComfyQueueButton-tmm_PINn.js (removed) 11.1 kB 🟢 -11.1 kB 🟢 -2.75 kB 🟢 -2.43 kB
assets/UserAvatar.vue_vue_type_script_setup_true_lang-C9bSkTC5.js 1.12 kB 1.12 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 1 added / 1 removed

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

Stores, services, APIs, and repositories

File Before After Δ Raw Δ Gzip Δ Brotli
assets/keybindingService-BCtfVnlf.js (new) 7.21 kB 🔴 +7.21 kB 🔴 +1.75 kB 🔴 +1.5 kB
assets/keybindingService-Dqi00elT.js (removed) 7.21 kB 🟢 -7.21 kB 🟢 -1.74 kB 🟢 -1.5 kB
assets/serverConfigStore-a46y6iwm.js (new) 2.79 kB 🔴 +2.79 kB 🔴 +889 B 🔴 +774 B
assets/serverConfigStore-w1N_nUPK.js (removed) 2.79 kB 🟢 -2.79 kB 🟢 -890 B 🟢 -775 B

Status: 2 added / 2 removed

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

Helpers, composables, and utility bundles

File Before After Δ Raw Δ Gzip Δ Brotli
assets/mathUtil-CTARWQ-l.js 1.07 kB 1.07 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
Vendor & Third-Party — 5.36 MB (baseline 5.36 MB) • ⚪ 0 B

External libraries and shared vendor chunks

File Before After Δ Raw Δ Gzip Δ Brotli
assets/vendor-other-BwM5763c.js (new) 3.22 MB 🔴 +3.22 MB 🔴 +685 kB 🔴 +549 kB
assets/vendor-other-CbHAysOD.js (removed) 3.22 MB 🟢 -3.22 MB 🟢 -685 kB 🟢 -549 kB
assets/vendor-tiptap-BucwppYX.js (removed) 232 kB 🟢 -232 kB 🟢 -45.7 kB 🟢 -37.7 kB
assets/vendor-tiptap-C6rhmSpC.js (new) 232 kB 🔴 +232 kB 🔴 +45.7 kB 🔴 +37.7 kB
assets/vendor-vue-BcpzXfvp.js (removed) 92.4 kB 🟢 -92.4 kB 🟢 -23.9 kB 🟢 -20.8 kB
assets/vendor-vue-Bze-dcMt.js (new) 92.4 kB 🔴 +92.4 kB 🔴 +23.9 kB 🔴 +20.8 kB
assets/vendor-primevue-PESgPnbc.js 517 B 517 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-visualization-BEfdbjRw.js 1.82 MB 1.82 MB ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 3 added / 3 removed

Other — 2.55 MB (baseline 2.55 MB) • ⚪ 0 B

Bundles that do not match a named category

File Before After Δ Raw Δ Gzip Δ Brotli
assets/commands-B2KZRBmX.js 15.1 kB 15.1 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-Bw-ckyga.js 13.9 kB 13.9 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-C_NmM85I.js 13.8 kB 13.8 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-CuozCW4W.js 14 kB 14 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-DGfVUJCR.js 16.2 kB 16.2 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-dOJNDogK.js 14.5 kB 14.5 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-DwiE551e.js 14.7 kB 14.7 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-Fw7mvqSy.js 13.1 kB 13.1 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-FXnO1W4Q.js 13.2 kB 13.2 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-Bgu6_Hvd.js 59.5 kB 59.5 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-Bv0L0qvp.js 93 kB 93 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-C3Doz3n_.js 67.6 kB 67.6 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-C7eBl607.js 70.7 kB 70.7 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-CHiV9ds2.js 76.4 kB 76.4 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-CIc79Nts.js 68.5 kB 68.5 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-DK5LmuBm.js 58.8 kB 58.8 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-J1nit7cj.js 66.3 kB 66.3 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-W97XgvAQ.js 80.4 kB 80.4 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-8Ef8lY1m.js 196 kB 196 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-BdF8EiZl.js 200 kB 200 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-Bv9Y8Cvp.js 229 kB 229 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-cMdB_wHv.js 179 kB 179 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-CvNWbbtX.js 194 kB 194 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-CwDWxzVz.js 215 kB 215 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-CyPAVHpA.js 191 kB 191 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-D6QTD6bJ.js 181 kB 181 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-DKn6VmRJ.js 192 kB 192 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B

viva-jinyi added a commit that referenced this pull request Oct 20, 2025
- Move composables to platform/assets directory structure
- Extract interface-based abstraction (IAssetsProvider) for cloud/internal implementations
- Move constants to module scope to avoid re-initialization
- Extract helper functions (truncateFilename, assetMappers) for reusability
- Rename getMediaTypeFromFilename to return singular form (image/video/audio)
- Add deprecated plural version for backward compatibility
- Add comprehensive test coverage for new utility functions

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
viva-jinyi added a commit that referenced this pull request Oct 20, 2025
- Move composables to platform/assets directory structure
- Extract interface-based abstraction (IAssetsProvider) for cloud/internal implementations
- Move constants to module scope to avoid re-initialization
- Extract helper functions (truncateFilename, assetMappers) for reusability
- Rename getMediaTypeFromFilename to return singular form (image/video/audio)
- Add deprecated plural version for backward compatibility
- Add comprehensive test coverage for new utility functions

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
@viva-jinyi viva-jinyi force-pushed the feature/media-asset-sidebar-tab branch from f6b8dbb to 308f864 Compare October 20, 2025 08:50
@viva-jinyi viva-jinyi marked this pull request as ready for review October 20, 2025 08:50
@dosubot dosubot bot added the size:XXL This PR changes 1000+ lines, ignoring generated files. label Oct 20, 2025
viva-jinyi added a commit that referenced this pull request Oct 22, 2025
- Move composables to platform/assets directory structure
- Extract interface-based abstraction (IAssetsProvider) for cloud/internal implementations
- Move constants to module scope to avoid re-initialization
- Extract helper functions (truncateFilename, assetMappers) for reusability
- Rename getMediaTypeFromFilename to return singular form (image/video/audio)
- Add deprecated plural version for backward compatibility
- Add comprehensive test coverage for new utility functions

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
@viva-jinyi viva-jinyi force-pushed the feature/media-asset-sidebar-tab branch from bee62d3 to 61eed48 Compare October 22, 2025 02:08
viva-jinyi added a commit that referenced this pull request Oct 22, 2025
- Move composables to platform/assets directory structure
- Extract interface-based abstraction (IAssetsProvider) for cloud/internal implementations
- Move constants to module scope to avoid re-initialization
- Extract helper functions (truncateFilename, assetMappers) for reusability
- Rename getMediaTypeFromFilename to return singular form (image/video/audio)
- Add deprecated plural version for backward compatibility
- Add comprehensive test coverage for new utility functions

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
@viva-jinyi viva-jinyi force-pushed the feature/media-asset-sidebar-tab branch from ac427e5 to bd23ccc Compare October 22, 2025 03:06
viva-jinyi added a commit that referenced this pull request Oct 22, 2025
- Move composables to platform/assets directory structure
- Extract interface-based abstraction (IAssetsProvider) for cloud/internal implementations
- Move constants to module scope to avoid re-initialization
- Extract helper functions (truncateFilename, assetMappers) for reusability
- Rename getMediaTypeFromFilename to return singular form (image/video/audio)
- Add deprecated plural version for backward compatibility
- Add comprehensive test coverage for new utility functions

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
@viva-jinyi viva-jinyi force-pushed the feature/media-asset-sidebar-tab branch from 97d6a6f to 6769687 Compare October 22, 2025 12:51
viva-jinyi added a commit that referenced this pull request Oct 22, 2025
- Move composables to platform/assets directory structure
- Extract interface-based abstraction (IAssetsProvider) for cloud/internal implementations
- Move constants to module scope to avoid re-initialization
- Extract helper functions (truncateFilename, assetMappers) for reusability
- Rename getMediaTypeFromFilename to return singular form (image/video/audio)
- Add deprecated plural version for backward compatibility
- Add comprehensive test coverage for new utility functions

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
Copy link
Contributor

@DrJKL DrJKL left a comment

Choose a reason for hiding this comment

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

Reviewed from the bottom up 🙃

@christian-byrne christian-byrne added the claude-review Add to trigger a PR code review from Claude Code label Oct 22, 2025
})
// Override the url getter to use asset.preview_url
Object.defineProperty(resultItem, 'url', {
Copy link

Choose a reason for hiding this comment

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

[security] high Priority

Issue: Direct DOM manipulation vulnerability - Using object.defineProperty to dynamically override url getter creates potential XSS vector
Context: Overriding object getters at runtime can lead to unexpected behavior and security issues if the asset data is not sanitized
Suggestion: Use a computed property or safer mapping approach instead of defineProperty to avoid runtime property manipulation

@viva-jinyi viva-jinyi enabled auto-merge (squash) October 29, 2025 02:29
Copy link
Contributor

@arjansingh arjansingh left a comment

Choose a reason for hiding this comment

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

Generally, I think if you reduced the number of components you could use inject/emit a little less and simplify the code.

Only follow up I have is the assetStore, we should definitely bring that into the platform directory for assets.

@@ -0,0 +1,133 @@
import { useAsyncState } from '@vueuse/core'
Copy link
Contributor

Choose a reason for hiding this comment

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

follow-up: This should go in /platform/assets

viva-jinyi added a commit that referenced this pull request Oct 29, 2025
- Move composables to platform/assets directory structure
- Extract interface-based abstraction (IAssetsProvider) for cloud/internal implementations
- Move constants to module scope to avoid re-initialization
- Extract helper functions (truncateFilename, assetMappers) for reusability
- Rename getMediaTypeFromFilename to return singular form (image/video/audio)
- Add deprecated plural version for backward compatibility
- Add comprehensive test coverage for new utility functions

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
viva-jinyi added a commit that referenced this pull request Oct 29, 2025
- Integrate AssetsStore with useNodeImageUpload
- Automatically update input assets when uploading to input folder
- Support drag & drop, paste, and file selection

Solution 2 complete: Real-time assets sync with upload triggers
Related: #6112 code review feedback applied
@viva-jinyi viva-jinyi force-pushed the feature/media-asset-sidebar-tab branch from 208e522 to 5780728 Compare October 29, 2025 03:11
viva-jinyi and others added 19 commits October 29, 2025 12:26
- Implement new sidebar tab for managing imported/generated files
- Add separate composables for internal and cloud environments
- Display execution time from history API on generated outputs
- Support gallery view with keyboard navigation
- Auto-truncate long filenames in cloud environment
- Add utility functions for media type detection
- Enable feature only in development mode

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
- Move composables to platform/assets directory structure
- Extract interface-based abstraction (IAssetsProvider) for cloud/internal implementations
- Move constants to module scope to avoid re-initialization
- Extract helper functions (truncateFilename, assetMappers) for reusability
- Rename getMediaTypeFromFilename to return singular form (image/video/audio)
- Add deprecated plural version for backward compatibility
- Add comprehensive test coverage for new utility functions

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
…truncation

- Add file format tags (PNG, JPG, etc.) for input directory assets
- Truncate long filenames in input assets with originalFilename preservation
- Show file format chip independently from duration chip
- Fix conditional display logic for chips in MediaAssetCard
- Apply consistent filename truncation (20 chars) across cloud assets

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
- Add optional includePublic parameter (defaults to true) to getAssetsByTag
- Exclude public assets for media assets in sidebar by passing false
- Use URLSearchParams for cleaner query string construction

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
- Implement factory pattern with useAsyncState for composables
- Add internationalization support for aria-labels
- Remove deprecated functions and improve type safety
- Simplify component logic with VueUse patterns
- Add comprehensive edge case tests
## Summary
- Extract sidebar template into reusable AssetSidebarTemplate component
- Replace PrimeVue Tabs with TextButton for better visual consistency  
- Improve job detail view header layout with better spacing

## Changes
- Created `AssetSidebarTemplate.vue` as a reusable template component
- Replaced PrimeVue Tabs with TextButton components for tab navigation
- Added i18n translation key for "Back to all assets" button
- Improved spacing and layout in job detail view header
- Maintained all existing functionality while cleaning up template
structure

## Test Plan
- [ ] Verify tab switching between Imported and Generated tabs works
correctly
- [ ] Test job detail view displays properly with Job ID and execution
time
- [ ] Confirm "Back to all assets" button returns to main view
- [ ] Check that all existing media asset features remain functional
- [ ] Verify UI consistency with other sidebar tabs


[screen-capture.webm](https://github.com/user-attachments/assets/4ed192e1-a9f7-4fc1-a41e-f732741dd55d)
- Create AssetsStore following QueueStore pattern for history-based assets
- Use useAsyncState for async state management (loading/error handling)
- Support both cloud and local environments (via isCloud flag)
- Auto-update history assets on status events in GraphView
- Refactor useMediaAssets composables to use AssetsStore
- Remove deprecated getMediaKindFromFilename function (no usages found)
- Define MediaType using const assertion pattern
- Apply as const to extension arrays with type guards
- Use type assertions for type-safe includes checks
- Integrate AssetsStore with useNodeImageUpload
- Automatically update input assets when uploading to input folder
- Support drag & drop, paste, and file selection

Solution 2 complete: Real-time assets sync with upload triggers
Related: #6112 code review feedback applied
- Integrate AssetsStore with WidgetSelectDropdown component
- Auto-refresh input assets after file upload via dropdown widget
- Ensures Assets sidebar stays in sync with uploaded files

Part of reactive assets update implementation for better UX
- refactor(components): Use defineModel in TabList.vue for cleaner v-model implementation
- refactor(components): Extract MediaTitle component to eliminate duplication across media bottom components
  - Consolidate title rendering logic from MediaImageBottom, MediaVideoBottom, MediaAudioBottom, Media3DBottom
  - Improve code reusability and maintainability
- refactor(composables): Restructure useMediaAssets directory structure
  - Rename directory from 'useMediaAssets' to 'media'
  - Rename index.ts to useMediaAssets.ts to avoid index pattern
  - Update all import paths accordingly
- refactor(utils): Simplify UUID utility exports
  - Remove isValidUuid wrapper function
  - Export validate directly from uuid library
  - Update tests to use validate instead of isValidUuid
- test(formatUtil): Apply it.for pattern for better test readability
  - Convert repetitive test cases to data-driven tests using it.for
- Fix issue where viewing image changes when new outputs are added to the gallery
- Add currentGalleryAssetId ref to track the opened asset ID
- Update index to maintain same image when displayAssets changes
- Clear stored ID when gallery closes
…ss promptId directly from metadata instead of encoding/parsing it in IDs
## Summary
- Implement asset deletion for media assets
- Add delete confirmation dialog  
- Support both cloud and internal asset deletion
- Refresh assets list after successful deletion

## Changes
- Add delete button to MediaAssetActions component
- Implement deleteAsset method in useMediaAssetActions
- Add confirmation dialog before deletion
- Handle asset-deleted event to refresh the list
- Refactor to use QueueStore.tasks for proper grouping

## Test plan
- [x] Delete output assets in internal mode
- [x] Delete input/output assets in cloud mode
- [x] Verify confirmation dialog appears
- [x] Check assets list refreshes after deletion
- [x] Test folder view functionality

[screen-capture
(3).webm](https://github.com/user-attachments/assets/3306262e-627a-4db0-90c1-fd59ba3abf7c)
@viva-jinyi viva-jinyi force-pushed the feature/media-asset-sidebar-tab branch from 5780728 to b778cde Compare October 29, 2025 03:26
@viva-jinyi viva-jinyi merged commit 06ba106 into main Oct 29, 2025
34 of 36 checks passed
@viva-jinyi viva-jinyi deleted the feature/media-asset-sidebar-tab branch October 29, 2025 03:39
christian-byrne added a commit that referenced this pull request Oct 30, 2025
Add missing English translation keys that were added in recent
releases (PR #6256, #6112, #6187) but not backported to rh-test:

- Media asset management (delete, selection, job ID toast)
- Asset browser aria labels
- Sidebar labels (console, menu, assets, imported, generated)
- File management strings (no files found messages)
- Resize handle tooltips
- Basic UI strings (edit/delete image, chart, file, etc.)

These will be translated in the next commit.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

claude-review Add to trigger a PR code review from Claude Code size:XL This PR changes 500-999 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

The queue windows are covering the generated images with information, that's not really needed.

6 participants