diff --git a/studio/components/layouts/StorageLayout/StorageLayout.tsx b/studio/components/layouts/StorageLayout/StorageLayout.tsx index 9592b2f9c6b..e0c06300a0a 100644 --- a/studio/components/layouts/StorageLayout/StorageLayout.tsx +++ b/studio/components/layouts/StorageLayout/StorageLayout.tsx @@ -1,7 +1,6 @@ import { ReactNode, useEffect } from 'react' import { useParams } from 'common/hooks' -import DeleteBucketModal from 'components/to-be-cleaned/Storage/DeleteBucketModal' import { AutoApiService, useProjectApiQuery } from 'data/config/project-api-query' import { useSelectedProject, useStore, withAuth } from 'hooks' import { PROJECT_STATUS } from 'lib/constants' @@ -18,10 +17,7 @@ const StorageLayout = ({ title, children }: StorageLayoutProps) => { const { ui } = useStore() const { ref: projectRef } = useParams() const project = useSelectedProject() - const storageExplorerStore = useStorageStore() - const { selectedBucketToEdit, closeDeleteBucketModal, showDeleteBucketModal } = - storageExplorerStore || {} const { data: settings, isLoading } = useProjectApiQuery({ projectRef }) const apiService = settings?.autoApiService @@ -55,11 +51,6 @@ const StorageLayout = ({ title, children }: StorageLayoutProps) => { return ( }> {children} - ) } diff --git a/studio/components/layouts/StorageLayout/StorageMenu.tsx b/studio/components/layouts/StorageLayout/StorageMenu.tsx index dd66d310e56..fc313c8bfae 100644 --- a/studio/components/layouts/StorageLayout/StorageMenu.tsx +++ b/studio/components/layouts/StorageLayout/StorageMenu.tsx @@ -1,26 +1,27 @@ -import { useState } from 'react' +import * as Tooltip from '@radix-ui/react-tooltip' +import { PermissionAction } from '@supabase/shared-types/out/constants' +import { observer } from 'mobx-react-lite' import Link from 'next/link' import { useRouter } from 'next/router' -import { observer } from 'mobx-react-lite' -import * as Tooltip from '@radix-ui/react-tooltip' -import { Button, Menu, Alert, IconEdit } from 'ui' -import { PermissionAction } from '@supabase/shared-types/out/constants' +import { useState } from 'react' +import { Alert, Button, IconEdit, Menu } from 'ui' -import { useCheckPermissions } from 'hooks' import { useParams } from 'common/hooks' -import BucketRow from './BucketRow' -import { useStorageStore } from 'localStores/storageExplorer/StorageExplorerStore' -import { StorageBucket } from 'components/interfaces/Storage/Storage.types' -import EditBucketModal from 'components/interfaces/Storage/EditBucketModal' import CreateBucketModal from 'components/interfaces/Storage/CreateBucketModal' +import EditBucketModal from 'components/interfaces/Storage/EditBucketModal' +import { StorageBucket } from 'components/interfaces/Storage/Storage.types' +import { DeleteBucketModal } from 'components/to-be-cleaned/Storage' import ShimmeringLoader from 'components/ui/ShimmeringLoader' import { useBucketsQuery } from 'data/storage/buckets-query' +import { useCheckPermissions } from 'hooks' +import BucketRow from './BucketRow' const StorageMenu = () => { const router = useRouter() const { ref, bucketId } = useParams() const [showCreateBucketModal, setShowCreateBucketModal] = useState(false) const [selectedBucketToEdit, setSelectedBucketToEdit] = useState() + const [selectedBucketToDelete, setSelectedBucketToDelete] = useState() const canCreateBuckets = useCheckPermissions(PermissionAction.STORAGE_ADMIN_WRITE, '*') const page = router.pathname.split('/')[4] as @@ -30,10 +31,7 @@ const StorageMenu = () => { | 'usage' | 'logs' - const storageExplorerStore = useStorageStore() const { data, isLoading, isError, isSuccess } = useBucketsQuery({ projectRef: ref }) - const { openDeleteBucketModal } = storageExplorerStore || {} - const buckets = data ?? [] return ( @@ -114,7 +112,7 @@ const StorageMenu = () => { bucket={bucket} projectRef={ref} isSelected={isSelected} - onSelectDeleteBucket={openDeleteBucketModal} + onSelectDeleteBucket={() => setSelectedBucketToDelete(bucket)} onSelectEditBucket={() => setSelectedBucketToEdit(bucket)} /> ) @@ -145,6 +143,12 @@ const StorageMenu = () => { bucket={selectedBucketToEdit} onClose={() => setSelectedBucketToEdit(undefined)} /> + + setSelectedBucketToDelete(undefined)} + /> ) } diff --git a/studio/components/to-be-cleaned/Storage/DeleteBucketModal.tsx b/studio/components/to-be-cleaned/Storage/DeleteBucketModal.tsx index bf17b863bbd..d89f20573fd 100644 --- a/studio/components/to-be-cleaned/Storage/DeleteBucketModal.tsx +++ b/studio/components/to-be-cleaned/Storage/DeleteBucketModal.tsx @@ -11,7 +11,7 @@ import { formatPoliciesForStorage } from './Storage.utils' export interface DeleteBucketModalProps { visible: boolean - bucket: Bucket + bucket?: Bucket onClose: () => void } @@ -32,6 +32,7 @@ const DeleteBucketModal = ({ visible = false, bucket, onClose }: DeleteBucketMod const onDeleteBucket = async () => { if (!projectRef) return console.error('Project ref is required') + if (!bucket) return console.error('No bucket is selected') setDeleting(true) try { @@ -74,20 +75,20 @@ const DeleteBucketModal = ({ visible = false, bucket, onClose }: DeleteBucketMod return ( - Your bucket {bucket.name} and all its contents will be + Your bucket {bucket?.name} and all its contents will be permanently deleted. } alert="You cannot recover this bucket once it is deleted." - confirmLabel={`Delete bucket ${bucket.name}`} + confirmLabel={`Delete bucket ${bucket?.name}`} /> ) } diff --git a/studio/localStores/storageExplorer/StorageExplorerStore.js b/studio/localStores/storageExplorer/StorageExplorerStore.js index f0148c926f2..8a6d483c631 100644 --- a/studio/localStores/storageExplorer/StorageExplorerStore.js +++ b/studio/localStores/storageExplorer/StorageExplorerStore.js @@ -1,21 +1,20 @@ -import toast from 'react-hot-toast' -import { createContext, useContext } from 'react' -import { makeAutoObservable } from 'mobx' -import { find, compact, isEqual, has, some, chunk, uniq, uniqBy, findIndex } from 'lodash' -import { BlobReader, BlobWriter, ZipWriter } from '@zip.js/zip.js' import { createClient } from '@supabase/supabase-js' +import { BlobReader, BlobWriter, ZipWriter } from '@zip.js/zip.js' +import { chunk, compact, find, findIndex, has, isEqual, some, uniq, uniqBy } from 'lodash' +import { makeAutoObservable } from 'mobx' +import { createContext, useContext } from 'react' +import toast from 'react-hot-toast' -import { useStore } from 'hooks' -import { copyToClipboard } from 'lib/helpers' -import { API_URL, IS_PLATFORM } from 'lib/constants' -import { post, delete_ } from 'lib/common/fetch' -import { PROJECT_ENDPOINT_PROTOCOL } from 'pages/api/constants' import { - STORAGE_VIEWS, - STORAGE_ROW_TYPES, STORAGE_ROW_STATUS, + STORAGE_ROW_TYPES, STORAGE_SORT_BY, + STORAGE_VIEWS, } from 'components/to-be-cleaned/Storage/Storage.constants.ts' +import { useStore } from 'hooks' +import { delete_, post } from 'lib/common/fetch' +import { API_URL, IS_PLATFORM } from 'lib/constants' +import { PROJECT_ENDPOINT_PROTOCOL } from 'pages/api/constants' /** * This is a preferred method rather than React Context and useStorageExplorerStore(). @@ -52,7 +51,6 @@ class StorageExplorerStore { sortByOrder = 'asc' buckets = [] selectedBucket = {} - selectedBucketToEdit = {} columns = [] openedFolders = [] selectedItems = [] @@ -75,9 +73,6 @@ class StorageExplorerStore { /* [Joshen] Move towards using API */ endpoint = '' - /* FE to toggle page level modals */ - showDeleteBucketModal = false - /* FE Cacheing for file previews */ filePreviewCache = [] @@ -90,6 +85,7 @@ class StorageExplorerStore { constructor(projectRef) { makeAutoObservable(this, { supabaseClient: false }) this.projectRef = projectRef + // eslint-disable-next-line react-hooks/rules-of-hooks this.ui = useStore().ui // ignore when in a non-browser environment @@ -182,15 +178,6 @@ class StorageExplorerStore { this.loaded = val } - openDeleteBucketModal = (bucket) => { - this.selectedBucketToEdit = bucket - this.showDeleteBucketModal = true - } - - closeDeleteBucketModal = () => { - this.showDeleteBucketModal = false - } - setSelectedBucket = (bucket) => { this.selectedBucket = bucket this.clearOpenedFolders()