Repository navigation
WPB-29385: Preview moving selected Drive items - #22767
cristianoliveira wants to merge 7 commits into
Conversation
Expose a Move entry point from the flagged selection bar and preview every selected item alongside a browsable destination picker. Keep destination changes local to the preview, preserve selection on close, and do not invoke move/copy operations. Retain the existing single-item move flow and gate the new action behind driveBulkActions.
Run the preview's folder query through the test fire-and-forget invoker and wait for the destination list before asserting selection state. Scope selected-name assertions to the accessible summary region.
Restore the shared Cells selection bar and render the conversation-only Move button from CellsTable. Keep the preview destination summary path-aware and update it when browsing into a folder. Cover browsing through nested destinations and reopening with a different selection so stale targets are not shown.
Label the modal as a move preview and explicitly state that no items will be moved yet. Keep the selection-bar Move entry point unchanged and update table assertions to protect against implying execution.
Normalize selected folder paths and browsed paths against the current Drive root before storing them. This keeps the preview summary stable when a destination is selected and then opened, including paths with nested folders. Add same-folder summary coverage using an explicit Drive root.
Keep the disposable preview copy, selected-item presentation, and placeholder cancel action in a focused presentation component. Move destination loading, canonical path handling, exclusions, and selection state into a feature-specific policy hook so real bulk execution can replace the preview without disturbing the picker. Preserve behavior and avoid shared components or generic abstractions.
Move the preview-only modal presentation and the feature-specific destination-selection policy into sibling modules. Keep cellsBulkMovePreviewModal as a short composition, with no shared component edits or behavior changes. This makes the temporary presentation replaceable while preserving the reusable folder loading and canonical path logic.
|
Sorry for the big PR, but in order to simplify the usage of the feature flag, I created a new Modal component that is modified for the multi-selection only available if FF is on and later we will merge it |
|
I split the PRs into #22780 but still 1k 🙈 |
| @@ -0,0 +1,138 @@ | |||
| /* | |||
There was a problem hiding this comment.
This entire hook here will be gone once we integrate with the moving API, for now this only give us a visual feedback on what's about to be moved
| <CellsFoldersListModalContent | ||
| items={destination.folders} | ||
| status={destination.status} | ||
| shouldShowLoadingSpinner={destination.shouldShowLoadingSpinner} | ||
| conversationName={conversationName} | ||
| currentPath={destination.currentPath} | ||
| onPathChange={destination.handlePathChange} | ||
| onSelectDestination={destination.handleDestinationSelect} | ||
| selectedDestinationPath={destination.selectedDestinationPath} | ||
| disabledDestinationPaths={destination.disabledDestinationPaths} | ||
| disabledDestinationLabels={destination.disabledDestinationLabels} |
There was a problem hiding this comment.
Nine out of ten props are passed through destination object. Can we modify CellsFoldersListModalContent to receive complete object?
| const normalizeDestinationPath = (path: string, rootPath: string): string => { | ||
| const normalizedRootPath = rootPath.replace(/\/+$/, ''); | ||
| const normalizedPath = path.replace(/^\/+|\/+$/g, ''); | ||
| if (normalizedPath === normalizedRootPath) { | ||
| return ''; | ||
| } | ||
|
|
||
| if (normalizedRootPath.length > 0 && normalizedPath.startsWith(`${normalizedRootPath}/`)) { | ||
| return normalizedPath.slice(normalizedRootPath.length + 1); | ||
| } | ||
|
|
||
| return normalizedPath; | ||
| }; |
There was a problem hiding this comment.
Can you check if we have similar function already in the code.
Could this be moved to shared space for better reusability?
| if (key === 'cells.selection.move') { | ||
| return 'Move'; | ||
| } | ||
| if (key === 'cells.bulkMove.previewTitle') { | ||
| return `Preview move of ${substitutions?.count} items`; | ||
| } | ||
| if (key === 'cells.bulkMove.previewDescription') { | ||
| return 'Preview only. No items will be moved. Destinations stay within this conversation’s Drive.'; | ||
| } | ||
| if (key === 'cells.bulkMove.selectedItems') { | ||
| return 'Selected items'; | ||
| } | ||
| if (key === 'cells.bulkMove.currentDestination') { | ||
| return `Current destination: ${substitutions?.destination}`; | ||
| } | ||
| if (key === 'cells.bulkMove.drive') { | ||
| return 'Drive'; | ||
| } | ||
| if (key === 'cells.bulkMove.selected') { | ||
| return 'Selected'; | ||
| } | ||
| if (key === 'cells.bulkMove.currentLocation') { | ||
| return 'Current location'; | ||
| } | ||
| if (key === 'cells.moveNodeModal.openFolder') { | ||
| return `Open ${substitutions?.folderName}`; | ||
| } |
There was a problem hiding this comment.
Can we replace it with ts-pattern?
There was a problem hiding this comment.
Why not create a hash map, like:
'cells.selection.move': 'Move' ,
'cells.selection.clear': 'Clear selection'
...
Problem
I can select more than one item in Drive, but there was no Move button to open the picker. So the folder picker work in this PR wasn't something I could actually try with a selection
I want to see which items are selected and where they would go, without moving anything yet. With the Drive bulk actions flag off, the existing single item flow should stay as it is
What changed
With the flag on, selecting items shows a Move button beside the selection count. Clicking it opens a preview with the names of all selected files and folders, plus the target folder path. Choosing or browsing another folder updates the target in the preview
The modal says it's a preview, and closing it keeps the selection. There's no bulk move call or confirmation button in this round. I've kept the preview copy and Cancel action separate from folder selection, so we can replace that part when we add the actual move next
This builds on #22780, which handles the picker states, single item failures, and flag-off behavior. This PR only adds the visible bulk preview
Tests cover both flag states, the button and modal, selected names, destination browsing, reopening the preview, and no move call
** Disclaimer **
For now we only collect the nodes and show the files for debugging purposes, it does not move yet
Demo
Screen.Recording.2026-10-16.at.18.07.43.mov
Jira: https://wearezeta.atlassian.net/browse/WPB-29385