mirror of
https://github.com/supabase/supabase.git
synced 2026-05-06 14:05:05 +08:00
Refactor merge page into smaller components + add admonition if branch cannot be merged via dashboard (#45515)
## Context Main fix is actually just the disabled check on the "Merge branch" button We're preventing merging of branches via the dashboard if the project has GH integration + "Deploy to production" enabled (the latter we're checking via if the `git_branch` property from the main branch exists, from the GET branches API endpoint) However, the `git_branch` property persists even after disabling the GH integration (by design), and hence we were incorrectly disabling the "Merge branch" button if the user removed the GH integration. Hence the fix is to also check if the project has an active GH integration ## Other changes - Refactored the merge page into smaller components - Added an admonition to callout the "Deploy to production" + what steps to take (otherwise it's not clear at all what to do in this scenario) <img width="1451" height="524" alt="image" src="https://github.com/user-attachments/assets/9df7d432-b220-4f71-b8f4-5ed0fd426afc" /> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Redesigned merge request page interface with dedicated components for title, subtitle, and merge actions, improving user clarity and experience. * Added GitHub production deployment restriction messaging—users cannot proceed with merge requests when this integration deployment method is enabled. * **Refactor** * Enhanced GitHub integration connection query patterns and overall code organization. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
248
apps/studio/components/interfaces/Branching/MergeRequest.tsx
Normal file
248
apps/studio/components/interfaces/Branching/MergeRequest.tsx
Normal file
@@ -0,0 +1,248 @@
|
||||
import { LOCAL_STORAGE_KEYS, useParams } from 'common'
|
||||
import dayjs from 'dayjs'
|
||||
import { GitBranchIcon, GitMerge, MoreVertical, Shield } from 'lucide-react'
|
||||
import Link from 'next/link'
|
||||
import { useRouter } from 'next/router'
|
||||
import { useMemo } from 'react'
|
||||
import { toast } from 'sonner'
|
||||
import {
|
||||
Button,
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuTrigger,
|
||||
} from 'ui'
|
||||
import { TimestampInfo } from 'ui-patterns'
|
||||
|
||||
import { useIsPgDeltaDiffEnabled } from '../App/FeaturePreview/FeaturePreviewContext'
|
||||
import { ReviewWithAI } from '../BranchManagement/ReviewWithAI'
|
||||
import { ButtonTooltip } from '@/components/ui/ButtonTooltip'
|
||||
import { FeaturePreviewBadge } from '@/components/ui/FeaturePreviewBadge'
|
||||
import { useBranchUpdateMutation } from '@/data/branches/branch-update-mutation'
|
||||
import { useBranchesQuery } from '@/data/branches/branches-query'
|
||||
import { useProjectGitHubConnectionQuery } from '@/data/integrations/github-connections-query'
|
||||
import { useProjectDetailQuery } from '@/data/projects/project-detail-query'
|
||||
import { useSendEventMutation } from '@/data/telemetry/send-event-mutation'
|
||||
import { useBranchMergeDiff } from '@/hooks/branches/useBranchMergeDiff'
|
||||
import { useSelectedOrganizationQuery } from '@/hooks/misc/useSelectedOrganization'
|
||||
import { useSelectedProjectQuery } from '@/hooks/misc/useSelectedProject'
|
||||
|
||||
export const MergeTitle = () => {
|
||||
const { ref } = useParams()
|
||||
const { data: project } = useSelectedProjectQuery()
|
||||
const pgDeltaDiffEnabled = useIsPgDeltaDiffEnabled()
|
||||
|
||||
const parentProjectRef = project?.parent_project_ref
|
||||
|
||||
const { data: branches } = useBranchesQuery(
|
||||
{ projectRef: parentProjectRef },
|
||||
{
|
||||
refetchOnMount: 'always',
|
||||
refetchOnWindowFocus: true,
|
||||
staleTime: 0,
|
||||
}
|
||||
)
|
||||
const currentBranch = branches?.find((branch) => branch.project_ref === ref)
|
||||
const mainBranch = branches?.find((branch) => branch.is_default)
|
||||
|
||||
return (
|
||||
<div className="flex items-center gap-x-4">
|
||||
<div className="flex items-center gap-x-2">
|
||||
<span>Merge</span>
|
||||
|
||||
<code className="flex items-center text-code-inline gap-x-1.5 px-2 py-1 border border-border">
|
||||
<GitBranchIcon strokeWidth={1.5} size={14} className="text-foreground-lighter" />
|
||||
{currentBranch?.name}
|
||||
</code>
|
||||
|
||||
<span>into</span>
|
||||
|
||||
<Link href={`/project/${mainBranch?.project_ref}`} className="font-mono inline-flex gap-4">
|
||||
<code className="flex items-center text-code-inline font-mono gap-x-1.5 px-2 py-1 border border-border">
|
||||
<Shield strokeWidth={1.5} size={14} className="text-warning" />
|
||||
{mainBranch?.name || 'main'}
|
||||
</code>
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
{pgDeltaDiffEnabled && (
|
||||
<FeaturePreviewBadge featureKey={LOCAL_STORAGE_KEYS.UI_PREVIEW_PG_DELTA_DIFF} />
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export const MergeSubtitle = () => {
|
||||
const { ref } = useParams()
|
||||
const { data: project } = useSelectedProjectQuery()
|
||||
const parentProjectRef = project?.parent_project_ref
|
||||
|
||||
const { data: branches } = useBranchesQuery(
|
||||
{ projectRef: parentProjectRef },
|
||||
{
|
||||
refetchOnMount: 'always',
|
||||
refetchOnWindowFocus: true,
|
||||
staleTime: 0,
|
||||
}
|
||||
)
|
||||
const currentBranch = branches?.find((branch) => branch.project_ref === ref)
|
||||
|
||||
const subtitle = useMemo(() => {
|
||||
if (!currentBranch?.created_at) return 'Branch information unavailable'
|
||||
|
||||
if (!currentBranch?.review_requested_at) {
|
||||
return 'Not ready for review'
|
||||
}
|
||||
|
||||
const reviewRequestedTime = dayjs(currentBranch.review_requested_at).fromNow()
|
||||
return (
|
||||
<>
|
||||
Request opened{' '}
|
||||
<TimestampInfo
|
||||
className="text-sm"
|
||||
utcTimestamp={currentBranch.review_requested_at}
|
||||
label={reviewRequestedTime}
|
||||
/>
|
||||
</>
|
||||
)
|
||||
}, [currentBranch?.created_at, currentBranch?.review_requested_at])
|
||||
|
||||
return <p className="text-foreground-lighter text-sm">{subtitle}</p>
|
||||
}
|
||||
|
||||
export const MergeActions = ({
|
||||
isWorkflowRunning,
|
||||
isSubmitting,
|
||||
onSelectMerge,
|
||||
}: {
|
||||
isWorkflowRunning: boolean
|
||||
isSubmitting: boolean
|
||||
onSelectMerge: () => void
|
||||
}) => {
|
||||
const router = useRouter()
|
||||
const { ref } = useParams()
|
||||
const { data: project } = useSelectedProjectQuery()
|
||||
const { data: selectedOrg } = useSelectedOrganizationQuery()
|
||||
|
||||
const { mutate: sendEvent } = useSendEventMutation()
|
||||
const { mutate: updateBranch, isPending: isUpdating } = useBranchUpdateMutation({
|
||||
onError: (error) => {
|
||||
toast.error(`Failed to update branch: ${error.message}`)
|
||||
},
|
||||
})
|
||||
|
||||
const parentProjectRef = project?.parent_project_ref
|
||||
const { data: parentProject } = useProjectDetailQuery({ ref: parentProjectRef })
|
||||
const { data: ghConnection } = useProjectGitHubConnectionQuery({ ref: parentProjectRef })
|
||||
|
||||
const { data: branches } = useBranchesQuery(
|
||||
{ projectRef: parentProjectRef },
|
||||
{
|
||||
refetchOnMount: 'always',
|
||||
refetchOnWindowFocus: true,
|
||||
staleTime: 0,
|
||||
}
|
||||
)
|
||||
const currentBranch = branches?.find((branch) => branch.project_ref === ref)
|
||||
const mainBranch = branches?.find((branch) => branch.is_default)
|
||||
|
||||
const {
|
||||
diffContent,
|
||||
isBranchOutOfDateOverall,
|
||||
isLoading: isCombinedDiffLoading,
|
||||
hasChanges: combinedHasChanges,
|
||||
} = useBranchMergeDiff({
|
||||
currentBranchRef: ref,
|
||||
parentProjectRef,
|
||||
currentBranchConnectionString: project?.connectionString || undefined,
|
||||
parentBranchConnectionString: parentProject?.connectionString || undefined,
|
||||
currentBranchCreatedAt: currentBranch?.created_at,
|
||||
})
|
||||
|
||||
const isMergeDisabled =
|
||||
!combinedHasChanges ||
|
||||
isCombinedDiffLoading ||
|
||||
isBranchOutOfDateOverall ||
|
||||
isWorkflowRunning ||
|
||||
(!!ghConnection && Boolean(mainBranch?.git_branch))
|
||||
|
||||
return (
|
||||
<div className="flex items-end gap-2">
|
||||
<ReviewWithAI
|
||||
currentBranch={currentBranch}
|
||||
mainBranch={mainBranch}
|
||||
parentProjectRef={parentProjectRef}
|
||||
diffContent={diffContent}
|
||||
disabled={!currentBranch || !mainBranch || isCombinedDiffLoading}
|
||||
/>
|
||||
{isMergeDisabled ? (
|
||||
<ButtonTooltip
|
||||
tooltip={{
|
||||
content: {
|
||||
side: 'bottom',
|
||||
text: !combinedHasChanges
|
||||
? 'No changes to merge'
|
||||
: isWorkflowRunning
|
||||
? 'Workflow is currently running'
|
||||
: !!ghConnection && Boolean(mainBranch?.git_branch)
|
||||
? 'Deploy to production from GitHub is enabled'
|
||||
: 'Unable to merge at this time',
|
||||
},
|
||||
}}
|
||||
type="primary"
|
||||
loading={isSubmitting}
|
||||
disabled={isMergeDisabled}
|
||||
onClick={onSelectMerge}
|
||||
icon={<GitMerge size={16} strokeWidth={1.5} className="text-brand" />}
|
||||
>
|
||||
Merge branch
|
||||
</ButtonTooltip>
|
||||
) : (
|
||||
<Button
|
||||
type="primary"
|
||||
loading={isSubmitting}
|
||||
onClick={onSelectMerge}
|
||||
icon={<GitMerge size={16} strokeWidth={1.5} className="text-brand" />}
|
||||
>
|
||||
Merge branch
|
||||
</Button>
|
||||
)}
|
||||
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<Button type="default" loading={isUpdating} className="px-1.5" icon={<MoreVertical />} />
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent side="bottom" align="end" className="w-52">
|
||||
<DropdownMenuItem
|
||||
className="gap-x-2"
|
||||
onClick={() => {
|
||||
if (!ref || !parentProjectRef) return
|
||||
updateBranch(
|
||||
{
|
||||
branchRef: ref,
|
||||
projectRef: parentProjectRef,
|
||||
requestReview: false,
|
||||
},
|
||||
{
|
||||
onSuccess: () => {
|
||||
toast.success('Successfully closed merge request')
|
||||
router.push(`/project/${project?.ref}/branches?tab=prs`)
|
||||
sendEvent({
|
||||
action: 'branch_close_merge_request_button_clicked',
|
||||
groups: {
|
||||
project: parentProjectRef ?? 'Unknown',
|
||||
organization: selectedOrg?.slug ?? 'Unknown',
|
||||
},
|
||||
})
|
||||
},
|
||||
}
|
||||
)
|
||||
}}
|
||||
>
|
||||
Close this merge request
|
||||
</DropdownMenuItem>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -47,6 +47,7 @@ export const IntegrationSettings = () => {
|
||||
</Admonition>
|
||||
</ScaffoldContainer>
|
||||
)}
|
||||
|
||||
<GitHubSection />
|
||||
|
||||
{showVercelIntegration && (
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import { useQuery } from '@tanstack/react-query'
|
||||
import { useMemo } from 'react'
|
||||
|
||||
import { integrationKeys } from './keys'
|
||||
import { get, handleError } from '@/data/fetchers'
|
||||
import { useSelectedOrganizationQuery } from '@/hooks/misc/useSelectedOrganization'
|
||||
import type { ResponseError, UseCustomQueryOptions } from '@/types'
|
||||
|
||||
export type GitHubConnectionsVariables = {
|
||||
@@ -47,3 +49,17 @@ export const useGitHubConnectionsQuery = <TData = GitHubConnectionsData>(
|
||||
...options,
|
||||
})
|
||||
}
|
||||
|
||||
export const useProjectGitHubConnectionQuery = ({ ref }: { ref?: string }) => {
|
||||
const { data: organization } = useSelectedOrganizationQuery()
|
||||
const { data: connections, ...props } = useGitHubConnectionsQuery(
|
||||
{ organizationId: organization?.id },
|
||||
{ enabled: !!ref && !!organization?.id }
|
||||
)
|
||||
|
||||
const existingConnection = useMemo(
|
||||
() => connections?.find((c) => c.project.ref === ref),
|
||||
[connections, ref]
|
||||
)
|
||||
return { data: existingConnection, ...props }
|
||||
}
|
||||
|
||||
@@ -1,41 +1,35 @@
|
||||
import { LOCAL_STORAGE_KEYS, useParams } from 'common'
|
||||
import dayjs from 'dayjs'
|
||||
import { AlertTriangle, GitBranchIcon, GitMerge, MoreVertical, Shield, X } from 'lucide-react'
|
||||
import { useParams } from 'common'
|
||||
import { AlertTriangle, GitBranchIcon, X } from 'lucide-react'
|
||||
import Link from 'next/link'
|
||||
import { useRouter } from 'next/router'
|
||||
import { useCallback, useEffect, useMemo, useState } from 'react'
|
||||
import { toast } from 'sonner'
|
||||
import {
|
||||
Badge,
|
||||
Button,
|
||||
cn,
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuTrigger,
|
||||
NavMenu,
|
||||
NavMenuItem,
|
||||
} from 'ui'
|
||||
import { Button, cn, NavMenu, NavMenuItem } from 'ui'
|
||||
import { Admonition } from 'ui-patterns'
|
||||
import { ConfirmationModal } from 'ui-patterns/Dialogs/ConfirmationModal'
|
||||
|
||||
import { useIsPgDeltaDiffEnabled } from '@/components/interfaces/App/FeaturePreview/FeaturePreviewContext'
|
||||
import {
|
||||
MergeActions,
|
||||
MergeSubtitle,
|
||||
MergeTitle,
|
||||
} from '@/components/interfaces/Branching/MergeRequest'
|
||||
import { DatabaseDiffPanel } from '@/components/interfaces/BranchManagement/DatabaseDiffPanel'
|
||||
import { EdgeFunctionsDiffPanel } from '@/components/interfaces/BranchManagement/EdgeFunctionsDiffPanel'
|
||||
import { OutOfDateNotice } from '@/components/interfaces/BranchManagement/OutOfDateNotice'
|
||||
import { ReviewWithAI } from '@/components/interfaces/BranchManagement/ReviewWithAI'
|
||||
import { WorkflowLogsCard } from '@/components/interfaces/BranchManagement/WorkflowLogsCard'
|
||||
import { DefaultLayout } from '@/components/layouts/DefaultLayout'
|
||||
import { PageLayout } from '@/components/layouts/PageLayout/PageLayout'
|
||||
import { ProjectLayoutWithAuth } from '@/components/layouts/ProjectLayout'
|
||||
import { ScaffoldContainer } from '@/components/layouts/Scaffold'
|
||||
import ProductEmptyState from '@/components/to-be-cleaned/ProductEmptyState'
|
||||
import { ButtonTooltip } from '@/components/ui/ButtonTooltip'
|
||||
import { FeaturePreviewBadge } from '@/components/ui/FeaturePreviewBadge'
|
||||
import { InlineLink } from '@/components/ui/InlineLink'
|
||||
import { useBranchDeleteMutation } from '@/data/branches/branch-delete-mutation'
|
||||
import { useBranchMergeMutation } from '@/data/branches/branch-merge-mutation'
|
||||
import { useBranchPushMutation } from '@/data/branches/branch-push-mutation'
|
||||
import { useBranchUpdateMutation } from '@/data/branches/branch-update-mutation'
|
||||
import { useBranchesQuery } from '@/data/branches/branches-query'
|
||||
import { useProjectGitHubConnectionQuery } from '@/data/integrations/github-connections-query'
|
||||
import { useProjectDetailQuery } from '@/data/projects/project-detail-query'
|
||||
import { useSendEventMutation } from '@/data/telemetry/send-event-mutation'
|
||||
import { useBranchMergeDiff } from '@/hooks/branches/useBranchMergeDiff'
|
||||
@@ -59,6 +53,7 @@ const MergePage: NextPageWithLayout = () => {
|
||||
const parentProjectRef = project?.parent_project_ref
|
||||
|
||||
const { data: parentProject } = useProjectDetailQuery({ ref: parentProjectRef })
|
||||
const { data: ghConnection } = useProjectGitHubConnectionQuery({ ref: parentProjectRef })
|
||||
|
||||
const { data: branches } = useBranchesQuery(
|
||||
{ projectRef: parentProjectRef },
|
||||
@@ -87,8 +82,6 @@ const MergePage: NextPageWithLayout = () => {
|
||||
isBranchOutOfDateOverall,
|
||||
missingMigrationsCount,
|
||||
modifiedFunctionsCount,
|
||||
isLoading: isCombinedDiffLoading,
|
||||
hasChanges: combinedHasChanges,
|
||||
} = useBranchMergeDiff({
|
||||
currentBranchRef: ref,
|
||||
parentProjectRef,
|
||||
@@ -97,7 +90,7 @@ const MergePage: NextPageWithLayout = () => {
|
||||
currentBranchCreatedAt: currentBranch?.created_at,
|
||||
})
|
||||
|
||||
const { mutate: updateBranch, isPending: isUpdating } = useBranchUpdateMutation({
|
||||
const { mutate: updateBranch } = useBranchUpdateMutation({
|
||||
onError: (error) => {
|
||||
toast.error(`Failed to update branch: ${error.message}`)
|
||||
},
|
||||
@@ -359,143 +352,42 @@ const MergePage: NextPageWithLayout = () => {
|
||||
)
|
||||
}
|
||||
|
||||
const isMergeDisabled =
|
||||
!combinedHasChanges ||
|
||||
isCombinedDiffLoading ||
|
||||
isBranchOutOfDateOverall ||
|
||||
isWorkflowRunning ||
|
||||
Boolean(mainBranch?.git_branch)
|
||||
|
||||
const primaryActions = (
|
||||
<div className="flex items-end gap-2">
|
||||
<ReviewWithAI
|
||||
currentBranch={currentBranch}
|
||||
mainBranch={mainBranch}
|
||||
parentProjectRef={parentProjectRef}
|
||||
diffContent={diffContent}
|
||||
disabled={!currentBranch || !mainBranch || isCombinedDiffLoading}
|
||||
/>
|
||||
{isMergeDisabled ? (
|
||||
<ButtonTooltip
|
||||
tooltip={{
|
||||
content: {
|
||||
text: !combinedHasChanges
|
||||
? 'No changes to merge'
|
||||
: isWorkflowRunning
|
||||
? 'Workflow is currently running'
|
||||
: Boolean(mainBranch?.git_branch)
|
||||
? 'Deploy to production from GitHub is enabled'
|
||||
: 'Unable to merge at this time',
|
||||
},
|
||||
}}
|
||||
type="primary"
|
||||
loading={isMerging || isSubmitting}
|
||||
disabled={isMergeDisabled}
|
||||
onClick={() => setShowConfirmDialog(true)}
|
||||
icon={<GitMerge size={16} strokeWidth={1.5} className="text-brand" />}
|
||||
>
|
||||
Merge branch
|
||||
</ButtonTooltip>
|
||||
) : (
|
||||
<Button
|
||||
type="primary"
|
||||
loading={isMerging || isSubmitting}
|
||||
onClick={() => setShowConfirmDialog(true)}
|
||||
icon={<GitMerge size={16} strokeWidth={1.5} className="text-brand" />}
|
||||
>
|
||||
Merge branch
|
||||
</Button>
|
||||
)}
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<Button type="default" loading={isUpdating} className="px-1.5" icon={<MoreVertical />} />
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent side="bottom" align="end" className="w-52">
|
||||
<DropdownMenuItem
|
||||
className="gap-x-2"
|
||||
onClick={() => {
|
||||
if (!ref || !parentProjectRef) return
|
||||
updateBranch(
|
||||
{
|
||||
branchRef: ref,
|
||||
projectRef: parentProjectRef,
|
||||
requestReview: false,
|
||||
},
|
||||
{
|
||||
onSuccess: () => {
|
||||
toast.success('Successfully closed merge request')
|
||||
router.push(`/project/${project?.ref}/branches?tab=prs`)
|
||||
sendEvent({
|
||||
action: 'branch_close_merge_request_button_clicked',
|
||||
groups: {
|
||||
project: parentProjectRef ?? 'Unknown',
|
||||
organization: selectedOrg?.slug ?? 'Unknown',
|
||||
},
|
||||
})
|
||||
},
|
||||
}
|
||||
)
|
||||
}}
|
||||
>
|
||||
Close this merge request
|
||||
</DropdownMenuItem>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
</div>
|
||||
)
|
||||
|
||||
const pageTitle = () => (
|
||||
<div className="flex items-center gap-x-4">
|
||||
<span>Merge</span>
|
||||
|
||||
<Link href={`/project/${ref}/editor`}>
|
||||
<Badge className="font-mono text-sm gap-1 px-2">
|
||||
<GitBranchIcon strokeWidth={1.5} size={16} className="text-foreground-muted" />
|
||||
{currentBranch.name}
|
||||
</Badge>
|
||||
</Link>
|
||||
|
||||
<span>into</span>
|
||||
|
||||
<Link
|
||||
href={`/project/${mainBranch?.project_ref}/editor`}
|
||||
className="font-mono inline-flex gap-4"
|
||||
>
|
||||
<Badge className="font-mono text-sm gap-1 px-2">
|
||||
<Shield strokeWidth={1.5} size={16} className="text-warning" />
|
||||
{mainBranch?.name || 'main'}
|
||||
</Badge>
|
||||
</Link>
|
||||
|
||||
{pgDeltaDiffEnabled && (
|
||||
<FeaturePreviewBadge featureKey={LOCAL_STORAGE_KEYS.UI_PREVIEW_PG_DELTA_DIFF} />
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
|
||||
const pageSubtitle = () => {
|
||||
if (!currentBranch?.created_at) return 'Branch information unavailable'
|
||||
|
||||
if (!currentBranch?.review_requested_at) {
|
||||
return 'Not ready for review'
|
||||
}
|
||||
|
||||
const reviewRequestedTime = dayjs(currentBranch.review_requested_at).fromNow()
|
||||
return `Request opened ${reviewRequestedTime}`
|
||||
}
|
||||
const hasGHProductionDeployEnabled = !!ghConnection && Boolean(mainBranch?.git_branch)
|
||||
|
||||
return (
|
||||
<PageLayout
|
||||
title={pageTitle()}
|
||||
subtitle={pageSubtitle()}
|
||||
title={<MergeTitle />}
|
||||
subtitle={<MergeSubtitle />}
|
||||
breadcrumbs={breadcrumbs}
|
||||
primaryActions={primaryActions}
|
||||
primaryActions={
|
||||
<MergeActions
|
||||
isWorkflowRunning={isWorkflowRunning}
|
||||
isSubmitting={isMerging || isSubmitting}
|
||||
onSelectMerge={() => setShowConfirmDialog(true)}
|
||||
/>
|
||||
}
|
||||
size="full"
|
||||
className="h-full border-b-0 pb-0"
|
||||
>
|
||||
<div className="border-b">
|
||||
<ScaffoldContainer size="full">
|
||||
{isBranchOutOfDateOverall && !currentWorkflowRunId ? (
|
||||
{hasGHProductionDeployEnabled ? (
|
||||
<Admonition
|
||||
type="default"
|
||||
title="Branch cannot be merged as deploy to production from GitHub is enabled"
|
||||
className="my-4"
|
||||
>
|
||||
<p className="text-balance">
|
||||
Branches should be managed via GitHub to prevent drifts in migrations from your
|
||||
repository's state. You may either move your schema changes to a GitHub pull
|
||||
request, or disable "Deploy to production" in the{' '}
|
||||
<InlineLink href={`/project/${parentProjectRef}/settings/integrations`}>
|
||||
GitHub integration settings
|
||||
</InlineLink>
|
||||
.
|
||||
</p>
|
||||
</Admonition>
|
||||
) : isBranchOutOfDateOverall && !currentWorkflowRunId ? (
|
||||
<OutOfDateNotice
|
||||
isBranchOutOfDateMigrations={isBranchOutOfDateMigrations}
|
||||
missingMigrationsCount={missingMigrationsCount}
|
||||
@@ -578,6 +470,7 @@ const MergePage: NextPageWithLayout = () => {
|
||||
</NavMenu>
|
||||
</ScaffoldContainer>
|
||||
</div>
|
||||
|
||||
<ScaffoldContainer size="full" className="flex min-h-0 flex-1 flex-col pt-6 pb-12">
|
||||
<div className="flex min-h-0 flex-1 flex-col">
|
||||
{currentTab === 'database' ? (
|
||||
|
||||
Reference in New Issue
Block a user