From 424d6ec2acce7992ab4c2aa097007e6180ba265d Mon Sep 17 00:00:00 2001 From: Joshen Lim Date: Wed, 21 Jun 2023 15:11:45 +0800 Subject: [PATCH] Improve empty state --- .../Database/Migrations/Migrations.tsx | 86 +++++++------- .../Migrations/MigrationsEmptyState.tsx | 111 ++++++++++++++++++ studio/data/database/migrations-query.ts | 10 ++ studio/data/sql/execute-sql-query.ts | 29 +++-- 4 files changed, 188 insertions(+), 48 deletions(-) create mode 100644 studio/components/interfaces/Database/Migrations/MigrationsEmptyState.tsx diff --git a/studio/components/interfaces/Database/Migrations/Migrations.tsx b/studio/components/interfaces/Database/Migrations/Migrations.tsx index fcf2f7649e9..b3e2172d214 100644 --- a/studio/components/interfaces/Database/Migrations/Migrations.tsx +++ b/studio/components/interfaces/Database/Migrations/Migrations.tsx @@ -9,6 +9,7 @@ import ShimmeringLoader from 'components/ui/ShimmeringLoader' import { DatabaseMigration, useMigrationsQuery } from 'data/database/migrations-query' import { Editor } from '@monaco-editor/react' import CodeEditor from 'components/ui/CodeEditor' +import MigrationsEmptyState from './MigrationsEmptyState' const Wrappers = () => { const [search, setSearch] = useState('') @@ -24,6 +25,8 @@ const Wrappers = () => { ? data?.result ?? [] : data?.result.filter((migration) => migration.version.includes(search)) ?? [] + console.log({ data }) + return ( <>
@@ -80,51 +83,52 @@ const Wrappers = () => { )} {isSuccess && (
-
- setSearch(e.target.value)} - icon={} - /> -
- - {data.result.length <= 0 &&
No migrations state...
} + {data.result.length <= 0 && } {data.result.length > 0 && ( - Version, - , - ]} - body={ - migrations.length > 0 ? ( - migrations.map((migration) => ( - - {migration.version} - - + <> +
+ setSearch(e.target.value)} + icon={} + /> +
+
Version, + , + ]} + body={ + migrations.length > 0 ? ( + migrations.map((migration) => ( + + {migration.version} + + + + + )) + ) : ( + + +

No results found

+

+ Your search for "{search}" did not return any results +

- )) - ) : ( - - -

No results found

-

- Your search for "{search}" did not return any results -

-
-
- ) - } - /> + ) + } + /> + )} )} diff --git a/studio/components/interfaces/Database/Migrations/MigrationsEmptyState.tsx b/studio/components/interfaces/Database/Migrations/MigrationsEmptyState.tsx new file mode 100644 index 00000000000..55ef19b3ea7 --- /dev/null +++ b/studio/components/interfaces/Database/Migrations/MigrationsEmptyState.tsx @@ -0,0 +1,111 @@ +import clsx from 'clsx' +import Link from 'next/link' +import { useState } from 'react' +import { + Button, + Collapsible, + IconExternalLink, + IconMaximize2, + IconMinimize2, + IconTerminal, +} from 'ui' + +import CommandRender from 'components/interfaces/Functions/CommandRender' +import { useParams } from 'common' + +const MigrationsEmptyState = () => { + const { ref } = useParams() + const [showInstructions, setShowInstructions] = useState(false) + + const commands = [ + { + comment: 'Link your project', + command: `supabase link --project-ref ${ref}`, + jsx: () => { + return ( + <> + supabase link --project-ref {ref} + + ) + }, + }, + { + comment: 'Create a new migration called "new-migration"', + command: `supabase migration new new-migration`, + jsx: () => { + return ( + <> + supabase migration new new-migration + + ) + }, + }, + { + comment: 'Run all migrations against this project', + command: `supabase db push`, + jsx: () => { + return ( + <> + supabase db push + + ) + }, + }, + ] + + return ( +
+
+
+

Database migrations

+

+ Database changes are managed through "migrations" and they are a common way of tracking + changes to your database over time. You can run migrations against your project's + database via the Supabase CLI. +

+
+ + + + + + +
+ +
+
+
+
+
+ ) +} + +export default MigrationsEmptyState diff --git a/studio/data/database/migrations-query.ts b/studio/data/database/migrations-query.ts index 00e24118c3c..f9a25136e8b 100644 --- a/studio/data/database/migrations-query.ts +++ b/studio/data/database/migrations-query.ts @@ -36,6 +36,16 @@ export const useMigrationsQuery = { + if ( + error.code === 400 && + error.message.includes('relation "supabase_migrations.schema_migrations" does not exist') + ) { + return { result: [] } + } else { + throw error + } + }, }, options ) diff --git a/studio/data/sql/execute-sql-query.ts b/studio/data/sql/execute-sql-query.ts index 1eb86b56373..76ef0f665aa 100644 --- a/studio/data/sql/execute-sql-query.ts +++ b/studio/data/sql/execute-sql-query.ts @@ -10,12 +10,16 @@ import { post } from 'lib/common/fetch' import { API_URL } from 'lib/constants' import { useCallback } from 'react' import { sqlKeys } from './keys' +import { noop } from 'lodash' + +export type Error = { code: number; message: string; requestId: string } export type ExecuteSqlVariables = { projectRef?: string connectionString?: string sql: string queryKey?: QueryKey + handleError?: (error: { code: number; message: string; requestId: string }) => any } export async function executeSql( @@ -24,7 +28,11 @@ export async function executeSql( connectionString, sql, queryKey, - }: Pick, + handleError, + }: Pick< + ExecuteSqlVariables, + 'projectRef' | 'connectionString' | 'sql' | 'queryKey' | 'handleError' + >, signal?: AbortSignal ) { if (!projectRef) { @@ -44,8 +52,13 @@ export async function executeSql( { query: sql }, { headers: Object.fromEntries(headers), signal } ) + if (response.error) { - throw response.error + if (handleError !== undefined) { + return handleError(response.error) + } else { + throw response.error + } } return { result: response } @@ -55,21 +68,22 @@ export type ExecuteSqlData = Awaited> export type ExecuteSqlError = unknown export const useExecuteSqlQuery = ( - { projectRef, connectionString, sql, queryKey }: ExecuteSqlVariables, + { projectRef, connectionString, sql, queryKey, handleError }: ExecuteSqlVariables, { enabled = true, ...options }: UseQueryOptions = {} ) => useQuery( sqlKeys.query(projectRef, queryKey ?? [md5(sql)]), - ({ signal }) => executeSql({ projectRef, connectionString, sql, queryKey }, signal), + ({ signal }) => + executeSql({ projectRef, connectionString, sql, queryKey, handleError }, signal), { enabled: enabled && typeof projectRef !== 'undefined', ...options } ) export const prefetchExecuteSql = ( client: QueryClient, - { projectRef, connectionString, sql, queryKey }: ExecuteSqlVariables + { projectRef, connectionString, sql, queryKey, handleError }: ExecuteSqlVariables ) => { return client.prefetchQuery(sqlKeys.query(projectRef, queryKey ?? [md5(sql)]), ({ signal }) => - executeSql({ projectRef, connectionString, sql, queryKey }, signal) + executeSql({ projectRef, connectionString, sql, queryKey, handleError }, signal) ) } @@ -89,13 +103,14 @@ export const useExecuteSqlPrefetch = () => { const client = useQueryClient() return useCallback( - ({ projectRef, connectionString, sql, queryKey }: ExecuteSqlVariables) => { + ({ projectRef, connectionString, sql, queryKey, handleError }: ExecuteSqlVariables) => { if (projectRef) { return prefetchExecuteSql(client, { projectRef, connectionString, sql, queryKey, + handleError, }) }