Skip to content

Conversation

@viva-jinyi
Copy link
Member

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

Summary

Implements file explorer-style multi-selection functionality for media assets in the AssetsSidebarTab component.

Changes

Multi-Selection Interactions

  • Normal click: Single selection (clears previous, selects new)
  • Shift + click: Range selection (from last selected to current)
  • Ctrl/Cmd + click: Toggle individual selection

State Management

  • Added assetSelectionStore to manage selected asset IDs using Set
  • Created useAssetSelection composable for selection logic and keyboard state

UI Enhancements

  • Display selection count in footer (output tab only)
  • Interactive selection count that shows "Deselect all" on hover
  • Added bulk action buttons for download/delete (UI only)

Translation Keys

Added new keys under mediaAsset.selection:

  • selectedCount: "{count} selected"
  • deselectAll: "Deselect all"
  • downloadSelected: "Download"
  • deleteSelected: "Delete"

Test Plan

  • Open Assets sidebar tab
  • Switch to Generated tab
  • Test single selection with normal click
  • Test range selection with Shift + click
  • Test toggle selection with Ctrl/Cmd + click
  • Verify selection count updates correctly
  • Test hover interaction on selection count
  • Click "Deselect all" to clear selection
  • Test bulk action buttons (UI only)

Notes

  • Bulk download/delete functionality to be implemented in separate PR
  • Selection UI currently only shows in output (Generated) tab
screen-capture.webm

@github-actions
Copy link

github-actions bot commented Oct 24, 2025

🎭 Playwright Test Results

⚠️ Tests passed with flaky tests

⏰ Completed at: 10/29/2025, 07:21:47 AM UTC

📈 Summary

  • Total Tests: 500
  • Passed: 468 ✅
  • Failed: 0
  • Flaky: 2 ⚠️
  • Skipped: 30 ⏭️

📊 Test Reports by Browser

  • chromium: View Report • ✅ 459 / ❌ 0 / ⚠️ 2 / ⏭️ 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.

@viva-jinyi viva-jinyi added the claude-review Add to trigger a PR code review from Claude Code label Oct 24, 2025
Copy link

@claude claude bot left a comment

Choose a reason for hiding this comment

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

Comprehensive PR Review

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

Review Summary

