| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152 |
- import dayjs from 'dayjs'
- import { Github } from 'lucide-react'
- import Link from 'next/link'
- import { useRouter } from 'next/router'
- import { PropsWithChildren, ReactNode } from 'react'
- import { Tooltip, TooltipContent, TooltipTrigger } from 'ui'
- import { TimestampInfo } from 'ui-patterns'
- import { ShimmeringLoader } from 'ui-patterns/ShimmeringLoader'
- import { WorkflowLogs } from './WorkflowLogs'
- import { ButtonTooltip } from '@/components/ui/ButtonTooltip'
- import type { Branch } from '@/data/branches/branches-query'
- interface BranchManagementSectionProps {
- header: string | ReactNode
- footer?: ReactNode
- }
- export const BranchManagementSection = ({
- header,
- footer,
- children,
- }: PropsWithChildren<BranchManagementSectionProps>) => {
- return (
- <div className="border rounded-lg overflow-hidden">
- <div className="bg-surface-100 shadow-xs flex justify-between items-center px-4 py-3 rounded-t-lg text-xs font-mono uppercase">
- {typeof header === 'string' ? <span>{header}</span> : header}
- </div>
- <div className="bg-surface border-t shadow-xs rounded-b-lg text-sm divide-y">{children}</div>
- {footer !== undefined && <div className="bg-surface-100 px-6 py-1 border-t">{footer}</div>}
- </div>
- )
- }
- export const BranchRowLoader = () => {
- return (
- <div className="flex items-center justify-between px-6 py-2.5">
- <div className="flex items-center gap-x-4">
- <ShimmeringLoader className="w-52" />
- <ShimmeringLoader className="w-52" />
- </div>
- <div className="flex items-center gap-x-4">
- <ShimmeringLoader className="w-52" />
- <ShimmeringLoader className="w-52" />
- </div>
- </div>
- )
- }
- export const BranchLoader = () => {
- return (
- <>
- <BranchRowLoader />
- <BranchRowLoader />
- <BranchRowLoader />
- <BranchRowLoader />
- <BranchRowLoader />
- </>
- )
- }
- interface BranchRowProps {
- repo: string
- label?: string | ReactNode
- branch: Branch
- isGithubConnected: boolean
- rowLink?: string
- external?: boolean
- rowActions?: ReactNode
- }
- export const BranchRow = ({
- branch,
- isGithubConnected,
- label,
- repo,
- rowLink,
- external = false,
- rowActions,
- }: BranchRowProps) => {
- const router = useRouter()
- const page = router.pathname.split('/').pop()
- const daysFromNow = dayjs().diff(dayjs(branch.updated_at), 'day')
- const willBeDeletedIn = branch.deletion_scheduled_at
- ? dayjs(branch.deletion_scheduled_at).diff(dayjs(), 'minutes')
- : null
- const isDeletionPending = willBeDeletedIn !== null && willBeDeletedIn < 0
- const formattedTimeFromNow = dayjs(branch.updated_at).fromNow()
- const navigateUrl = rowLink ?? `/project/${branch.project_ref}`
- return (
- <div className="w-full flex items-center justify-between px-4 py-2.5 hover:bg-surface-100">
- <div className="flex items-center gap-x-3">
- {branch.git_branch && isGithubConnected && (
- <ButtonTooltip
- asChild
- type="default"
- className="px-1.5"
- tooltip={{ content: { side: 'bottom', text: 'View branch on GitHub' } }}
- >
- <a
- target="_blank"
- rel="noreferrer noopener"
- href={`https://github.com/${repo}/tree/${branch.git_branch}`}
- >
- <Github size={14} className="text-foreground-light" />
- </a>
- </ButtonTooltip>
- )}
- <Tooltip>
- <TooltipTrigger>
- <Link
- target={external ? '_blank' : '_self'}
- rel={external ? 'noopener noreferrer' : undefined}
- href={navigateUrl}
- className="flex items-center"
- >
- {label || branch.name}
- </Link>
- </TooltipTrigger>
- {((page === 'branches' && !branch.is_default) || page === 'merge-requests') && (
- <TooltipContent side="bottom">
- {page === 'branches' && !branch.is_default && 'Switch to branch'}
- {page === 'merge-requests' && 'View merge request'}
- </TooltipContent>
- )}
- </Tooltip>
- </div>
- <div className="flex items-center gap-x-4">
- {branch.deletion_scheduled_at ? (
- <p className="text-xs text-foreground-lighter">
- {isDeletionPending
- ? 'Deletion pending...'
- : `Will be deleted in ${willBeDeletedIn} minutes`}
- </p>
- ) : (
- <p className="text-xs text-foreground-lighter">
- {daysFromNow > 1 ? 'Updated on' : 'Updated'}{' '}
- <TimestampInfo
- utcTimestamp={branch.updated_at}
- label={daysFromNow <= 1 ? formattedTimeFromNow : undefined}
- />
- </p>
- )}
- <WorkflowLogs branch={branch} />
- {rowActions}
- </div>
- </div>
- )
- }
|