mirror of
https://github.com/supabase/supabase.git
synced 2026-10-11 04:15:04 +03:00
more project link stuff and integration panel UI changes. Side panel added for project linking idea
This commit is contained in:
1 parent
0343189017
commit
bb47aeff34
11 files changed
+351
-47
No files matched your search
@@ -1,12 +1,11 @@
|
||||
import { useParams } from 'common'
|
||||
import { Markdown } from 'components/interfaces/Markdown'
|
||||
import { Integration, IntegrationProjectConnection } from 'data/integrations/integrations-query'
|
||||
import dayjs from 'dayjs'
|
||||
import { useStore } from 'hooks'
|
||||
import Image from 'next/image'
|
||||
import { useRouter } from 'next/router'
|
||||
|
||||
import React from 'react'
|
||||
import { Project } from 'types'
|
||||
|
||||
import { Badge, Button, IconArrowRight, IconGitHub, IconSquare } from 'ui'
|
||||
import { cn } from 'ui/src/utils/cn'
|
||||
|
||||
@@ -14,7 +13,6 @@ const ICON_STROKE_WIDTH = 2
|
||||
const ICON_SIZE = 14
|
||||
export interface IntegrationInstallationProps extends React.HTMLAttributes<HTMLLIElement> {
|
||||
title: string
|
||||
// orgName: string
|
||||
connection: Integration
|
||||
}
|
||||
|
||||
@@ -40,11 +38,9 @@ const HandleIcon = ({ type }: { type: HandleIconType }) => {
|
||||
</svg>
|
||||
)
|
||||
|
||||
// <IconTriangle strokeWidth={ICON_STROKE_WIDTH} size={ICON_SIZE} />
|
||||
break
|
||||
case 'Supabase':
|
||||
return <img src="/img/supabase-logo.svg" alt="Supabase" className="w-3.5"></img>
|
||||
// <IconCloudLightning strokeWidth={ICON_STROKE_WIDTH} size={ICON_SIZE} />
|
||||
break
|
||||
|
||||
default:
|
||||
@@ -118,10 +114,11 @@ const IntegrationInstallation = React.forwardRef<HTMLLIElement, IntegrationInsta
|
||||
export interface IntegrationConnectionProps extends React.HTMLAttributes<HTMLLIElement> {
|
||||
connection: IntegrationProjectConnection
|
||||
type: Integration['integration']['name']
|
||||
actions: React.ReactNode
|
||||
}
|
||||
|
||||
const IntegrationConnection = React.forwardRef<HTMLLIElement, IntegrationConnectionProps>(
|
||||
({ className, connection, type, ...props }, ref) => {
|
||||
({ className, connection, type, actions, ...props }, ref) => {
|
||||
const { app } = useStore()
|
||||
|
||||
const { projects } = app
|
||||
@@ -163,9 +160,7 @@ const IntegrationConnection = React.forwardRef<HTMLLIElement, IntegrationConnect
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<Button type="default">Disconnect</Button>
|
||||
</div>
|
||||
<div>{actions}</div>
|
||||
</div>
|
||||
</li>
|
||||
)
|
||||
@@ -216,8 +211,6 @@ const EmptyIntegrationConnection = React.forwardRef<
|
||||
>
|
||||
<div className="absolute w-8 rounded-bl-full border-b border-l h-10 -left-px"></div>
|
||||
<div
|
||||
{...props}
|
||||
ref={ref}
|
||||
className={cn(
|
||||
'w-full',
|
||||
'border border-dashed',
|
||||
@@ -240,10 +233,6 @@ const IntegrationConnectionHeader = React.forwardRef<HTMLDivElement, Integration
|
||||
({ className, name, markdown = '', ...props }, ref) => {
|
||||
return (
|
||||
<div {...props} ref={ref} className={cn('border-l ml-6 pl-8 pt-6 pb-3', className)}>
|
||||
{/* <h3>{props.title}</h3>
|
||||
<p className="text-scale-1100 text-sm">
|
||||
Repository connections for <span className="capitalize">{name?.toLowerCase()}</span>
|
||||
</p> */}
|
||||
<Markdown content={markdown} className="" />
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -2,8 +2,7 @@ import { databaseIcon, vercelIcon } from 'components/to-be-cleaned/ListIcons'
|
||||
import { useIntegrationConnectionsCreateMutation } from 'data/integrations/integration-connections-create-mutation'
|
||||
import { VercelProjectsResponse } from 'data/integrations/integrations-vercel-projects-query'
|
||||
import { useState } from 'react'
|
||||
import { TRUE } from 'sass'
|
||||
import { Button, IconArrowRight, IconPlus, IconX, Listbox } from 'ui'
|
||||
import { Button, IconArrowRight, IconPlus, IconX, Listbox, Select } from 'ui'
|
||||
|
||||
interface Project {
|
||||
id: string
|
||||
@@ -18,6 +17,7 @@ export interface ProjectLinkerProps {
|
||||
foreignProjects: VercelProjectsResponse[]
|
||||
supabaseProjects: Project[]
|
||||
onCreateConnections?: () => void
|
||||
installedConnections?: any[]
|
||||
}
|
||||
|
||||
const UNDEFINED_SELECT_VALUE = 'undefined'
|
||||
@@ -28,20 +28,34 @@ const ProjectLinker = ({
|
||||
foreignProjects,
|
||||
supabaseProjects,
|
||||
onCreateConnections: _onCreateConnections,
|
||||
installedConnections,
|
||||
}: ProjectLinkerProps) => {
|
||||
const [connections, setConnections] = useState([
|
||||
{
|
||||
foreignProjectId: UNDEFINED_SELECT_VALUE,
|
||||
supabaseProjectId: UNDEFINED_SELECT_VALUE,
|
||||
integrationId: INTEGRATION_INTERNAL_ID,
|
||||
metadata: UNDEFINED_METADATA_VALUE,
|
||||
},
|
||||
])
|
||||
const [connections, setConnections] = useState(
|
||||
installedConnections && installedConnections.length > 0
|
||||
? installedConnections?.map((connection) => {
|
||||
return {
|
||||
foreignProjectId: connection?.foreign_project_id,
|
||||
supabaseProjectId: connection?.supabase_project_id,
|
||||
integrationId: INTEGRATION_INTERNAL_ID,
|
||||
metadata: UNDEFINED_METADATA_VALUE,
|
||||
}
|
||||
})
|
||||
: [
|
||||
{
|
||||
foreignProjectId: UNDEFINED_SELECT_VALUE,
|
||||
supabaseProjectId: UNDEFINED_SELECT_VALUE,
|
||||
integrationId: INTEGRATION_INTERNAL_ID,
|
||||
metadata: UNDEFINED_METADATA_VALUE,
|
||||
},
|
||||
]
|
||||
)
|
||||
|
||||
console.log('installedConnections', installedConnections)
|
||||
console.log('connections', connections)
|
||||
console.log('foreignProjects', foreignProjects)
|
||||
console.log('supabaseProjects', supabaseProjects)
|
||||
|
||||
function onSetForeignProjectId(idx: number, id: string) {
|
||||
console.log(id)
|
||||
|
||||
console.log(foreignProjects)
|
||||
const newConnections = [...connections]
|
||||
const projectDetails = foreignProjects.filter((x) => x.id === id)[0]
|
||||
newConnections[idx].metadata = { ...projectDetails }
|
||||
@@ -86,13 +100,14 @@ const ProjectLinker = ({
|
||||
})
|
||||
|
||||
function onCreateConnections() {
|
||||
console.log('connections', connections)
|
||||
createConnections({
|
||||
organizationIntegrationId,
|
||||
connections,
|
||||
})
|
||||
}
|
||||
|
||||
console.log(connections)
|
||||
|
||||
return (
|
||||
<div className="flex flex-col gap-4">
|
||||
<ul>
|
||||
@@ -159,29 +174,27 @@ const ProjectLinkerItem = ({
|
||||
removeConnection,
|
||||
canRemove,
|
||||
}: ProjectLinkerItemProps) => {
|
||||
console.log(supabaseProjectId)
|
||||
return (
|
||||
<li className="py-2">
|
||||
<div className="relative flex w-full space-x-2">
|
||||
<div className="w-1/2 flex-grow">
|
||||
<Listbox
|
||||
value={supabaseProjectId ?? UNDEFINED_SELECT_VALUE}
|
||||
onChange={setSupabaseProjectId}
|
||||
>
|
||||
<Listbox.Option value={UNDEFINED_SELECT_VALUE} label="Choose a project" disabled>
|
||||
<Select value={supabaseProjectId} onChange={(e) => setSupabaseProjectId(e.target.value)}>
|
||||
<Select.Option value={UNDEFINED_SELECT_VALUE} label="Choose a project" disabled>
|
||||
Choose a project
|
||||
</Listbox.Option>
|
||||
</Select.Option>
|
||||
|
||||
{supabaseProjects.map((project) => (
|
||||
<Listbox.Option
|
||||
<Select.Option
|
||||
key={project.id}
|
||||
value={project.id}
|
||||
label={project.name}
|
||||
addOnBefore={() => databaseIcon}
|
||||
// label={project.name}
|
||||
// addOnBefore={() => databaseIcon}
|
||||
>
|
||||
{project.name}
|
||||
</Listbox.Option>
|
||||
</Select.Option>
|
||||
))}
|
||||
</Listbox>
|
||||
</Select>
|
||||
</div>
|
||||
<div className="flex flex-shrink items-center">
|
||||
<IconArrowRight className="text-scale-1000" />
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { useParams } from 'common'
|
||||
import {
|
||||
EmptyIntegrationConnection,
|
||||
IntegrationConnection,
|
||||
@@ -11,11 +12,17 @@ import {
|
||||
ScaffoldSectionContent,
|
||||
ScaffoldSectionDetail,
|
||||
} from 'components/layouts/Scaffold'
|
||||
import { Integration as TIntegration } from 'data/integrations/integrations-query'
|
||||
import { useIntegrationConnectionsCreateMutation } from 'data/integrations/integration-connections-create-mutation'
|
||||
import {
|
||||
Integration as TIntegration,
|
||||
useIntegrationsQuery,
|
||||
} from 'data/integrations/integrations-query'
|
||||
import { useIntegrationsVercelInstalledConnectionDeleteMutation } from 'data/integrations/integrations-vercel-installed-connection-delete-mutation'
|
||||
import { pluralize } from 'lib/helpers'
|
||||
import { EMPTY_ARR } from 'lib/void'
|
||||
import { useMemo } from 'react'
|
||||
import { useGithubConnectionConfigPanelSnapshot } from 'state/github-connection-config-panel'
|
||||
import { Button, Dropdown, IconChevronDown, IconRefreshCcw, IconTrash } from 'ui'
|
||||
|
||||
export interface IntegrationProps {
|
||||
title: string
|
||||
@@ -35,6 +42,11 @@ const Integration = ({
|
||||
integrations = EMPTY_ARR,
|
||||
}: IntegrationProps) => {
|
||||
const githubConnectionConfigPanelShotshot = useGithubConnectionConfigPanelSnapshot()
|
||||
const deleteMutation = useIntegrationsVercelInstalledConnectionDeleteMutation({
|
||||
onSuccess: (data, variables, context) => {
|
||||
// Handle the success case
|
||||
},
|
||||
})
|
||||
|
||||
const ConnectionHeading = ({ integration }: { integration: TIntegration }) => {
|
||||
return (
|
||||
@@ -49,6 +61,16 @@ Repository connections for ${title?.toLowerCase()}
|
||||
)
|
||||
}
|
||||
|
||||
// Call the mutation when needed
|
||||
const handleDelete = (organizationIntegrationId: string, projectIntegrationId: string) => {
|
||||
const variables = {
|
||||
organization_integration_id: organizationIntegrationId,
|
||||
id: projectIntegrationId,
|
||||
}
|
||||
|
||||
deleteMutation.mutate(variables)
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<ScaffoldContainer>
|
||||
@@ -84,6 +106,42 @@ Repository connections for ${title?.toLowerCase()}
|
||||
key={i}
|
||||
connection={connection}
|
||||
type={integration.integration.name}
|
||||
actions={
|
||||
<Dropdown
|
||||
side="bottom"
|
||||
align="end"
|
||||
size="large"
|
||||
overlay={
|
||||
<>
|
||||
<Dropdown.Item
|
||||
icon={
|
||||
<div>
|
||||
<IconRefreshCcw size={14} />
|
||||
</div>
|
||||
}
|
||||
>
|
||||
<div>Refresh Enviroment Variables</div>
|
||||
<div className="text-scale-900 text-xs">
|
||||
Reapply env vars in vercel.
|
||||
</div>
|
||||
</Dropdown.Item>
|
||||
<Dropdown.Separator />
|
||||
<Dropdown.Item
|
||||
icon={<IconTrash size={14} />}
|
||||
onSelect={() =>
|
||||
handleDelete(integration.id, connection.id)
|
||||
}
|
||||
>
|
||||
Delete
|
||||
</Dropdown.Item>
|
||||
</>
|
||||
}
|
||||
>
|
||||
<Button asChild iconRight={<IconChevronDown />} type="default">
|
||||
<span>Manage</span>
|
||||
</Button>
|
||||
</Dropdown>
|
||||
}
|
||||
/>
|
||||
))}
|
||||
</ul>
|
||||
|
||||
+5
-2
@@ -3,8 +3,10 @@ import { ScaffoldDivider } from 'components/layouts/Scaffold'
|
||||
import { useIntegrationsQuery } from 'data/integrations/integrations-query'
|
||||
import { useStore } from 'hooks'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
import GitHubRepoSelection from './GitHubRepoSelection'
|
||||
import GitHubRepoSelection from './SidePanelGitHubRepoSelection'
|
||||
import Integration from './Integration'
|
||||
import SidePanelGitHubRepoSelection from './SidePanelGitHubRepoSelection'
|
||||
import SidePanelVercelProjectLinker from './SidePanelVercelProjectLinker'
|
||||
|
||||
const IntegrationSettings = () => {
|
||||
const { ui } = useStore()
|
||||
@@ -68,7 +70,8 @@ You can change the scope of the access for Supabase by configuring here.
|
||||
`}
|
||||
integrations={githubIntegrations}
|
||||
/>
|
||||
<GitHubRepoSelection />
|
||||
{/* <SidePanelGitHubRepoSelection /> */}
|
||||
<SidePanelVercelProjectLinker />
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
File renamed without changes.
+108
@@ -0,0 +1,108 @@
|
||||
import { useParams } from 'common'
|
||||
import ProjectLinker from 'components/interfaces/Integrations/ProjectLinker'
|
||||
import { Markdown } from 'components/interfaces/Markdown'
|
||||
import { useIntegrationsQuery } from 'data/integrations/integrations-query'
|
||||
import { useStore } from 'hooks'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
import { useMemo, useState } from 'react'
|
||||
import { useGithubConnectionConfigPanelSnapshot } from 'state/github-connection-config-panel'
|
||||
import { SidePanel } from 'ui'
|
||||
|
||||
import { useVercelProjectsQuery } from 'data/integrations/integrations-vercel-projects-query'
|
||||
import { useProjectsQuery } from 'data/projects/projects-query'
|
||||
import { EMPTY_ARR } from 'lib/void'
|
||||
import { Organization } from 'types'
|
||||
import { useVercelProjectConnectionsQuery } from 'data/integrations/integrations-vercel-installed-connections-query'
|
||||
|
||||
const SidePanelVercelProjectLinker = () => {
|
||||
const { ui } = useStore()
|
||||
const { slug } = useParams()
|
||||
const { data } = useIntegrationsQuery({ orgSlug: slug })
|
||||
|
||||
const vercelIntegrations = data?.filter((integration) => integration.integration.id === 1) // vercel
|
||||
|
||||
const selectedOrg = ui.selectedOrganization
|
||||
|
||||
const [organizationIntegrationId, setOrganizationIntegrationId] = useState<string>(
|
||||
'880cb835-54b4-415b-8178-6f7920fdc40d'
|
||||
)
|
||||
|
||||
const githubConnectionConfigPanelSnapshot = useGithubConnectionConfigPanelSnapshot()
|
||||
|
||||
const { data: supabaseProjectsData } = useProjectsQuery({
|
||||
enabled: organizationIntegrationId !== null,
|
||||
})
|
||||
const supabaseProjects = useMemo(
|
||||
() =>
|
||||
supabaseProjectsData
|
||||
?.filter((project) => project.organization_id === selectedOrg?.id)
|
||||
.map((project) => ({ id: project.id.toString(), name: project.name })) ?? EMPTY_ARR,
|
||||
[selectedOrg?.id, supabaseProjectsData]
|
||||
)
|
||||
|
||||
const { data: vercelProjectConnectionsData } = useVercelProjectConnectionsQuery(
|
||||
{
|
||||
organization_integration_id: organizationIntegrationId,
|
||||
},
|
||||
{ enabled: organizationIntegrationId !== null }
|
||||
)
|
||||
|
||||
const vercelProjectConnections = useMemo(
|
||||
() => vercelProjectConnectionsData ?? EMPTY_ARR,
|
||||
[vercelProjectConnectionsData]
|
||||
)
|
||||
|
||||
const { data: vercelProjectsData } = useVercelProjectsQuery(
|
||||
{
|
||||
orgId: selectedOrg?.id,
|
||||
orgSlug: selectedOrg?.slug,
|
||||
},
|
||||
{ enabled: organizationIntegrationId !== null }
|
||||
)
|
||||
|
||||
console.log('vercelProjectsData', vercelProjectsData)
|
||||
const vercelProjects = useMemo(() => vercelProjectsData ?? EMPTY_ARR, [vercelProjectsData])
|
||||
|
||||
return (
|
||||
<SidePanel
|
||||
header={'Add GitHub repository'}
|
||||
size="large"
|
||||
visible={githubConnectionConfigPanelSnapshot.visible}
|
||||
onCancel={() => githubConnectionConfigPanelSnapshot.setVisible(false)}
|
||||
>
|
||||
<div className="my-10 flex flex-col gap-6">
|
||||
<SidePanel.Content>
|
||||
<Markdown
|
||||
content={`
|
||||
### Choose repository to connect to
|
||||
|
||||
Check the details below before proceeding
|
||||
`}
|
||||
/>
|
||||
</SidePanel.Content>
|
||||
<SidePanel.Content className="flex flex-col gap-2">
|
||||
<ProjectLinker
|
||||
organizationIntegrationId={'880cb835-54b4-415b-8178-6f7920fdc40d'}
|
||||
foreignProjects={vercelProjects}
|
||||
supabaseProjects={supabaseProjects}
|
||||
onCreateConnections={() => {
|
||||
// if (next) {
|
||||
// window.location.href = next
|
||||
// }
|
||||
}}
|
||||
installedConnections={vercelProjectConnections}
|
||||
/>
|
||||
</SidePanel.Content>
|
||||
<SidePanel.Content>
|
||||
<ul>
|
||||
<li className="border px-10">
|
||||
{/* <IntegrationConnectionOption connection={githubIntegrations[0]} /> */}
|
||||
</li>
|
||||
</ul>
|
||||
</SidePanel.Content>
|
||||
</div>
|
||||
</SidePanel>
|
||||
)
|
||||
}
|
||||
|
||||
export default observer(SidePanelVercelProjectLinker)
|
||||
@@ -1,7 +1,7 @@
|
||||
import React from 'react'
|
||||
import { cn } from 'ui/src/utils/cn'
|
||||
|
||||
const maxWdithClasses = 'mx-auto w-full max-w-[1600px]'
|
||||
const maxWidthClasses = 'mx-auto w-full max-w-[1600px]'
|
||||
const paddingClasses = 'px-6 lg:px-14 xl:px-28 2xl:px-32'
|
||||
|
||||
// lg: pt - 8
|
||||
@@ -23,7 +23,7 @@ const ScaffoldTitle = React.forwardRef<
|
||||
|
||||
const ScaffoldContainer = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
|
||||
({ className, ...props }, ref) => {
|
||||
return <div ref={ref} {...props} className={cn(maxWdithClasses, paddingClasses, className)} />
|
||||
return <div ref={ref} {...props} className={cn(maxWidthClasses, paddingClasses, className)} />
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ export async function createIntegrationConnections({
|
||||
organizationIntegrationId,
|
||||
connections,
|
||||
}: IntegrationConnectionsCreateVariables) {
|
||||
const response = await post(`${API_URL}/integrations/connections`, {
|
||||
const response = await post(`${API_URL}/integrations/vercel/connections`, {
|
||||
organizationIntegrationId,
|
||||
connections,
|
||||
})
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
import { useMutation, UseMutationOptions } from '@tanstack/react-query'
|
||||
import { delete_ } from 'lib/common/fetch'
|
||||
import { API_URL } from 'lib/constants'
|
||||
import { UserContent } from 'types'
|
||||
|
||||
type DeleteVariables = { organization_integration_id: string; id: string }
|
||||
|
||||
export async function deleteConnection(
|
||||
{ organization_integration_id, id }: DeleteVariables,
|
||||
signal?: AbortSignal
|
||||
) {
|
||||
if (!organization_integration_id) {
|
||||
throw new Error('organization_integration_id is required')
|
||||
}
|
||||
|
||||
const response = await delete_<UserContent>(
|
||||
`${API_URL}/integrations/vercel/connections/${id}`,
|
||||
{ organization_integration_id },
|
||||
{ signal }
|
||||
)
|
||||
|
||||
if (response.error) throw response.error
|
||||
return response
|
||||
}
|
||||
|
||||
type DeleteContentData = Awaited<ReturnType<typeof deleteConnection>>
|
||||
|
||||
export const useIntegrationsVercelInstalledConnectionDeleteMutation = ({
|
||||
onSuccess,
|
||||
...options
|
||||
}: Omit<UseMutationOptions<DeleteContentData, unknown, DeleteVariables>, 'mutationFn'> = {}) => {
|
||||
return useMutation<DeleteContentData, unknown, DeleteVariables>(
|
||||
(args) => deleteConnection(args),
|
||||
{
|
||||
async onSuccess(data, variables, context) {
|
||||
await onSuccess?.(data, variables, context)
|
||||
},
|
||||
...options,
|
||||
}
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
import { useQuery, useQueryClient, UseQueryOptions } from '@tanstack/react-query'
|
||||
import { get } from 'lib/common/fetch'
|
||||
import { API_URL } from 'lib/constants'
|
||||
import { useCallback } from 'react'
|
||||
import { integrationKeys } from './keys'
|
||||
|
||||
export type VercelProjectsVariables = {
|
||||
organization_integration_id?: string
|
||||
}
|
||||
|
||||
export type VercelProjectsResponse = {
|
||||
id: string
|
||||
name: string
|
||||
metadata: {
|
||||
id: string
|
||||
name: string
|
||||
framework: string
|
||||
link: string
|
||||
}
|
||||
}
|
||||
|
||||
export async function getVercelInstalledConnections(
|
||||
{ organization_integration_id }: VercelProjectsVariables,
|
||||
signal?: AbortSignal
|
||||
) {
|
||||
if (!organization_integration_id) {
|
||||
throw new Error('organization_integration_id is required')
|
||||
}
|
||||
|
||||
const response = await get(
|
||||
`${API_URL}/integrations/vercel/connections/${organization_integration_id}`,
|
||||
{
|
||||
signal,
|
||||
}
|
||||
)
|
||||
if (response.error) {
|
||||
throw response.error
|
||||
}
|
||||
|
||||
return response as VercelProjectsResponse[]
|
||||
}
|
||||
|
||||
export type VercelProjectsData = Awaited<ReturnType<typeof getVercelInstalledConnections>>
|
||||
export type VercelProjectsError = unknown
|
||||
|
||||
export const useVercelProjectConnectionsQuery = <TData = VercelProjectsData>(
|
||||
{ organization_integration_id }: VercelProjectsVariables,
|
||||
{
|
||||
enabled = true,
|
||||
...options
|
||||
}: UseQueryOptions<VercelProjectsData, VercelProjectsError, TData> = {}
|
||||
) =>
|
||||
useQuery<VercelProjectsData, VercelProjectsError, TData>(
|
||||
integrationKeys.vercelProjectList(organization_integration_id),
|
||||
({ signal }) => getVercelInstalledConnections({ organization_integration_id }, signal),
|
||||
{
|
||||
enabled:
|
||||
enabled &&
|
||||
typeof organization_integration_id !== 'undefined' &&
|
||||
typeof organization_integration_id !== 'undefined',
|
||||
...options,
|
||||
}
|
||||
)
|
||||
|
||||
/**
|
||||
* useVercelProjectsPrefetch is used for prefetching data. For example, starting a query loading before a page is navigated to.
|
||||
*
|
||||
* @example
|
||||
* const prefetch = useVercelProjectsPrefetch({ orgSlug })
|
||||
*
|
||||
* return (
|
||||
* <Link onMouseEnter={() => prefetch()}>
|
||||
* Start loading on hover
|
||||
* </Link>
|
||||
* )
|
||||
*/
|
||||
export const useVercelProjectsPrefetch = ({
|
||||
organization_integration_id,
|
||||
}: VercelProjectsVariables) => {
|
||||
const client = useQueryClient()
|
||||
|
||||
return useCallback(() => {
|
||||
if (organization_integration_id) {
|
||||
client.prefetchQuery(
|
||||
integrationKeys.vercelConnectionsList(organization_integration_id),
|
||||
({ signal }) => getVercelInstalledConnections({ organization_integration_id }, signal)
|
||||
)
|
||||
}
|
||||
}, [organization_integration_id])
|
||||
}
|
||||
@@ -2,4 +2,6 @@ export const integrationKeys = {
|
||||
list: (orgSlug: string | undefined) => ['organizations', orgSlug, 'integrations'] as const,
|
||||
vercelProjectList: (orgSlug: string | undefined) =>
|
||||
['organizations', orgSlug, 'vercel-projects'] as const,
|
||||
vercelConnectionsList: (organization_integration_id: string | undefined) =>
|
||||
['organizations', organization_integration_id, 'vercel-connections'] as const,
|
||||
}
|
||||
Reference in new issue
Block a user