performance.tsx104 lines · main
1import { useParams } from 'common'
2import { useMemo, useState } from 'react'
3import { LoadingLine } from 'ui'
4
5import { LINTER_LEVELS } from '@/components/interfaces/Linter/Linter.constants'
6import { lintInfoMap } from '@/components/interfaces/Linter/Linter.utils'
7import { LinterDataGrid } from '@/components/interfaces/Linter/LinterDataGrid'
8import LinterFilters from '@/components/interfaces/Linter/LinterFilters'
9import { LinterPageFooter } from '@/components/interfaces/Linter/LinterPageFooter'
10import LintPageTabs from '@/components/interfaces/Linter/LintPageTabs'
11import AdvisorsLayout from '@/components/layouts/AdvisorsLayout/AdvisorsLayout'
12import { DefaultLayout } from '@/components/layouts/DefaultLayout'
13import { FormHeader } from '@/components/ui/Forms/FormHeader'
14import { Lint, useProjectLintsQuery } from '@/data/lint/lint-query'
15import { useSelectedProjectQuery } from '@/hooks/misc/useSelectedProject'
16import { DOCS_URL } from '@/lib/constants'
17import type { NextPageWithLayout } from '@/types'
18
19const ProjectLints: NextPageWithLayout = () => {
20 const { preset, id } = useParams()
21 const { data: project } = useSelectedProjectQuery()
22
23 // need to maintain a list of filters for each tab
24 const [filters, setFilters] = useState<{ level: LINTER_LEVELS; filters: string[] }[]>([
25 { level: LINTER_LEVELS.ERROR, filters: [] },
26 { level: LINTER_LEVELS.WARN, filters: [] },
27 { level: LINTER_LEVELS.INFO, filters: [] },
28 ])
29 const [currentTab, setCurrentTab] = useState<LINTER_LEVELS>(
30 (preset as LINTER_LEVELS) ?? LINTER_LEVELS.ERROR
31 )
32 const {
33 data,
34 isPending: isLoading,
35 isRefetching,
36 refetch,
37 } = useProjectLintsQuery({
38 projectRef: project?.ref,
39 })
40
41 const activeLints = useMemo(() => {
42 return [...(data ?? [])]?.filter((x) => x.categories.includes('PERFORMANCE'))
43 }, [data])
44 const currentTabFilters = (filters.find((filter) => filter.level === currentTab)?.filters ||
45 []) as string[]
46 const filteredLints = activeLints
47 .filter((x) => x.level === currentTab)
48 .filter((x) => (currentTabFilters.length > 0 ? currentTabFilters.includes(x.name) : x))
49 const filterOptions = lintInfoMap
50 // only show filters for lint types which are present in the results and not ignored
51 .filter((item) =>
52 activeLints.some((lint) => lint.name === item.name && lint.level === currentTab)
53 )
54 .map((type) => ({
55 name: type.title,
56 value: type.name,
57 }))
58
59 const selectedLint: Lint | null = useMemo(() => {
60 return activeLints.find((lint) => lint.cache_key === id) ?? null
61 }, [id, activeLints])
62
63 return (
64 <div className="h-full flex flex-col">
65 <FormHeader
66 className="py-4 px-6 mb-0!"
67 title="Performance Advisor"
68 docsUrl={`${DOCS_URL}/guides/database/database-linter`}
69 />
70 <LintPageTabs
71 activeLints={activeLints}
72 isLoading={isLoading}
73 currentTab={currentTab}
74 setCurrentTab={setCurrentTab}
75 />
76 <LinterFilters
77 filterOptions={filterOptions}
78 activeLints={activeLints}
79 filteredLints={filteredLints}
80 currentTab={currentTab}
81 filters={filters}
82 isLoading={isLoading || isRefetching}
83 setFilters={setFilters}
84 onClickRefresh={refetch}
85 />
86 <LoadingLine loading={isRefetching} />
87 <LinterDataGrid
88 filteredLints={filteredLints}
89 currentTab={currentTab}
90 selectedLint={selectedLint}
91 isLoading={isLoading}
92 />
93 <LinterPageFooter isLoading={isLoading} isRefetching={isRefetching} refetch={refetch} />
94 </div>
95 )
96}
97
98ProjectLints.getLayout = (page) => (
99 <DefaultLayout>
100 <AdvisorsLayout title="Linter">{page}</AdvisorsLayout>
101 </DefaultLayout>
102)
103
104export default ProjectLints