diff --git a/apps/studio/components/interfaces/TableGridEditor/SidePanelEditor/SidePanelEditor.tsx b/apps/studio/components/interfaces/TableGridEditor/SidePanelEditor/SidePanelEditor.tsx
index a1fc06afd64..fffee92bf70 100644
--- a/apps/studio/components/interfaces/TableGridEditor/SidePanelEditor/SidePanelEditor.tsx
+++ b/apps/studio/components/interfaces/TableGridEditor/SidePanelEditor/SidePanelEditor.tsx
@@ -3,13 +3,13 @@ import { useQueryClient } from '@tanstack/react-query'
import { isEmpty, isUndefined, noop } from 'lodash'
import { useState } from 'react'
import { toast } from 'react-hot-toast'
-import { Modal } from 'ui'
import { useProjectContext } from 'components/layouts/ProjectLayout/ProjectContext'
-import ConfirmationModal from 'ui-patterns/Dialogs/ConfirmationModal'
+import { ToastLoader } from 'components/ui/ToastLoader'
import { useDatabasePublicationCreateMutation } from 'data/database-publications/database-publications-create-mutation'
import { useDatabasePublicationsQuery } from 'data/database-publications/database-publications-query'
import { useDatabasePublicationUpdateMutation } from 'data/database-publications/database-publications-update-mutation'
+import type { Constraint } from 'data/database/constraints-query'
import type { ForeignKeyConstraint } from 'data/database/foreign-key-constraints-query'
import { entityTypeKeys } from 'data/entity-types/keys'
import { sqlKeys } from 'data/sql/keys'
@@ -17,10 +17,12 @@ import { useTableRowCreateMutation } from 'data/table-rows/table-row-create-muta
import { useTableRowUpdateMutation } from 'data/table-rows/table-row-update-mutation'
import { tableKeys } from 'data/tables/keys'
import { getTables } from 'data/tables/tables-query'
-import { useStore, useUrlState } from 'hooks'
+import { useUrlState } from 'hooks'
import { useGetImpersonatedRole } from 'state/role-impersonation-state'
import { useTableEditorStateSnapshot } from 'state/table-editor'
import type { Dictionary } from 'types'
+import { Modal } from 'ui'
+import ConfirmationModal from 'ui-patterns/Dialogs/ConfirmationModal'
import { ColumnEditor, RowEditor, SpreadsheetImport, TableEditor } from '.'
import type { ForeignKey } from './ForeignKeySelector/ForeignKeySelector.types'
import ForeignRowSelector from './RowEditor/ForeignRowSelector/ForeignRowSelector'
@@ -38,7 +40,6 @@ import {
updateTable,
} from './SidePanelEditor.utils'
import type { ImportContent } from './TableEditor/TableEditor.types'
-import type { Constraint } from 'data/database/constraints-query'
export interface SidePanelEditorProps {
editable?: boolean
@@ -59,7 +60,6 @@ const SidePanelEditor = ({
const snap = useTableEditorStateSnapshot()
const [_, setParams] = useUrlState({ arrayKeys: ['filter', 'sort'] })
- const { ui } = useStore()
const queryClient = useQueryClient()
const { project } = useProjectContext()
@@ -508,12 +508,13 @@ const SidePanelEditor = ({
selectedTable,
selectedHeaders,
(progress: number) => {
- ui.setNotification({
- id: toastId,
- progress,
- category: 'loading',
- message: `Adding ${rowCount.toLocaleString()} rows to ${selectedTable.name}`,
- })
+ toast.loading(
+ ,
+ { id: toastId }
+ )
}
)
if (res.error) {
@@ -529,14 +530,15 @@ const SidePanelEditor = ({
importContent.rows,
selectedHeaders,
(progress: number) => {
- ui.setNotification({
- id: toastId,
- progress,
- category: 'loading',
- message: `Adding ${importContent.rows.length.toLocaleString()} rows to ${
- selectedTable.name
- }`,
- })
+ toast.loading(
+ ,
+ { id: toastId }
+ )
}
)
if (res.error) {
diff --git a/apps/studio/components/ui/ToastLoader.tsx b/apps/studio/components/ui/ToastLoader.tsx
new file mode 100644
index 00000000000..6e88277acf6
--- /dev/null
+++ b/apps/studio/components/ui/ToastLoader.tsx
@@ -0,0 +1,27 @@
+// [Joshen] Just FYI eventually we're going to move to use toasts
+// from the UI library, but this is a transition to move everything to
+// react-hot-toast while we're trying to deprecate mobx entirely
+
+import SparkBar from './SparkBar'
+
+interface ToastLoaderProps {
+ progress: number
+ message: string
+ description?: string
+}
+
+export const ToastLoader = ({ progress, message, description }: ToastLoaderProps) => {
+ return (
+
+
+ {description !== undefined &&
{description}
}
+
+ )
+}
diff --git a/apps/studio/localStores/storageExplorer/StorageExplorerStore.ts b/apps/studio/localStores/storageExplorer/StorageExplorerStore.tsx
similarity index 95%
rename from apps/studio/localStores/storageExplorer/StorageExplorerStore.ts
rename to apps/studio/localStores/storageExplorer/StorageExplorerStore.tsx
index 5581824837a..68c469b0083 100644
--- a/apps/studio/localStores/storageExplorer/StorageExplorerStore.ts
+++ b/apps/studio/localStores/storageExplorer/StorageExplorerStore.tsx
@@ -1,5 +1,4 @@
// @ts-nocheck
-
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'
@@ -7,6 +6,7 @@ import { makeAutoObservable } from 'mobx'
import toast from 'react-hot-toast'
import { toast as UiToast } from 'ui'
+import { ToastLoader } from 'components/ui/ToastLoader'
import {
STORAGE_ROW_STATUS,
STORAGE_ROW_TYPES,
@@ -59,9 +59,6 @@ class StorageExplorerStore {
sortBy: { column: this.sortBy, order: this.sortByOrder },
}
- /* UI store */
- ui = null
-
/* Supabase client */
supabaseClient = null
/* [Joshen] Move towards using API */
@@ -79,8 +76,6 @@ 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
if (typeof window !== 'undefined') {
@@ -509,14 +504,15 @@ class StorageExplorerStore {
.map((folder) => folder.name)
.join('/')
- const toastId = this.ui.setNotification({
- category: 'loading',
- message: `Uploading ${formattedFilesToUpload.length} file${
- formattedFilesToUpload.length > 1 ? 's' : ''
- }...`,
- description: STORAGE_PROGRESS_INFO_TEXT,
- progress: 0,
- })
+ const toastId = toast.loading(
+ 1 ? 's' : ''
+ }...`}
+ description={STORAGE_PROGRESS_INFO_TEXT}
+ />
+ )
// Upload files in batches
const promises = formattedFilesToUpload.map((file) => {
@@ -582,15 +578,16 @@ class StorageExplorerStore {
await batchedPromises.reduce(async (previousPromise, nextBatch) => {
await previousPromise
await Promise.allSettled(nextBatch.map((batch) => batch()))
- this.ui.setNotification({
- id: toastId,
- category: 'loading',
- message: `Uploading ${formattedFilesToUpload.length} file${
- formattedFilesToUpload.length > 1 ? 's' : ''
- }...`,
- description: STORAGE_PROGRESS_INFO_TEXT,
- progress: this.uploadProgress * 100,
- })
+ toast.loading(
+ 1 ? 's' : ''
+ }...`}
+ description={STORAGE_PROGRESS_INFO_TEXT}
+ />,
+ { id: toastId }
+ )
}, Promise.resolve())
if (numberOfFilesUploadedSuccess > 0) {
@@ -738,12 +735,13 @@ class StorageExplorerStore {
this.clearSelectedItems()
- const toastId = this.ui.setNotification({
- category: 'loading',
- message: `Deleting ${prefixes.length} file(s)...`,
- description: STORAGE_PROGRESS_INFO_TEXT,
- progress: 0,
- })
+ const toastId = toast.loading(
+
+ )
// batch BATCH_SIZE prefixes per request
const batches = chunk(prefixes, BATCH_SIZE).map((batch) => () => {
@@ -757,13 +755,14 @@ class StorageExplorerStore {
await chunk(batches, BATCH_SIZE).reduce(async (previousPromise, nextBatch) => {
await previousPromise
await Promise.all(nextBatch.map((batch) => batch()))
- this.ui.setNotification({
- id: toastId,
- category: 'loading',
- message: `Deleting ${prefixes.length} file(s)...`,
- description: STORAGE_PROGRESS_INFO_TEXT,
- progress: progress * 100,
- })
+ toast.loading(
+ ,
+ { id: toastId }
+ )
}, Promise.resolve())
// Clear file preview cache if deleted files exist in cache
@@ -798,13 +797,14 @@ class StorageExplorerStore {
const files = await this.getAllItemsAlongFolder(folder)
- this.ui.setNotification({
- id: toastId,
- category: 'loading',
- message: `Downloading ${files.length} files...`,
- description: STORAGE_PROGRESS_INFO_TEXT,
- progress: 0,
- })
+ toast.loading(
+ 1 ? 's' : ''}...`}
+ desription={STORAGE_PROGRESS_INFO_TEXT}
+ />,
+ { id: toastId }
+ )
const promises = files.map((file) => {
const fileMimeType = file.metadata?.mimetype ?? null
@@ -835,13 +835,14 @@ class StorageExplorerStore {
const downloadedFiles = await batchedPromises.reduce(async (previousPromise, nextBatch) => {
const previousResults = await previousPromise
const batchResults = await Promise.allSettled(nextBatch.map((batch) => batch()))
- this.ui.setNotification({
- id: toastId,
- category: 'loading',
- message: `Downloading ${files.length} file${files.length > 1 ? 's' : ''}...`,
- description: STORAGE_PROGRESS_INFO_TEXT,
- progress: progress * 100,
- })
+ toast.loading(
+ 1 ? 's' : ''}...`}
+ desription={STORAGE_PROGRESS_INFO_TEXT}
+ />,
+ { id: toastId }
+ )
return (previousResults ?? []).concat(batchResults.map((x) => x.value).filter(Boolean))
}, Promise.resolve())
@@ -890,7 +891,9 @@ class StorageExplorerStore {
let progress = 0
const returnBlob = true
const showIndividualToast = false
- const toastId = toast.loading(`Downloading ${files.length} files...`)
+ const toastId = toast.loading(
+ `Downloading ${files.length} file${files.length > 1 ? 's' : ''}...`
+ )
const promises = formattedFilesWithPrefix.map((file) => {
return () => {
@@ -906,13 +909,14 @@ class StorageExplorerStore {
const downloadedFiles = await batchedPromises.reduce(async (previousPromise, nextBatch) => {
const previousResults = await previousPromise
const batchResults = await Promise.allSettled(nextBatch.map((batch) => batch()))
- this.ui.setNotification({
- id: toastId,
- category: 'loading',
- message: `Downloading ${files.length} file${files.length > 1 ? 's' : ''}...`,
- description: STORAGE_PROGRESS_INFO_TEXT,
- progress: progress * 100,
- })
+ toast.loading(
+ 1 ? 's' : ''}...`}
+ description={STORAGE_PROGRESS_INFO_TEXT}
+ />,
+ { id: toastId }
+ )
return (previousResults ?? []).concat(batchResults.map((x) => x.value).filter(Boolean))
}, Promise.resolve())
@@ -1208,12 +1212,13 @@ class StorageExplorerStore {
return this.updateRowStatus(originalName, STORAGE_ROW_STATUS.READY, columnIndex)
}
- const toastId = this.ui.setNotification({
- category: 'loading',
- message: `Renaming folder to ${newName}`,
- description: STORAGE_PROGRESS_INFO_TEXT,
- progress: 0,
- })
+ const toastId = toast.loading(
+
+ )
/**
* Catch any folder names that contain slash or backslash
@@ -1268,13 +1273,14 @@ class StorageExplorerStore {
await batchedPromises.reduce(async (previousPromise, nextBatch) => {
await previousPromise
await Promise.all(nextBatch.map((batch) => batch()))
- this.ui.setNotification({
- id: toastId,
- category: 'loading',
- message: `Renaming folder to ${newName}`,
- description: STORAGE_PROGRESS_INFO_TEXT,
- progress: progress * 100,
- })
+ toast.loader(
+ ,
+ { id: toastId }
+ )
}, Promise.resolve())
if (!hasErrors) {