Skip to content

WPB-29385: Preview moving selected Drive items - #22767

Open
cristianoliveira wants to merge 7 commits into
WPB-29385-picker-foundationfrom
WPB-29385-reuse-folder-picker
Open

cristianoliveira wants to merge 7 commits into
WPB-29385-picker-foundationfrom
WPB-29385-reuse-folder-picker

Conversation

@cristianoliveira

@cristianoliveira cristianoliveira commented Oct 16, 2026 •

Copy link
Copy Markdown
Contributor
TaskWPB-29385 [Web][Drive] Reuse folder picker flow when moving files

Stacked on #22780. Please review the picker foundation first.

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

@cristianoliveira cristianoliveira added the semver:patch Bug fix, dependency update or other released-product change. Next release increments PATCH label Oct 16, 2026
@cristianoliveira
cristianoliveira marked this pull request as draft October 16, 2026 14:36
@cristianoliveira cristianoliveira changed the title WPB-29385 Reuse Drive folder picker for move flows WPB-29385: Reuse the Drive folder picker for moves Oct 16, 2026
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.
@cristianoliveira cristianoliveira changed the title WPB-29385: Reuse the Drive folder picker for moves WPB-29385: Preview moving selected Drive items Oct 16, 2026
@cristianoliveira
cristianoliveira marked this pull request as ready for review October 16, 2026 16:10
@cristianoliveira
cristianoliveira requested a review from a team October 16, 2026 16:11
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.
@cristianoliveira

Copy link
Copy Markdown
Contributor Author

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

@cristianoliveira
cristianoliveira changed the base branch from main to WPB-29385-picker-foundation October 19, 2026 08:58
@cristianoliveira
cristianoliveira added this pull request to stack #22781 October 19, 2026 09:13
@cristianoliveira

Copy link
Copy Markdown
Contributor Author

I split the PRs into #22780 but still 1k 🙈

@@ -0,0 +1,138 @@
/*

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

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

@e-maad e-maad left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Added few suggestions

Comment on lines +60 to +70
<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}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nine out of ten props are passed through destination object. Can we modify CellsFoldersListModalContent to receive complete object?

Comment on lines +51 to +63
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;
};

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Can you check if we have similar function already in the code.
Could this be moved to shared space for better reusability?

Comment on lines +51 to +77
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}`;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Can we replace it with ts-pattern?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Why not create a hash map, like:
'cells.selection.move': 'Move' ,
'cells.selection.clear': 'Clear selection'
...

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

semver:patch Bug fix, dependency update or other released-product change. Next release increments PATCH

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants