Files
supabase/apps/studio/components/interfaces/BranchManagement/BranchPanels.tsx
Danny White 476d4a5851 refactor(ui): drop redundant Button variant="default" props (#50161)
## What kind of change does this PR introduce?

Mechanical cleanup on top of the Button default-variant change (#50160).

## What is the current behavior?

Many callsites still pass `variant="default"` even though that is now
the component default.

## What is the new behavior?

Removes redundant static `variant="default"` from legacy `Button` and
`ButtonTooltip` callsites. Keeps explicit defaults where they document
the API:

- `button-default.tsx` and `button-sizes.tsx` demos
- `DocsButton`, which pins neutral styling at the wrapper boundary

## To test

Studio:

- [Auth → Rate
Limits](https://studio-staging-2s957kwc4-supabase.vercel.app/dashboard/project/_/auth/rate-limits):
dirty the form so Cancel appears; Cancel stays neutral, Save stays green
- [Project Settings → API
Keys](https://studio-staging-2s957kwc4-supabase.vercel.app/dashboard/project/_/settings/api-keys):
`DocsButton` in the header actions stays neutral

Design system:

- [Design system →
Button](https://design-system-git-dnywh-dc924ac1-supabase.vercel.app/design-system/docs/components/button):
`button-default` / `button-sizes` still show explicit default styling;
Primary (green) is restricted to the Primary section (and `asChild`)

WWW:

- [www → Brand
assets](https://zone-www-dot-com-git-dnywh-dc924ac1-supabase.vercel.app/brand-assets):
Download logo kit / Download button kit stay neutral
2026-09-11 17:05:26 +10:00

152 lines
4.7 KiB
TypeScript

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 { ShimmeringLoader } from 'ui-patterns/ShimmeringLoader'
import { TimestampInfo } from 'ui-patterns/TimestampInfo'
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
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>
)
}