IntegrationsProductMenu.tsx 3.1 KB

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