ProjectBranchSelector.tsx 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. import { useBreakpoint, useParams } from 'common'
  2. import { useRouter } from 'next/router'
  3. import { useState } from 'react'
  4. import {
  5. Popover,
  6. PopoverContent,
  7. PopoverTrigger,
  8. SidebarMenu,
  9. SidebarMenuButton,
  10. SidebarMenuItem,
  11. } from 'ui'
  12. import { ShimmeringLoader } from 'ui-patterns/ShimmeringLoader'
  13. import { getProjectBranchSelectorState } from './ProjectBranchSelector.utils'
  14. import { ProjectBranchSelectorPopover } from './ProjectBranchSelectorPopover'
  15. import { ProjectBranchSelectorSheet } from './ProjectBranchSelectorSheet'
  16. import { ProjectBranchSelectorTrigger } from './ProjectBranchSelectorTrigger'
  17. import { useBranchesQuery } from '@/data/branches/branches-query'
  18. import { useProjectDetailQuery } from '@/data/projects/project-detail-query'
  19. import { useSelectedOrganizationQuery } from '@/hooks/misc/useSelectedOrganization'
  20. import { useSelectedProjectQuery } from '@/hooks/misc/useSelectedProject'
  21. import { IS_PLATFORM } from '@/lib/constants'
  22. export function ProjectBranchSelector() {
  23. const router = useRouter()
  24. const { ref } = useParams()
  25. const { data: selectedOrganization } = useSelectedOrganizationQuery()
  26. const { data: project, isPending: isLoadingProject } = useSelectedProjectQuery()
  27. const isBranch = project?.parentRef !== project?.ref
  28. const isProductionBranch = !isBranch
  29. const { data: parentProject } = useProjectDetailQuery(
  30. { ref: project?.parent_project_ref },
  31. { enabled: isBranch }
  32. )
  33. const displayProject = parentProject ?? project
  34. const [open, setOpen] = useState(false)
  35. const isBranchingEnabled = project?.is_branch_enabled === true
  36. const { data: branches } = useBranchesQuery(
  37. { projectRef: project?.parent_project_ref || ref },
  38. { enabled: open && Boolean(project) }
  39. )
  40. const selectedBranch = branches?.find((b) => b.project_ref === ref)
  41. const { isMainBranch, branchDisplayName, selectedOrgInitial, organizationHref } =
  42. getProjectBranchSelectorState({
  43. selectedBranch,
  44. isBranchingEnabled,
  45. selectedOrganization: selectedOrganization ?? undefined,
  46. })
  47. const goToOrganization = () => {
  48. setOpen(false)
  49. router.push(organizationHref)
  50. }
  51. const isMobile = useBreakpoint('md')
  52. if (isLoadingProject || !displayProject)
  53. return <ShimmeringLoader className="w-[120px] ml-1 md:py-3" />
  54. if (!IS_PLATFORM) {
  55. return (
  56. <SidebarMenu>
  57. <SidebarMenuItem>
  58. <SidebarMenuButton className="grid flex-1 text-left text-sm leading-tight text-foreground">
  59. <span className="truncate">{displayProject.name}</span>
  60. </SidebarMenuButton>
  61. </SidebarMenuItem>
  62. </SidebarMenu>
  63. )
  64. }
  65. const triggerProps = {
  66. displayProjectName: displayProject.name,
  67. selectedOrgInitial,
  68. isBranch,
  69. isProductionBranch,
  70. branchDisplayName,
  71. onGoToOrganization: goToOrganization,
  72. }
  73. if (isMobile) {
  74. return (
  75. <>
  76. <ProjectBranchSelectorTrigger {...triggerProps} onClick={() => setOpen(true)} />
  77. <ProjectBranchSelectorSheet
  78. open={open}
  79. onOpenChange={setOpen}
  80. selectedRef={ref}
  81. onClose={() => setOpen(false)}
  82. selectedOrganization={selectedOrganization ?? null}
  83. displayProject={displayProject ?? null}
  84. selectedBranch={selectedBranch ?? null}
  85. isMainBranch={isMainBranch}
  86. />
  87. </>
  88. )
  89. }
  90. return (
  91. <SidebarMenu>
  92. <SidebarMenuItem>
  93. <Popover open={open} onOpenChange={setOpen} modal={false}>
  94. <PopoverTrigger asChild>
  95. <ProjectBranchSelectorTrigger {...triggerProps} />
  96. </PopoverTrigger>
  97. <PopoverContent className="p-0 w-[780px]" side="bottom" align="start">
  98. <ProjectBranchSelectorPopover onClose={() => setOpen(false)} />
  99. </PopoverContent>
  100. </Popover>
  101. </SidebarMenuItem>
  102. </SidebarMenu>
  103. )
  104. }