@@ -242,4 +247,4 @@ const CustomDomainVerify = ({ projectRef, customDomain, settings }: CustomDomain
)
}
-export default observer(CustomDomainVerify)
+export default CustomDomainVerify
diff --git a/apps/studio/components/interfaces/Settings/General/CustomDomainConfig/CustomDomainsConfigureHostname.tsx b/apps/studio/components/interfaces/Settings/General/CustomDomainConfig/CustomDomainsConfigureHostname.tsx
index 379cfe4c432..d781187b989 100644
--- a/apps/studio/components/interfaces/Settings/General/CustomDomainConfig/CustomDomainsConfigureHostname.tsx
+++ b/apps/studio/components/interfaces/Settings/General/CustomDomainConfig/CustomDomainsConfigureHostname.tsx
@@ -1,10 +1,8 @@
import { PermissionAction } from '@supabase/shared-types/out/constants'
-import { useParams } from 'common'
-import { observer } from 'mobx-react-lite'
import Link from 'next/link'
-import { Button, Form, IconExternalLink, Input } from 'ui'
import * as yup from 'yup'
+import { useParams } from 'common'
import { useProjectContext } from 'components/layouts/ProjectLayout/ProjectContext'
import {
FormActions,
@@ -17,6 +15,7 @@ import { useProjectApiQuery } from 'data/config/project-api-query'
import { useCheckCNAMERecordMutation } from 'data/custom-domains/check-cname-mutation'
import { useCustomDomainCreateMutation } from 'data/custom-domains/custom-domains-create-mutation'
import { useCheckPermissions } from 'hooks'
+import { Button, Form, IconExternalLink, Input } from 'ui'
const schema = yup.object({
domain: yup.string().required('A value for your custom domain is required'),
@@ -131,4 +130,4 @@ const CustomDomainsConfigureHostname = () => {
)
}
-export default observer(CustomDomainsConfigureHostname)
+export default CustomDomainsConfigureHostname
diff --git a/apps/studio/components/interfaces/Settings/General/Infrastructure/RestartServerButton.tsx b/apps/studio/components/interfaces/Settings/General/Infrastructure/RestartServerButton.tsx
index 51208880e0a..8eb59429c5b 100644
--- a/apps/studio/components/interfaces/Settings/General/Infrastructure/RestartServerButton.tsx
+++ b/apps/studio/components/interfaces/Settings/General/Infrastructure/RestartServerButton.tsx
@@ -1,7 +1,6 @@
import * as Tooltip from '@radix-ui/react-tooltip'
import { PermissionAction } from '@supabase/shared-types/out/constants'
import { useQueryClient } from '@tanstack/react-query'
-import { observer } from 'mobx-react-lite'
import { useRouter } from 'next/router'
import { useState } from 'react'
import toast from 'react-hot-toast'
@@ -175,4 +174,4 @@ const RestartServerButton = () => {
)
}
-export default observer(RestartServerButton)
+export default RestartServerButton
diff --git a/apps/studio/components/interfaces/Settings/Vault/Keys/EncryptionKeysManagement.tsx b/apps/studio/components/interfaces/Settings/Vault/Keys/EncryptionKeysManagement.tsx
index 3c6282419dd..1704d357e3b 100644
--- a/apps/studio/components/interfaces/Settings/Vault/Keys/EncryptionKeysManagement.tsx
+++ b/apps/studio/components/interfaces/Settings/Vault/Keys/EncryptionKeysManagement.tsx
@@ -2,7 +2,6 @@ import * as Tooltip from '@radix-ui/react-tooltip'
import { PermissionAction } from '@supabase/shared-types/out/constants'
import dayjs from 'dayjs'
import { sortBy } from 'lodash'
-import { observer } from 'mobx-react-lite'
import Link from 'next/link'
import { Fragment, useEffect, useState } from 'react'
import toast from 'react-hot-toast'
@@ -383,4 +382,4 @@ const EncryptionKeysManagement = () => {
)
}
-export default observer(EncryptionKeysManagement)
+export default EncryptionKeysManagement
diff --git a/apps/studio/components/interfaces/Settings/Vault/Secrets/SecretsManagement.tsx b/apps/studio/components/interfaces/Settings/Vault/Secrets/SecretsManagement.tsx
index 30c62774ddd..99ffbf7048f 100644
--- a/apps/studio/components/interfaces/Settings/Vault/Secrets/SecretsManagement.tsx
+++ b/apps/studio/components/interfaces/Settings/Vault/Secrets/SecretsManagement.tsx
@@ -1,17 +1,16 @@
import * as Tooltip from '@radix-ui/react-tooltip'
import { PermissionAction } from '@supabase/shared-types/out/constants'
-import { useParams } from 'common'
import { sortBy } from 'lodash'
-import { observer } from 'mobx-react-lite'
import Link from 'next/link'
import { Fragment, useEffect, useState } from 'react'
-import { Button, IconExternalLink, IconLoader, IconSearch, IconX, Input, Listbox } from 'ui'
+import { useParams } from 'common'
import { useProjectContext } from 'components/layouts/ProjectLayout/ProjectContext'
import Divider from 'components/ui/Divider'
import { useVaultSecretsQuery } from 'data/vault/vault-secrets-query'
import { useCheckPermissions } from 'hooks'
import type { VaultSecret } from 'types'
+import { Button, IconExternalLink, IconLoader, IconSearch, IconX, Input, Listbox } from 'ui'
import AddNewSecretModal from './AddNewSecretModal'
import DeleteSecretModal from './DeleteSecretModal'
import EditSecretModal from './EditSecretModal'
@@ -217,4 +216,4 @@ const SecretsManagement = () => {
)
}
-export default observer(SecretsManagement)
+export default SecretsManagement
diff --git a/apps/studio/components/interfaces/Settings/Vault/VaultToggle.tsx b/apps/studio/components/interfaces/Settings/Vault/VaultToggle.tsx
index b7de3eea001..e3112dee147 100644
--- a/apps/studio/components/interfaces/Settings/Vault/VaultToggle.tsx
+++ b/apps/studio/components/interfaces/Settings/Vault/VaultToggle.tsx
@@ -1,6 +1,5 @@
import * as Tooltip from '@radix-ui/react-tooltip'
import { PermissionAction } from '@supabase/shared-types/out/constants'
-import { observer } from 'mobx-react-lite'
import { useTheme } from 'next-themes'
import Link from 'next/link'
import { useState } from 'react'
@@ -161,4 +160,4 @@ const VaultToggle = () => {
)
}
-export default observer(VaultToggle)
+export default VaultToggle
diff --git a/apps/studio/components/interfaces/TableGridEditor/SidePanelEditor/SidePanelEditor.tsx b/apps/studio/components/interfaces/TableGridEditor/SidePanelEditor/SidePanelEditor.tsx
index a1fc06afd64..bbac0394d9f 100644
--- a/apps/studio/components/interfaces/TableGridEditor/SidePanelEditor/SidePanelEditor.tsx
+++ b/apps/studio/components/interfaces/TableGridEditor/SidePanelEditor/SidePanelEditor.tsx
@@ -6,10 +6,11 @@ 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 +18,11 @@ 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 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/interfaces/TableGridEditor/TableDefinition.tsx b/apps/studio/components/interfaces/TableGridEditor/TableDefinition.tsx
index 8105dc325e4..e09e347138f 100644
--- a/apps/studio/components/interfaces/TableGridEditor/TableDefinition.tsx
+++ b/apps/studio/components/interfaces/TableGridEditor/TableDefinition.tsx
@@ -1,10 +1,11 @@
import Editor from '@monaco-editor/react'
import { useTheme } from 'next-themes'
-import { useParams } from 'common'
-import { observer } from 'mobx-react-lite'
+import Link from 'next/link'
import { useMemo, useRef } from 'react'
import { format } from 'sql-formatter'
+import { useParams } from 'common'
+import Footer from 'components/grid/components/footer/Footer'
import { useProjectContext } from 'components/layouts/ProjectLayout/ProjectContext'
import { GenericSkeletonLoader } from 'components/ui/ShimmeringLoader'
import { useTableDefinitionQuery } from 'data/database/table-definition-query'
@@ -12,9 +13,7 @@ import { useViewDefinitionQuery } from 'data/database/view-definition-query'
import { ENTITY_TYPE } from 'data/entity-types/entity-type-constants'
import useEntityType from 'hooks/misc/useEntityType'
import { timeout } from 'lib/helpers'
-import Link from 'next/link'
import { Button } from 'ui'
-import Footer from 'components/grid/components/footer/Footer'
export interface TableDefinitionProps {
id?: number
@@ -148,4 +147,4 @@ const TableDefinition = ({ id }: TableDefinitionProps) => {
)
}
-export default observer(TableDefinition)
+export default TableDefinition
diff --git a/apps/studio/components/interfaces/TableGridEditor/TableGridEditor.tsx b/apps/studio/components/interfaces/TableGridEditor/TableGridEditor.tsx
index 9111f4a2576..cb3a61e490e 100644
--- a/apps/studio/components/interfaces/TableGridEditor/TableGridEditor.tsx
+++ b/apps/studio/components/interfaces/TableGridEditor/TableGridEditor.tsx
@@ -1,12 +1,11 @@
import type { PostgresColumn, PostgresRelationship, PostgresTable } from '@supabase/postgres-meta'
import { PermissionAction } from '@supabase/shared-types/out/constants'
import { QueryKey, useQueryClient } from '@tanstack/react-query'
-import { useParams } from 'common'
import { find, isUndefined } from 'lodash'
-import { observer } from 'mobx-react-lite'
import { useRouter } from 'next/router'
import toast from 'react-hot-toast'
+import { useParams } from 'common'
import { parseSupaTable, SupabaseGrid, SupaTable } from 'components/grid'
import { ERROR_PRIMARY_KEY_NOTFOUND } from 'components/grid/constants'
import { useProjectContext } from 'components/layouts/ProjectLayout/ProjectContext'
@@ -311,4 +310,4 @@ const TableGridEditor = ({
)
}
-export default observer(TableGridEditor)
+export default TableGridEditor
diff --git a/apps/studio/components/layouts/DatabaseLayout/DatabaseLayout.tsx b/apps/studio/components/layouts/DatabaseLayout/DatabaseLayout.tsx
index 4341217d156..735ebbaba78 100644
--- a/apps/studio/components/layouts/DatabaseLayout/DatabaseLayout.tsx
+++ b/apps/studio/components/layouts/DatabaseLayout/DatabaseLayout.tsx
@@ -1,4 +1,3 @@
-import { observer } from 'mobx-react-lite'
import { useRouter } from 'next/router'
import { PropsWithChildren } from 'react'
@@ -46,4 +45,4 @@ const DatabaseLayout = ({ children }: PropsWithChildren
) =>
)
}
-export default withAuth(observer(DatabaseLayout))
+export default withAuth(DatabaseLayout)
diff --git a/apps/studio/components/layouts/DocsLayout/DocsLayout.tsx b/apps/studio/components/layouts/DocsLayout/DocsLayout.tsx
index ad906c325c3..30d63d082e4 100644
--- a/apps/studio/components/layouts/DocsLayout/DocsLayout.tsx
+++ b/apps/studio/components/layouts/DocsLayout/DocsLayout.tsx
@@ -1,4 +1,3 @@
-import { observer } from 'mobx-react-lite'
import { useRouter } from 'next/router'
import { ReactElement } from 'react'
@@ -67,4 +66,4 @@ function DocsLayout({ title, children }: { title: string; children: ReactElement
)
}
-export default withAuth(observer(DocsLayout))
+export default withAuth(DocsLayout)
diff --git a/apps/studio/components/layouts/FunctionsLayout.tsx b/apps/studio/components/layouts/FunctionsLayout.tsx
index a41dd3b0ab1..689578617f6 100644
--- a/apps/studio/components/layouts/FunctionsLayout.tsx
+++ b/apps/studio/components/layouts/FunctionsLayout.tsx
@@ -1,16 +1,15 @@
import { PermissionAction } from '@supabase/shared-types/out/constants'
-import { useParams } from 'common'
-import { observer } from 'mobx-react-lite'
import Link from 'next/link'
import type { PropsWithChildren } from 'react'
-import { Button, IconCode, IconExternalLink } from 'ui'
+import { useParams } from 'common'
import { useIsAPIDocsSidePanelEnabled } from 'components/interfaces/App/FeaturePreview/FeaturePreviewContext'
import APIDocsButton from 'components/ui/APIDocsButton'
import NoPermission from 'components/ui/NoPermission'
import { useEdgeFunctionQuery } from 'data/edge-functions/edge-function-query'
import { useEdgeFunctionsQuery } from 'data/edge-functions/edge-functions-query'
import { useCheckPermissions, withAuth } from 'hooks'
+import { Button, IconCode, IconExternalLink } from 'ui'
import FunctionsNav from '../interfaces/Functions/FunctionsNav'
import { ProjectLayout } from './'
@@ -152,4 +151,4 @@ const FunctionsLayout = ({ title, children }: PropsWithChildren
)
}
-export default observer(BreadcrumbsView)
+export default BreadcrumbsView
diff --git a/apps/studio/components/layouts/WizardLayout.tsx b/apps/studio/components/layouts/WizardLayout.tsx
index d181a263a1a..5725f7b652b 100644
--- a/apps/studio/components/layouts/WizardLayout.tsx
+++ b/apps/studio/components/layouts/WizardLayout.tsx
@@ -1,11 +1,10 @@
-import { observer } from 'mobx-react-lite'
import Link from 'next/link'
import { PropsWithChildren } from 'react'
-import { IconChevronRight } from 'ui'
import { withAuth } from 'hooks'
import { BASE_PATH } from 'lib/constants'
import type { Organization, Project } from 'types'
+import { IconChevronRight } from 'ui'
import { FeedbackDropdown } from './ProjectLayout/LayoutHeader/FeedbackDropdown'
import HelpPopover from './ProjectLayout/LayoutHeader/HelpPopover'
@@ -31,9 +30,9 @@ const WizardLayout = ({
)
}
-export default withAuth(observer(WizardLayout))
+export default withAuth(WizardLayout)
-export const WizardLayoutWithoutAuth = observer(WizardLayout)
+export const WizardLayoutWithoutAuth = WizardLayout
const Header = ({ organization, project }: WizardLayoutProps) => {
let stepNumber = organization ? 1 : project ? 2 : 0
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/hooks/index.ts b/apps/studio/hooks/index.ts
index b8238bfbc3d..d977689467a 100644
--- a/apps/studio/hooks/index.ts
+++ b/apps/studio/hooks/index.ts
@@ -2,10 +2,9 @@ export * from './deprecated'
export * from './misc/useCheckPermissions'
export * from './misc/useImmutableValue'
export * from './misc/useIsFeatureEnabled'
+export * from './misc/useLatest'
export * from './misc/useLocalStorage'
export * from './misc/useSelectedOrganization'
export * from './misc/useSelectedProject'
-export * from './misc/useStore'
export * from './misc/withAuth'
-export * from './misc/useLatest'
export * from './ui'
diff --git a/apps/studio/hooks/misc/useStore.tsx b/apps/studio/hooks/misc/useStore.tsx
deleted file mode 100644
index 93d8629ce4a..00000000000
--- a/apps/studio/hooks/misc/useStore.tsx
+++ /dev/null
@@ -1,68 +0,0 @@
-import { autorun } from 'mobx'
-import { createContext, PropsWithChildren, useContext, useEffect } from 'react'
-import toast from 'react-hot-toast'
-
-import SparkBar from 'components/ui/SparkBar'
-import { IUiStore } from 'stores/UiStore'
-
-const StoreContext = createContext<{ ui: IUiStore }>(undefined!)
-
-/**
- * @deprecated use the toast.success/loading/error functions, imported from 'react-hot-toast'
- */
-export function useStore() {
- const context = useContext(StoreContext)
- if (context === undefined) {
- throw new Error('useStore must be used within StoreProvider')
- }
-
- // returning in this way so that it's backwards compatible.
- return context
-}
-
-interface StoreProvider {
- rootStore: { ui: IUiStore }
-}
-export const StoreProvider = ({ children, rootStore }: PropsWithChildren) => {
- const { ui } = rootStore
- useEffect(() => {
- autorun(() => {
- if (ui.notification) {
- const { id, category, error, message, description, progress, duration } = ui.notification
- const toastDuration = duration || 4000
- switch (category) {
- case 'info':
- return toast(message, { id, duration: toastDuration })
- case 'success':
- return toast.success(message, { id, duration: toastDuration })
- case 'error':
- console.error('Error:', { error, message })
- return toast.error(message, { id, duration: duration || Infinity })
- case 'loading':
- if (progress !== undefined) {
- return toast.loading(
-
-
- {description !== undefined && (
-
{description}
- )}
-
,
- { id }
- )
- } else {
- return toast.loading(message, { id })
- }
- }
- }
- })
- }, [])
-
- return {children}
-}
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..fd525d6b9b0 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'
@@ -13,7 +12,7 @@ import {
STORAGE_SORT_BY,
STORAGE_VIEWS,
} from 'components/to-be-cleaned/Storage/Storage.constants'
-import { useStore } from 'hooks'
+import { ToastLoader } from 'components/ui/ToastLoader'
import { delete_, post } from 'lib/common/fetch'
import { API_URL, IS_PLATFORM } from 'lib/constants'
import { PROJECT_ENDPOINT_PROTOCOL } from 'pages/api/constants'
@@ -59,9 +58,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 +75,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 +503,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 +577,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 +734,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 +754,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 +796,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 +834,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 +890,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 +908,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 +1211,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 +1272,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) {
diff --git a/apps/studio/pages/README.md b/apps/studio/pages/README.md
index 32423b193de..77609973fa0 100644
--- a/apps/studio/pages/README.md
+++ b/apps/studio/pages/README.md
@@ -9,9 +9,7 @@
```tsx
import { NextPage } from 'next'
-import { observer } from 'mobx-react-lite'
-
-import { useStore, withAuth } from 'hooks'
+import { withAuth } from 'hooks'
// Import the corresponding layout based on the page
import { Layout } from 'components/layouts'
@@ -25,9 +23,6 @@ import { ... } from 'components/ui/xxx'
// Name your page accordingly
const Page: NextPage = () => {
- // Access the store via the useStore hook
- const { meta } = useStore()
-
return (
Page content
@@ -35,5 +30,5 @@ const Page: NextPage = () => {
)
}
-export default withAuth(observer(Page))
+export default withAuth(Page)
```
diff --git a/apps/studio/pages/_app.tsx b/apps/studio/pages/_app.tsx
index bb4e9eef9fb..f2febfb2485 100644
--- a/apps/studio/pages/_app.tsx
+++ b/apps/studio/pages/_app.tsx
@@ -46,12 +46,10 @@ import FeaturePreviewModal from 'components/interfaces/App/FeaturePreview/Featur
import FlagProvider from 'components/ui/Flag/FlagProvider'
import PageTelemetry from 'components/ui/PageTelemetry'
import { useRootQueryClient } from 'data/query-client'
-import { StoreProvider } from 'hooks'
import { AuthProvider } from 'lib/auth'
import { BASE_PATH, IS_PLATFORM, LOCAL_STORAGE_KEYS } from 'lib/constants'
import { ProfileProvider } from 'lib/profile'
import { useAppStateSnapshot } from 'state/app-state'
-import UiStore from 'stores/UiStore'
import HCaptchaLoadedStore from 'stores/hcaptcha-loaded-store'
import { AppPropsWithLayout } from 'types'
@@ -81,9 +79,7 @@ loader.config({
function CustomApp({ Component, pageProps }: AppPropsWithLayout) {
const snap = useAppStateSnapshot()
const queryClient = useRootQueryClient()
-
const consentToastId = useRef()
- const [rootStore] = useState(() => ({ ui: new UiStore() }))
// [Joshen] Some issues with using createBrowserSupabaseClient
const [supabase] = useState(() =>
@@ -146,43 +142,41 @@ function CustomApp({ Component, pageProps }: AppPropsWithLayout) {
return (
-
-
-
-
-
- Supabase
-
-
-
+
+
+
+
+ Supabase
+
+
+
-
-
-
-
-
-
-
-
- {getLayout()}
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+ {getLayout()}
+
+
+
+
+
+
+
+
+
-
-
-
- {!isTestEnv && }
-
-
-
-
+
+
+
+ {!isTestEnv && }
+
+
+
)
diff --git a/apps/studio/pages/project/[ref]/reports/index.tsx b/apps/studio/pages/project/[ref]/reports/index.tsx
index bbcb2d7d49c..3972cdc5b62 100644
--- a/apps/studio/pages/project/[ref]/reports/index.tsx
+++ b/apps/studio/pages/project/[ref]/reports/index.tsx
@@ -3,15 +3,14 @@ import { useRouter } from 'next/router'
import { useEffect, useState } from 'react'
import { useParams } from 'common/hooks'
+import { CreateReportModal } from 'components/interfaces/Reports/Reports.CreateReportModal'
import { ReportsLayout } from 'components/layouts'
import ProductEmptyState from 'components/to-be-cleaned/ProductEmptyState'
-import { createReport } from 'components/to-be-cleaned/Reports/Reports.utils'
import { Loading } from 'components/ui/Loading'
-import { useCheckPermissions, useStore } from 'hooks'
+import { useCheckPermissions } from 'hooks'
import { useProfile } from 'lib/profile'
import { useProjectContentStore } from 'stores/projectContentStore'
import type { NextPageWithLayout } from 'types'
-import { CreateReportModal } from 'components/interfaces/Reports/Reports.CreateReportModal'
export const UserReportPage: NextPageWithLayout = () => {
const [loading, setLoading] = useState(true)
@@ -20,7 +19,6 @@ export const UserReportPage: NextPageWithLayout = () => {
const { ref } = useParams()
const { profile } = useProfile()
- const { ui } = useStore()
const [showCreateReportModal, setShowCreateReportModal] = useState(false)
const contentStore = useProjectContentStore(ref)
diff --git a/apps/studio/pages/project/[ref]/sql/[id].tsx b/apps/studio/pages/project/[ref]/sql/[id].tsx
index 57c26080ae9..7fa0997cde0 100644
--- a/apps/studio/pages/project/[ref]/sql/[id].tsx
+++ b/apps/studio/pages/project/[ref]/sql/[id].tsx
@@ -1,6 +1,5 @@
import { useMonaco } from '@monaco-editor/react'
import { useParams } from 'common'
-import { observer } from 'mobx-react-lite'
import { useRouter } from 'next/router'
import { useEffect, useRef } from 'react'
@@ -158,4 +157,4 @@ const SqlEditor: NextPageWithLayout = () => {
SqlEditor.getLayout = (page) => {page}
-export default observer(SqlEditor)
+export default SqlEditor
diff --git a/apps/studio/pages/project/[ref]/storage/buckets/[bucketId].tsx b/apps/studio/pages/project/[ref]/storage/buckets/[bucketId].tsx
index 38559efc142..81bf034da0f 100644
--- a/apps/studio/pages/project/[ref]/storage/buckets/[bucketId].tsx
+++ b/apps/studio/pages/project/[ref]/storage/buckets/[bucketId].tsx
@@ -1,6 +1,5 @@
import { useParams } from 'common'
import { find } from 'lodash'
-import { observer } from 'mobx-react-lite'
import { StorageLayout } from 'components/layouts'
import { useProjectContext } from 'components/layouts/ProjectLayout/ProjectContext'
@@ -40,4 +39,4 @@ const PageLayout: NextPageWithLayout = () => {
PageLayout.getLayout = (page) => {page}
-export default observer(PageLayout)
+export default PageLayout
diff --git a/apps/studio/pages/project/[ref]/storage/index.tsx b/apps/studio/pages/project/[ref]/storage/index.tsx
index 23206ef662a..d0c2fcde310 100644
--- a/apps/studio/pages/project/[ref]/storage/index.tsx
+++ b/apps/studio/pages/project/[ref]/storage/index.tsx
@@ -1,5 +1,3 @@
-import { observer } from 'mobx-react-lite'
-
import { StorageLayout } from 'components/layouts'
import type { NextPageWithLayout } from 'types'
@@ -9,4 +7,4 @@ const Storage: NextPageWithLayout = () => {
Storage.getLayout = (page) => {page}
-export default observer(Storage)
+export default Storage
diff --git a/apps/studio/stores/README.md b/apps/studio/stores/README.md
deleted file mode 100644
index fc5b9804f67..00000000000
--- a/apps/studio/stores/README.md
+++ /dev/null
@@ -1,23 +0,0 @@
-# Store
-
-## Store structure
-
-At the root, there are currently 3 top-level stores in use: `app`, `meta` and `ui` (`content` is WIP at the moment). Each of them store the following information:
-
-- `app`: Application level data (Projects and organizations)
-- `meta`: Database information (e.g Tables, Columns, Policies)
-- `ui`: UI states that are common globally
-- `content`: User-specific content (e.g Saved SQL snippets)
-
-## Accessing the store
-
-The `useStore` hook is the entry point to access the store in your pages and components.
-
-```
-import { useStore } from 'hooks'
-const { app, meta, ui } = useStore()
-```
-
-## What is the jsonSchema folder
-
-The files here are used to populate form fields on the dashboard with the `ajv` library. We have in mind to move away from this way of rendering form fields due to its rigid nature but we've yet to decide.
diff --git a/apps/studio/stores/UiStore.ts b/apps/studio/stores/UiStore.ts
deleted file mode 100644
index 475fe3f08f9..00000000000
--- a/apps/studio/stores/UiStore.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-import { makeAutoObservable } from 'mobx'
-
-import { uuidv4 } from 'lib/helpers'
-import type { Notification } from 'types'
-
-export interface IUiStore {
- notification?: Notification
- setNotification: (notification: Notification) => string
-}
-export default class UiStore implements IUiStore {
- notification?: Notification
-
- constructor() {
- makeAutoObservable(this)
- }
-
- setNotification(notification: Notification): string {
- const id = notification?.id ?? uuidv4()
- this.notification = { ...notification, id }
- return id
- }
-}
diff --git a/apps/studio/stores/authConfig/schema/index.ts b/apps/studio/stores/authConfig/schema/index.ts
deleted file mode 100644
index 43266b2cd49..00000000000
--- a/apps/studio/stores/authConfig/schema/index.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-export { PROVIDERS_SCHEMAS, PROVIDER_SAML } from './AuthProviders/AuthProvidersFormValidation'
-export { TEMPLATES_SCHEMAS } from './AuthProviders/AuthTemplatesValidation'
diff --git a/apps/studio/tests/helpers.tsx b/apps/studio/tests/helpers.tsx
index 9e60805c266..0ea2d731498 100644
--- a/apps/studio/tests/helpers.tsx
+++ b/apps/studio/tests/helpers.tsx
@@ -1,11 +1,8 @@
-import { fireEvent, getByText, screen } from '@testing-library/react'
+import { fireEvent, getByText, screen, render as originalRender } from '@testing-library/react'
import React, { useState } from 'react'
-
import { TooltipProvider } from '@radix-ui/react-tooltip'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
-import { render as originalRender } from '@testing-library/react'
-import { StoreProvider } from 'hooks'
-import UiStore from 'stores/UiStore'
+
interface SelectorOptions {
container?: HTMLElement
}
@@ -48,8 +45,6 @@ export const clickDropdown = (elem: HTMLElement) => {
* https://testing-library.com/docs/react-testing-library/setup/#custom-render
*/
const ReactQueryTestConfig: React.FC = ({ children }) => {
- const [rootStore] = useState(() => ({ ui: new UiStore() }))
-
const [queryClient] = useState(
() =>
new QueryClient({
@@ -68,11 +63,9 @@ const ReactQueryTestConfig: React.FC = ({ children }) =
)
return (
-
-
- {children}
-
-
+
+ {children}
+
)
}
type renderParams = Parameters