Files
Francesco Sansalvadore 92fdb1d3c5 feat: update storage move UI (#50346)
Update path selection as destination where to move files in the Storage
File Explorer.

## What is the current behavior?

Currently you need to write out the entire path by hand, which is error
prone and quirky.

<img width="727" height="436" alt="Screenshot 2026-09-14 at 15 49 11"
src="https://github.com/user-attachments/assets/2bb8fc78-d973-4b17-9343-08df23b67d2a"
/>

## What is the new behavior?

This PR adds a ui that lets the user select any folder as the
destination of the file move.

<img width="923" height="606" alt="Screenshot 2026-09-15 at 11 40 00"
src="https://github.com/user-attachments/assets/2f4c50f8-3c11-4896-832e-b1e99defc9af"
/>


https://github.com/user-attachments/assets/261ac24e-ec24-4bcf-ad47-72bc48e27bab

To test:
- go to Storage File explorer and pick a file to "move" (action in the
dropdown menu)
- mov file to any other folder in the same bucket selecting destination
folder from the ui in the dialog
- both empty folder or also a folder with sub-folders can be
destinations, as any selected folder becomes the active destination
(notice the cta changing when selecting a folder)
- batch move multiple items via multi-select (already supported, but
using the updated ui now)
- only folders should appear in this ui
- destination folders can be searched using the search input

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Replaced the move-items path field with an interactive folder browser.
- Browse, select, and search folders by name or path, with pagination
and loading or empty states.
- Navigate using breadcrumbs, including collapsed-path menus for deeply
nested folders.
- Receive warnings when folder search results are incomplete for very
large buckets.
- See clearer destination labels and protection against moving items to
their current location.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-09-16 09:38:15 +02:00

80 lines
2.7 KiB
TypeScript

export const storageKeys = {
bucket: (projectRef: string | undefined, bucketId: string | undefined) =>
['projects', projectRef, 'buckets', bucketId] as const,
buckets: (projectRef: string | undefined) => ['projects', projectRef, 'buckets'] as const,
bucketsList: (
projectRef: string | undefined,
params: {
limit?: number
search?: string
sortColumn?: string
sortOrder?: string
} = {}
) =>
[
'projects',
projectRef,
'buckets',
'list',
{
limit: params.limit,
search: params.search,
sortColumn: params.sortColumn,
sortOrder: params.sortOrder,
},
] as const,
analyticsBuckets: (projectRef: string | undefined) =>
['projects', projectRef, 'analytics-buckets'] as const,
vectorBuckets: (projectRef: string | undefined) =>
['projects', projectRef, 'vector-buckets'] as const,
vectorBucket: (projectRef: string | undefined, vectorbucketName: string | undefined) =>
['projects', projectRef, 'vector-bucket', vectorbucketName] as const,
vectorBucketsIndexes: (projectRef: string | undefined, vectorBucketName: string | undefined) =>
['projects', projectRef, 'vector-buckets', vectorBucketName, 'indexes'] as const,
archive: (projectRef: string | undefined) => ['projects', projectRef, 'archive'] as const,
publicBucketsWithSelectPolicies: (projectRef: string | undefined, bucketId: string | undefined) =>
['projects', projectRef, 'public-buckets-with-select-policies', bucketId] as const,
objects: (
projectRef: string | undefined,
bucketId: string | undefined,
path: string,
params: {
limit?: number
search?: string
sortColumn?: string
sortOrder?: string
} = {}
) =>
[
'projects',
projectRef,
'buckets',
bucketId,
'objects',
...(path ? [path] : []),
...(params ? [params] : []),
] as const,
folders: (projectRef: string | undefined, bucketId: string | undefined) =>
['projects', projectRef, 'buckets', bucketId, 'folders'] as const,
icebergNamespaces: ({ projectRef, warehouse }: { projectRef?: string; warehouse?: string }) =>
[projectRef, 'warehouse', warehouse, 'namespaces'] as const,
icebergNamespace: ({
projectRef,
warehouse,
namespace,
}: {
projectRef?: string
warehouse: string
namespace: string
}) => [projectRef, 'warehouse', warehouse, 'namespaces', namespace] as const,
icebergNamespaceTables: ({
projectRef,
warehouse,
namespace,
}: {
projectRef?: string
warehouse?: string
namespace?: string
}) => [projectRef, 'warehouse', warehouse, 'namespaces', namespace, 'tables'] as const,
}