mirror of
https://github.com/supabase/supabase.git
synced 2026-10-05 09:25:06 +03:00
Merge pull request #6650 from supabase/chore/getlayout-refactor-2
chore: implement getLayout in ProjectLayout & DatabaseLayout
This commit is contained in:
18 files changed
+216
-216
No files matched your search
@@ -2,7 +2,7 @@ import { FC, ReactNode, useEffect, useState } from 'react'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
import { useRouter } from 'next/router'
|
||||
|
||||
import { useStore } from 'hooks'
|
||||
import { useStore, withAuth } from 'hooks'
|
||||
import BaseLayout from '../'
|
||||
import Error from 'components/ui/Error'
|
||||
import ProductMenu from 'components/ui/ProductMenu'
|
||||
@@ -63,4 +63,4 @@ const DatabaseLayout: FC<Props> = ({ title, children }) => {
|
||||
)
|
||||
}
|
||||
|
||||
export default observer(DatabaseLayout)
|
||||
export default withAuth(observer(DatabaseLayout))
|
||||
@@ -1,8 +1,8 @@
|
||||
import Head from 'next/head'
|
||||
import { FC, ReactNode } from 'react'
|
||||
import { FC, ReactNode, PropsWithChildren } from 'react'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
import { useRouter } from 'next/router'
|
||||
import { useStore } from 'hooks'
|
||||
import { useStore, withAuth } from 'hooks'
|
||||
import { PROJECT_STATUS } from 'lib/constants'
|
||||
|
||||
import Connecting from 'components/ui/Loading'
|
||||
@@ -17,12 +17,11 @@ interface Props {
|
||||
isLoading?: boolean
|
||||
product?: string
|
||||
productMenu?: ReactNode
|
||||
children: ReactNode
|
||||
hideHeader?: boolean
|
||||
hideIconBar?: boolean
|
||||
}
|
||||
|
||||
const ProjectLayout: FC<Props> = ({
|
||||
const ProjectLayout = ({
|
||||
title,
|
||||
isLoading = false,
|
||||
product = '',
|
||||
@@ -30,7 +29,7 @@ const ProjectLayout: FC<Props> = ({
|
||||
children,
|
||||
hideHeader = false,
|
||||
hideIconBar = false,
|
||||
}) => {
|
||||
}: PropsWithChildren<Props>) => {
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
@@ -49,7 +48,7 @@ const ProjectLayout: FC<Props> = ({
|
||||
|
||||
<main
|
||||
style={{ maxHeight: '100vh' }}
|
||||
className="w-full flex flex-col flex-1 overflow-x-hidden"
|
||||
className="flex w-full flex-1 flex-col overflow-x-hidden"
|
||||
>
|
||||
{!hideHeader && <LayoutHeader />}
|
||||
<ContentWrapper isLoading={isLoading}>{children}</ContentWrapper>
|
||||
@@ -59,7 +58,7 @@ const ProjectLayout: FC<Props> = ({
|
||||
)
|
||||
}
|
||||
|
||||
export default ProjectLayout
|
||||
export default withAuth(ProjectLayout)
|
||||
|
||||
interface MenuBarWrapperProps {
|
||||
isLoading: boolean
|
||||
|
||||
@@ -6,8 +6,8 @@ import Connecting from 'components/ui/Loading'
|
||||
|
||||
const PLATFORM_ONLY_PAGES = ['storage', 'reports', 'settings']
|
||||
|
||||
export function withAuth(
|
||||
WrappedComponent: ComponentType,
|
||||
export function withAuth<T>(
|
||||
WrappedComponent: ComponentType<T>,
|
||||
options?: {
|
||||
redirectTo: string
|
||||
redirectIfFound?: boolean
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
import { FC, useEffect } from 'react'
|
||||
import { useRouter } from 'next/router'
|
||||
import { withAuth } from 'hooks'
|
||||
import ProjectLayout from 'components/layouts'
|
||||
import { NextPageWithLayout } from 'types'
|
||||
|
||||
const ProjectBuildingPage: FC = () => {
|
||||
return (
|
||||
<ProjectLayout title="Project Building">
|
||||
<RedirectToDashboard />
|
||||
</ProjectLayout>
|
||||
)
|
||||
const ProjectBuildingPage: NextPageWithLayout = () => {
|
||||
return <RedirectToDashboard />
|
||||
}
|
||||
export default withAuth(ProjectBuildingPage)
|
||||
|
||||
ProjectBuildingPage.getLayout = (page) => (
|
||||
<ProjectLayout title="Project Building">{page}</ProjectLayout>
|
||||
)
|
||||
|
||||
export default ProjectBuildingPage
|
||||
|
||||
const RedirectToDashboard: FC = () => {
|
||||
const router = useRouter()
|
||||
@@ -27,5 +28,6 @@ const RedirectToDashboard: FC = () => {
|
||||
// just use normal router.push is enough
|
||||
router.push(`/project/${ref}`)
|
||||
}, [])
|
||||
|
||||
return null
|
||||
}
|
||||
@@ -1,27 +1,25 @@
|
||||
import React from 'react'
|
||||
import { NextPage } from 'next'
|
||||
import { useRouter } from 'next/router'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
import { withAuth } from 'hooks'
|
||||
import { DatabaseLayout } from 'components/layouts/'
|
||||
import { LogsTableName } from 'components/interfaces/Settings/Logs'
|
||||
import { DatabaseLayout } from 'components/layouts'
|
||||
import LogsPreviewer from 'components/interfaces/Settings/Logs/LogsPreviewer'
|
||||
import { NextPageWithLayout } from 'types'
|
||||
|
||||
export const LogPage: NextPage = () => {
|
||||
export const LogPage: NextPageWithLayout = () => {
|
||||
const router = useRouter()
|
||||
const { ref } = router.query
|
||||
|
||||
return (
|
||||
<DatabaseLayout>
|
||||
<LogsPreviewer
|
||||
projectRef={ref as string}
|
||||
condensedLayout={true}
|
||||
// @ts-ignore
|
||||
tableName={'edge_logs'}
|
||||
queryType={'api'}
|
||||
/>
|
||||
</DatabaseLayout>
|
||||
<LogsPreviewer
|
||||
projectRef={ref as string}
|
||||
condensedLayout={true}
|
||||
// @ts-ignore
|
||||
tableName={'edge_logs'}
|
||||
queryType={'api'}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
export default withAuth(observer(LogPage))
|
||||
LogPage.getLayout = (page) => <DatabaseLayout title="Database">{page}</DatabaseLayout>
|
||||
|
||||
export default observer(LogPage)
|
||||
@@ -1,27 +1,25 @@
|
||||
import { NextPage } from 'next'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
import { Typography } from '@supabase/ui'
|
||||
|
||||
import { withAuth } from 'hooks'
|
||||
import { DatabaseLayout } from 'components/layouts'
|
||||
import { BackupsList } from 'components/interfaces/Database'
|
||||
import { NextPageWithLayout } from 'types'
|
||||
|
||||
const DatabaseBackups: NextPage = () => {
|
||||
const DatabaseBackups: NextPageWithLayout = () => {
|
||||
return (
|
||||
<DatabaseLayout title="Database">
|
||||
<div className="flex">
|
||||
<div className="p-4 w-full my-2 max-w-4xl mx-auto space-y-8">
|
||||
<h3 className="text-2xl">Backups</h3>
|
||||
<div className="space-y-4">
|
||||
<p className="text-sm text-scale-1100">
|
||||
Projects are backed up daily and can be restored at any time.
|
||||
</p>
|
||||
<BackupsList />
|
||||
</div>
|
||||
<div className="flex">
|
||||
<div className="my-2 mx-auto w-full max-w-4xl space-y-8 p-4">
|
||||
<h3 className="text-2xl">Backups</h3>
|
||||
<div className="space-y-4">
|
||||
<p className="text-scale-1100 text-sm">
|
||||
Projects are backed up daily and can be restored at any time.
|
||||
</p>
|
||||
<BackupsList />
|
||||
</div>
|
||||
</div>
|
||||
</DatabaseLayout>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default withAuth(observer(DatabaseBackups))
|
||||
DatabaseBackups.getLayout = (page) => <DatabaseLayout title="Database">{page}</DatabaseLayout>
|
||||
|
||||
export default observer(DatabaseBackups)
|
||||
@@ -1,18 +1,17 @@
|
||||
import { NextPage } from 'next'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
|
||||
import { withAuth } from 'hooks'
|
||||
import { DatabaseLayout } from 'components/layouts'
|
||||
import { Extensions } from 'components/interfaces/Database'
|
||||
import { NextPageWithLayout } from 'types'
|
||||
|
||||
const DatabaseExtensions: NextPage = () => {
|
||||
const DatabaseExtensions: NextPageWithLayout = () => {
|
||||
return (
|
||||
<DatabaseLayout title="Database">
|
||||
<div className="p-4">
|
||||
<Extensions />
|
||||
</div>
|
||||
</DatabaseLayout>
|
||||
<div className="p-4">
|
||||
<Extensions />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default withAuth(observer(DatabaseExtensions))
|
||||
DatabaseExtensions.getLayout = (page) => <DatabaseLayout title="Database">{page}</DatabaseLayout>
|
||||
|
||||
export default observer(DatabaseExtensions)
|
||||
@@ -15,14 +15,15 @@ import {
|
||||
} from '@supabase/ui'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
|
||||
import { useStore, withAuth } from 'hooks'
|
||||
import { useStore } from 'hooks'
|
||||
import { DatabaseLayout } from 'components/layouts'
|
||||
import { CreateFunction, DeleteFunction } from 'components/interfaces/Database'
|
||||
import Table from 'components/to-be-cleaned/Table'
|
||||
import AlphaPreview from 'components/to-be-cleaned/AlphaPreview'
|
||||
import ProductEmptyState from 'components/to-be-cleaned/ProductEmptyState'
|
||||
import { NextPageWithLayout } from 'types'
|
||||
|
||||
const FunctionsPage: FC<any> = () => {
|
||||
const FunctionsPage: NextPageWithLayout = () => {
|
||||
const { meta, ui } = useStore()
|
||||
const [filterString, setFilterString] = useState<string>('')
|
||||
const [selectedFunction, setSelectedFunction] = useState<any>()
|
||||
@@ -55,7 +56,7 @@ const FunctionsPage: FC<any> = () => {
|
||||
}
|
||||
|
||||
return (
|
||||
<DatabaseLayout title="Database">
|
||||
<>
|
||||
<PageLayout
|
||||
filterString={filterString}
|
||||
setFilterString={setFilterString}
|
||||
@@ -73,11 +74,13 @@ const FunctionsPage: FC<any> = () => {
|
||||
visible={showDeleteFunctionForm}
|
||||
setVisible={setShowDeleteFunctionForm}
|
||||
/>
|
||||
</DatabaseLayout>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default withAuth(observer(FunctionsPage))
|
||||
FunctionsPage.getLayout = (page) => <DatabaseLayout title="Database">{page}</DatabaseLayout>
|
||||
|
||||
export default observer(FunctionsPage)
|
||||
|
||||
const PageLayout: FC<any> = observer(
|
||||
({
|
||||
@@ -96,7 +99,7 @@ const PageLayout: FC<any> = observer(
|
||||
|
||||
if (meta.functions.isLoading) {
|
||||
return (
|
||||
<div className="w-full h-full flex items-center justify-center space-x-2">
|
||||
<div className="flex h-full w-full items-center justify-center space-x-2">
|
||||
<IconLoader className="animate-spin" size={14} />
|
||||
<Typography.Text>Loading functions...</Typography.Text>
|
||||
</div>
|
||||
@@ -122,18 +125,18 @@ const PageLayout: FC<any> = observer(
|
||||
onClickCta={() => createFunction()}
|
||||
>
|
||||
<AlphaPreview />
|
||||
<p className="text-sm text-scale-1100">
|
||||
<p className="text-scale-1100 text-sm">
|
||||
PostgreSQL functions, also known as stored procedures, is a set of SQL and
|
||||
procedural commands such as declarations, assignments, loops, flow-of-control, etc.
|
||||
</p>
|
||||
<p className="text-sm text-scale-1100">
|
||||
<p className="text-scale-1100 text-sm">
|
||||
It's stored on the database server and can be invoked using the SQL interface.
|
||||
</p>
|
||||
</ProductEmptyState>
|
||||
</div>
|
||||
) : (
|
||||
<div className="w-full py-4 space-y-4">
|
||||
<div className="flex justify-between items-center px-6">
|
||||
<div className="w-full space-y-4 py-4">
|
||||
<div className="flex items-center justify-between px-6">
|
||||
<Input
|
||||
placeholder="Filter by name"
|
||||
size="small"
|
||||
@@ -144,7 +147,7 @@ const PageLayout: FC<any> = observer(
|
||||
<Button onClick={() => createFunction()}>Create a new function</Button>
|
||||
</div>
|
||||
{filteredFunctions.length <= 0 && (
|
||||
<div className="border dark:border-dark rounded p-6 max-w-lg mx-auto flex justify-center space-x-3 items-center shadow-md">
|
||||
<div className="dark:border-dark mx-auto flex max-w-lg items-center justify-center space-x-3 rounded border p-6 shadow-md">
|
||||
<Typography.Text>No results match your filter query</Typography.Text>
|
||||
<Button type="outline" onClick={() => setFilterString('')}>
|
||||
Reset filter
|
||||
@@ -178,8 +181,8 @@ const SchemaTable: FC<SchemaTableProps> = observer(
|
||||
({ schema, filterString, editFunction = () => {}, deleteFunction = () => {} }) => {
|
||||
return (
|
||||
<div key={schema} className="">
|
||||
<div className="sticky top-0 backdrop-filter backdrop-blur">
|
||||
<div className="flex space-x-1 items-baseline py-2 px-6">
|
||||
<div className="sticky top-0 backdrop-blur backdrop-filter">
|
||||
<div className="flex items-baseline space-x-1 py-2 px-6">
|
||||
<Typography.Title level={5} className="opacity-50">
|
||||
schema
|
||||
</Typography.Title>
|
||||
|
||||
@@ -10,20 +10,21 @@ import { useStore, withAuth } from 'hooks'
|
||||
import { get } from 'lib/common/fetch'
|
||||
import { API_URL } from 'lib/constants'
|
||||
import { DatabaseLayout } from 'components/layouts'
|
||||
import { NextPageWithLayout } from 'types'
|
||||
|
||||
const FunctionsPage = () => {
|
||||
const FunctionsPage: NextPageWithLayout = () => {
|
||||
return (
|
||||
<DatabaseLayout title="Hooks">
|
||||
<div className="flex">
|
||||
<div className="w-full my-4">
|
||||
<HookLogs />
|
||||
</div>
|
||||
<div className="flex">
|
||||
<div className="my-4 w-full">
|
||||
<HookLogs />
|
||||
</div>
|
||||
</DatabaseLayout>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default withAuth(observer(FunctionsPage))
|
||||
FunctionsPage.getLayout = (page) => <DatabaseLayout title="Hooks">{page}</DatabaseLayout>
|
||||
|
||||
export default observer(FunctionsPage)
|
||||
|
||||
const HookLogs: FC<any> = observer(() => {
|
||||
const router = useRouter()
|
||||
@@ -83,8 +84,8 @@ const HookLogs: FC<any> = observer(() => {
|
||||
<div className="divide-y-2 ">
|
||||
{logsData?.map((log: any) => {
|
||||
return (
|
||||
<div className="space-y-1 flex flex-col py-4 px-6">
|
||||
<div className="flex justify-between items-center">
|
||||
<div className="flex flex-col space-y-1 py-4 px-6">
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="space-x-3">
|
||||
<Typography.Text className="font-mono" type="secondary">
|
||||
[{log.method}]
|
||||
|
||||
@@ -15,7 +15,7 @@ import {
|
||||
IconLoader,
|
||||
} from '@supabase/ui'
|
||||
|
||||
import { useStore, withAuth } from 'hooks'
|
||||
import { useStore } from 'hooks'
|
||||
import { API_URL } from 'lib/constants'
|
||||
import { post } from 'lib/common/fetch'
|
||||
import { DatabaseLayout } from 'components/layouts'
|
||||
@@ -24,12 +24,13 @@ import AlphaPreview from 'components/to-be-cleaned/AlphaPreview'
|
||||
import ProductEmptyState from 'components/to-be-cleaned/ProductEmptyState'
|
||||
import CreateHook from 'components/interfaces/Database/Hooks/CreateHook'
|
||||
import DeleteHook from 'components/interfaces/Database/Hooks/DeleteHook'
|
||||
import { NextPageWithLayout } from 'types'
|
||||
|
||||
function isHooksEnabled(schemas: any): boolean {
|
||||
return schemas.some((schema: any) => schema.name === 'supabase_functions')
|
||||
}
|
||||
|
||||
const HooksPage: FC<any> = () => {
|
||||
const HooksPage: NextPageWithLayout = () => {
|
||||
const { meta, ui } = useStore()
|
||||
|
||||
const router = useRouter()
|
||||
@@ -79,7 +80,7 @@ const HooksPage: FC<any> = () => {
|
||||
}
|
||||
|
||||
return (
|
||||
<DatabaseLayout title="Triggers">
|
||||
<>
|
||||
<TriggersList
|
||||
hooksEnabled={hooksEnabled}
|
||||
filterString={filterString}
|
||||
@@ -99,11 +100,13 @@ const HooksPage: FC<any> = () => {
|
||||
visible={showDeleteHookForm}
|
||||
setVisible={setShowDeleteHookForm}
|
||||
/>
|
||||
</DatabaseLayout>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default withAuth(observer(HooksPage))
|
||||
HooksPage.getLayout = (page) => <DatabaseLayout title="Hooks">{page}</DatabaseLayout>
|
||||
|
||||
export default observer(HooksPage)
|
||||
|
||||
const TriggersList: FC<any> = observer(
|
||||
({
|
||||
@@ -137,7 +140,7 @@ const TriggersList: FC<any> = observer(
|
||||
onClickCta={() => enableHooks()}
|
||||
>
|
||||
<AlphaPreview />
|
||||
<p className="text-sm text-scale-1100">Enable hooks on your project.</p>
|
||||
<p className="text-scale-1100 text-sm">Enable hooks on your project.</p>
|
||||
</ProductEmptyState>
|
||||
)}
|
||||
</>
|
||||
@@ -146,7 +149,7 @@ const TriggersList: FC<any> = observer(
|
||||
|
||||
if (meta.hooks.isLoading) {
|
||||
return (
|
||||
<div className="w-full h-full flex items-center justify-center space-x-2">
|
||||
<div className="flex h-full w-full items-center justify-center space-x-2">
|
||||
<IconLoader className="animate-spin" size={14} />
|
||||
<Typography.Text>Loading hooks...</Typography.Text>
|
||||
</div>
|
||||
@@ -172,15 +175,15 @@ const TriggersList: FC<any> = observer(
|
||||
onClickCta={() => createHook()}
|
||||
>
|
||||
<AlphaPreview />
|
||||
<p className="text-sm text-scale-1100">
|
||||
<p className="text-scale-1100 text-sm">
|
||||
Function Hooks can be used to trigger serverless functions or send requests to an
|
||||
HTTP endpoint.
|
||||
</p>
|
||||
</ProductEmptyState>
|
||||
</div>
|
||||
) : (
|
||||
<div className="w-full py-4 space-y-4">
|
||||
<div className="flex justify-between items-center px-6">
|
||||
<div className="w-full space-y-4 py-4">
|
||||
<div className="flex items-center justify-between px-6">
|
||||
<Input
|
||||
placeholder="Filter by name"
|
||||
size="small"
|
||||
@@ -191,7 +194,7 @@ const TriggersList: FC<any> = observer(
|
||||
<Button onClick={() => createHook()}>Create a new hook</Button>
|
||||
</div>
|
||||
{filteredHooks.length <= 0 && (
|
||||
<div className="border dark:border-dark rounded p-6 max-w-lg mx-auto flex justify-center space-x-3 items-center shadow-md">
|
||||
<div className="dark:border-dark mx-auto flex max-w-lg items-center justify-center space-x-3 rounded border p-6 shadow-md">
|
||||
<Typography.Text>No results match your filter query</Typography.Text>
|
||||
<Button type="outline" onClick={() => setFilterString('')}>
|
||||
Reset filter
|
||||
@@ -225,8 +228,8 @@ const SchemaTable: FC<SchemaTableProps> = observer(
|
||||
({ schema, filterString, editHook = () => {}, deleteHook = () => {} }) => {
|
||||
return (
|
||||
<div key={schema} className="">
|
||||
<div className="sticky top-0 backdrop-filter backdrop-blur">
|
||||
<div className="flex space-x-1 items-baseline py-2 px-6">
|
||||
<div className="sticky top-0 backdrop-blur backdrop-filter">
|
||||
<div className="flex items-baseline space-x-1 py-2 px-6">
|
||||
<Typography.Title level={5} className="opacity-50">
|
||||
schema
|
||||
</Typography.Title>
|
||||
@@ -297,7 +300,7 @@ const HookList: FC<HookListProps> = observer(
|
||||
<Table.td className="space-x-2">
|
||||
<Typography.Text>{x.name}</Typography.Text>
|
||||
</Table.td>
|
||||
<Table.td className="space-x-2 hidden lg:table-cell">
|
||||
<Table.td className="hidden space-x-2 lg:table-cell">
|
||||
<Typography.Text>{x.table}</Typography.Text>
|
||||
</Table.td>
|
||||
<Table.td className="hidden xl:table-cell">
|
||||
@@ -313,7 +316,7 @@ const HookList: FC<HookListProps> = observer(
|
||||
</Typography.Text>
|
||||
</Table.td>
|
||||
<Table.td className="text-right">
|
||||
<div className="flex gap-4 justify-end">
|
||||
<div className="flex justify-end gap-4">
|
||||
{/* <Link href={`/project/${_pageState.project.ref}/database/hooks/${x.id}/logs`}>
|
||||
<Button type="default">Logs</Button>
|
||||
</Link> */}
|
||||
|
||||
@@ -1,15 +1,11 @@
|
||||
import { NextPage } from 'next'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
|
||||
import { withAuth } from 'hooks'
|
||||
import { DatabaseLayout } from 'components/layouts'
|
||||
import { NextPageWithLayout } from 'types'
|
||||
|
||||
const Database: NextPage = () => {
|
||||
return (
|
||||
<DatabaseLayout title="Database">
|
||||
<>{/* <h1>Use this as a page template for database</h1> */}</>
|
||||
</DatabaseLayout>
|
||||
)
|
||||
const Database: NextPageWithLayout = () => {
|
||||
return <>{/* <h1>Use this as a page template for database</h1> */}</>
|
||||
}
|
||||
|
||||
export default withAuth(observer(Database))
|
||||
Database.getLayout = (page) => <DatabaseLayout title="Database">{page}</DatabaseLayout>
|
||||
|
||||
export default observer(Database)
|
||||
@@ -1,20 +1,19 @@
|
||||
import { NextPage } from 'next'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
|
||||
import { withAuth } from 'hooks'
|
||||
import { DatabaseLayout } from 'components/layouts'
|
||||
import { BouncerSettings } from 'components/interfaces/Database'
|
||||
import { NextPageWithLayout } from 'types'
|
||||
|
||||
const DatabasePooling: NextPage = () => {
|
||||
const DatabasePooling: NextPageWithLayout = () => {
|
||||
return (
|
||||
<DatabaseLayout title="Database">
|
||||
<div className="content w-full h-full overflow-y-auto">
|
||||
<div className="mx-auto h-full w-full">
|
||||
<BouncerSettings />
|
||||
</div>
|
||||
<div className="content h-full w-full overflow-y-auto">
|
||||
<div className="mx-auto h-full w-full">
|
||||
<BouncerSettings />
|
||||
</div>
|
||||
</DatabaseLayout>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default withAuth(observer(DatabasePooling))
|
||||
DatabasePooling.getLayout = (page) => <DatabaseLayout title="Database">{page}</DatabaseLayout>
|
||||
|
||||
export default observer(DatabasePooling)
|
||||
@@ -1,27 +1,25 @@
|
||||
import React from 'react'
|
||||
import { NextPage } from 'next'
|
||||
import { useRouter } from 'next/router'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
import { withAuth } from 'hooks'
|
||||
import { DatabaseLayout } from 'components/layouts/'
|
||||
import { LogsTableName } from 'components/interfaces/Settings/Logs'
|
||||
import { DatabaseLayout } from 'components/layouts'
|
||||
import LogsPreviewer from 'components/interfaces/Settings/Logs/LogsPreviewer'
|
||||
import { NextPageWithLayout } from 'types'
|
||||
|
||||
export const LogPage: NextPage = () => {
|
||||
export const LogPage: NextPageWithLayout = () => {
|
||||
const router = useRouter()
|
||||
const { ref } = router.query
|
||||
|
||||
return (
|
||||
<DatabaseLayout>
|
||||
<LogsPreviewer
|
||||
projectRef={ref as string}
|
||||
condensedLayout={true}
|
||||
// @ts-ignore
|
||||
tableName={'postgres_logs'}
|
||||
queryType={'database'}
|
||||
/>
|
||||
</DatabaseLayout>
|
||||
<LogsPreviewer
|
||||
projectRef={ref as string}
|
||||
condensedLayout={true}
|
||||
// @ts-ignore
|
||||
tableName={'postgres_logs'}
|
||||
queryType={'database'}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
export default withAuth(observer(LogPage))
|
||||
LogPage.getLayout = (page) => <DatabaseLayout title="Database">{page}</DatabaseLayout>
|
||||
|
||||
export default observer(LogPage)
|
||||
@@ -1,29 +1,29 @@
|
||||
import { NextPage } from 'next'
|
||||
import { useState } from 'react'
|
||||
import { isUndefined } from 'lodash'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
|
||||
import { withAuth } from 'hooks'
|
||||
import { DatabaseLayout } from 'components/layouts'
|
||||
import { PublicationsList, PublicationsTables } from 'components/interfaces/Database'
|
||||
import { NextPageWithLayout } from 'types'
|
||||
|
||||
const DatabaseReplication: NextPage = () => {
|
||||
const DatabaseReplication: NextPageWithLayout = () => {
|
||||
const [selectedPublication, setSelectedPublication] = useState<any>()
|
||||
|
||||
return (
|
||||
<DatabaseLayout title="Database">
|
||||
<div className="p-4">
|
||||
{isUndefined(selectedPublication) ? (
|
||||
<PublicationsList onSelectPublication={setSelectedPublication} />
|
||||
) : (
|
||||
<PublicationsTables
|
||||
selectedPublication={selectedPublication}
|
||||
onSelectBack={() => setSelectedPublication(undefined)}
|
||||
onPublicationUpdated={setSelectedPublication}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</DatabaseLayout>
|
||||
<div className="p-4">
|
||||
{isUndefined(selectedPublication) ? (
|
||||
<PublicationsList onSelectPublication={setSelectedPublication} />
|
||||
) : (
|
||||
<PublicationsTables
|
||||
selectedPublication={selectedPublication}
|
||||
onSelectBack={() => setSelectedPublication(undefined)}
|
||||
onPublicationUpdated={setSelectedPublication}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default withAuth(observer(DatabaseReplication))
|
||||
DatabaseReplication.getLayout = (page) => <DatabaseLayout title="Database">{page}</DatabaseLayout>
|
||||
|
||||
export default observer(DatabaseReplication)
|
||||
@@ -1,29 +1,28 @@
|
||||
import { useState } from 'react'
|
||||
import { NextPage } from 'next'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
import { isUndefined } from 'lodash'
|
||||
|
||||
import { withAuth } from 'hooks'
|
||||
import { DatabaseLayout } from 'components/layouts'
|
||||
import { RolesList, RolesSettings } from 'components/interfaces/Database'
|
||||
import { NextPageWithLayout } from 'types'
|
||||
|
||||
const DatabaseRoles: NextPage = () => {
|
||||
const DatabaseRoles: NextPageWithLayout = () => {
|
||||
const [selectedRole, setSelectedRole] = useState<any>()
|
||||
|
||||
return (
|
||||
<DatabaseLayout title="Database">
|
||||
<div className="p-4">
|
||||
{isUndefined(selectedRole) ? (
|
||||
<RolesList onSelectRole={setSelectedRole} />
|
||||
) : (
|
||||
<RolesSettings
|
||||
selectedRole={selectedRole}
|
||||
onSelectBack={() => setSelectedRole(undefined)}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</DatabaseLayout>
|
||||
<div className="p-4">
|
||||
{isUndefined(selectedRole) ? (
|
||||
<RolesList onSelectRole={setSelectedRole} />
|
||||
) : (
|
||||
<RolesSettings
|
||||
selectedRole={selectedRole}
|
||||
onSelectBack={() => setSelectedRole(undefined)}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default withAuth(observer(DatabaseRoles))
|
||||
DatabaseRoles.getLayout = (page) => <DatabaseLayout title="Database">{page}</DatabaseLayout>
|
||||
|
||||
export default observer(DatabaseRoles)
|
||||
@@ -1,18 +1,18 @@
|
||||
import { NextPage } from 'next'
|
||||
import { useState } from 'react'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
import { isUndefined } from 'lodash'
|
||||
import { PostgresColumn, PostgresTable } from '@supabase/postgres-meta'
|
||||
import { Modal } from '@supabase/ui'
|
||||
|
||||
import { withAuth, useStore } from 'hooks'
|
||||
import { useStore } from 'hooks'
|
||||
|
||||
import { DatabaseLayout } from 'components/layouts'
|
||||
import ConfirmationModal from 'components/ui/ConfirmationModal'
|
||||
import { TableList, ColumnList } from 'components/interfaces/Database'
|
||||
import { SidePanelEditor } from 'components/interfaces/TableGridEditor'
|
||||
import { NextPageWithLayout } from 'types'
|
||||
|
||||
const DatabaseTables: NextPage = () => {
|
||||
const DatabaseTables: NextPageWithLayout = () => {
|
||||
const { meta, ui } = useStore()
|
||||
|
||||
const [isDeleting, setIsDeleting] = useState<boolean>(false)
|
||||
@@ -111,7 +111,7 @@ const DatabaseTables: NextPage = () => {
|
||||
}
|
||||
|
||||
return (
|
||||
<DatabaseLayout title="Database">
|
||||
<>
|
||||
<div className="p-4">
|
||||
{isUndefined(selectedTable) ? (
|
||||
<TableList
|
||||
@@ -136,7 +136,7 @@ const DatabaseTables: NextPage = () => {
|
||||
header={`Confirm deletion of table "${selectedTableToDelete?.name}"`}
|
||||
children={
|
||||
<Modal.Content>
|
||||
<p className="py-4 text-sm text-scale-1100">
|
||||
<p className="text-scale-1100 py-4 text-sm">
|
||||
Are you sure you want to delete the selected table? This action cannot be undone.
|
||||
</p>
|
||||
</Modal.Content>
|
||||
@@ -152,7 +152,7 @@ const DatabaseTables: NextPage = () => {
|
||||
header={`Confirm deletion of column "${selectedColumnToDelete?.name}"`}
|
||||
children={
|
||||
<Modal.Content>
|
||||
<p className="py-4 text-sm text-scale-1100">
|
||||
<p className="text-scale-1100 py-4 text-sm">
|
||||
Are you sure you want to delete the selected column? This action cannot be undone.
|
||||
</p>
|
||||
</Modal.Content>
|
||||
@@ -171,8 +171,10 @@ const DatabaseTables: NextPage = () => {
|
||||
selectedColumnToEdit={selectedColumnToEdit}
|
||||
selectedTableToEdit={selectedTableToEdit}
|
||||
/>
|
||||
</DatabaseLayout>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default withAuth(observer(DatabaseTables))
|
||||
DatabaseTables.getLayout = (page) => <DatabaseLayout title="Database">{page}</DatabaseLayout>
|
||||
|
||||
export default observer(DatabaseTables)
|
||||
@@ -14,14 +14,15 @@ import {
|
||||
} from '@supabase/ui'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
|
||||
import { useStore, withAuth } from 'hooks'
|
||||
import { useStore } from 'hooks'
|
||||
import { DatabaseLayout } from 'components/layouts'
|
||||
import Table from 'components/to-be-cleaned/Table'
|
||||
import AlphaPreview from 'components/to-be-cleaned/AlphaPreview'
|
||||
import ProductEmptyState from 'components/to-be-cleaned/ProductEmptyState'
|
||||
import { CreateTrigger, DeleteTrigger } from 'components/interfaces/Database'
|
||||
import { NextPageWithLayout } from 'types'
|
||||
|
||||
const TriggersPage: FC<any> = () => {
|
||||
const TriggersPage: NextPageWithLayout = () => {
|
||||
const { meta, ui } = useStore()
|
||||
|
||||
const [filterString, setFilterString] = useState<string>('')
|
||||
@@ -55,7 +56,7 @@ const TriggersPage: FC<any> = () => {
|
||||
}
|
||||
|
||||
return (
|
||||
<DatabaseLayout title="Database">
|
||||
<>
|
||||
<TriggersList
|
||||
filterString={filterString}
|
||||
setFilterString={setFilterString}
|
||||
@@ -73,11 +74,13 @@ const TriggersPage: FC<any> = () => {
|
||||
visible={showDeleteTriggerForm}
|
||||
setVisible={setShowDeleteTriggerForm}
|
||||
/>
|
||||
</DatabaseLayout>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default withAuth(observer(TriggersPage))
|
||||
TriggersPage.getLayout = (page) => <DatabaseLayout title="Database">{page}</DatabaseLayout>
|
||||
|
||||
export default observer(TriggersPage)
|
||||
|
||||
const TriggersList: FC<any> = observer(
|
||||
({
|
||||
@@ -96,7 +99,7 @@ const TriggersList: FC<any> = observer(
|
||||
|
||||
if (meta.triggers.isLoading) {
|
||||
return (
|
||||
<div className="w-full h-full flex items-center justify-center space-x-2">
|
||||
<div className="flex h-full w-full items-center justify-center space-x-2">
|
||||
<IconLoader className="animate-spin" size={14} />
|
||||
<Typography.Text>Loading triggers...</Typography.Text>
|
||||
</div>
|
||||
@@ -122,19 +125,19 @@ const TriggersList: FC<any> = observer(
|
||||
onClickCta={() => createTrigger()}
|
||||
>
|
||||
<AlphaPreview />
|
||||
<p className="text-sm text-scale-1100">
|
||||
<p className="text-scale-1100 text-sm">
|
||||
A PostgreSQL trigger is a function invoked automatically whenever an event
|
||||
associated with a table occurs.
|
||||
</p>
|
||||
<p className="text-sm text-scale-1100">
|
||||
<p className="text-scale-1100 text-sm">
|
||||
An event could be any of the following: INSERT, UPDATE, DELETE. A trigger is a
|
||||
special user-defined function associated with a table.
|
||||
</p>
|
||||
</ProductEmptyState>
|
||||
</div>
|
||||
) : (
|
||||
<div className="w-full py-4 space-y-4">
|
||||
<div className="flex justify-between items-center px-6">
|
||||
<div className="w-full space-y-4 py-4">
|
||||
<div className="flex items-center justify-between px-6">
|
||||
<Input
|
||||
placeholder="Filter by name"
|
||||
size="small"
|
||||
@@ -145,7 +148,7 @@ const TriggersList: FC<any> = observer(
|
||||
<Button onClick={() => createTrigger()}>Create a new trigger</Button>
|
||||
</div>
|
||||
{filteredTriggers.length <= 0 && (
|
||||
<div className="border dark:border-dark rounded p-6 max-w-lg mx-auto flex justify-center space-x-3 items-center shadow-md">
|
||||
<div className="dark:border-dark mx-auto flex max-w-lg items-center justify-center space-x-3 rounded border p-6 shadow-md">
|
||||
<Typography.Text>No results match your filter query</Typography.Text>
|
||||
<Button type="outline" onClick={() => setFilterString('')}>
|
||||
Reset filter
|
||||
@@ -179,8 +182,8 @@ const SchemaTable: FC<SchemaTableProps> = observer(
|
||||
({ filterString, schema, editTrigger, deleteTrigger }) => {
|
||||
return (
|
||||
<div key={schema} className="">
|
||||
<div className="sticky top-0 backdrop-filter backdrop-blur">
|
||||
<div className="flex space-x-1 items-baseline py-2 px-6">
|
||||
<div className="sticky top-0 backdrop-blur backdrop-filter">
|
||||
<div className="flex items-baseline space-x-1 py-2 px-6">
|
||||
<Typography.Title level={5} className="opacity-50">
|
||||
schema
|
||||
</Typography.Title>
|
||||
@@ -255,7 +258,7 @@ const TriggerList: FC<TriggerListProps> = observer(
|
||||
<Table.td className="hidden lg:table-cell">
|
||||
<Typography.Text>{x.table}</Typography.Text>
|
||||
</Table.td>
|
||||
<Table.td className="space-x-2 hidden xl:table-cell">
|
||||
<Table.td className="hidden space-x-2 xl:table-cell">
|
||||
<div className="flex flex-col">
|
||||
<Typography.Text>{x.function_name}</Typography.Text>
|
||||
<Typography.Text type="secondary">{x.function_schema}</Typography.Text>
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
import { NextPage } from 'next'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
import { Typography } from '@supabase/ui'
|
||||
import { useStore, withAuth } from 'hooks'
|
||||
import { useStore } from 'hooks'
|
||||
import { ExampleProject, ClientLibrary } from 'components/interfaces/Home'
|
||||
import { CLIENT_LIBRARIES, EXAMPLE_PROJECTS } from 'components/interfaces/Home/Home.constants'
|
||||
import { IS_PLATFORM } from 'lib/constants'
|
||||
import ProjectLayout from 'components/layouts'
|
||||
import ProjectUsageSection from 'components/interfaces/Home/ProjectUsageSection'
|
||||
import { NextPageWithLayout } from 'types'
|
||||
|
||||
const Home: NextPage = () => {
|
||||
const Home: NextPageWithLayout = () => {
|
||||
const { ui } = useStore()
|
||||
|
||||
const project = ui.selectedProject
|
||||
@@ -18,35 +18,35 @@ const Home: NextPage = () => {
|
||||
: 'Welcome to your project'
|
||||
|
||||
return (
|
||||
<ProjectLayout>
|
||||
<div className="max-w-7xl mx-auto w-full my-16 space-y-16">
|
||||
<div className="mx-6 flex space-x-6 items-center">
|
||||
<h1 className="text-3xl">{projectName}</h1>
|
||||
<div className="mx-auto my-16 w-full max-w-7xl space-y-16">
|
||||
<div className="mx-6 flex items-center space-x-6">
|
||||
<h1 className="text-3xl">{projectName}</h1>
|
||||
</div>
|
||||
{IS_PLATFORM && <ProjectUsageSection />}
|
||||
<div className="space-y-8">
|
||||
<div className="mx-6">
|
||||
<Typography.Title level={4}>Client libraries</Typography.Title>
|
||||
</div>
|
||||
{IS_PLATFORM && <ProjectUsageSection />}
|
||||
<div className="space-y-8">
|
||||
<div className="mx-6">
|
||||
<Typography.Title level={4}>Client libraries</Typography.Title>
|
||||
</div>
|
||||
<div className="mx-6 grid md:grid-cols-3 gap-12 mb-12">
|
||||
{CLIENT_LIBRARIES.map((library) => (
|
||||
<ClientLibrary key={library.language} {...library} />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<div className="space-y-8">
|
||||
<div className="mx-6">
|
||||
<Typography.Title level={4}>Example projects</Typography.Title>
|
||||
</div>
|
||||
<div className="mx-6 grid md:grid-cols-2 lg:grid-cols-3 gap-8">
|
||||
{EXAMPLE_PROJECTS.map((project) => (
|
||||
<ExampleProject key={project.url} {...project} />
|
||||
))}
|
||||
</div>
|
||||
<div className="mx-6 mb-12 grid gap-12 md:grid-cols-3">
|
||||
{CLIENT_LIBRARIES.map((library) => (
|
||||
<ClientLibrary key={library.language} {...library} />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</ProjectLayout>
|
||||
<div className="space-y-8">
|
||||
<div className="mx-6">
|
||||
<Typography.Title level={4}>Example projects</Typography.Title>
|
||||
</div>
|
||||
<div className="mx-6 grid gap-8 md:grid-cols-2 lg:grid-cols-3">
|
||||
{EXAMPLE_PROJECTS.map((project) => (
|
||||
<ExampleProject key={project.url} {...project} />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default withAuth(observer(Home))
|
||||
Home.getLayout = (page) => <ProjectLayout>{page}</ProjectLayout>
|
||||
|
||||
export default observer(Home)
|
||||
Reference in new issue
Block a user