index.tsx104 lines · main
1import { PermissionAction } from '@supabase/shared-types/out/constants'
2import { useFeatureFlags, useFlag, useParams } from 'common'
3import { useRouter } from 'next/router'
4import { parseAsBoolean, useQueryState } from 'nuqs'
5import { useEffect } from 'react'
6import { LogoLoader } from 'ui'
7
8import { ObservabilityOverview } from '@/components/interfaces/Observability/ObservabilityOverview'
9import { CreateReportModal } from '@/components/interfaces/Reports/CreateReportModal'
10import DefaultLayout from '@/components/layouts/DefaultLayout'
11import ObservabilityLayout from '@/components/layouts/ObservabilityLayout/ObservabilityLayout'
12import ProductEmptyState from '@/components/to-be-cleaned/ProductEmptyState'
13import { useContentQuery } from '@/data/content/content-query'
14import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions'
15import { useProfile } from '@/lib/profile'
16import type { NextPageWithLayout } from '@/types'
17
18export const UserReportPage: NextPageWithLayout = () => {
19 const router = useRouter()
20 const { ref } = useParams()
21
22 const { profile } = useProfile()
23 const { hasLoaded: flagsLoaded } = useFeatureFlags()
24 const showOverview = useFlag('observabilityOverview')
25 const [showCreateReportModal, setShowCreateReportModal] = useQueryState(
26 'newReport',
27 parseAsBoolean.withDefault(false).withOptions({ history: 'push', clearOnDefault: true })
28 )
29
30 const {
31 isPending: isLoading,
32 isSuccess,
33 data,
34 } = useContentQuery({
35 projectRef: ref,
36 type: 'report',
37 })
38
39 useEffect(() => {
40 if (!isSuccess) return
41 if (!flagsLoaded) return // Wait for flags to load before checking redirect
42 if (showOverview) return // Don't redirect if overview is enabled
43
44 const reports = data.content
45 .filter((x) => x.type === 'report')
46 .sort((a, b) => a.name.localeCompare(b.name))
47 if (reports.length >= 1) router.replace(`/project/${ref}/observability/${reports[0].id}`)
48 if (reports.length === 0) router.replace(`/project/${ref}/observability/api-overview`)
49 }, [isSuccess, data, router, ref, showOverview, flagsLoaded])
50
51 const { can: canCreateReport } = useAsyncCheckPermissions(
52 PermissionAction.CREATE,
53 'user_content',
54 {
55 resource: { type: 'report', owner_id: profile?.id },
56 subject: { id: profile?.id },
57 }
58 )
59
60 // Wait for flags to load before rendering to avoid flashing wrong page
61 if (!flagsLoaded || isLoading) {
62 return <LogoLoader />
63 }
64
65 // Show overview page if feature flag is enabled
66 if (showOverview) {
67 return <ObservabilityOverview />
68 }
69
70 return (
71 <div className="h-full w-full">
72 <>
73 <ProductEmptyState
74 title="Observability"
75 ctaButtonLabel="New custom report"
76 onClickCta={() => {
77 setShowCreateReportModal(true)
78 }}
79 disabled={!canCreateReport}
80 disabledMessage="You need additional permissions to create a report"
81 >
82 <p className="text-foreground-light text-sm">Create custom reports for your projects.</p>
83 <p className="text-foreground-light text-sm">
84 Get a high level overview of your network traffic, user actions, and infrastructure
85 health.
86 </p>
87 </ProductEmptyState>
88 <CreateReportModal
89 visible={showCreateReportModal}
90 onCancel={() => setShowCreateReportModal(false)}
91 afterSubmit={() => setShowCreateReportModal(false)}
92 />
93 </>
94 </div>
95 )
96}
97
98UserReportPage.getLayout = (page) => (
99 <DefaultLayout>
100 <ObservabilityLayout title="Overview">{page}</ObservabilityLayout>
101 </DefaultLayout>
102)
103
104export default UserReportPage