IntegrationsProductMenu.tsx93 lines · main
1import { useParams } from 'common'
2import { useRouter } from 'next/router'
3import { Menu, Separator } from 'ui'
4import { GenericSkeletonLoader } from 'ui-patterns'
5
6import { getCategoryParamFromAsPath, getIntegrationsPageFromPathname } from './Integrations.utils'
7import { generateIntegrationsMenu } from './IntegrationsMenu.utils'
8import { useInstalledIntegrations } from '@/components/interfaces/Integrations/Landing/useInstalledIntegrations'
9import AlertError from '@/components/ui/AlertError'
10import { ProductMenu } from '@/components/ui/ProductMenu'
11import { useIsFeatureEnabled } from '@/hooks/misc/useIsFeatureEnabled'
12import { useSelectedProjectQuery } from '@/hooks/misc/useSelectedProject'
13import { getPathnameWithoutQuery } from '@/lib/pathname.utils'
14
15export function IntegrationsProductMenu() {
16 const router = useRouter()
17 const { ref: projectRef } = useParams()
18 const { data: project } = useSelectedProjectQuery()
19 const { integrationsWrappers: showWrappers } = useIsFeatureEnabled(['integrations:wrappers'])
20 const resolvedProjectRef = projectRef ?? project?.ref
21
22 const pathname = getPathnameWithoutQuery(router.asPath, router.pathname)
23 const page = getIntegrationsPageFromPathname(pathname)
24 const categoryParam = getCategoryParamFromAsPath(router.asPath)
25
26 const {
27 installedIntegrations: integrations,
28 error,
29 isLoading,
30 isSuccess,
31 isError,
32 } = useInstalledIntegrations()
33
34 const resolvedPage =
35 page === 'integrations'
36 ? categoryParam
37 ? `integrations-${categoryParam}`
38 : 'integrations'
39 : page
40
41 return (
42 <>
43 <ProductMenu
44 page={resolvedPage}
45 menu={generateIntegrationsMenu({ projectRef, flags: { showWrappers } })}
46 />
47 <Separator />
48 {isSuccess && resolvedProjectRef ? (
49 <ProductMenu
50 page={page}
51 menu={[
52 {
53 key: 'installed',
54 title: 'Installed',
55 items: integrations.map((integration) => ({
56 name: integration.name,
57 label: integration.status,
58 key: `integrations/${integration.id}`,
59 url: `/project/${resolvedProjectRef}/integrations/${integration.id}/overview`,
60 icon: (
61 <div className="relative w-6 h-6 bg-white border rounded-sm flex items-center justify-center">
62 {integration.icon({ className: 'p-1' })}
63 </div>
64 ),
65 items: [],
66 })),
67 },
68 ]}
69 />
70 ) : (
71 <div className="px-4 py-6 md:px-6">
72 <Menu type="pills">
73 <Menu.Group
74 title={
75 <div className="flex flex-col space-y-2 uppercase font-mono">
76 <span>Installed</span>
77 </div>
78 }
79 />
80 </Menu>
81 {isLoading && <GenericSkeletonLoader />}
82 {isError && (
83 <AlertError
84 showIcon={false}
85 error={error}
86 subject="Failed to retrieve installed integrations"
87 />
88 )}
89 </div>
90 )}
91 </>
92 )
93}