mirror of
https://github.com/supabase/supabase.git
synced 2026-10-05 17:35:10 +03:00
Move logs explorer to new logs route
This commit is contained in:
1 parent
044df61b7a
commit
acc14fd3cb
14 files changed
+195
-113
No files matched your search
@@ -1,3 +1,3 @@
|
||||
const MockLayout = jest.fn().mockImplementation(({ children }) => <>{children}</>)
|
||||
export const LogsExplorerLayout = MockLayout
|
||||
export const LogsLayout = MockLayout
|
||||
export default MockLayout
|
||||
@@ -8,7 +8,7 @@ interface TabItem {
|
||||
}
|
||||
const LogsNavigation = () => {
|
||||
const router = useRouter()
|
||||
const activeRoute = router.pathname.split('/')[4]
|
||||
const activeRoute = router.pathname.split('/')[5]
|
||||
const { ref } = router.query
|
||||
|
||||
const indexRoute = 'query'
|
||||
@@ -27,7 +27,7 @@ const LogsNavigation = () => {
|
||||
size="medium"
|
||||
activeId={!activeRoute ? indexRoute : activeRoute}
|
||||
onClick={(e: string) => {
|
||||
router.push(`/project/${ref}/logs-explorer/${e === indexRoute ? '' : e}`)
|
||||
router.push(`/project/${ref}/logs/explorer/${e === indexRoute ? '' : e}`)
|
||||
}}
|
||||
>
|
||||
{tabs.map((item) => (
|
||||
|
||||
@@ -63,12 +63,6 @@ export const generateDatabaseMenu = (project?: Project): ProductMenuGroup[] => {
|
||||
{
|
||||
title: 'Logs and Usage',
|
||||
items: [
|
||||
{
|
||||
name: 'API logs',
|
||||
key: 'api-logs',
|
||||
url: `/project/${ref}/database/api-logs`,
|
||||
items: [],
|
||||
},
|
||||
...(reportsOverview
|
||||
? [
|
||||
{
|
||||
@@ -79,22 +73,6 @@ export const generateDatabaseMenu = (project?: Project): ProductMenuGroup[] => {
|
||||
},
|
||||
]
|
||||
: []),
|
||||
{
|
||||
name: 'Postgres logs',
|
||||
key: 'postgres-logs',
|
||||
url: `/project/${ref}/database/postgres-logs`,
|
||||
items: [],
|
||||
},
|
||||
...(logsRealtime
|
||||
? [
|
||||
{
|
||||
name: 'Realtime logs',
|
||||
key: 'realtime-logs',
|
||||
url: `/project/${ref}/database/realtime-logs`,
|
||||
items: [],
|
||||
},
|
||||
]
|
||||
: []),
|
||||
],
|
||||
},
|
||||
]
|
||||
|
||||
@@ -1,64 +0,0 @@
|
||||
import { FC, useEffect, ReactNode } from 'react'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
import { Badge, IconList, Loading } from 'ui'
|
||||
import { PermissionAction } from '@supabase/shared-types/out/constants'
|
||||
|
||||
import { checkPermissions, useStore, withAuth } from 'hooks'
|
||||
import BaseLayout from 'components/layouts'
|
||||
import NoPermission from 'components/ui/NoPermission'
|
||||
import LogsNavigation from 'components/interfaces/Settings/Logs/LogsNavigation'
|
||||
|
||||
interface Props {
|
||||
subtitle?: ReactNode
|
||||
children?: ReactNode
|
||||
}
|
||||
|
||||
const PageLayout: FC<Props> = ({ subtitle, children }) => {
|
||||
const canUseLogsExplorer = checkPermissions(PermissionAction.ANALYTICS_READ, 'logflare')
|
||||
|
||||
if (!canUseLogsExplorer) {
|
||||
return (
|
||||
<BaseLayout>
|
||||
<main style={{ maxHeight: '100vh' }} className="flex-1 overflow-y-auto">
|
||||
<NoPermission isFullPage resourceText="access your project's logs explorer" />
|
||||
</main>
|
||||
</BaseLayout>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<BaseLayout>
|
||||
<div className="flex h-full flex-grow flex-col py-6">
|
||||
<div
|
||||
className={[
|
||||
'mx-auto flex w-full flex-col gap-4 px-5 transition-all',
|
||||
'1xl:px-28 lg:px-16 xl:px-24 2xl:px-32',
|
||||
].join(' ')}
|
||||
>
|
||||
<div className="flex items-center gap-3">
|
||||
<div
|
||||
className="flex h-6 w-6 items-center justify-center rounded border
|
||||
border-brand-600 bg-brand-300 text-brand-900
|
||||
"
|
||||
>
|
||||
<IconList size={14} strokeWidth={3} />
|
||||
</div>
|
||||
<h1 className="text-2xl text-scale-1200">Logs Explorer</h1>
|
||||
{subtitle && <Badge color="scale">{subtitle}</Badge>}
|
||||
</div>
|
||||
<LogsNavigation />
|
||||
</div>
|
||||
<div
|
||||
className={[
|
||||
'mx-auto flex h-full w-full flex-grow flex-col gap-4 transition-all',
|
||||
'1xl:px-28 px-5 lg:px-16 2xl:px-32',
|
||||
].join(' ')}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
</BaseLayout>
|
||||
)
|
||||
}
|
||||
|
||||
export default withAuth(observer(PageLayout))
|
||||
@@ -0,0 +1,47 @@
|
||||
import { FC, ReactNode } from 'react'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
import { PermissionAction } from '@supabase/shared-types/out/constants'
|
||||
import { useRouter } from 'next/router'
|
||||
import { checkPermissions, useStore, withAuth } from 'hooks'
|
||||
import BaseLayout from 'components/layouts'
|
||||
import NoPermission from 'components/ui/NoPermission'
|
||||
import { generateLogsMenu } from './LogsMenu.utils'
|
||||
import ProductMenu from 'components/ui/ProductMenu'
|
||||
|
||||
interface Props {
|
||||
subtitle?: ReactNode
|
||||
children?: ReactNode
|
||||
}
|
||||
|
||||
const LogsLayout: FC<Props> = ({ subtitle, children }) => {
|
||||
const { ui } = useStore()
|
||||
const router = useRouter()
|
||||
const page = router.pathname.split('/')[4]
|
||||
|
||||
const project = ui.selectedProject
|
||||
|
||||
const canUseLogsExplorer = checkPermissions(PermissionAction.ANALYTICS_READ, 'logflare')
|
||||
|
||||
if (!canUseLogsExplorer) {
|
||||
return (
|
||||
<BaseLayout>
|
||||
<main style={{ maxHeight: '100vh' }} className="flex-1 overflow-y-auto">
|
||||
<NoPermission isFullPage resourceText="access your project's logs explorer" />
|
||||
</main>
|
||||
</BaseLayout>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<BaseLayout
|
||||
product="Logs"
|
||||
productMenu={<ProductMenu page={page} menu={generateLogsMenu(project)} />}
|
||||
>
|
||||
<main style={{ maxHeight: '100vh' }} className="flex-1 overflow-y-auto">
|
||||
{children}
|
||||
</main>
|
||||
</BaseLayout>
|
||||
)
|
||||
}
|
||||
|
||||
export default withAuth(observer(LogsLayout))
|
||||
@@ -0,0 +1,88 @@
|
||||
import { Project } from 'types'
|
||||
import { IS_PLATFORM } from 'lib/constants'
|
||||
import { ProductMenuGroup } from 'components/ui/ProductMenu/ProductMenu.types'
|
||||
import { useFlag } from 'hooks'
|
||||
|
||||
export const generateLogsMenu = (project?: Project): ProductMenuGroup[] => {
|
||||
const ref = project?.ref ?? 'default'
|
||||
const logsRealtime = useFlag('logsRealtime')
|
||||
|
||||
return [
|
||||
{
|
||||
title: 'Logs',
|
||||
items: [
|
||||
{
|
||||
name: 'Explorer',
|
||||
key: 'explorer',
|
||||
url: `/project/${ref}/logs/explorer`,
|
||||
items: [],
|
||||
},
|
||||
{
|
||||
name: 'Postgres logs',
|
||||
key: 'postgres-logs',
|
||||
url: `/project/${ref}/logs/postgres-logs`,
|
||||
items: [],
|
||||
},
|
||||
{
|
||||
name: 'Query logs(?)',
|
||||
key: 'api-logs',
|
||||
url: `/project/${ref}/database/insights?`,
|
||||
items: [],
|
||||
},
|
||||
{
|
||||
name: 'PostgREST logs',
|
||||
key: 'api-logs',
|
||||
url: `/project/${ref}/database/api-logs`,
|
||||
items: [],
|
||||
},
|
||||
{
|
||||
name: 'API logs(?)',
|
||||
key: 'api-logs',
|
||||
url: `/project/${ref}/database/api-logs`,
|
||||
items: [],
|
||||
},
|
||||
...(IS_PLATFORM
|
||||
? [
|
||||
{
|
||||
name: 'Auth logs',
|
||||
key: 'logs',
|
||||
url: `/project/${ref}/auth/logs`,
|
||||
items: [],
|
||||
},
|
||||
]
|
||||
: []),
|
||||
...(IS_PLATFORM
|
||||
? [
|
||||
{
|
||||
name: 'Auth audit logs(?)',
|
||||
key: 'logs',
|
||||
url: `/project/${ref}/auth/logs`,
|
||||
items: [],
|
||||
},
|
||||
]
|
||||
: []),
|
||||
...(IS_PLATFORM
|
||||
? [
|
||||
{
|
||||
name: 'Storage logs',
|
||||
key: 'logs',
|
||||
url: `/project/${ref}/storage/logs`,
|
||||
items: [],
|
||||
},
|
||||
]
|
||||
: []),
|
||||
|
||||
...(logsRealtime
|
||||
? [
|
||||
{
|
||||
name: 'Realtime logs',
|
||||
key: 'realtime-logs',
|
||||
url: `/project/${ref}/database/realtime-logs`,
|
||||
items: [],
|
||||
},
|
||||
]
|
||||
: []),
|
||||
],
|
||||
},
|
||||
]
|
||||
}
|
||||
@@ -104,10 +104,10 @@ export const generateOtherRoutes = (ref?: string, project?: ProjectBase): Route[
|
||||
...(IS_PLATFORM
|
||||
? [
|
||||
{
|
||||
key: 'logs-explorer',
|
||||
key: 'explorer',
|
||||
label: 'Logs',
|
||||
icon: <IconList size={18} strokeWidth={2} />,
|
||||
link: ref && (isProjectBuilding ? buildingUrl : `/project/${ref}/logs-explorer`),
|
||||
link: ref && (isProjectBuilding ? buildingUrl : `/project/${ref}/logs/explorer`),
|
||||
},
|
||||
]
|
||||
: []),
|
||||
|
||||
@@ -12,7 +12,7 @@ import WizardLayout from './WizardLayout'
|
||||
import { WizardLayoutWithoutAuth } from './WizardLayout'
|
||||
import VercelIntegrationLayout from './VercelIntegrationLayout'
|
||||
import BillingLayout from './BillingLayout'
|
||||
import LogsExplorerLayout from './LogsExplorerLayout/LogsExplorerLayout'
|
||||
import LogsLayout from './LogsLayout/LogsLayout'
|
||||
|
||||
export {
|
||||
ProjectLayoutWithAuth,
|
||||
@@ -29,7 +29,7 @@ export {
|
||||
WizardLayoutWithoutAuth,
|
||||
VercelIntegrationLayout,
|
||||
BillingLayout,
|
||||
LogsExplorerLayout,
|
||||
LogsLayout,
|
||||
}
|
||||
|
||||
export default ProjectLayout
|
||||
@@ -0,0 +1,23 @@
|
||||
import LogsNavigation from 'components/interfaces/Settings/Logs/LogsNavigation'
|
||||
import { IconList } from 'ui'
|
||||
|
||||
const LogsExplorerHeader = () => {
|
||||
return (
|
||||
<div className={['flex flex-col gap-4 transition-all'].join(' ')}>
|
||||
<div className="flex items-center gap-3">
|
||||
<div
|
||||
className="flex h-6 w-6 items-center justify-center rounded border
|
||||
border-brand-600 bg-brand-300 text-brand-900
|
||||
"
|
||||
>
|
||||
<IconList size={14} strokeWidth={3} />
|
||||
</div>
|
||||
<h1 className="text-2xl text-scale-1200">Logs Explorer</h1>
|
||||
{/* {subtitle && <Badge color="scale">{subtitle}</Badge>} */}
|
||||
</div>
|
||||
<LogsNavigation />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default LogsExplorerHeader
|
||||
+9
-5
@@ -3,13 +3,13 @@ import toast from 'react-hot-toast'
|
||||
import { useEffect, useState } from 'react'
|
||||
import { useRouter } from 'next/router'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
import { Input, Modal, Form, Button } from 'ui'
|
||||
import { Input, Modal, Form, Button, Badge, IconList } from 'ui'
|
||||
|
||||
import { useStore } from 'hooks'
|
||||
import useLogsQuery from 'hooks/analytics/useLogsQuery'
|
||||
import { NextPageWithLayout, UserContent } from 'types'
|
||||
import { uuidv4 } from 'lib/helpers'
|
||||
import { LogsExplorerLayout } from 'components/layouts'
|
||||
import { LogsLayout } from 'components/layouts'
|
||||
import CodeEditor from 'components/ui/CodeEditor'
|
||||
import ShimmerLine from 'components/ui/ShimmerLine'
|
||||
import LoadingOpacity from 'components/ui/LoadingOpacity'
|
||||
@@ -24,6 +24,8 @@ import {
|
||||
TEMPLATES,
|
||||
} from 'components/interfaces/Settings/Logs'
|
||||
import UpgradePrompt from 'components/interfaces/Settings/Logs/UpgradePrompt'
|
||||
import LogsNavigation from 'components/interfaces/Settings/Logs/LogsNavigation'
|
||||
import LogsExplorerHeader from 'components/ui/Logs/LogsExplorerHeader'
|
||||
|
||||
export const LogsExplorerPage: NextPageWithLayout = () => {
|
||||
const router = useRouter()
|
||||
@@ -119,7 +121,9 @@ export const LogsExplorerPage: NextPageWithLayout = () => {
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="mx-auto w-full px-5 py-6 h-full">
|
||||
<LogsExplorerHeader />
|
||||
|
||||
<div className="flex h-full flex-grow flex-col gap-4">
|
||||
<div className="rounded border">
|
||||
<LogsQueryPanel
|
||||
@@ -239,10 +243,10 @@ export const LogsExplorerPage: NextPageWithLayout = () => {
|
||||
)}
|
||||
</Form>
|
||||
</Modal>
|
||||
</>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
LogsExplorerPage.getLayout = (page) => <LogsExplorerLayout>{page}</LogsExplorerLayout>
|
||||
LogsExplorerPage.getLayout = (page) => <LogsLayout>{page}</LogsLayout>
|
||||
|
||||
export default observer(LogsExplorerPage)
|
||||
+6
-4
@@ -4,11 +4,12 @@ import { observer } from 'mobx-react-lite'
|
||||
import { Button, IconClock, IconSave, Loading } from 'ui'
|
||||
import { useStore, withAuth } from 'hooks'
|
||||
import RecentQueriesItem from 'components/interfaces/Settings/Logs/RecentQueriesItem'
|
||||
import LogsExplorerLayout from 'components/layouts/LogsExplorerLayout/LogsExplorerLayout'
|
||||
import LogsLayout from 'components/layouts/LogsLayout/LogsLayout'
|
||||
|
||||
import Table from 'components/to-be-cleaned/Table'
|
||||
import { useRouter } from 'next/router'
|
||||
import { LogSqlSnippets, NextPageWithLayout } from 'types'
|
||||
import LogsExplorerHeader from 'components/ui/Logs/LogsExplorerHeader'
|
||||
|
||||
export const LogsSavedPage: NextPageWithLayout = () => {
|
||||
const { content, ui } = useStore()
|
||||
@@ -21,7 +22,8 @@ export const LogsSavedPage: NextPageWithLayout = () => {
|
||||
const recent = content.recentLogSqlSnippets.slice().reverse()
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="mx-auto w-full px-5 py-6 h-full">
|
||||
<LogsExplorerHeader />
|
||||
{recent.length > 0 && (
|
||||
<Table
|
||||
head={
|
||||
@@ -60,10 +62,10 @@ export const LogsSavedPage: NextPageWithLayout = () => {
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
LogsSavedPage.getLayout = (page) => <LogsExplorerLayout>{page}</LogsExplorerLayout>
|
||||
LogsSavedPage.getLayout = (page) => <LogsLayout>{page}</LogsLayout>
|
||||
|
||||
export default observer(LogsSavedPage)
|
||||
+7
-5
@@ -4,11 +4,12 @@ import { observer } from 'mobx-react-lite'
|
||||
import { IconSave, Loading } from 'ui'
|
||||
import { useStore } from 'hooks'
|
||||
import { LogsSavedQueriesItem } from 'components/interfaces/Settings/Logs'
|
||||
import { LogsExplorerLayout } from 'components/layouts'
|
||||
import { LogsLayout } from 'components/layouts'
|
||||
|
||||
import Table from 'components/to-be-cleaned/Table'
|
||||
import { useRouter } from 'next/router'
|
||||
import { NextPageWithLayout } from 'types'
|
||||
import LogsExplorerHeader from 'components/ui/Logs/LogsExplorerHeader'
|
||||
|
||||
export const LogsSavedPage: NextPageWithLayout = () => {
|
||||
const { content, ui } = useStore()
|
||||
@@ -24,8 +25,9 @@ export const LogsSavedPage: NextPageWithLayout = () => {
|
||||
}
|
||||
const saved = content.savedLogSqlSnippets()
|
||||
return (
|
||||
<>
|
||||
<div className="flex flex-col gap-3">
|
||||
<div className="mx-auto w-full px-5 py-6 h-full">
|
||||
<LogsExplorerHeader />
|
||||
<div className="flex flex-col gap-3 py-6">
|
||||
{saved.length > 0 && (
|
||||
<Table
|
||||
headTrClasses="expandable-tr"
|
||||
@@ -57,10 +59,10 @@ export const LogsSavedPage: NextPageWithLayout = () => {
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
LogsSavedPage.getLayout = (page) => <LogsExplorerLayout>{page}</LogsExplorerLayout>
|
||||
LogsSavedPage.getLayout = (page) => <LogsLayout>{page}</LogsLayout>
|
||||
|
||||
export default observer(LogsSavedPage)
|
||||
+6
-4
@@ -3,17 +3,19 @@ import { useRouter } from 'next/router'
|
||||
import { observer, useStaticRendering } from 'mobx-react-lite'
|
||||
import { IconCode, Badge, Collapsible, Button, Popover } from 'ui'
|
||||
import { TEMPLATES } from 'components/interfaces/Settings/Logs'
|
||||
import LogsExplorerLayout from 'components/layouts/LogsExplorerLayout/LogsExplorerLayout'
|
||||
import LogsLayout from 'components/layouts/LogsLayout/LogsLayout'
|
||||
import CardButton from 'components/ui/CardButton'
|
||||
import { NextPageWithLayout } from 'types'
|
||||
import LogsExplorerHeader from 'components/ui/Logs/LogsExplorerHeader'
|
||||
|
||||
export const LogsTemplatesPage: NextPageWithLayout = () => {
|
||||
const router = useRouter()
|
||||
const { ref } = router.query
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className="grid grid-cols-3 gap-6">
|
||||
<div className="mx-auto h-full w-full px-5 py-6">
|
||||
<LogsExplorerHeader />
|
||||
<div className="grid grid-cols-3 gap-6 mt-4">
|
||||
{TEMPLATES.filter((template) => template.mode === 'custom').map((template, i) => {
|
||||
const [showPreview, setShowPreview] = useState(false)
|
||||
return (
|
||||
@@ -72,6 +74,6 @@ export const LogsTemplatesPage: NextPageWithLayout = () => {
|
||||
)
|
||||
}
|
||||
|
||||
LogsTemplatesPage.getLayout = (page) => <LogsExplorerLayout>{page}</LogsExplorerLayout>
|
||||
LogsTemplatesPage.getLayout = (page) => <LogsLayout>{page}</LogsLayout>
|
||||
|
||||
export default observer(LogsTemplatesPage)
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
import React from 'react'
|
||||
import { useRouter } from 'next/router'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
import { DatabaseLayout } from 'components/layouts'
|
||||
import { LogsLayout } from 'components/layouts'
|
||||
import LogsPreviewer from 'components/interfaces/Settings/Logs/LogsPreviewer'
|
||||
import { NextPageWithLayout } from 'types'
|
||||
|
||||
@@ -20,6 +20,6 @@ export const LogPage: NextPageWithLayout = () => {
|
||||
)
|
||||
}
|
||||
|
||||
LogPage.getLayout = (page) => <DatabaseLayout title="Database">{page}</DatabaseLayout>
|
||||
LogPage.getLayout = (page) => <LogsLayout title="Database">{page}</LogsLayout>
|
||||
|
||||
export default observer(LogPage)
|
||||
Reference in new issue
Block a user