BranchDropdownCommandContent.tsx 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. import { ListTree, MessageCircle, Plus } from 'lucide-react'
  2. import Link from 'next/link'
  3. import {
  4. Button,
  5. cn,
  6. Command,
  7. CommandEmpty,
  8. CommandGroup,
  9. CommandInput,
  10. CommandItem,
  11. CommandList,
  12. CommandSeparator,
  13. ScrollArea,
  14. } from 'ui'
  15. import { BranchLink } from './BranchLink'
  16. import type { Branch } from '@/data/branches/branches-query'
  17. import { useTrack } from '@/lib/telemetry/track'
  18. const BRANCHING_GITHUB_DISCUSSION_LINK = 'https://github.com/orgs/briven/discussions/18937'
  19. export interface BranchDropdownCommandContentProps {
  20. embedded: boolean
  21. className?: string
  22. branchList: Branch[]
  23. selectedBranch: Branch | undefined
  24. branchesCount: number
  25. isBranchingEnabled: boolean
  26. projectRef: string | undefined
  27. onClose: () => void
  28. onCreateBranch: () => void
  29. }
  30. export function BranchDropdownCommandContent({
  31. embedded,
  32. className,
  33. branchList,
  34. selectedBranch,
  35. branchesCount,
  36. isBranchingEnabled,
  37. projectRef,
  38. onClose,
  39. onCreateBranch,
  40. }: BranchDropdownCommandContentProps) {
  41. const track = useTrack()
  42. if (embedded) {
  43. return (
  44. <Command className={cn(className, 'flex flex-col flex-1 min-h-0 overflow-hidden')}>
  45. <div className="grid grid-cols-2 gap-2 shrink-0 p-2 border-b">
  46. <Button
  47. type="text"
  48. size="small"
  49. asChild
  50. block
  51. icon={<ListTree size={14} strokeWidth={1.5} />}
  52. >
  53. <Link
  54. href={`/project/${projectRef}/branches`}
  55. className="text-xs text-foreground-light hover:text-foreground"
  56. onClick={onClose}
  57. >
  58. Manage branches
  59. </Link>
  60. </Button>
  61. <Button
  62. type="text"
  63. size="small"
  64. asChild
  65. block
  66. icon={<MessageCircle size={14} strokeWidth={1.5} />}
  67. >
  68. <a
  69. target="_blank"
  70. rel="noreferrer noopener"
  71. href={BRANCHING_GITHUB_DISCUSSION_LINK}
  72. onClick={onClose}
  73. className="text-xs text-foreground-light hover:text-foreground"
  74. >
  75. Branching feedback
  76. </a>
  77. </Button>
  78. <Button
  79. type="default"
  80. size="small"
  81. block
  82. className="col-span-full text-xs text-foreground-light hover:text-foreground"
  83. onClick={() => {
  84. track('branch_selector_create_clicked')
  85. onClose()
  86. onCreateBranch()
  87. }}
  88. icon={<Plus size={14} strokeWidth={1.5} />}
  89. >
  90. Create branch
  91. </Button>
  92. </div>
  93. {isBranchingEnabled && (
  94. <CommandInput placeholder="Find branch..." wrapperClassName="shrink-0 border-b" />
  95. )}
  96. <CommandList className="flex flex-col flex-1 p-1 min-h-0 overflow-y-auto max-h-none!">
  97. {isBranchingEnabled && <CommandEmpty>No branches found</CommandEmpty>}
  98. <CommandGroup className="min-h-0">
  99. {branchList.map((branch) => (
  100. <BranchLink
  101. key={branch.id}
  102. branch={branch}
  103. isSelected={branch.id === selectedBranch?.id || branchesCount === 0}
  104. onClose={onClose}
  105. />
  106. ))}
  107. </CommandGroup>
  108. </CommandList>
  109. </Command>
  110. )
  111. }
  112. return (
  113. <Command className={className}>
  114. {isBranchingEnabled && <CommandInput placeholder="Find branch..." />}
  115. <CommandList>
  116. {isBranchingEnabled && <CommandEmpty>No branches found</CommandEmpty>}
  117. <CommandGroup>
  118. <ScrollArea className="max-h-[210px] overflow-y-auto">
  119. {branchList.map((branch) => (
  120. <BranchLink
  121. key={branch.id}
  122. branch={branch}
  123. isSelected={branch.id === selectedBranch?.id || branchesCount === 0}
  124. onClose={onClose}
  125. />
  126. ))}
  127. </ScrollArea>
  128. </CommandGroup>
  129. <CommandSeparator />
  130. <CommandGroup>
  131. <CommandItem
  132. className="cursor-pointer w-full"
  133. onSelect={() => {
  134. track('branch_selector_create_clicked')
  135. onClose()
  136. onCreateBranch()
  137. }}
  138. >
  139. <div className="w-full flex items-center gap-2">
  140. <Plus size={14} strokeWidth={1.5} />
  141. <p>Create branch</p>
  142. </div>
  143. </CommandItem>
  144. <CommandItem
  145. className="cursor-pointer w-full"
  146. onSelect={() => {
  147. track('branch_selector_manage_clicked')
  148. onClose()
  149. }}
  150. >
  151. <Link
  152. href={`/project/${projectRef}/branches`}
  153. className="w-full flex items-center gap-2"
  154. >
  155. <ListTree size={14} strokeWidth={1.5} />
  156. <p>Manage branches</p>
  157. </Link>
  158. </CommandItem>
  159. </CommandGroup>
  160. <CommandSeparator />
  161. <CommandGroup>
  162. <CommandItem
  163. className="cursor-pointer w-full"
  164. onSelect={() => {
  165. onClose()
  166. window?.open(BRANCHING_GITHUB_DISCUSSION_LINK, '_blank')?.focus()
  167. }}
  168. onClick={onClose}
  169. >
  170. <a
  171. target="_blank"
  172. rel="noreferrer noopener"
  173. href={BRANCHING_GITHUB_DISCUSSION_LINK}
  174. onClick={onClose}
  175. className="w-full flex gap-2"
  176. >
  177. <MessageCircle size={14} strokeWidth={1} className="mt-0.5" />
  178. <div>
  179. <p>Branching feedback</p>
  180. <p className="text-lighter">Join GitHub Discussion</p>
  181. </div>
  182. </a>
  183. </CommandItem>
  184. </CommandGroup>
  185. </CommandList>
  186. </Command>
  187. )
  188. }