mirror of
https://github.com/supabase/supabase.git
synced 2026-10-14 21:59:16 +03:00
fixes
This commit is contained in:
1 parent
67eebdd850
commit
862e30864a
8 files changed
+139
-96
No files matched your search
@@ -27,13 +27,8 @@ import { Button } from 'ui'
|
||||
import ConfirmationModal from 'ui-patterns/Dialogs/ConfirmationModal'
|
||||
import TextConfirmModal from 'ui-patterns/Dialogs/TextConfirmModal'
|
||||
import { BranchLoader, BranchManagementSection, BranchRow, MergeRequestRow } from './BranchPanels'
|
||||
import { CreateBranchModal } from './CreateBranchModal'
|
||||
import {
|
||||
BranchingEmptyState,
|
||||
PreviewBranchesEmptyState,
|
||||
PullRequestsEmptyState,
|
||||
} from './EmptyStates'
|
||||
import Overview from './Overview'
|
||||
import { PreviewBranchesEmptyState, PullRequestsEmptyState } from './EmptyStates'
|
||||
import { Overview } from './Overview'
|
||||
|
||||
type Tab = 'overview' | 'prs' | 'branches'
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@ import {
|
||||
} from 'ui'
|
||||
import { sanitizeRoute } from './ProjectDropdown'
|
||||
import { useFlag } from 'hooks/ui/useFlag'
|
||||
import { useAppStateSnapshot } from 'state/app-state'
|
||||
|
||||
const BranchLink = ({
|
||||
branch,
|
||||
@@ -80,11 +81,11 @@ export const BranchDropdown = () => {
|
||||
const gitlessBranching = useFlag('gitlessBranching')
|
||||
const projectDetails = useSelectedProject()
|
||||
const snap = useAppStateSnapshot()
|
||||
const [open, setOpen] = useState(false)
|
||||
const [showDeployRequestModal, setShowDeployRequestModal] = useState(false)
|
||||
|
||||
const projectRef = projectDetails?.parent_project_ref || ref
|
||||
|
||||
const [open, setOpen] = useState(false)
|
||||
const [showDeployRequestModal, setShowDeployRequestModal] = useState(false)
|
||||
const {
|
||||
data: branches,
|
||||
isLoading,
|
||||
@@ -116,8 +117,6 @@ export const BranchDropdown = () => {
|
||||
|
||||
const BRANCHING_GITHUB_DISCUSSION_LINK = 'https://github.com/orgs/supabase/discussions/18937'
|
||||
|
||||
const [open, setOpen] = useState(false)
|
||||
|
||||
const MenuContent = ({
|
||||
branchList,
|
||||
showSearch,
|
||||
@@ -162,23 +161,26 @@ export const BranchDropdown = () => {
|
||||
<p>Create branch</p>
|
||||
</div>
|
||||
</CommandItem_Shadcn_>
|
||||
{gitlessBranching && isBranch && selectedBranch && !selectedBranch.is_default && (
|
||||
<>
|
||||
<CommandItem_Shadcn_
|
||||
className="cursor-pointer w-full"
|
||||
onSelect={() => {
|
||||
setOpen(false)
|
||||
setShowDeployRequestModal(true)
|
||||
}}
|
||||
onClick={() => setOpen(false)}
|
||||
>
|
||||
<div className="w-full flex items-center gap-2">
|
||||
<Send size={14} strokeWidth={1.5} />
|
||||
Create deploy request
|
||||
</div>
|
||||
</CommandItem_Shadcn_>
|
||||
</>
|
||||
)}
|
||||
{gitlessBranching &&
|
||||
isBranchingEnabled &&
|
||||
selectedBranch &&
|
||||
!selectedBranch.is_default && (
|
||||
<>
|
||||
<CommandItem_Shadcn_
|
||||
className="cursor-pointer w-full"
|
||||
onSelect={() => {
|
||||
setOpen(false)
|
||||
setShowDeployRequestModal(true)
|
||||
}}
|
||||
onClick={() => setOpen(false)}
|
||||
>
|
||||
<div className="w-full flex items-center gap-2">
|
||||
<Send size={14} strokeWidth={1.5} />
|
||||
Create deploy request
|
||||
</div>
|
||||
</CommandItem_Shadcn_>
|
||||
</>
|
||||
)}
|
||||
<CommandItem_Shadcn_
|
||||
className="cursor-pointer w-full"
|
||||
onSelect={() => {
|
||||
|
||||
@@ -27,7 +27,7 @@ export async function createMergeRequest({
|
||||
id: `mr-${Date.now()}`,
|
||||
project_ref: projectRef,
|
||||
base: '6b3b94fe-f9f9-4c12-8796-ff67db250757',
|
||||
head: '7902c891-5286-4366-a44d-007b39e0782d',
|
||||
head: '3b13fe5b-a529-4bc4-a0c8-a333f83f03e9',
|
||||
title,
|
||||
description,
|
||||
merge_requested_by: 'current-user-id',
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
import { useMutation, UseMutationOptions, useQueryClient } from '@tanstack/react-query'
|
||||
import { toast } from 'sonner'
|
||||
import { handleError, del } from 'data/fetchers'
|
||||
import type { ResponseError } from 'types'
|
||||
import { mergeRequestKeys } from './keys'
|
||||
|
||||
export type MergeRequestDeleteVariables = {
|
||||
id: string
|
||||
projectRef: string
|
||||
}
|
||||
|
||||
export async function deleteMergeRequest({
|
||||
id,
|
||||
projectRef,
|
||||
}: MergeRequestDeleteVariables): Promise<void> {
|
||||
// Mock data for development
|
||||
return new Promise((resolve) => {
|
||||
setTimeout(() => {
|
||||
resolve()
|
||||
}, 500)
|
||||
})
|
||||
|
||||
// Real API call (commented out for now)
|
||||
// const { error } = await del('/v1/merge-requests/{merge_request_id}', {
|
||||
// params: {
|
||||
// path: { merge_request_id: id },
|
||||
// },
|
||||
// })
|
||||
|
||||
// if (error) handleError(error)
|
||||
}
|
||||
|
||||
export const useMergeRequestDeleteMutation = ({
|
||||
onSuccess,
|
||||
onError,
|
||||
...options
|
||||
}: Omit<
|
||||
UseMutationOptions<void, ResponseError, MergeRequestDeleteVariables>,
|
||||
'mutationFn'
|
||||
> = {}) => {
|
||||
const queryClient = useQueryClient()
|
||||
return useMutation<void, ResponseError, MergeRequestDeleteVariables>(
|
||||
(vars) => deleteMergeRequest(vars),
|
||||
{
|
||||
async onSuccess(data, variables, context) {
|
||||
const { projectRef } = variables
|
||||
await queryClient.invalidateQueries(mergeRequestKeys.list(projectRef))
|
||||
await queryClient.invalidateQueries(mergeRequestKeys.detail(projectRef, variables.id))
|
||||
await onSuccess?.(data, variables, context)
|
||||
},
|
||||
async onError(data, variables, context) {
|
||||
if (onError === undefined) {
|
||||
toast.error(`Failed to delete merge request: ${data.message}`)
|
||||
} else {
|
||||
onError(data, variables, context)
|
||||
}
|
||||
},
|
||||
...options,
|
||||
}
|
||||
)
|
||||
}
|
||||
@@ -22,14 +22,12 @@ export async function getMergeRequest(
|
||||
id: id,
|
||||
project_ref: 'mock-project-ref',
|
||||
base: '6b3b94fe-f9f9-4c12-8796-ff67db250757',
|
||||
head: '7902c891-5286-4366-a44d-007b39e0782d',
|
||||
head: '3b13fe5b-a529-4bc4-a0c8-a333f83f03e9',
|
||||
title: 'Deploy feature-auth to production',
|
||||
description:
|
||||
'This deploy request includes new authentication features, improved error handling, and several bug fixes. The changes have been thoroughly tested in the staging environment.',
|
||||
merge_requested_by: 'user-123',
|
||||
merge_approved_by: null,
|
||||
merge_requested_at: '2024-01-15T10:30:00Z',
|
||||
merge_approved_at: null,
|
||||
created_at: '2024-01-15T10:30:00Z',
|
||||
updated_at: '2024-01-15T10:30:00Z',
|
||||
})
|
||||
|
||||
@@ -22,7 +22,7 @@ export async function updateMergeRequest({
|
||||
id: id,
|
||||
project_ref: 'mock-project-ref',
|
||||
base: '6b3b94fe-f9f9-4c12-8796-ff67db250757',
|
||||
head: '7902c891-5286-4366-a44d-007b39e0782d',
|
||||
head: '3b13fe5b-a529-4bc4-a0c8-a333f83f03e9',
|
||||
title: 'Deploy feature-auth to production',
|
||||
description:
|
||||
'This deploy request includes new authentication features, improved error handling, and several bug fixes.',
|
||||
|
||||
@@ -15,9 +15,7 @@ export type MergeRequest = {
|
||||
title: string
|
||||
description?: string
|
||||
merge_requested_by: string | null
|
||||
merge_approved_by: string | null
|
||||
merge_requested_at: string | null
|
||||
merge_approved_at: string | null
|
||||
created_at: string
|
||||
updated_at: string
|
||||
}
|
||||
@@ -36,13 +34,11 @@ export async function getMergeRequests(
|
||||
id: 'mr-1',
|
||||
project_ref: projectRef,
|
||||
base: '6b3b94fe-f9f9-4c12-8796-ff67db250757',
|
||||
head: '7902c891-5286-4366-a44d-007b39e0782d',
|
||||
head: '3b13fe5b-a529-4bc4-a0c8-a333f83f03e9',
|
||||
title: 'Deploy feature-auth to production',
|
||||
description: 'This PR includes new authentication features and bug fixes.',
|
||||
merge_requested_by: 'user-123',
|
||||
merge_approved_by: null,
|
||||
merge_requested_at: '2024-01-15T10:30:00Z',
|
||||
merge_approved_at: null,
|
||||
created_at: '2024-01-15T10:30:00Z',
|
||||
updated_at: '2024-01-15T10:30:00Z',
|
||||
},
|
||||
@@ -50,13 +46,11 @@ export async function getMergeRequests(
|
||||
id: 'mr-2',
|
||||
project_ref: projectRef,
|
||||
base: '6b3b94fe-f9f9-4c12-8796-ff67db250757',
|
||||
head: '7902c891-5286-4366-a44d-007b39e0782d',
|
||||
head: '3b13fe5b-a529-4bc4-a0c8-a333f83f03e9',
|
||||
title: 'Deploy hotfix-db-migration to production',
|
||||
description: 'Critical database schema updates for user table.',
|
||||
merge_requested_by: 'user-456',
|
||||
merge_approved_by: 'user-789',
|
||||
merge_requested_at: '2024-01-14T14:20:00Z',
|
||||
merge_approved_at: '2024-01-14T15:45:00Z',
|
||||
created_at: '2024-01-14T14:20:00Z',
|
||||
updated_at: '2024-01-14T15:45:00Z',
|
||||
},
|
||||
|
||||
@@ -12,7 +12,7 @@ import { useBranchesQuery } from 'data/branches/branches-query'
|
||||
import { useBranchMergeMutation } from 'data/branches/branch-merge-mutation'
|
||||
import { useBranchPushMutation } from 'data/branches/branch-push-mutation'
|
||||
import { useMergeRequestQuery } from 'data/merge-requests/merge-request-query'
|
||||
import { useMergeRequestUpdateMutation } from 'data/merge-requests/merge-request-update-mutation'
|
||||
import { useMergeRequestDeleteMutation } from 'data/merge-requests/merge-request-delete-mutation'
|
||||
import { useBranchMergeDiff } from 'hooks/branches/useBranchMergeDiff'
|
||||
import { useWorkflowManagement } from 'hooks/branches/useWorkflowManagement'
|
||||
import DatabaseDiffPanel from 'components/interfaces/BranchManagement/DatabaseDiffPanel'
|
||||
@@ -31,6 +31,7 @@ import {
|
||||
AlertTriangle,
|
||||
CheckCircle,
|
||||
Clock,
|
||||
Trash,
|
||||
} from 'lucide-react'
|
||||
import Link from 'next/link'
|
||||
import { ButtonTooltip } from 'components/ui/ButtonTooltip'
|
||||
@@ -49,7 +50,6 @@ const MergeRequestPage: NextPageWithLayout = () => {
|
||||
const [isSubmitting, setIsSubmitting] = useState(false)
|
||||
const [workflowFinalStatus, setWorkflowFinalStatus] = useState<string | null>(null)
|
||||
|
||||
const isBranch = project?.parent_project_ref !== undefined
|
||||
const parentProjectRef = project?.parent_project_ref || project?.ref
|
||||
|
||||
const parentProject = useProjectByRef(parentProjectRef)
|
||||
@@ -124,8 +124,7 @@ const MergeRequestPage: NextPageWithLayout = () => {
|
||||
onWorkflowComplete: (status) => {
|
||||
setWorkflowFinalStatus(status)
|
||||
refetchDiff()
|
||||
edgeFunctionsDiff.refetchCurrentBranchFunctions()
|
||||
edgeFunctionsDiff.refetchMainBranchFunctions()
|
||||
edgeFunctionsDiff.clearDiffsOptimistically()
|
||||
},
|
||||
})
|
||||
|
||||
@@ -136,8 +135,7 @@ const MergeRequestPage: NextPageWithLayout = () => {
|
||||
onWorkflowComplete: (status) => {
|
||||
setWorkflowFinalStatus(status)
|
||||
refetchDiff()
|
||||
edgeFunctionsDiff.refetchCurrentBranchFunctions()
|
||||
edgeFunctionsDiff.refetchMainBranchFunctions()
|
||||
edgeFunctionsDiff.clearDiffsOptimistically()
|
||||
},
|
||||
})
|
||||
|
||||
@@ -186,18 +184,11 @@ const MergeRequestPage: NextPageWithLayout = () => {
|
||||
const { mutate: mergeBranch, isLoading: isMerging } = useBranchMergeMutation({
|
||||
onSuccess: (data) => {
|
||||
setIsSubmitting(false)
|
||||
if (data.hadChanges) {
|
||||
if (data.migrationCreated) {
|
||||
toast.success('Migration created and branch merge initiated!')
|
||||
} else {
|
||||
toast.success('Branch merge initiated!')
|
||||
}
|
||||
// Add workflow run ID to URL for persistence
|
||||
if (data.workflowRunId) {
|
||||
addWorkflowRun(data.workflowRunId)
|
||||
}
|
||||
if (data.workflowRunId) {
|
||||
toast.success('Branch merge initiated!')
|
||||
addWorkflowRun(data.workflowRunId)
|
||||
} else {
|
||||
toast.info('No changes to merge - branch merged successfully!')
|
||||
toast.info('No changes to merge')
|
||||
}
|
||||
},
|
||||
onError: (error) => {
|
||||
@@ -206,15 +197,15 @@ const MergeRequestPage: NextPageWithLayout = () => {
|
||||
},
|
||||
})
|
||||
|
||||
const { mutate: updateMergeRequest, isLoading: isUpdatingMergeRequest } =
|
||||
useMergeRequestUpdateMutation({
|
||||
const { mutate: deleteMergeRequest, isLoading: isDeletingMergeRequest } =
|
||||
useMergeRequestDeleteMutation({
|
||||
onSuccess: () => {
|
||||
toast.success('Merge request approved!')
|
||||
// Proceed with actual merge
|
||||
handleMerge()
|
||||
toast.success('Merge request deleted!')
|
||||
// Navigate back to merge requests list
|
||||
router.push(`/project/${parentProjectRef}/branches?tab=prs`)
|
||||
},
|
||||
onError: (error) => {
|
||||
toast.error(`Failed to approve merge request: ${error.message}`)
|
||||
onError: (error: any) => {
|
||||
toast.error(`Failed to delete merge request: ${error.message}`)
|
||||
},
|
||||
})
|
||||
|
||||
@@ -237,13 +228,11 @@ const MergeRequestPage: NextPageWithLayout = () => {
|
||||
})
|
||||
}
|
||||
|
||||
const handleApproveMerge = () => {
|
||||
const handleDeleteMergeRequest = () => {
|
||||
if (!mergeRequest?.id || !parentProjectRef) return
|
||||
// TODO: Get current user ID
|
||||
updateMergeRequest({
|
||||
deleteMergeRequest({
|
||||
id: mergeRequest.id,
|
||||
projectRef: parentProjectRef,
|
||||
merge_approved_by: 'current-user-id', // This should be replaced with actual user ID
|
||||
})
|
||||
}
|
||||
|
||||
@@ -355,25 +344,11 @@ const MergeRequestPage: NextPageWithLayout = () => {
|
||||
)
|
||||
}
|
||||
|
||||
const isMergeDisabled =
|
||||
!combinedHasChanges ||
|
||||
isCombinedDiffLoading ||
|
||||
isBranchOutOfDateOverall ||
|
||||
!mergeRequest.merge_approved_by
|
||||
const isMergeDisabled = !combinedHasChanges || isCombinedDiffLoading || isBranchOutOfDateOverall
|
||||
|
||||
// Update primary actions - separate approve and merge actions
|
||||
// Update primary actions - just merge action
|
||||
const primaryActions = (
|
||||
<div className="flex items-end gap-2">
|
||||
{!mergeRequest.merge_approved_by && (
|
||||
<Button
|
||||
type="default"
|
||||
loading={isUpdatingMergeRequest}
|
||||
onClick={handleApproveMerge}
|
||||
icon={<CheckCircle size={16} strokeWidth={1.5} />}
|
||||
>
|
||||
Approve
|
||||
</Button>
|
||||
)}
|
||||
{isMergeDisabled ? (
|
||||
<ButtonTooltip
|
||||
tooltip={{
|
||||
@@ -403,20 +378,15 @@ const MergeRequestPage: NextPageWithLayout = () => {
|
||||
</div>
|
||||
)
|
||||
|
||||
const pageTitle = () => (
|
||||
<div className="flex items-center gap-4 flex-wrap">
|
||||
<span>{mergeRequest?.title || `${mergeRequest?.head} → ${mergeRequest?.base}`}</span>
|
||||
</div>
|
||||
)
|
||||
const pageTitle = () => mergeRequest?.title || `${mergeRequest?.head} → ${mergeRequest?.base}`
|
||||
|
||||
const pageSubtitle = () => {
|
||||
if (!mergeRequest?.merge_requested_at) return 'Merge request information unavailable'
|
||||
|
||||
const requestedTime = dayjs(mergeRequest.merge_requested_at).fromNow()
|
||||
const approvalStatus = mergeRequest.merge_approved_by ? 'Approved' : 'Open'
|
||||
return (
|
||||
<div className="flex items-center gap-2 mt-2">
|
||||
<Badge variant="warning">{approvalStatus}</Badge>
|
||||
<Badge variant="warning">Open</Badge>
|
||||
{mergeRequest.merge_requested_by} requested to merge
|
||||
<Link
|
||||
href={`/project/${headBranch?.project_ref}/editor`}
|
||||
@@ -485,13 +455,36 @@ const MergeRequestPage: NextPageWithLayout = () => {
|
||||
}
|
||||
overrideAction={
|
||||
hasCurrentWorkflowFailed ? (
|
||||
<div className="flex items-center gap-2">
|
||||
<Button
|
||||
type="default"
|
||||
asChild
|
||||
icon={<GitBranchIcon size={16} strokeWidth={1.5} />}
|
||||
className="shrink-0"
|
||||
>
|
||||
<Link href={`/project/${parentProjectRef}/branches`}>
|
||||
Create new branch
|
||||
</Link>
|
||||
</Button>
|
||||
<Button
|
||||
type="outline"
|
||||
loading={isDeletingMergeRequest}
|
||||
onClick={handleDeleteMergeRequest}
|
||||
icon={<Trash size={16} strokeWidth={1.5} />}
|
||||
className="shrink-0"
|
||||
>
|
||||
Delete merge request
|
||||
</Button>
|
||||
</div>
|
||||
) : currentWorkflowRun?.status === 'FUNCTIONS_DEPLOYED' ? (
|
||||
<Button
|
||||
type="default"
|
||||
asChild
|
||||
icon={<GitBranchIcon size={16} strokeWidth={1.5} />}
|
||||
type="outline"
|
||||
loading={isDeletingMergeRequest}
|
||||
onClick={handleDeleteMergeRequest}
|
||||
icon={<Trash size={16} strokeWidth={1.5} />}
|
||||
className="shrink-0"
|
||||
>
|
||||
<Link href={`/project/${parentProjectRef}/branches`}>Create new branch</Link>
|
||||
Delete merge request
|
||||
</Button>
|
||||
) : undefined
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user