mirror of
https://github.com/supabase/supabase.git
synced 2026-10-17 23:29:08 +03:00
Show main branch as part of the empty state (#51607)
## Context Shows the production branch as part of the branching empty state (Shifts `BranchingEmptyState` into `Overview`) It's so that users can still then reach the "View logs" button for the production branch which was otherwise hidden <img width="1214" height="531" alt="image" src="https://github.com/user-attachments/assets/3bc702f2-950b-4d9e-8b4f-78149af9ed82" />
This commit is contained in:
1 parent
287c36447a
commit
3a33cbcce5
2 files changed
+142
-131
No files matched your search
@@ -10,6 +10,7 @@ import {
|
||||
Pencil,
|
||||
Redo,
|
||||
RefreshCw,
|
||||
RefreshCwIcon,
|
||||
Shield,
|
||||
Trash2,
|
||||
} from 'lucide-react'
|
||||
@@ -26,10 +27,12 @@ import {
|
||||
} from 'ui'
|
||||
import { ConfirmationModal } from 'ui-patterns/Dialogs/ConfirmationModal'
|
||||
|
||||
import { BranchingEmptyState } from './BranchingEmptyState'
|
||||
import { BranchLoader, BranchManagementSection, BranchRow, BranchRowLoader } from './BranchPanels'
|
||||
import { EditBranchModal } from './EditBranchModal'
|
||||
import { PreviewBranchesEmptyState } from './EmptyStates'
|
||||
import { SwitchToPreviewModal } from './SwitchToPreviewModal'
|
||||
import { ButtonTooltip } from '@/components/ui/ButtonTooltip'
|
||||
import { DropdownMenuItemTooltip } from '@/components/ui/DropdownMenuItemTooltip'
|
||||
import { TextConfirmModal } from '@/components/ui/TextConfirmModalWrapper'
|
||||
import { useBranchPushMutation } from '@/data/branches/branch-push-mutation'
|
||||
@@ -81,6 +84,8 @@ export const Overview = ({
|
||||
const { hasAccess: hasAccessToPersistentBranching, isLoading: isLoadingEntitlement } =
|
||||
useCheckEntitlements('branching_persistent')
|
||||
|
||||
const showEmptyState = isSuccess && previewBranches.length === 0
|
||||
|
||||
return (
|
||||
<>
|
||||
<BranchManagementSection header="Production branch">
|
||||
@@ -111,118 +116,125 @@ export const Overview = ({
|
||||
)}
|
||||
</BranchManagementSection>
|
||||
|
||||
{/* Persistent Branches Section */}
|
||||
<BranchManagementSection header="Persistent branches">
|
||||
{(isLoading || isLoadingEntitlement) && <BranchLoader />}
|
||||
{isSuccess &&
|
||||
!isLoadingEntitlement &&
|
||||
!hasAccessToPersistentBranching &&
|
||||
IS_PLATFORM &&
|
||||
persistentBranches.length === 0 && (
|
||||
<div className="px-6 py-10 flex items-center justify-between">
|
||||
<div className="flex flex-col gap-0.5">
|
||||
<p className="text-sm">Upgrade to unlock persistent branches</p>
|
||||
<p className="text-sm text-foreground-lighter text-balance">
|
||||
Persistent branches are long-lived, cannot be reset, and are ideal for staging
|
||||
environments.
|
||||
</p>
|
||||
</div>
|
||||
<Button variant="primary" asChild>
|
||||
<Link href={`/org/${selectedOrg?.slug}/billing?panel=subscriptionPlan`}>
|
||||
Upgrade
|
||||
</Link>
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
{isSuccess &&
|
||||
!isLoadingEntitlement &&
|
||||
hasAccessToPersistentBranching &&
|
||||
persistentBranches.length === 0 && (
|
||||
<div className="flex items-center flex-col gap-0.5 justify-center w-full py-10">
|
||||
<p>No persistent branches</p>
|
||||
<p className="text-foreground-lighter text-center text-balance">
|
||||
Persistent branches are long-lived, cannot be reset, and are ideal for staging
|
||||
environments.
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
{isSuccess &&
|
||||
!isLoadingEntitlement &&
|
||||
persistentBranches.map((branch) => {
|
||||
return (
|
||||
<BranchRow
|
||||
isGithubConnected={isGithubConnected}
|
||||
key={branch.id}
|
||||
repo={repo}
|
||||
branch={branch}
|
||||
rowActions={
|
||||
<PreviewBranchActions
|
||||
branch={branch}
|
||||
{showEmptyState ? (
|
||||
<BranchingEmptyState isGithubConnected={isGithubConnected} />
|
||||
) : (
|
||||
<>
|
||||
{/* Persistent Branches Section */}
|
||||
<BranchManagementSection header="Persistent branches">
|
||||
{(isLoading || isLoadingEntitlement) && <BranchLoader />}
|
||||
{isSuccess &&
|
||||
!isLoadingEntitlement &&
|
||||
!hasAccessToPersistentBranching &&
|
||||
IS_PLATFORM &&
|
||||
persistentBranches.length === 0 && (
|
||||
<div className="px-6 py-10 flex items-center justify-between">
|
||||
<div className="flex flex-col gap-0.5">
|
||||
<p className="text-sm">Upgrade to unlock persistent branches</p>
|
||||
<p className="text-sm text-foreground-lighter text-balance">
|
||||
Persistent branches are long-lived, cannot be reset, and are ideal for staging
|
||||
environments.
|
||||
</p>
|
||||
</div>
|
||||
<Button variant="primary" asChild>
|
||||
<Link href={`/org/${selectedOrg?.slug}/billing?panel=subscriptionPlan`}>
|
||||
Upgrade
|
||||
</Link>
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
{isSuccess &&
|
||||
!isLoadingEntitlement &&
|
||||
hasAccessToPersistentBranching &&
|
||||
persistentBranches.length === 0 && (
|
||||
<div className="flex items-center flex-col gap-0.5 justify-center w-full py-10">
|
||||
<p>No persistent branches</p>
|
||||
<p className="text-foreground-lighter text-center text-balance">
|
||||
Persistent branches are long-lived, cannot be reset, and are ideal for staging
|
||||
environments.
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
{isSuccess &&
|
||||
!isLoadingEntitlement &&
|
||||
persistentBranches.map((branch) => {
|
||||
return (
|
||||
<BranchRow
|
||||
isGithubConnected={isGithubConnected}
|
||||
key={branch.id}
|
||||
repo={repo}
|
||||
onSelectDeleteBranch={() => onSelectDeleteBranch(branch)}
|
||||
generateCreatePullRequestURL={generateCreatePullRequestURL}
|
||||
branch={branch}
|
||||
rowActions={
|
||||
<PreviewBranchActions
|
||||
branch={branch}
|
||||
repo={repo}
|
||||
onSelectDeleteBranch={() => onSelectDeleteBranch(branch)}
|
||||
generateCreatePullRequestURL={generateCreatePullRequestURL}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
)
|
||||
})}
|
||||
</BranchManagementSection>
|
||||
)
|
||||
})}
|
||||
</BranchManagementSection>
|
||||
|
||||
{/* Ephemeral/Preview Branches Section */}
|
||||
<BranchManagementSection header="Preview branches">
|
||||
{isLoading && <BranchLoader />}
|
||||
{isSuccess && ephemeralBranches.length === 0 && (
|
||||
<PreviewBranchesEmptyState onSelectCreateBranch={onSelectCreateBranch} />
|
||||
)}
|
||||
{isSuccess &&
|
||||
ephemeralBranches.map((branch) => {
|
||||
return (
|
||||
<BranchRow
|
||||
isGithubConnected={isGithubConnected}
|
||||
key={branch.id}
|
||||
repo={repo}
|
||||
branch={branch}
|
||||
rowActions={
|
||||
<PreviewBranchActions
|
||||
branch={branch}
|
||||
{/* Ephemeral/Preview Branches Section */}
|
||||
<BranchManagementSection header="Preview branches">
|
||||
{isLoading && <BranchLoader />}
|
||||
{isSuccess && ephemeralBranches.length === 0 && (
|
||||
<PreviewBranchesEmptyState onSelectCreateBranch={onSelectCreateBranch} />
|
||||
)}
|
||||
{isSuccess &&
|
||||
ephemeralBranches.map((branch) => {
|
||||
return (
|
||||
<BranchRow
|
||||
isGithubConnected={isGithubConnected}
|
||||
key={branch.id}
|
||||
repo={repo}
|
||||
onSelectDeleteBranch={() => onSelectDeleteBranch(branch)}
|
||||
generateCreatePullRequestURL={generateCreatePullRequestURL}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
)
|
||||
})}
|
||||
</BranchManagementSection>
|
||||
{/* Scheduled for deletion branches section */}
|
||||
<BranchManagementSection header="Scheduled for deletion branches">
|
||||
{isLoading && <BranchLoader />}
|
||||
{isSuccess && scheduledForDeletionBranches.length === 0 && (
|
||||
<div className="flex items-center flex-col gap-0.5 justify-center w-full py-10">
|
||||
<p className="text-foreground-lighter">No branches scheduled for deletion</p>
|
||||
</div>
|
||||
)}
|
||||
{isSuccess &&
|
||||
scheduledForDeletionBranches.map((branch) => {
|
||||
return (
|
||||
<BranchRow
|
||||
isGithubConnected={isGithubConnected}
|
||||
key={branch.id}
|
||||
repo={repo}
|
||||
branch={branch}
|
||||
rowActions={
|
||||
<PreviewBranchActions
|
||||
branch={branch}
|
||||
repo={repo}
|
||||
// If a scheduled for deletion branch is deleted, we force the deletion
|
||||
onSelectDeleteBranch={() => onSelectDeleteBranch(branch)}
|
||||
generateCreatePullRequestURL={generateCreatePullRequestURL}
|
||||
rowActions={
|
||||
<PreviewBranchActions
|
||||
branch={branch}
|
||||
repo={repo}
|
||||
onSelectDeleteBranch={() => onSelectDeleteBranch(branch)}
|
||||
generateCreatePullRequestURL={generateCreatePullRequestURL}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
)
|
||||
})}
|
||||
</BranchManagementSection>
|
||||
)
|
||||
})}
|
||||
</BranchManagementSection>
|
||||
|
||||
{/* Scheduled for deletion branches section */}
|
||||
<BranchManagementSection header="Scheduled for deletion branches">
|
||||
{isLoading && <BranchLoader />}
|
||||
{isSuccess && scheduledForDeletionBranches.length === 0 && (
|
||||
<div className="flex items-center flex-col gap-0.5 justify-center w-full py-10">
|
||||
<p className="text-foreground-lighter">No branches scheduled for deletion</p>
|
||||
</div>
|
||||
)}
|
||||
{isSuccess &&
|
||||
scheduledForDeletionBranches.map((branch) => {
|
||||
return (
|
||||
<BranchRow
|
||||
isGithubConnected={isGithubConnected}
|
||||
key={branch.id}
|
||||
repo={repo}
|
||||
branch={branch}
|
||||
rowActions={
|
||||
<PreviewBranchActions
|
||||
branch={branch}
|
||||
repo={repo}
|
||||
// If a scheduled for deletion branch is deleted, we force the deletion
|
||||
onSelectDeleteBranch={() => onSelectDeleteBranch(branch)}
|
||||
generateCreatePullRequestURL={generateCreatePullRequestURL}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
)
|
||||
})}
|
||||
</BranchManagementSection>
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
@@ -596,15 +608,21 @@ const MainBranchActions = ({ branch, repo }: { branch: Branch; repo: string }) =
|
||||
<>
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<Button variant="text" icon={<MoreVertical />} className="px-1" />
|
||||
<ButtonTooltip
|
||||
variant="text"
|
||||
icon={<MoreVertical />}
|
||||
className="px-1"
|
||||
tooltip={{ content: { side: 'bottom', text: 'More options' } }}
|
||||
/>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent className="w-56" side="bottom" align="end">
|
||||
{repo ? (
|
||||
<Link passHref href={`/project/${projectRef}/settings/integrations`}>
|
||||
<DropdownMenuItem asChild className="gap-x-2">
|
||||
<a>Change production branch</a>
|
||||
</DropdownMenuItem>
|
||||
</Link>
|
||||
<DropdownMenuItem asChild className="gap-x-2">
|
||||
<Link href={`/project/${projectRef}/settings/integrations`}>
|
||||
<Pencil size={14} />
|
||||
Change production branch
|
||||
</Link>
|
||||
</DropdownMenuItem>
|
||||
) : (
|
||||
<DropdownMenuItem
|
||||
className="gap-x-2"
|
||||
@@ -636,7 +654,7 @@ const MainBranchActions = ({ branch, repo }: { branch: Branch; repo: string }) =
|
||||
},
|
||||
}}
|
||||
>
|
||||
<Redo size={14} /> Resync branch
|
||||
<RefreshCwIcon size={14} /> Resync branch
|
||||
</DropdownMenuItemTooltip>
|
||||
) : null}
|
||||
</DropdownMenuContent>
|
||||
|
||||
@@ -4,7 +4,6 @@ import { partition } from 'lodash'
|
||||
import { useRouter } from 'next/router'
|
||||
import { useState, type PropsWithChildren } from 'react'
|
||||
|
||||
import { BranchingEmptyState } from '@/components/interfaces/BranchManagement/BranchingEmptyState'
|
||||
import { CreateBranchButton } from '@/components/interfaces/BranchManagement/CreateBranchButton'
|
||||
import { DeleteBranchModal } from '@/components/interfaces/BranchManagement/DeleteBranchModal'
|
||||
import { Overview } from '@/components/interfaces/BranchManagement/Overview'
|
||||
@@ -70,9 +69,7 @@ const BranchesPage: NextPageWithLayout = () => {
|
||||
const githubConnection = connections?.find((connection) => connection.project.ref === projectRef)
|
||||
const isGithubConnected = githubConnection !== undefined
|
||||
const repo = githubConnection?.repository.name ?? ''
|
||||
const showEmptyState = isSuccessConnections && isSuccessBranches && previewBranches.length === 0
|
||||
|
||||
const isError = isErrorConnections || isErrorBranches
|
||||
const isLoading = isLoadingConnections || isLoadingBranches
|
||||
const isSuccess = isSuccessConnections && isSuccessBranches
|
||||
|
||||
@@ -108,21 +105,17 @@ const BranchesPage: NextPageWithLayout = () => {
|
||||
/>
|
||||
)}
|
||||
|
||||
{!isError && showEmptyState ? (
|
||||
<BranchingEmptyState isGithubConnected={isGithubConnected} />
|
||||
) : (
|
||||
<Overview
|
||||
isGithubConnected={isGithubConnected}
|
||||
isLoading={isLoading}
|
||||
isSuccess={isSuccess}
|
||||
repo={repo}
|
||||
mainBranch={mainBranch}
|
||||
previewBranches={previewBranches}
|
||||
onSelectCreateBranch={() => snap.setShowCreateBranchModal(true)}
|
||||
onSelectDeleteBranch={setSelectedBranchToDelete}
|
||||
generateCreatePullRequestURL={generateCreatePullRequestURL}
|
||||
/>
|
||||
)}
|
||||
<Overview
|
||||
isGithubConnected={isGithubConnected}
|
||||
isLoading={isLoading}
|
||||
isSuccess={isSuccess}
|
||||
repo={repo}
|
||||
mainBranch={mainBranch}
|
||||
previewBranches={previewBranches}
|
||||
onSelectCreateBranch={() => snap.setShowCreateBranchModal(true)}
|
||||
onSelectDeleteBranch={setSelectedBranchToDelete}
|
||||
generateCreatePullRequestURL={generateCreatePullRequestURL}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
|
||||
Reference in new issue
Block a user