Files
supabase/apps/studio/data/integrations/vercel-integration-create-mutation.ts
Danny White 9b3e0a9060 show Vercel connection errors inline (#48473)
## What kind of change does this PR introduce?

Bug fix.

## What is the current behavior?

Vercel install and project-link failures use transient toasts.

## What is the new behavior?

Failures remain visible below the relevant action and clear when the
user retries or changes a selection.

The Vercel mutation hooks expose errors without choosing their
presentation. Interstitial callers render them inline, while existing
non-interstitial callers explicitly retain their toasts.

| Before | After |
| --- | --- |
| <img width="1024" height="759" alt="Install Vercel Integration
Supabase"
src="https://github.com/user-attachments/assets/6348cdd2-220a-4ad8-89f9-7fc51de36a3c"
/> | <img width="1024" height="759" alt="Install Vercel Integration
Supabase"
src="https://github.com/user-attachments/assets/ecc50c4e-daab-4f6d-bf86-7282e2aff92c"
/> |

## To test

1. Switch to `dnywh/inline-vercel-errors` (this branch).
2. Open `apps/studio/pages/integrations/vercel/install.tsx`.
3. Find the `actionError` assignment immediately below
`useVercelIntegrationCreateMutation` and replace the whole assignment
with:
   ```tsx
   const actionError = 'Creating Vercel integration failed: Test error'
   ```
4. With local Studio running and while signed in, open
`http://localhost:8082/integrations/vercel/install?code=test&configurationId=test&source=marketplace`
5. Confirm the error remains visible below **Install integration**. No
Vercel installation or real authorisation code is required.
6. Revert the temporary edit.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

## Bug Fixes

* Improved error handling across Vercel project connection and
installation flows.
* Validation, duplicate-connection, and connection failures now appear
inline in the relevant setup steps.
* Errors clear automatically when the selected project or organization
changes.
* Notifications remain available in supported flows, including new
project creation and side-panel setup.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-08-05 16:06:58 +10:00

76 lines
2.3 KiB
TypeScript

import { useMutation, useQueryClient } from '@tanstack/react-query'
import { integrationKeys } from './keys'
import { handleError, post } from '@/data/fetchers'
import type { ResponseError, UseCustomMutationOptions } from '@/types'
export type VercelIntegrationCreateVariables = {
code: string
configurationId: string
orgSlug: string
metadata: { [key: string]: string }
source: string
// teamId is only present when a team is being installed
// personal accounts (hobby) will not have this value defined
teamId?: string
}
export async function createVercelIntegration({
code,
configurationId,
orgSlug,
metadata,
source,
teamId,
}: VercelIntegrationCreateVariables) {
const { data, error } = await post('/platform/integrations/vercel', {
body: {
code,
configuration_id: configurationId,
organization_slug: orgSlug,
metadata: metadata as Record<string, never>,
source,
teamId,
},
})
if (error) handleError(error)
// [Joshen] API isn't typed on this endpoint
// https://github.com/supabase/platform/blob/develop/api/src/routes/platform/integrations/vercel/vercel-integration.controller.ts#L50
return data as { id: string }
}
type VercelIntegrationCreateData = Awaited<ReturnType<typeof createVercelIntegration>>
export const useVercelIntegrationCreateMutation = ({
onSuccess,
onError,
...options
}: Omit<
UseCustomMutationOptions<
VercelIntegrationCreateData,
ResponseError,
VercelIntegrationCreateVariables
>,
'mutationFn'
> = {}) => {
const queryClient = useQueryClient()
return useMutation<VercelIntegrationCreateData, ResponseError, VercelIntegrationCreateVariables>({
mutationFn: (vars) => createVercelIntegration(vars),
async onSuccess(data, variables, context) {
await Promise.all([
queryClient.invalidateQueries({ queryKey: integrationKeys.integrationsList() }),
queryClient.invalidateQueries({
queryKey: integrationKeys.integrationsListWithOrg(variables.orgSlug),
}),
queryClient.invalidateQueries({ queryKey: integrationKeys.vercelProjectList(data.id) }),
])
await onSuccess?.(data, variables, context)
},
async onError(data, variables, context) {
await onError?.(data, variables, context)
},
...options,
})
}