PR: feat: Add multi-select support for media assets (#6256)
Impact: 291 additions, 42 deletions across 5 files

Issue Distribution

  • Critical: 1
  • High: 2
  • Medium: 3
  • Low: 1

Category Breakdown

  • Architecture: 2 issues
  • Security: 1 issue
  • Performance: 2 issues
  • Code Quality: 3 issues

Key Findings

Architecture & Design

The multi-select implementation follows Vue 3 Composition API patterns well with proper separation of concerns through a dedicated Pinia store and composable. However, there are concerns about state management consistency between folder and normal views, and potential memory management issues with Set operations without proper cleanup lifecycle management.

Security Considerations

Input validation is missing for asset IDs and array indices, which could potentially allow out-of-bounds access or injection attacks in edge cases. Asset metadata operations need validation before use in selection logic.

Performance Impact

The range selection implementation has potential O(n) performance issues for large asset lists (1000+ items), which could cause UI freezing during shift-click operations. Additionally, reactive Set operations may cause excessive re-rendering without proper memoization.

Integration Points

The feature integrates well with existing media asset infrastructure and properly handles keyboard modifiers. However, the TODO placeholders for download/delete functionality should be addressed with proper implementation or issue tracking.

Positive Observations

  • Excellent use of TypeScript with proper type definitions
  • Good separation of concerns with dedicated store and composable
  • Proper use of VueUse for keyboard modifier detection
  • Clean i18n integration with appropriate translation keys
  • Follows existing component patterns and architecture
  • Comprehensive selection interactions (single, range, toggle)

References

Next Steps

  1. Address critical performance issue in range selection before merge
  2. Add input validation for asset operations
  3. Implement proper cleanup lifecycle management
  4. Consider accessibility improvements for keyboard navigation
  5. Replace TODO comments with proper implementation or issue tracking
  6. Add comprehensive unit tests for selection logic edge cases

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

@github-actions github-actions bot removed the claude-review Add to trigger a PR code review from Claude Code label Oct 24, 2025
@viva-jinyi viva-jinyi marked this pull request as ready for review October 24, 2025 15:50
@dosubot dosubot bot added the size:L This PR changes 100-499 lines, ignoring generated files. label Oct 24, 2025
@DrJKL DrJKL force-pushed the feature/media-asset-sidebar-tab branch from d578518 to 208e522 Compare October 29, 2025 02:14
@viva-jinyi viva-jinyi force-pushed the feature/media-asset-sidebar-tab branch 2 times, most recently from 5780728 to b778cde Compare October 29, 2025 03:26
Base automatically changed from feature/media-asset-sidebar-tab to main October 29, 2025 03:39
@dosubot dosubot bot added size:XL This PR changes 500-999 lines, ignoring generated files. and removed size:L This PR changes 100-499 lines, ignoring generated files. labels Oct 29, 2025
@viva-jinyi viva-jinyi force-pushed the feature/asset-select branch from 9c64c8f to 5a494cb Compare October 29, 2025 05:51
@dosubot dosubot bot added size:L This PR changes 100-499 lines, ignoring generated files. and removed size:XL This PR changes 500-999 lines, ignoring generated files. labels Oct 29, 2025
@github-actions
Copy link

github-actions bot commented Oct 29, 2025

🎨 Storybook Build Status

Build completed successfully!

⏰ Completed at: 10/29/2025, 07:02:59 AM UTC

🔗 Links


🎉 Your Storybook is ready for review!

@github-actions
Copy link

github-actions bot commented Oct 29, 2025

Bundle Size Report

Summary

  • Raw size: 12.3 MB baseline 12.3 MB — 🔴 +539 B
  • Gzip: 2.49 MB baseline 2.49 MB — 🔴 +96 B
  • Brotli: 1.96 MB baseline 1.96 MB — 🟢 -20 B
  • Bundles: 56 current • 56 baseline • 12 added / 12 removed

Category Glance
App Entry Points 🔴 +539 B (3.31 MB) · Vendor & Third-Party ⚪ 0 B (5.36 MB) · Other ⚪ 0 B (2.55 MB) · Graph Workspace ⚪ 0 B (716 kB) · 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.31 MB) • 🔴 +539 B

Main entry bundles and manifests

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

Status: 2 added / 2 removed

Graph Workspace — 716 kB (baseline 716 kB) • ⚪ 0 B

Graph editor runtime, canvas, workflow orchestration

File Before After Δ Raw Δ Gzip Δ Brotli
assets/GraphView-BLyaYAr1.js (removed) 716 kB 🟢 -716 kB 🟢 -140 kB 🟢 -108 kB
assets/GraphView-BZd0h8ig.js (new) 716 kB 🔴 +716 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-BZoOD1Kw.js (removed) 8.15 kB 🟢 -8.15 kB 🟢 -2.47 kB 🟢 -2.15 kB
assets/UserSelectView-DgavoxmL.js (new) 8.15 kB 🔴 +8.15 kB 🔴 +2.46 kB 🔴 +2.16 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-BxfGGvRM.js (removed) 22.1 kB 🟢 -22.1 kB 🟢 -5.28 kB 🟢 -4.62 kB
assets/CreditsPanel-DQsr9N0c.js (new) 22.1 kB 🔴 +22.1 kB 🔴 +5.28 kB 🔴 +4.62 kB
assets/KeybindingPanel-Gnvk9pFB.js (new) 15.2 kB 🔴 +15.2 kB 🔴 +3.77 kB 🔴 +3.31 kB
assets/KeybindingPanel-JAXQQtt3.js (removed) 15.2 kB 🟢 -15.2 kB 🟢 -3.77 kB 🟢 -3.31 kB
assets/ExtensionPanel-BBu3Mkob.js (new) 12.1 kB 🔴 +12.1 kB 🔴 +2.82 kB 🔴 +2.47 kB
assets/ExtensionPanel-HxbGVlBD.js (removed) 12.1 kB 🟢 -12.1 kB 🟢 -2.83 kB 🟢 -2.47 kB
assets/AboutPanel-BqQTppWV.js (new) 10.3 kB 🔴 +10.3 kB 🔴 +2.66 kB 🔴 +2.33 kB
assets/AboutPanel-DBG5Y-iE.js (removed) 10.3 kB 🟢 -10.3 kB 🟢 -2.66 kB 🟢 -2.33 kB
assets/ServerConfigPanel-DVtusrWB.js (new) 8.2 kB 🔴 +8.2 kB 🔴 +2.16 kB 🔴 +1.9 kB
assets/ServerConfigPanel-DWI18TNS.js (removed) 8.2 kB 🟢 -8.2 kB 🟢 -2.17 kB 🟢 -1.9 kB
assets/UserPanel-BIL1rAAv.js (new) 7.91 kB 🔴 +7.91 kB 🔴 +2.06 kB 🔴 +1.8 kB
assets/UserPanel-DHIoGCK2.js (removed) 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 (removed) 11.1 kB 🟢 -11.1 kB 🟢 -2.76 kB 🟢 -2.43 kB
assets/ComfyQueueButton-wHUUXnEP.js (new) 11.1 kB 🔴 +11.1 kB 🔴 +2.75 kB 🔴 +2.44 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 (removed) 7.21 kB 🟢 -7.21 kB 🟢 -1.75 kB 🟢 -1.5 kB
assets/keybindingService-BggkbJPZ.js (new) 7.21 kB 🔴 +7.21 kB 🔴 +1.75 kB 🔴 +1.5 kB
assets/serverConfigStore-a46y6iwm.js 2.79 kB 2.79 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 1 added / 1 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 3.22 MB 3.22 MB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-primevue-PESgPnbc.js 517 B 517 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-tiptap-C6rhmSpC.js 232 kB 232 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-visualization-BEfdbjRw.js 1.82 MB 1.82 MB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-vue-Bze-dcMt.js 92.4 kB 92.4 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
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

@dosubot dosubot bot added size:XL This PR changes 500-999 lines, ignoring generated files. and removed size:L This PR changes 100-499 lines, ignoring generated files. labels Oct 29, 2025
@viva-jinyi
Copy link
Member Author

🎯 Multi-Select Improvements

  • Bulk Download: Download multiple selected assets at once
  • Bulk Delete: Delete selected assets with confirmation dialog
  • Added downloadMultipleAssets and deleteMultipleAssets methods to useMediaAssetActions

🔒 Folder View Restrictions

  • Individual delete buttons are now hidden in folder view
  • Bulk delete button is hidden in folder view
  • Controlled via show-delete-button prop from parent component

⌨️ Keyboard Event Optimization

  • Shift/Ctrl key events only active when asset sidebar is open
  • Lifecycle managed via activate()/deactivate() methods
  • Selection state automatically resets when sidebar closes

- Add multi-select interactions with Shift/Ctrl(Cmd) keys
- Normal click: Single selection
- Shift + click: Range selection
- Ctrl/Cmd + click: Individual multi-selection
- Create assetSelectionStore for managing selected assets
- Encapsulate selection logic in useAssetSelection composable
- Add selection count display and bulk action buttons in footer
- Shows "Deselect all" on hover
- Download/Delete buttons (actual implementation pending)
- Performance: Use batch operations for range selection instead of forEach
- Memory: Add reset function to clear selection on component unmount
- Security: Add input validation for asset operations
- Accessibility: Add keyboard support for selection count interaction
- Optimization: Prevent unnecessary re-renders in Set operations
- Clear isHoveringSelectionCount when deselecting all assets
- Prevents 'Deselect all' text from staying visible after clearing selection
- Improves UX by returning to normal selection count display
…a assets

  - Add bulk download/delete for multiple selected assets
  - Hide delete buttons in folder view
  - Activate keyboard shortcuts only when sidebar is open
  - Add activate/deactivate lifecycle methods to useAssetSelection
@viva-jinyi viva-jinyi force-pushed the feature/asset-select branch from de2695f to f2ae87e Compare October 29, 2025 07:01
@christian-byrne christian-byrne merged commit 9651d2a into main Oct 29, 2025
27 checks passed
@christian-byrne christian-byrne deleted the feature/asset-select branch October 29, 2025 07:26
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

area:assets size:XL This PR changes 500-999 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants