From b93c483cb9b3ad216d4e6d22da1e5f30c15266d7 Mon Sep 17 00:00:00 2001 From: Alaister Young Date: Thu, 25 May 2023 15:06:28 +1000 Subject: [PATCH 01/59] initial changes for vercel integration --- .../interfaces/Integrations/ProjectLinker.tsx | 84 +++++++++++++++++++ studio/components/ui/OrganizationPicker.tsx | 59 +++++++++++++ studio/data/integrations/keys.ts | 4 + .../vercel-integration-create-mutation.ts | 46 ++++++++++ .../integrations/vercel-projects-query.ts | 72 ++++++++++++++++ studio/hooks/misc/useAutoAuthRedirect.tsx | 4 +- studio/pages/integrations/vercel.tsx | 67 +++++++++++++++ 7 files changed, 333 insertions(+), 3 deletions(-) create mode 100644 studio/components/interfaces/Integrations/ProjectLinker.tsx create mode 100644 studio/components/ui/OrganizationPicker.tsx create mode 100644 studio/data/integrations/keys.ts create mode 100644 studio/data/integrations/vercel-integration-create-mutation.ts create mode 100644 studio/data/integrations/vercel-projects-query.ts create mode 100644 studio/pages/integrations/vercel.tsx diff --git a/studio/components/interfaces/Integrations/ProjectLinker.tsx b/studio/components/interfaces/Integrations/ProjectLinker.tsx new file mode 100644 index 00000000000..f00e815e59f --- /dev/null +++ b/studio/components/interfaces/Integrations/ProjectLinker.tsx @@ -0,0 +1,84 @@ +import { IconChevronRight, Listbox } from 'ui' + +const ProjectLinker = () => { + return
+} + +export default ProjectLinker + +type ProjectLinkerItemProps = {} +const ProjectLinkerItem = ({}: ProjectLinkerItemProps) => { + function onVercelProjectChange(e: string) { + const value = e != UNDEFINED_SELECT_VALUE ? e : undefined + } + + function onSupabaseProjectChange(e: string) { + const value = e != UNDEFINED_SELECT_VALUE ? e : undefined + } + + function onRemove() {} + + return ( +
  • +
    +
    + + + Choose a project + + {selectedVercelProject && ( + vercelIcon} + > + {selectedVercelProject.name} + + )} + {_store.vercelProjectsAvailable.map((x) => ( + vercelIcon}> + {x.name} + + ))} + +
    +
    + +
    +
    + + + Choose a project + + {sortedProjects?.map((x: Dictionary) => ( + databaseIcon} + > + {x.name} + + ))} + +
    + {/* {idx != 0 && ( +
    +
    + )} */} +
    +
  • + ) +} diff --git a/studio/components/ui/OrganizationPicker.tsx b/studio/components/ui/OrganizationPicker.tsx new file mode 100644 index 00000000000..808a5166f68 --- /dev/null +++ b/studio/components/ui/OrganizationPicker.tsx @@ -0,0 +1,59 @@ +import { useOrganizationsQuery } from 'data/organizations/organizations-query' +import { useState } from 'react' +import { Organization } from 'types' +import { Listbox } from 'ui' + +export interface OrganizationPickerProps { + label?: string + onSelectedOrgChange?: (org: Organization) => void +} + +const OrganizationPicker = ({ + label = 'Choose an organization', + onSelectedOrgChange, +}: OrganizationPickerProps) => { + const [selectedOrg, setSelectedOrg] = useState(null) + + const { data, isLoading } = useOrganizationsQuery({ + onSuccess(organizations) { + const firstOrg = organizations?.[0] + if (firstOrg && selectedOrg === null) { + setSelectedOrg(firstOrg) + onSelectedOrgChange?.(firstOrg) + } + }, + }) + + function _onSelectedOrgChange(slug: string) { + const org = data?.find((org) => org.slug === slug) + + if (org) { + setSelectedOrg(org) + onSelectedOrgChange?.(org) + } + } + + if (isLoading) { + return ( + + + Loading... + + + ) + } + + return ( + + {data?.map((org) => { + return ( + + {org.name} + + ) + })} + + ) +} + +export default OrganizationPicker diff --git a/studio/data/integrations/keys.ts b/studio/data/integrations/keys.ts new file mode 100644 index 00000000000..6859ecd3b0c --- /dev/null +++ b/studio/data/integrations/keys.ts @@ -0,0 +1,4 @@ +export const integrationKeys = { + vercelProjectList: (orgSlug: string | undefined) => + ['organizations', orgSlug, 'vercel-projects'] as const, +} diff --git a/studio/data/integrations/vercel-integration-create-mutation.ts b/studio/data/integrations/vercel-integration-create-mutation.ts new file mode 100644 index 00000000000..69703a157ac --- /dev/null +++ b/studio/data/integrations/vercel-integration-create-mutation.ts @@ -0,0 +1,46 @@ +import { useMutation, UseMutationOptions } from '@tanstack/react-query' +import { post } from 'lib/common/fetch' +import { API_URL } from 'lib/constants' + +export type VercelIntegrationCreateVariables = { + code: string + configurationId: string + orgId: number +} + +export async function createVercelIntegration({ + code, + configurationId, + orgId, +}: VercelIntegrationCreateVariables) { + const response = await post(`${API_URL}/integrations/vercel`, { + code, + configurationId, + orgId, + }) + if (response.error) { + throw response.error + } + + return response +} + +type VercelIntegrationCreateData = Awaited> + +export const useVercelIntegrationCreateMutation = ({ + onSuccess, + ...options +}: Omit< + UseMutationOptions, + 'mutationFn' +> = {}) => { + return useMutation( + (vars) => createVercelIntegration(vars), + { + async onSuccess(data, variables, context) { + await onSuccess?.(data, variables, context) + }, + ...options, + } + ) +} diff --git a/studio/data/integrations/vercel-projects-query.ts b/studio/data/integrations/vercel-projects-query.ts new file mode 100644 index 00000000000..06fe30f1c86 --- /dev/null +++ b/studio/data/integrations/vercel-projects-query.ts @@ -0,0 +1,72 @@ +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 = { + orgId?: number + orgSlug?: string +} + +export type VercelProjectsResponse = { + id: string +} + +export async function getVercelProjects({ orgId }: VercelProjectsVariables, signal?: AbortSignal) { + if (!orgId) { + throw new Error('orgId is required') + } + + const response = await get(`${API_URL}/integrations/vercel/projects?orgId=${orgId}`, { + signal, + }) + if (response.error) { + throw response.error + } + + return response as VercelProjectsResponse[] +} + +export type VercelProjectsData = Awaited> +export type VercelProjectsError = unknown + +export const useVercelProjectsQuery = ( + { orgSlug, orgId }: VercelProjectsVariables, + { + enabled = true, + ...options + }: UseQueryOptions = {} +) => + useQuery( + integrationKeys.vercelProjectList(orgSlug), + ({ signal }) => getVercelProjects({ orgSlug, orgId }, signal), + { + enabled: enabled && typeof orgSlug !== 'undefined' && typeof orgId !== '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 ( + * prefetch()}> + * Start loading on hover + * + * ) + */ +export const useVercelProjectsPrefetch = ({ orgSlug, orgId }: VercelProjectsVariables) => { + const client = useQueryClient() + + return useCallback(() => { + if (orgSlug) { + client.prefetchQuery(integrationKeys.vercelProjectList(orgSlug), ({ signal }) => + getVercelProjects({ orgSlug, orgId }, signal) + ) + } + }, [orgSlug]) +} diff --git a/studio/hooks/misc/useAutoAuthRedirect.tsx b/studio/hooks/misc/useAutoAuthRedirect.tsx index 3a63cae6976..ca97fe8d486 100644 --- a/studio/hooks/misc/useAutoAuthRedirect.tsx +++ b/studio/hooks/misc/useAutoAuthRedirect.tsx @@ -19,9 +19,7 @@ export function usePushNext() { // vercel integration const isVercelIntegration = next.includes('https://vercel.com') if (isVercelIntegration) { - searchParams.delete('returnTo') - - return await router.push(`/vercel/integrate?${searchParams.toString()}`) + return } // database.new integration diff --git a/studio/pages/integrations/vercel.tsx b/studio/pages/integrations/vercel.tsx new file mode 100644 index 00000000000..173a0eb2460 --- /dev/null +++ b/studio/pages/integrations/vercel.tsx @@ -0,0 +1,67 @@ +import { useParams } from 'common' +import { WizardLayout } from 'components/layouts' +import OrganizationPicker from 'components/ui/OrganizationPicker' +import { useVercelIntegrationCreateMutation } from 'data/integrations/vercel-integration-create-mutation' +import { useVercelProjectsQuery } from 'data/integrations/vercel-projects-query' +import { useStore } from 'hooks' +import { useState } from 'react' +import { NextPageWithLayout, Organization } from 'types' +import { Button } from 'ui' + +const VercelIntegration: NextPageWithLayout = () => { + const { ui } = useStore() + const { code, configurationId } = useParams() + const [selectedOrg, setSelectedOrg] = useState(null) + const [hasInstalled, setHasInstalled] = useState(true) + + const { mutate, isLoading } = useVercelIntegrationCreateMutation({ + onSuccess() { + setHasInstalled(true) + }, + }) + + function onInstall() { + const orgId = selectedOrg?.id + if (!orgId) { + return ui.setNotification({ category: 'error', message: 'Please select an organization' }) + } + + if (!code) { + return ui.setNotification({ category: 'error', message: 'Vercel code missing' }) + } + + if (!configurationId) { + return ui.setNotification({ category: 'error', message: 'Vercel Configuration ID missing' }) + } + + mutate({ + code, + configurationId, + orgId, + }) + } + + const { data: projects } = useVercelProjectsQuery( + { + orgId: selectedOrg?.id, + orgSlug: selectedOrg?.slug, + }, + { enabled: hasInstalled } + ) + + return ( +
    +

    Vercel Integration

    + + + + +
    + ) +} + +VercelIntegration.getLayout = (page) => {page} + +export default VercelIntegration From 4d8df9602d4399ce7dc2a8f09fbfae313cd90ba2 Mon Sep 17 00:00:00 2001 From: Alaister Young Date: Tue, 30 May 2023 15:49:53 +1000 Subject: [PATCH 02/59] adds integrations page scaffold in settings --- .../components/layouts/OrganizationLayout.tsx | 40 +++++++++++++++---- studio/pages/org/[slug]/billing.tsx | 35 +--------------- studio/pages/org/[slug]/general.tsx | 35 +--------------- studio/pages/org/[slug]/integrations.tsx | 14 +++++++ studio/pages/org/[slug]/invoices.tsx | 35 +--------------- 5 files changed, 53 insertions(+), 106 deletions(-) create mode 100644 studio/pages/org/[slug]/integrations.tsx diff --git a/studio/components/layouts/OrganizationLayout.tsx b/studio/components/layouts/OrganizationLayout.tsx index 0b323386d03..0dadc3f8ae0 100644 --- a/studio/components/layouts/OrganizationLayout.tsx +++ b/studio/components/layouts/OrganizationLayout.tsx @@ -1,21 +1,47 @@ +import { useParams } from 'common' import { useStore } from 'hooks' import { observer } from 'mobx-react-lite' -import { FC, ReactNode } from 'react' +import { useRouter } from 'next/router' +import { PropsWithChildren } from 'react' +import { Tabs } from 'ui' import { AccountLayout } from './' -interface Props { - children: ReactNode -} - -const OrganizationLayout: FC = ({ children }) => { +const OrganizationLayout = ({ children }: PropsWithChildren<{}>) => { const { ui } = useStore() + const router = useRouter() + const { slug } = useParams() + const id = router.asPath.split('/').at(-1) return ( - {children} +
    +
    +
    +

    {ui.selectedOrganization?.name ?? 'Organization'} settings

    +
    + +
    + +
    {children}
    +
    ) } diff --git a/studio/pages/org/[slug]/billing.tsx b/studio/pages/org/[slug]/billing.tsx index 83c44735b40..83248fec7a6 100644 --- a/studio/pages/org/[slug]/billing.tsx +++ b/studio/pages/org/[slug]/billing.tsx @@ -1,56 +1,25 @@ -import { useRouter } from 'next/router' import { observer } from 'mobx-react-lite' -import { Tabs } from 'ui' import { NextPageWithLayout } from 'types' import { useStore } from 'hooks' -import { useParams } from 'common/hooks' import Loading from 'components/ui/Loading' import { OrganizationLayout } from 'components/layouts' import { BillingSettings } from 'components/interfaces/Organization' const OrgBillingSettings: NextPageWithLayout = () => { const { ui } = useStore() - const { slug } = useParams() - const router = useRouter() return ( <> {ui.selectedOrganization === undefined && (ui?.permissions ?? []).length === 0 ? ( ) : ( -
    -
    -
    -

    - {ui.selectedOrganization?.name ?? 'Organization'} settings -

    -
    - -
    - -
    - -
    -
    + )} ) } OrgBillingSettings.getLayout = (page) => {page} + export default observer(OrgBillingSettings) diff --git a/studio/pages/org/[slug]/general.tsx b/studio/pages/org/[slug]/general.tsx index f07415ba47e..a62ed0e7c4b 100644 --- a/studio/pages/org/[slug]/general.tsx +++ b/studio/pages/org/[slug]/general.tsx @@ -1,56 +1,25 @@ -import { useRouter } from 'next/router' import { observer } from 'mobx-react-lite' -import { Tabs } from 'ui' import { NextPageWithLayout } from 'types' import { useStore } from 'hooks' -import { useParams } from 'common/hooks' import Loading from 'components/ui/Loading' import { OrganizationLayout } from 'components/layouts' import { GeneralSettings } from 'components/interfaces/Organization' const OrgGeneralSettings: NextPageWithLayout = () => { const { ui } = useStore() - const { slug } = useParams() - const router = useRouter() return ( <> {ui.selectedOrganization === undefined && (ui?.permissions ?? []).length === 0 ? ( ) : ( -
    -
    -
    -

    - {ui.selectedOrganization?.name ?? 'Organization'} settings -

    -
    - -
    - -
    - -
    -
    + )} ) } OrgGeneralSettings.getLayout = (page) => {page} + export default observer(OrgGeneralSettings) diff --git a/studio/pages/org/[slug]/integrations.tsx b/studio/pages/org/[slug]/integrations.tsx new file mode 100644 index 00000000000..6a9c54bedfc --- /dev/null +++ b/studio/pages/org/[slug]/integrations.tsx @@ -0,0 +1,14 @@ +import { NextPageWithLayout } from 'types' +import { OrganizationLayout } from 'components/layouts' +// import { IntegrationSettings } from 'components/interfaces/Organization' + +const OrgIntegrationSettings: NextPageWithLayout = () => { + return ( +
    howdy
    + // + ) +} + +OrgIntegrationSettings.getLayout = (page) => {page} + +export default OrgIntegrationSettings diff --git a/studio/pages/org/[slug]/invoices.tsx b/studio/pages/org/[slug]/invoices.tsx index 5ccf1ebc825..f1c7127198a 100644 --- a/studio/pages/org/[slug]/invoices.tsx +++ b/studio/pages/org/[slug]/invoices.tsx @@ -1,56 +1,25 @@ -import { useRouter } from 'next/router' import { observer } from 'mobx-react-lite' -import { Tabs } from 'ui' import { NextPageWithLayout } from 'types' import { useStore } from 'hooks' -import { useParams } from 'common/hooks' import Loading from 'components/ui/Loading' import { OrganizationLayout } from 'components/layouts' import { InvoicesSettings } from 'components/interfaces/Organization' const OrgInvoices: NextPageWithLayout = () => { const { ui } = useStore() - const { slug } = useParams() - const router = useRouter() return ( <> {ui.selectedOrganization === undefined && (ui?.permissions ?? []).length === 0 ? ( ) : ( -
    -
    -
    -

    - {ui.selectedOrganization?.name ?? 'Organization'} settings -

    -
    - -
    - -
    - -
    -
    + )} ) } OrgInvoices.getLayout = (page) => {page} + export default observer(OrgInvoices) From 2635932f8f781309e2210633e8b9b40d12bd95b9 Mon Sep 17 00:00:00 2001 From: Alaister Young Date: Thu, 1 Jun 2023 17:15:13 +1000 Subject: [PATCH 03/59] adds IntegrationSettings interface --- .../IntegrationSettings/Integration.tsx | 117 ++++++++++++++++++ .../IntegrationSettings.tsx | 30 +++++ .../interfaces/Organization/index.ts | 3 +- .../components/layouts/OrganizationLayout.tsx | 3 +- studio/lib/helpers.ts | 7 ++ studio/lib/void.ts | 7 ++ studio/pages/org/[slug]/integrations.tsx | 7 +- 7 files changed, 167 insertions(+), 7 deletions(-) create mode 100644 studio/components/interfaces/Organization/IntegrationSettings/Integration.tsx create mode 100644 studio/components/interfaces/Organization/IntegrationSettings/IntegrationSettings.tsx create mode 100644 studio/lib/void.ts diff --git a/studio/components/interfaces/Organization/IntegrationSettings/Integration.tsx b/studio/components/interfaces/Organization/IntegrationSettings/Integration.tsx new file mode 100644 index 00000000000..0e746edd52e --- /dev/null +++ b/studio/components/interfaces/Organization/IntegrationSettings/Integration.tsx @@ -0,0 +1,117 @@ +import dayjs from 'dayjs' +import { pluralize } from 'lib/helpers' +import { EMPTY_ARR } from 'lib/void' +import { Button, IconArrowRight } from 'ui' + +export interface OrganizationConnection { + id: string + orgName: string + addedByUser: string +} + +export interface ProjectConnection { + id: string + createdAt: string + /** External resource name */ + fromProjectName: string + /** Supabase project name */ + toProjectName: string +} + +export interface IntegrationProps { + title: string + description?: string + note?: string + organizationConnections?: OrganizationConnection[] + projectConnections?: ProjectConnection[] +} + +const Integration = ({ + title, + description, + note, + organizationConnections = EMPTY_ARR, + projectConnections = EMPTY_ARR, +}: IntegrationProps) => { + return ( + <> +
    +

    {title}

    +
    + +
    + {description !== undefined && ( +
    +

    How does the {title} integration work?

    +

    {description}

    +
    + )} + + {organizationConnections.length > 0 && ( +
      + {organizationConnections.map((connection) => ( +
    • +
      + + {title} integration connection | {connection.orgName} + + Added by {connection.addedByUser} +
      + +
      + +
      +
    • + ))} +
    + )} + +
    + + {projectConnections.length > 0 && ( +
    +

    + {projectConnections.length} project{' '} + {pluralize(projectConnections.length, 'connection')} +

    + +
      + {projectConnections.map((connection) => ( +
    • +
      +
      + {connection.fromProjectName} + + {connection.toProjectName} +
      + + + Connected {dayjs(connection.createdAt).fromNow()} + +
      + +
      + +
      +
    • + ))} +
    + + + {note !== undefined &&

    {note}

    } +
    + )} +
    + + ) +} + +export default Integration diff --git a/studio/components/interfaces/Organization/IntegrationSettings/IntegrationSettings.tsx b/studio/components/interfaces/Organization/IntegrationSettings/IntegrationSettings.tsx new file mode 100644 index 00000000000..e4564cf6a7e --- /dev/null +++ b/studio/components/interfaces/Organization/IntegrationSettings/IntegrationSettings.tsx @@ -0,0 +1,30 @@ +import Integration from './Integration' + +const IntegrationSettings = () => { + return ( +
    + +
    + ) +} + +export default IntegrationSettings diff --git a/studio/components/interfaces/Organization/index.ts b/studio/components/interfaces/Organization/index.ts index 08d77572274..48df8a473a6 100644 --- a/studio/components/interfaces/Organization/index.ts +++ b/studio/components/interfaces/Organization/index.ts @@ -2,5 +2,6 @@ import GeneralSettings from './GeneralSettings/GeneralSettings' import TeamSettings from './TeamSettings/TeamSettings' import BillingSettings from './BillingSettings/BillingSettings' import InvoicesSettings from './InvoicesSettings/InvoicesSettings' +import IntegrationSettings from './IntegrationSettings/IntegrationSettings' -export { GeneralSettings, TeamSettings, BillingSettings, InvoicesSettings } +export { GeneralSettings, TeamSettings, BillingSettings, InvoicesSettings, IntegrationSettings } diff --git a/studio/components/layouts/OrganizationLayout.tsx b/studio/components/layouts/OrganizationLayout.tsx index 0dadc3f8ae0..7eac56171f3 100644 --- a/studio/components/layouts/OrganizationLayout.tsx +++ b/studio/components/layouts/OrganizationLayout.tsx @@ -17,11 +17,12 @@ const OrganizationLayout = ({ children }: PropsWithChildren<{}>) => { title={ui.selectedOrganization?.name ?? 'Supabase'} breadcrumbs={[{ key: `org-settings`, label: 'Settings' }]} > -
    +

    {ui.selectedOrganization?.name ?? 'Organization'} settings

    +
    ) diff --git a/studio/data/integrations/integration-connections-create-mutation.ts b/studio/data/integrations/integration-connections-create-mutation.ts new file mode 100644 index 00000000000..82ffa0d8b27 --- /dev/null +++ b/studio/data/integrations/integration-connections-create-mutation.ts @@ -0,0 +1,51 @@ +import { useMutation, UseMutationOptions } from '@tanstack/react-query' +import { post } from 'lib/common/fetch' +import { API_URL } from 'lib/constants' + +export type IntegrationConnectionsCreateVariables = { + organizationIntegrationId: string + connections: { + foreignProjectId: string + supabaseProjectId: string + }[] +} + +export async function createIntegrationConnections({ + organizationIntegrationId, + connections, +}: IntegrationConnectionsCreateVariables) { + const response = await post(`${API_URL}/integrations/connections`, { + organizationIntegrationId, + connections, + }) + if (response.error) { + throw response.error + } + + return response +} + +type IntegrationConnectionsCreateData = Awaited> + +export const useIntegrationConnectionsCreateMutation = ({ + onSuccess, + ...options +}: Omit< + UseMutationOptions< + IntegrationConnectionsCreateData, + unknown, + IntegrationConnectionsCreateVariables + >, + 'mutationFn' +> = {}) => { + return useMutation< + IntegrationConnectionsCreateData, + unknown, + IntegrationConnectionsCreateVariables + >((vars) => createIntegrationConnections(vars), { + async onSuccess(data, variables, context) { + await onSuccess?.(data, variables, context) + }, + ...options, + }) +} diff --git a/studio/pages/integrations/vercel.tsx b/studio/pages/integrations/vercel.tsx index bb060a236fe..8d0e77d637a 100644 --- a/studio/pages/integrations/vercel.tsx +++ b/studio/pages/integrations/vercel.tsx @@ -14,13 +14,13 @@ import { Button } from 'ui' const VercelIntegration: NextPageWithLayout = () => { const { ui } = useStore() - const { code, configurationId } = useParams() + const { code, configurationId, next } = useParams() const [selectedOrg, setSelectedOrg] = useState(null) - const [hasInstalled, setHasInstalled] = useState(true) + const [organizationIntegrationId, setOrganizationIntegrationId] = useState(null) const { mutate, isLoading } = useVercelIntegrationCreateMutation({ - onSuccess() { - setHasInstalled(true) + onSuccess({ id }) { + setOrganizationIntegrationId(id) }, }) @@ -45,12 +45,14 @@ const VercelIntegration: NextPageWithLayout = () => { }) } - const { data: supabaseProjectsData } = useProjectsQuery({ enabled: hasInstalled }) + const { data: supabaseProjectsData } = useProjectsQuery({ + enabled: organizationIntegrationId !== null, + }) const supabaseProjects = useMemo( () => supabaseProjectsData ?.filter((project) => project.organization_id === selectedOrg?.id) - .map((project) => ({ id: project.ref, name: project.name })) ?? EMPTY_ARR, + .map((project) => ({ id: project.id.toString(), name: project.name })) ?? EMPTY_ARR, [selectedOrg?.id, supabaseProjectsData] ) @@ -59,7 +61,7 @@ const VercelIntegration: NextPageWithLayout = () => { orgId: selectedOrg?.id, orgSlug: selectedOrg?.slug, }, - { enabled: hasInstalled } + { enabled: organizationIntegrationId !== null } ) const vercelProjects = useMemo( () => @@ -74,7 +76,7 @@ const VercelIntegration: NextPageWithLayout = () => {

    Vercel Integration

    - {!hasInstalled ? ( + {organizationIntegrationId === null ? ( <> @@ -84,7 +86,16 @@ const VercelIntegration: NextPageWithLayout = () => { ) : ( <> - + { + if (next) { + window.location.href = next + } + }} + /> )}
    From 178697eed7006d219f9121466faf5666e3883ca4 Mon Sep 17 00:00:00 2001 From: Jonathan Summers-Muir Date: Wed, 14 Jun 2023 18:07:33 +0800 Subject: [PATCH 08/59] first pass on introducing new UI. although added a rogue new thing to mobx store --- .../Integrations/IntegrationPanels.tsx | 233 ++++++++++++++++++ studio/components/interfaces/Markdown.tsx | 18 ++ .../GitHubRepoSelection.tsx | 57 +++++ .../IntegrationSettings/Integration.tsx | 164 ++++++------ .../IntegrationSettings/IntegrationGitHub.tsx | 95 +++++++ .../IntegrationSettings.tsx | 50 +++- .../components/layouts/OrganizationLayout.tsx | 31 +-- studio/components/layouts/Scaffold.tsx | 84 +++++++ .../data/integrations/integrations-query.ts | 72 +++++- .../img/integrations/covers/github-cover.png | Bin 0 -> 196269 bytes .../img/integrations/covers/vercel-cover.png | Bin 0 -> 197501 bytes studio/stores/UiStore.ts | 7 + 12 files changed, 709 insertions(+), 102 deletions(-) create mode 100644 studio/components/interfaces/Integrations/IntegrationPanels.tsx create mode 100644 studio/components/interfaces/Markdown.tsx create mode 100644 studio/components/interfaces/Organization/IntegrationSettings/GitHubRepoSelection.tsx create mode 100644 studio/components/interfaces/Organization/IntegrationSettings/IntegrationGitHub.tsx create mode 100644 studio/components/layouts/Scaffold.tsx create mode 100644 studio/public/img/integrations/covers/github-cover.png create mode 100644 studio/public/img/integrations/covers/vercel-cover.png diff --git a/studio/components/interfaces/Integrations/IntegrationPanels.tsx b/studio/components/interfaces/Integrations/IntegrationPanels.tsx new file mode 100644 index 00000000000..5d301ecc747 --- /dev/null +++ b/studio/components/interfaces/Integrations/IntegrationPanels.tsx @@ -0,0 +1,233 @@ +import { Integration, IntegrationProjectConnection } from 'data/integrations/integrations-query' +import dayjs from 'dayjs' +import React from 'react' +import { + Button, + IconArrowRight, + IconCloudLightning, + IconGitHub, + IconSquare, + IconTriangle, +} from 'ui' +import { cn } from 'ui/src/utils/cn' + +var relativeTime = require('dayjs/plugin/relativeTime') +dayjs.extend(relativeTime) + +const ICON_STROKE_WIDTH = 2 +const ICON_SIZE = 14 +export interface IntegrationInstallationProps extends React.HTMLAttributes { + title: string + orgName: string + connection: Integration +} + +type HandleIconType = Integration['type'] | 'SUPABASE' + +const HandleIcon = ({ type }: { type: HandleIconType }) => { + switch (type) { + case 'GITHUB': + return + break + case 'NETLIFY': + return + break + case 'VERCEL': + return ( + + + + ) + + // + break + case 'SUPABASE': + return ( + Supabase + ) + // + break + + default: + return <> + break + } +} + +const IntegrationInstallation = React.forwardRef( + ({ className, title, orgName, connection, ...props }, ref) => { + const IntegrationIconBlock = () => { + return ( +
    + +
    + ) + } + + return ( +
  • +
    +
    + + + + + +
    +
    + + {title} integration connection •{' '} + {connection.metadata?.vercelTeam || connection.metadata?.gitHubConnectionOwner} + +
    + + Created {dayjs(connection.createdAt).fromNow()} + + Added by {connection.createdBy} +
    +
    +
    + + +
  • + ) + } +) + +export interface IntegrationConnectionProps extends React.HTMLAttributes { + connection: IntegrationProjectConnection + type: Integration['type'] +} + +const IntegrationConnection = React.forwardRef( + ({ className, connection, type, ...props }, ref) => { + return ( +
  • +
    +
    +
    +
    + + {connection.from.name} + + + {connection.to.name} +
    + + + Connected {dayjs(connection.createdAt).fromNow()} + +
    + +
    + +
    +
    +
  • + ) + } +) + +const IntegrationConnectionOption = React.forwardRef( + ({ className, connection, type, ...props }, ref) => { + return ( +
  • +
    +
    + + {connection.from.name} + + + {connection.to.name} +
    + + + Connected {dayjs(connection.createdAt).fromNow()} + +
    + + +
  • + ) + } +) + +const EmptyIntegrationConnection = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => { + return ( +
    +
    + +
    +
    + ) +}) + +interface IntegrationConnectionHeader extends React.HTMLAttributes { + name?: string +} + +const IntegrationConnectionHeader = React.forwardRef( + ({ className, name, ...props }, ref) => { + return ( +
    +

    {props.title}

    +

    + Repository connections for {name?.toLowerCase()} +

    +
    + ) + } +) + +IntegrationInstallation.displayName = 'IntegrationInstallation' +IntegrationConnection.displayName = 'IntegrationConnection' +IntegrationConnectionHeader.displayName = 'IntegrationConnectionHeader' +EmptyIntegrationConnection.displayName = 'EmptyIntegrationConnection' +IntegrationConnectionOption.displayName = 'IntegrationConnectionOption' + +export { + EmptyIntegrationConnection, + IntegrationConnection, + IntegrationConnectionHeader, + IntegrationInstallation, + IntegrationConnectionOption, +} diff --git a/studio/components/interfaces/Markdown.tsx b/studio/components/interfaces/Markdown.tsx new file mode 100644 index 00000000000..db85f97f4f3 --- /dev/null +++ b/studio/components/interfaces/Markdown.tsx @@ -0,0 +1,18 @@ +import { ReactMarkdownProps } from 'react-markdown/lib/complex-types' +import { ReactMarkdown } from 'react-markdown/lib/react-markdown' +import { cn } from 'ui/src/utils/cn' + +interface Props extends Omit { + className?: string + content: string +} + +const Markdown = ({ className, content, ...props }: Props) => { + return ( + + {content} + + ) +} + +export { Markdown } diff --git a/studio/components/interfaces/Organization/IntegrationSettings/GitHubRepoSelection.tsx b/studio/components/interfaces/Organization/IntegrationSettings/GitHubRepoSelection.tsx new file mode 100644 index 00000000000..fb036c6cabc --- /dev/null +++ b/studio/components/interfaces/Organization/IntegrationSettings/GitHubRepoSelection.tsx @@ -0,0 +1,57 @@ +import { useParams } from 'common' +import { IntegrationConnectionOption } from 'components/interfaces/Integrations/IntegrationPanels' +import { Markdown } from 'components/interfaces/Markdown' +import { useIntegrationsQuery } from 'data/integrations/integrations-query' +import { useStore } from 'hooks' +import { observer } from 'mobx-react-lite' +import { IconGitHub, IconSearch, Input, Select, SidePanel } from 'ui' + +const GitHubRepoSelection = () => { + const { ui } = useStore() + const { slug } = useParams() + const { data } = useIntegrationsQuery({ orgSlug: slug }) + + const visible = ui.showGitHubRepoSelectionPanel + + const githubIntegrations = data?.filter((integration) => integration.type === 'GITHUB') + + return ( + ui.setShowGitHubRepoSelectionPanel(false)} + > +
    + + + + + +
    + + } className="w-full" placeholder="Search..." /> +
    +
    + +
      +
    • + {/* */} +
    • +
    +
    +
    +
    + ) +} + +export default observer(GitHubRepoSelection) diff --git a/studio/components/interfaces/Organization/IntegrationSettings/Integration.tsx b/studio/components/interfaces/Organization/IntegrationSettings/Integration.tsx index 835d58a42ff..4e8bfc3739e 100644 --- a/studio/components/interfaces/Organization/IntegrationSettings/Integration.tsx +++ b/studio/components/interfaces/Organization/IntegrationSettings/Integration.tsx @@ -1,14 +1,28 @@ +import { + EmptyIntegrationConnection, + IntegrationConnection, + IntegrationConnectionHeader, + IntegrationInstallation, +} from 'components/interfaces/Integrations/IntegrationPanels' +import { Markdown } from 'components/interfaces/Markdown' +import { + ScaffoldContainer, + ScaffoldSection, + ScaffoldSectionContent, + ScaffoldSectionDetail, +} from 'components/layouts/Scaffold' import { Integration as TIntegration } from 'data/integrations/integrations-query' -import dayjs from 'dayjs' +import { useStore } from 'hooks' import { pluralize } from 'lib/helpers' import { EMPTY_ARR } from 'lib/void' import { useMemo } from 'react' -import { Button, IconArrowRight } from 'ui' + export interface IntegrationProps { title: string orgName?: string description?: string note?: string + detail?: string integrations?: TIntegration[] } @@ -17,8 +31,11 @@ const Integration = ({ orgName, description, note, + detail, integrations = EMPTY_ARR, }: IntegrationProps) => { + const { ui } = useStore() + const projectConnections = useMemo( () => integrations.flatMap((integration) => integration.connections), [integrations] @@ -26,81 +43,80 @@ const Integration = ({ return ( <> -
    -

    {title}

    -
    + + + + {detail && } + cover + + +
    + +
    +
    + {integrations.length > 0 && + integrations.map((integration, i) => { + return ( +
    + + {integration.connections.length > 0 ? ( + <> + -
    - {description !== undefined && ( -
    -

    How does the {title} integration work?

    -

    {description}

    -
    - )} - - {integrations.length > 0 && ( -
      - {integrations.map((connection) => ( -
    • -
      - - {title} integration connection | {orgName} - - Added by {connection.createdBy} -
      - -
      - -
      -
    • - ))} -
    - )} - -
    - - {projectConnections.length > 0 && ( -
    -

    - {projectConnections.length} project{' '} - {pluralize(projectConnections.length, 'connection')} -

    - -
      - {projectConnections.map((connection) => ( -
    • -
      -
      - {connection.from.name} - - {connection.to.name} +
        + {integration.connections.map((connection, i) => ( + + ))} +
      + + ) : ( + + )} + ui.setShowGitHubRepoSelectionPanel(true)} + > + Add new project connection +
      + ) + })} +
      - - Connected {dayjs(connection.createdAt).fromNow()} - -
    - -
    - -
    - - ))} - - - - {note !== undefined &&

    {note}

    } -
    - )} -
    + + + + ) } diff --git a/studio/components/interfaces/Organization/IntegrationSettings/IntegrationGitHub.tsx b/studio/components/interfaces/Organization/IntegrationSettings/IntegrationGitHub.tsx new file mode 100644 index 00000000000..11ff03fdf45 --- /dev/null +++ b/studio/components/interfaces/Organization/IntegrationSettings/IntegrationGitHub.tsx @@ -0,0 +1,95 @@ +import { + EmptyIntegrationConnection, + IntegrationConnection, + IntegrationConnectionHeader, + IntegrationInstallation, +} from 'components/interfaces/Integrations/IntegrationPanels' +import { Markdown } from 'components/interfaces/Markdown' +import { + ScaffoldContainer, + ScaffoldSection, + ScaffoldSectionContent, + ScaffoldSectionDetail, +} from 'components/layouts/Scaffold' +import { Integration as TIntegration } from 'data/integrations/integrations-query' +import { pluralize } from 'lib/helpers' +import { EMPTY_ARR } from 'lib/void' +import { useMemo } from 'react' + +export interface IntegrationProps { + title: string + orgName?: string + description?: string + note?: string + integrations?: TIntegration[] +} + +const Integration = ({ + title, + orgName, + description, + note, + integrations = EMPTY_ARR, +}: IntegrationProps) => { + const projectConnections = useMemo( + () => integrations.flatMap((integration) => integration.connections), + [integrations] + ) + + return ( + <> + + + +

    {title}

    +
    + + {description !== undefined && ( + + )} +
    + {integrations.length > 0 && + integrations.map((integraton, i) => { + return ( +
    + + {integraton.connections.length > 0 && ( + <> + + +
      + {integraton.connections.map((connection, i) => ( + + ))} +
    + + + Add new project connection + + + )} +
    + ) + })} +
    + + +
    +
    +
    + + ) +} + +export default Integration diff --git a/studio/components/interfaces/Organization/IntegrationSettings/IntegrationSettings.tsx b/studio/components/interfaces/Organization/IntegrationSettings/IntegrationSettings.tsx index 154a869bf6c..a5e423fc918 100644 --- a/studio/components/interfaces/Organization/IntegrationSettings/IntegrationSettings.tsx +++ b/studio/components/interfaces/Organization/IntegrationSettings/IntegrationSettings.tsx @@ -1,8 +1,9 @@ -import { observer } from 'mobx-react-lite' - import { useParams } from 'common' +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 Integration from './Integration' const IntegrationSettings = () => { @@ -13,17 +14,54 @@ const IntegrationSettings = () => { const org = ui.selectedOrganization const vercelIntegrations = data?.filter((integration) => integration.type === 'VERCEL') + const githubIntegrations = data?.filter((integration) => integration.type === 'GITHUB') return ( -
    + <> -
    + + + + ) } diff --git a/studio/components/layouts/OrganizationLayout.tsx b/studio/components/layouts/OrganizationLayout.tsx index 7eac56171f3..35d35debe4f 100644 --- a/studio/components/layouts/OrganizationLayout.tsx +++ b/studio/components/layouts/OrganizationLayout.tsx @@ -5,6 +5,7 @@ import { useRouter } from 'next/router' import { PropsWithChildren } from 'react' import { Tabs } from 'ui' import { AccountLayout } from './' +import { ScaffoldContainer, ScaffoldDivider, ScaffoldHeader, ScaffoldTitle } from './Scaffold' const OrganizationLayout = ({ children }: PropsWithChildren<{}>) => { const { ui } = useStore() @@ -17,14 +18,14 @@ const OrganizationLayout = ({ children }: PropsWithChildren<{}>) => { title={ui.selectedOrganization?.name ?? 'Supabase'} breadcrumbs={[{ key: `org-settings`, label: 'Settings' }]} > -
    -
    -
    -

    {ui.selectedOrganization?.name ?? 'Organization'} settings

    -
    - + + + {ui.selectedOrganization?.name ?? 'Organization'} settings + + -
    - -
    {children}
    -
    + + + + {children} ) } diff --git a/studio/components/layouts/Scaffold.tsx b/studio/components/layouts/Scaffold.tsx new file mode 100644 index 00000000000..e69a4a44cd0 --- /dev/null +++ b/studio/components/layouts/Scaffold.tsx @@ -0,0 +1,84 @@ +import React from 'react' +import { cn } from 'ui/src/utils/cn' + +const maxWdithClasses = 'mx-auto w-full max-w-[1600px]' +const paddingClasses = 'px-6 lg:px-14 xl:px-28 2xl:px-32' + +// lg: pt - 8 + +const ScaffoldHeader = React.forwardRef>( + ({ className, ...props }, ref) => { + return ( +
    + ) + } +) + +const ScaffoldTitle = React.forwardRef< + HTMLHeadingElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => { + return

    +}) + +const ScaffoldContainer = React.forwardRef>( + ({ className, ...props }, ref) => { + return
    + } +) + +const ScaffoldDivider = React.forwardRef>( + ({ className, ...props }, ref) => { + return
    + } +) + +const ScaffoldSection = React.forwardRef>( + ({ className, ...props }, ref) => { + return ( +
    + ) + } +) + +const ScaffoldSectionDetail = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => { + return
    +}) + +const ScaffoldSectionContent = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => { + return ( +
    + ) +}) + +ScaffoldHeader.displayName = 'ScaffoldHeader' +ScaffoldTitle.displayName = 'ScaffoldTitle' +ScaffoldContainer.displayName = 'ScaffoldContainer' +ScaffoldDivider.displayName = 'ScaffoldDivider' +ScaffoldSection.displayName = 'ScaffoldSection' +ScaffoldSectionDetail.displayName = 'ScaffoldSectionDetail' +ScaffoldSectionContent.displayName = 'ScaffoldSectionContent' + +export { + ScaffoldHeader, + ScaffoldTitle, + ScaffoldContainer, + ScaffoldDivider, + ScaffoldSection, + ScaffoldSectionDetail, + ScaffoldSectionContent, +} diff --git a/studio/data/integrations/integrations-query.ts b/studio/data/integrations/integrations-query.ts index a15a6c0d55d..bb3e7e91015 100644 --- a/studio/data/integrations/integrations-query.ts +++ b/studio/data/integrations/integrations-query.ts @@ -24,6 +24,10 @@ export type Integration = { createdBy: string createdAt: string connections: IntegrationProjectConnection[] + metadata?: { + vercelTeam?: string + gitHubConnectionOwner?: string + } } export type IntegrationsResponse = Integration[] @@ -37,17 +41,71 @@ export async function getIntegrations({ orgSlug }: IntegrationsVariables, signal { id: '1', type: 'VERCEL', - createdBy: 'Alaister', + createdBy: 'alaister@supabase.io', createdAt: '2023-06-05T06:56:25.565Z', + metadata: { + vercelTeam: 'alaister-team', + }, connections: [ { - id: '1.1', - createdAt: '2023-06-05T06:56:25.565Z', - from: { - name: 'supabase-vercel', - }, + id: '1.0', + createdAt: '2023-06-05T01:56:25.565Z', to: { - name: 'alaister', + name: 'www prod', + }, + from: { + name: 'alaister project prod', + }, + }, + { + id: '1.1', + createdAt: '2023-06-14T06:56:25.565Z', + to: { + name: 'www staging', + }, + from: { + name: 'alaister project staging', + }, + }, + { + id: '1.1', + createdAt: '2023-06-02T21:56:25.565Z', + to: { + name: 'bees knees', + }, + from: { + name: 'jonny bee project', + }, + }, + ], + }, + { + id: '1.5', + type: 'VERCEL', + createdBy: 'alaister@supabase.io', + createdAt: '2023-06-05T06:56:25.565Z', + metadata: { + vercelTeam: 'alaister-team', + }, + connections: [], + }, + { + id: '2', + type: 'GITHUB', + createdBy: 'Alaister', + createdAt: '2023-06-05T06:56:25.565Z', + metadata: { + gitHubConnectionOwner: 'alaister', + }, + connections: [ + { + id: '1.2', + createdAt: '2023-06-05T06:56:25.565Z', + to: { + name: 'supabase/supabase', + }, + from: { + name: 'alaister project', }, }, ], diff --git a/studio/public/img/integrations/covers/github-cover.png b/studio/public/img/integrations/covers/github-cover.png new file mode 100644 index 0000000000000000000000000000000000000000..853f5322db52711cfba3cac2ec4b486bf8568ea9 GIT binary patch literal 196269 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[bnxQs@;fYc5`=3! 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ŠIw{eZ#?pq}fj=wK zsaSx?64~k|FyNw3sLKFAq}njd%6k8Ou=Nz)e!S(~ci+vgLUzYa_$CnmrysaA7W9%$ z41;anwST>?Li`JClPNBcz;d^LBl~Y8r24=zns|tluW03Y9h!8|+&6;;D6}0$_Z#kO zil;xDG(A7Yc!YcG7hIp+9YlajK1365OlU0~Z_}L^b+dI6G9_P!{PK?f9K;sctJf{5 zE7HxmB`!8J5w_1dK^cO0-hjAQUpI26jmztei;h3jd5y)+b1Cz}eilcUW9R*W=FrEN zG1i+l&Vdn<$rhJU|F90nS#^=@LktdT-uinic;j77)=%bazQt>4?yQ26KjtV^b$C$B ztim9GCf>u9z;E}eprDn{!b2oCE73X8?=%E0AZ?oG?8I{BaaI)t&in}pK7QmKl0q9N z)eOjDvCcypaoueZ4@l3!!Ovv-d%OQCT`4KB(Ccrbz)GOiNSdo8eVY}u}k628z-`CK*RTXop&IIE|p;kN9YaNp`Y4n zs4FId37$z^uhIIK$(ZbJCv&BfBwwMMK92Tw*cEq9eJ91naX#9Tzif{Vb1CKEa8=oE zR9kn_GoNz}#!LWHZWUGtnh360;Fx8Yw!tvm`Abcb>#?NRXecYZ(zvb^2NRxmr&nnI z9!g?z8c_`z=5g{Bi(K!IzP$VHdqPRPK~gW_2E=`mgJf*D(LHaRYmWu7td?oh=+;LP zTb&=jLAomgdW3o!*?)!p7$0iTqnM=L;YK5Sd89$eb>hFy^HLdI4ETSk<`2QRw1Tlh z%5HINGRG9*FV4X-d70>*=PEMhGB^q14?t=cu%_NkS^`*5k{`UU0Ss66zY74eJU)IH z{2yP|a{gGb&&&O`kgZ%kRiHS_XkI9ftEU)d{3M6tK>>NEMflq9tpwZkF>B&A@r3Pm zWlUu9CihR!Iom^gq@b*(gEkF

    LeKto{YiJtTCi8!8W|DP542-qMHux-O6_Pv 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�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ð$;rFzgtY&DUkPe6Y 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 literal 0 HcmV?d00001 diff --git a/studio/public/img/integrations/covers/vercel-cover.png b/studio/public/img/integrations/covers/vercel-cover.png new file mode 100644 index 0000000000000000000000000000000000000000..d2965eefdc6465e972dc79bb46742f9e240628f5 GIT binary patch literal 197501 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 mO*<+mP#N(rS+`rAD4aS8AeZa)Y{4V+PgPk void setProjectRef: (ref?: string) => void setOrganizationSlug: (slug?: string) => void setNotification: (notification: Notification) => string setPermissions: (permissions?: Permission[]) => void + setShowGitHubRepoSelectionPanel: (visible?: boolean) => void } export default class UiStore implements IUiStore { rootStore: IRootStore @@ -24,6 +26,7 @@ export default class UiStore implements IUiStore { selectedOrganizationSlug?: string notification?: Notification permissions?: Permission[] = [] + showGitHubRepoSelectionPanel: boolean = false constructor(rootStore: IRootStore) { this.rootStore = rootStore @@ -101,4 +104,8 @@ export default class UiStore implements IUiStore { setPermissions(permissions?: any) { this.permissions = permissions } + + setShowGitHubRepoSelectionPanel(visible: boolean) { + this.showGitHubRepoSelectionPanel = visible + } } From 2598b269d46e7eb586f83604c5aa4a982554820c Mon Sep 17 00:00:00 2001 From: Jonathan Summers-Muir Date: Fri, 16 Jun 2023 03:05:53 +0800 Subject: [PATCH 09/59] upgrade UI for vercel integration. added icons for frameworks as well --- .../Integrations/IntegrationPanels.tsx | 122 +++--- .../interfaces/Integrations/ProjectLinker.tsx | 99 +++-- .../GitHubRepoSelection.tsx | 8 +- .../IntegrationSettings/Integration.tsx | 53 +-- .../IntegrationSettings.tsx | 5 +- ...integration-connections-create-mutation.ts | 2 + .../integrations-github-repos-query.ts | 137 +++++++ .../data/integrations/integrations-query.ts | 347 +++++++++++++----- ... => integrations-vercel-projects-query.ts} | 8 +- .../vercel-integration-create-mutation.ts | 9 +- studio/next.config.js | 2 +- studio/pages/integrations/vercel.tsx | 22 +- .../public/img/icons/frameworks/angular.svg | 1 + studio/public/img/icons/frameworks/astro.svg | 15 + .../public/img/icons/frameworks/blitzjs.svg | 30 ++ studio/public/img/icons/frameworks/brunch.svg | 3 + .../img/icons/frameworks/create-react-app.svg | 1 + .../img/icons/frameworks/docusaurus-2.svg | 1 + .../img/icons/frameworks/docusaurus.svg | 1 + studio/public/img/icons/frameworks/dojo.svg | 1 + .../public/img/icons/frameworks/eleventy.svg | 1 + studio/public/img/icons/frameworks/ember.svg | 1 + studio/public/img/icons/frameworks/gatsby.svg | 1 + .../public/img/icons/frameworks/gridsome.svg | 1 + studio/public/img/icons/frameworks/hexo.svg | 1 + studio/public/img/icons/frameworks/hugo.svg | 5 + .../public/img/icons/frameworks/hydrogen.svg | 12 + .../img/icons/frameworks/ionic-angular.svg | 4 + .../img/icons/frameworks/ionic-react.svg | 4 + studio/public/img/icons/frameworks/jekyll.svg | 19 + .../public/img/icons/frameworks/middleman.svg | 9 + studio/public/img/icons/frameworks/nextjs.svg | 1 + studio/public/img/icons/frameworks/nuxtjs.svg | 5 + studio/public/img/icons/frameworks/parcel.svg | 9 + .../public/img/icons/frameworks/polymer.svg | 1 + studio/public/img/icons/frameworks/preact.svg | 1 + .../public/img/icons/frameworks/redwoodjs.svg | 1 + studio/public/img/icons/frameworks/remix.svg | 6 + studio/public/img/icons/frameworks/saber.svg | 1 + studio/public/img/icons/frameworks/sanity.svg | 6 + studio/public/img/icons/frameworks/sapper.svg | 1 + studio/public/img/icons/frameworks/scully.svg | 94 +++++ .../img/icons/frameworks/solidstart.svg | 1 + .../public/img/icons/frameworks/stencil.svg | 4 + .../public/img/icons/frameworks/storybook.svg | 9 + studio/public/img/icons/frameworks/svelte.svg | 1 + .../img/icons/frameworks/sveltekit-1.svg | 1 + .../public/img/icons/frameworks/sveltekit.svg | 1 + studio/public/img/icons/frameworks/umijs.svg | 19 + studio/public/img/icons/frameworks/vite.svg | 15 + .../public/img/icons/frameworks/vitepress.svg | 15 + studio/public/img/icons/frameworks/vue.svg | 1 + .../public/img/icons/frameworks/vuepress.svg | 1 + studio/public/img/icons/frameworks/zola.svg | 4 + .../state/github-connection-config-panel.ts | 15 + studio/stores/UiStore.ts | 7 - 56 files changed, 910 insertions(+), 235 deletions(-) create mode 100644 studio/data/integrations/integrations-github-repos-query.ts rename studio/data/integrations/{vercel-projects-query.ts => integrations-vercel-projects-query.ts} (95%) create mode 100644 studio/public/img/icons/frameworks/angular.svg create mode 100644 studio/public/img/icons/frameworks/astro.svg create mode 100644 studio/public/img/icons/frameworks/blitzjs.svg create mode 100644 studio/public/img/icons/frameworks/brunch.svg create mode 100644 studio/public/img/icons/frameworks/create-react-app.svg create mode 100644 studio/public/img/icons/frameworks/docusaurus-2.svg create mode 100644 studio/public/img/icons/frameworks/docusaurus.svg create mode 100644 studio/public/img/icons/frameworks/dojo.svg create mode 100644 studio/public/img/icons/frameworks/eleventy.svg create mode 100644 studio/public/img/icons/frameworks/ember.svg create mode 100644 studio/public/img/icons/frameworks/gatsby.svg create mode 100644 studio/public/img/icons/frameworks/gridsome.svg create mode 100644 studio/public/img/icons/frameworks/hexo.svg create mode 100644 studio/public/img/icons/frameworks/hugo.svg create mode 100644 studio/public/img/icons/frameworks/hydrogen.svg create mode 100644 studio/public/img/icons/frameworks/ionic-angular.svg create mode 100644 studio/public/img/icons/frameworks/ionic-react.svg create mode 100644 studio/public/img/icons/frameworks/jekyll.svg create mode 100644 studio/public/img/icons/frameworks/middleman.svg create mode 100644 studio/public/img/icons/frameworks/nextjs.svg create mode 100644 studio/public/img/icons/frameworks/nuxtjs.svg create mode 100644 studio/public/img/icons/frameworks/parcel.svg create mode 100644 studio/public/img/icons/frameworks/polymer.svg create mode 100644 studio/public/img/icons/frameworks/preact.svg create mode 100644 studio/public/img/icons/frameworks/redwoodjs.svg create mode 100644 studio/public/img/icons/frameworks/remix.svg create mode 100644 studio/public/img/icons/frameworks/saber.svg create mode 100644 studio/public/img/icons/frameworks/sanity.svg create mode 100644 studio/public/img/icons/frameworks/sapper.svg create mode 100644 studio/public/img/icons/frameworks/scully.svg create mode 100644 studio/public/img/icons/frameworks/solidstart.svg create mode 100644 studio/public/img/icons/frameworks/stencil.svg create mode 100644 studio/public/img/icons/frameworks/storybook.svg create mode 100644 studio/public/img/icons/frameworks/svelte.svg create mode 100644 studio/public/img/icons/frameworks/sveltekit-1.svg create mode 100644 studio/public/img/icons/frameworks/sveltekit.svg create mode 100644 studio/public/img/icons/frameworks/umijs.svg create mode 100644 studio/public/img/icons/frameworks/vite.svg create mode 100644 studio/public/img/icons/frameworks/vitepress.svg create mode 100644 studio/public/img/icons/frameworks/vue.svg create mode 100644 studio/public/img/icons/frameworks/vuepress.svg create mode 100644 studio/public/img/icons/frameworks/zola.svg create mode 100644 studio/state/github-connection-config-panel.ts diff --git a/studio/components/interfaces/Integrations/IntegrationPanels.tsx b/studio/components/interfaces/Integrations/IntegrationPanels.tsx index 5d301ecc747..3ac3b3e79d8 100644 --- a/studio/components/interfaces/Integrations/IntegrationPanels.tsx +++ b/studio/components/interfaces/Integrations/IntegrationPanels.tsx @@ -1,38 +1,34 @@ +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 { - Button, - IconArrowRight, - IconCloudLightning, - IconGitHub, - IconSquare, - IconTriangle, -} from 'ui' +import { Project } from 'types' +import { Button, IconArrowRight, IconGitHub, IconSquare } from 'ui' import { cn } from 'ui/src/utils/cn' -var relativeTime = require('dayjs/plugin/relativeTime') -dayjs.extend(relativeTime) - const ICON_STROKE_WIDTH = 2 const ICON_SIZE = 14 export interface IntegrationInstallationProps extends React.HTMLAttributes { title: string - orgName: string + // orgName: string connection: Integration } -type HandleIconType = Integration['type'] | 'SUPABASE' +type HandleIconType = Integration['integration']['name'] | 'Supabase' const HandleIcon = ({ type }: { type: HandleIconType }) => { switch (type) { - case 'GITHUB': + case 'GitHub': return break - case 'NETLIFY': + case 'Netlify': return break - case 'VERCEL': + case 'Vercel': return ( { // break - case 'SUPABASE': - return ( - Supabase - ) + case 'Supabase': + return Supabase // break @@ -64,11 +54,11 @@ const HandleIcon = ({ type }: { type: HandleIconType }) => { } const IntegrationInstallation = React.forwardRef( - ({ className, title, orgName, connection, ...props }, ref) => { + ({ className, title, connection, ...props }, ref) => { const IntegrationIconBlock = () => { return (

    - +
    ) } @@ -93,9 +83,11 @@ const IntegrationInstallation = React.forwardRef
    - Created {dayjs(connection.createdAt).fromNow()} + Created {dayjs(connection.created_at).fromNow()} + + + Added by {connection?.added_by?.primary_email} - Added by {connection.createdBy}
    @@ -108,36 +100,51 @@ const IntegrationInstallation = React.forwardRef { connection: IntegrationProjectConnection - type: Integration['type'] + type: Integration['integration']['name'] } const IntegrationConnection = React.forwardRef( ({ className, connection, type, ...props }, ref) => { + const { app } = useStore() + + const { projects } = app + return (
  • - - {connection.from.name} + + {projects.byId(connection.project_ref)?.name} - - {connection.to.name} + {!connection.metadata.framework ? ( + + ) : ( + {`icon`} + )} + + {connection.metadata.name}
    - - Connected {dayjs(connection.createdAt).fromNow()} - +
    + + Connected {dayjs(connection?.created_at).fromNow()} + + + Added by {connection?.added_by?.primary_email} + +
    @@ -151,6 +158,9 @@ const IntegrationConnection = React.forwardRef( ({ className, connection, type, ...props }, ref) => { + const { app } = useStore() + + const { projects } = app return (
  • - - {connection.from.name} + + {projects.byId(connection.project_ref)?.name} - {connection.to.name} + {connection.metadata.name}
    - Connected {dayjs(connection.createdAt).fromNow()} + Connected {dayjs(connection.created_at).fromNow()}
    @@ -183,7 +193,12 @@ const EmptyIntegrationConnection = React.forwardRef< React.HTMLAttributes >(({ className, ...props }, ref) => { return ( -
    +
    +
    @@ -203,16 +217,18 @@ const EmptyIntegrationConnection = React.forwardRef< interface IntegrationConnectionHeader extends React.HTMLAttributes { name?: string + markdown?: string } const IntegrationConnectionHeader = React.forwardRef( - ({ className, name, ...props }, ref) => { + ({ className, name, markdown = '', ...props }, ref) => { return ( -
    -

    {props.title}

    +
    + {/*

    {props.title}

    Repository connections for {name?.toLowerCase()} -

    +

    */} +
    ) } @@ -228,6 +244,6 @@ export { EmptyIntegrationConnection, IntegrationConnection, IntegrationConnectionHeader, - IntegrationInstallation, IntegrationConnectionOption, + IntegrationInstallation, } diff --git a/studio/components/interfaces/Integrations/ProjectLinker.tsx b/studio/components/interfaces/Integrations/ProjectLinker.tsx index 05a4b10d94f..9c694ead9ab 100644 --- a/studio/components/interfaces/Integrations/ProjectLinker.tsx +++ b/studio/components/interfaces/Integrations/ProjectLinker.tsx @@ -1,6 +1,8 @@ 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' interface Project { @@ -8,14 +10,18 @@ interface Project { name: string } +// to do: move this somewhere +const INTEGRATION_INTERNAL_ID = 1 + export interface ProjectLinkerProps { organizationIntegrationId: string - foreignProjects: Project[] + foreignProjects: VercelProjectsResponse[] supabaseProjects: Project[] onCreateConnections?: () => void } const UNDEFINED_SELECT_VALUE = 'undefined' +const UNDEFINED_METADATA_VALUE = {} const ProjectLinker = ({ organizationIntegrationId, @@ -24,12 +30,28 @@ const ProjectLinker = ({ onCreateConnections: _onCreateConnections, }: ProjectLinkerProps) => { const [connections, setConnections] = useState([ - { foreignProjectId: UNDEFINED_SELECT_VALUE, supabaseProjectId: UNDEFINED_SELECT_VALUE }, + { + foreignProjectId: UNDEFINED_SELECT_VALUE, + supabaseProjectId: UNDEFINED_SELECT_VALUE, + integrationId: INTEGRATION_INTERNAL_ID, + metadata: UNDEFINED_METADATA_VALUE, + }, ]) 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 } newConnections[idx].foreignProjectId = id + newConnections[idx].supabaseConfig = { + projectEnvVars: { + write: true, + }, + } + setConnections(newConnections) } @@ -42,7 +64,12 @@ const ProjectLinker = ({ function addConnection() { setConnections([ ...connections, - { foreignProjectId: UNDEFINED_SELECT_VALUE, supabaseProjectId: UNDEFINED_SELECT_VALUE }, + { + foreignProjectId: UNDEFINED_SELECT_VALUE, + supabaseProjectId: UNDEFINED_SELECT_VALUE, + integrationId: INTEGRATION_INTERNAL_ID, + metadata: UNDEFINED_METADATA_VALUE, + }, ]) } @@ -59,6 +86,7 @@ const ProjectLinker = ({ }) function onCreateConnections() { + console.log('connections', connections) createConnections({ organizationIntegrationId, connections, @@ -71,6 +99,7 @@ const ProjectLinker = ({ {connections.map((connection, i) => ( void removeConnection: () => void canRemove: boolean + connections: any[] } const ProjectLinkerItem = ({ @@ -132,30 +162,6 @@ const ProjectLinkerItem = ({ return (
  • -
    - - - Choose a project - - - {foreignProjects.map((project) => ( - vercelIcon} - > - {project.name} - - ))} - -
    -
    - -
    +
    + +
    +
    + + + Choose a project + + + {foreignProjects.map((project) => ( + { + return ( + <> + {!project?.framework ? ( + vercelIcon + ) : ( + {`icon`} + )} + + ) + }} + > + {project.name} + + ))} + +
    {canRemove && ( -
    +
    {actions}
  • ) @@ -216,8 +211,6 @@ const EmptyIntegrationConnection = React.forwardRef< >
    { return (
    - {/*

    {props.title}

    -

    - Repository connections for {name?.toLowerCase()} -

    */}
    ) diff --git a/studio/components/interfaces/Integrations/ProjectLinker.tsx b/studio/components/interfaces/Integrations/ProjectLinker.tsx index 9c694ead9ab..7488298a8a8 100644 --- a/studio/components/interfaces/Integrations/ProjectLinker.tsx +++ b/studio/components/interfaces/Integrations/ProjectLinker.tsx @@ -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 (
      @@ -159,29 +174,27 @@ const ProjectLinkerItem = ({ removeConnection, canRemove, }: ProjectLinkerItemProps) => { + console.log(supabaseProjectId) return (
    • - - +
      diff --git a/studio/components/interfaces/Organization/IntegrationSettings/Integration.tsx b/studio/components/interfaces/Organization/IntegrationSettings/Integration.tsx index 9be3d46e382..ecbd6751ea2 100644 --- a/studio/components/interfaces/Organization/IntegrationSettings/Integration.tsx +++ b/studio/components/interfaces/Organization/IntegrationSettings/Integration.tsx @@ -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 ( <> @@ -84,6 +106,42 @@ Repository connections for ${title?.toLowerCase()} key={i} connection={connection} type={integration.integration.name} + actions={ + + + +
      + } + > +
      Refresh Enviroment Variables
      +
      + Reapply env vars in vercel. +
      + + + } + onSelect={() => + handleDelete(integration.id, connection.id) + } + > + Delete + + + } + > + + + } /> ))}
    diff --git a/studio/components/interfaces/Organization/IntegrationSettings/IntegrationSettings.tsx b/studio/components/interfaces/Organization/IntegrationSettings/IntegrationSettings.tsx index 4e13f013ad0..7576bb5187c 100644 --- a/studio/components/interfaces/Organization/IntegrationSettings/IntegrationSettings.tsx +++ b/studio/components/interfaces/Organization/IntegrationSettings/IntegrationSettings.tsx @@ -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} /> - + {/* */} + ) } diff --git a/studio/components/interfaces/Organization/IntegrationSettings/GitHubRepoSelection.tsx b/studio/components/interfaces/Organization/IntegrationSettings/SidePanelGitHubRepoSelection.tsx similarity index 100% rename from studio/components/interfaces/Organization/IntegrationSettings/GitHubRepoSelection.tsx rename to studio/components/interfaces/Organization/IntegrationSettings/SidePanelGitHubRepoSelection.tsx diff --git a/studio/components/interfaces/Organization/IntegrationSettings/SidePanelVercelProjectLinker.tsx b/studio/components/interfaces/Organization/IntegrationSettings/SidePanelVercelProjectLinker.tsx new file mode 100644 index 00000000000..44132a299db --- /dev/null +++ b/studio/components/interfaces/Organization/IntegrationSettings/SidePanelVercelProjectLinker.tsx @@ -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( + '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 ( + githubConnectionConfigPanelSnapshot.setVisible(false)} + > +
    + + + + + { + // if (next) { + // window.location.href = next + // } + }} + installedConnections={vercelProjectConnections} + /> + + +
      +
    • + {/* */} +
    • +
    +
    +
    +
    + ) +} + +export default observer(SidePanelVercelProjectLinker) diff --git a/studio/components/layouts/Scaffold.tsx b/studio/components/layouts/Scaffold.tsx index e69a4a44cd0..b3adc0714f7 100644 --- a/studio/components/layouts/Scaffold.tsx +++ b/studio/components/layouts/Scaffold.tsx @@ -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>( ({ className, ...props }, ref) => { - return
    + return
    } ) diff --git a/studio/data/integrations/integration-connections-create-mutation.ts b/studio/data/integrations/integration-connections-create-mutation.ts index d60828ca565..6881b405fab 100644 --- a/studio/data/integrations/integration-connections-create-mutation.ts +++ b/studio/data/integrations/integration-connections-create-mutation.ts @@ -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, }) diff --git a/studio/data/integrations/integrations-vercel-installed-connection-delete-mutation.ts b/studio/data/integrations/integrations-vercel-installed-connection-delete-mutation.ts new file mode 100644 index 00000000000..5c9825553b4 --- /dev/null +++ b/studio/data/integrations/integrations-vercel-installed-connection-delete-mutation.ts @@ -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_( + `${API_URL}/integrations/vercel/connections/${id}`, + { organization_integration_id }, + { signal } + ) + + if (response.error) throw response.error + return response +} + +type DeleteContentData = Awaited> + +export const useIntegrationsVercelInstalledConnectionDeleteMutation = ({ + onSuccess, + ...options +}: Omit, 'mutationFn'> = {}) => { + return useMutation( + (args) => deleteConnection(args), + { + async onSuccess(data, variables, context) { + await onSuccess?.(data, variables, context) + }, + ...options, + } + ) +} diff --git a/studio/data/integrations/integrations-vercel-installed-connections-query.ts b/studio/data/integrations/integrations-vercel-installed-connections-query.ts new file mode 100644 index 00000000000..f4136c2f11d --- /dev/null +++ b/studio/data/integrations/integrations-vercel-installed-connections-query.ts @@ -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> +export type VercelProjectsError = unknown + +export const useVercelProjectConnectionsQuery = ( + { organization_integration_id }: VercelProjectsVariables, + { + enabled = true, + ...options + }: UseQueryOptions = {} +) => + useQuery( + 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 ( + * prefetch()}> + * Start loading on hover + * + * ) + */ +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]) +} diff --git a/studio/data/integrations/keys.ts b/studio/data/integrations/keys.ts index f317710e2b3..be833c0d307 100644 --- a/studio/data/integrations/keys.ts +++ b/studio/data/integrations/keys.ts @@ -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, } From dc9f9956df3a0a27ec043aafd69806de465dadf8 Mon Sep 17 00:00:00 2001 From: Jonathan Summers-Muir Date: Mon, 19 Jun 2023 18:50:18 +0800 Subject: [PATCH 12/59] fix issues using new API changes --- .../interfaces/Integrations/ProjectLinker.tsx | 20 +-- .../IntegrationSettings.tsx | 4 +- .../SidePanelVercelProjectLinker.tsx | 4 +- ...integration-connections-create-mutation.ts | 2 +- .../data/integrations/integrations-query.ts | 128 +++--------------- .../integrations-vercel-projects-query.ts | 2 +- 6 files changed, 34 insertions(+), 126 deletions(-) diff --git a/studio/components/interfaces/Integrations/ProjectLinker.tsx b/studio/components/interfaces/Integrations/ProjectLinker.tsx index 7488298a8a8..81e9ca7e6d2 100644 --- a/studio/components/interfaces/Integrations/ProjectLinker.tsx +++ b/studio/components/interfaces/Integrations/ProjectLinker.tsx @@ -34,16 +34,16 @@ const ProjectLinker = ({ installedConnections && installedConnections.length > 0 ? installedConnections?.map((connection) => { return { - foreignProjectId: connection?.foreign_project_id, - supabaseProjectId: connection?.supabase_project_id, + foreign_project_id: connection?.foreign_project_id, + supabase_project_id: connection?.supabase_project_id, integrationId: INTEGRATION_INTERNAL_ID, metadata: UNDEFINED_METADATA_VALUE, } }) : [ { - foreignProjectId: UNDEFINED_SELECT_VALUE, - supabaseProjectId: UNDEFINED_SELECT_VALUE, + foreign_project_id: UNDEFINED_SELECT_VALUE, + supabase_project_id: UNDEFINED_SELECT_VALUE, integrationId: INTEGRATION_INTERNAL_ID, metadata: UNDEFINED_METADATA_VALUE, }, @@ -59,7 +59,7 @@ const ProjectLinker = ({ const newConnections = [...connections] const projectDetails = foreignProjects.filter((x) => x.id === id)[0] newConnections[idx].metadata = { ...projectDetails } - newConnections[idx].foreignProjectId = id + newConnections[idx].foreign_project_id = id newConnections[idx].supabaseConfig = { projectEnvVars: { write: true, @@ -71,7 +71,7 @@ const ProjectLinker = ({ function onSetSupabaseProjectId(idx: number, id: string) { const newConnections = [...connections] - newConnections[idx].supabaseProjectId = id + newConnections[idx].supabase_project_id = id setConnections(newConnections) } @@ -79,8 +79,8 @@ const ProjectLinker = ({ setConnections([ ...connections, { - foreignProjectId: UNDEFINED_SELECT_VALUE, - supabaseProjectId: UNDEFINED_SELECT_VALUE, + foreign_project_id: UNDEFINED_SELECT_VALUE, + supabase_project_id: UNDEFINED_SELECT_VALUE, integrationId: INTEGRATION_INTERNAL_ID, metadata: UNDEFINED_METADATA_VALUE, }, @@ -117,9 +117,9 @@ const ProjectLinker = ({ connections={connections} foreignProjects={foreignProjects} supabaseProjects={supabaseProjects} - foreignProjectId={connection.foreignProjectId} + foreignProjectId={connection.foreign_project_id} setForeignProjectId={(id) => onSetForeignProjectId(i, id)} - supabaseProjectId={connection.supabaseProjectId} + supabaseProjectId={connection.supabase_project_id} setSupabaseProjectId={(id) => onSetSupabaseProjectId(i, id)} removeConnection={() => removeConnection(i)} canRemove={connections.length > 1} diff --git a/studio/components/interfaces/Organization/IntegrationSettings/IntegrationSettings.tsx b/studio/components/interfaces/Organization/IntegrationSettings/IntegrationSettings.tsx index 7576bb5187c..240cce5449c 100644 --- a/studio/components/interfaces/Organization/IntegrationSettings/IntegrationSettings.tsx +++ b/studio/components/interfaces/Organization/IntegrationSettings/IntegrationSettings.tsx @@ -11,7 +11,7 @@ import SidePanelVercelProjectLinker from './SidePanelVercelProjectLinker' const IntegrationSettings = () => { const { ui } = useStore() const { slug } = useParams() - const { data } = useIntegrationsQuery({ orgSlug: slug }) + const { data } = useIntegrationsQuery({ orgId: ui.selectedOrganization?.id }) const org = ui.selectedOrganization @@ -71,7 +71,7 @@ You can change the scope of the access for Supabase by configuring here. integrations={githubIntegrations} /> {/* */} - + {/* */} ) } diff --git a/studio/components/interfaces/Organization/IntegrationSettings/SidePanelVercelProjectLinker.tsx b/studio/components/interfaces/Organization/IntegrationSettings/SidePanelVercelProjectLinker.tsx index 44132a299db..f5c459773b5 100644 --- a/studio/components/interfaces/Organization/IntegrationSettings/SidePanelVercelProjectLinker.tsx +++ b/studio/components/interfaces/Organization/IntegrationSettings/SidePanelVercelProjectLinker.tsx @@ -16,8 +16,8 @@ import { useVercelProjectConnectionsQuery } from 'data/integrations/integrations const SidePanelVercelProjectLinker = () => { const { ui } = useStore() - const { slug } = useParams() - const { data } = useIntegrationsQuery({ orgSlug: slug }) + + const { data } = useIntegrationsQuery({ orgId: ui.selectedOrganization?.id }) const vercelIntegrations = data?.filter((integration) => integration.integration.id === 1) // vercel diff --git a/studio/data/integrations/integration-connections-create-mutation.ts b/studio/data/integrations/integration-connections-create-mutation.ts index 6881b405fab..3c58ea49072 100644 --- a/studio/data/integrations/integration-connections-create-mutation.ts +++ b/studio/data/integrations/integration-connections-create-mutation.ts @@ -17,7 +17,7 @@ export async function createIntegrationConnections({ connections, }: IntegrationConnectionsCreateVariables) { const response = await post(`${API_URL}/integrations/vercel/connections`, { - organizationIntegrationId, + organization_integration_id: organizationIntegrationId, connections, }) if (response.error) { diff --git a/studio/data/integrations/integrations-query.ts b/studio/data/integrations/integrations-query.ts index 1dff671601a..39cc1f7b7ad 100644 --- a/studio/data/integrations/integrations-query.ts +++ b/studio/data/integrations/integrations-query.ts @@ -7,20 +7,15 @@ type metadata = { metadata: { id: string supabaseConfig: { - // branching: { - // prodBranch: string - // } projectEnvVars: { write: boolean } - // supabaseDeploymentConfig: { - // functions: { - // deploy: false - // } - // } } link?: | { + /** + * GitHub link + */ org?: string repo?: string repoId?: number @@ -39,6 +34,9 @@ type metadata = { productionBranch?: string } | { + /** + * GitLab link + */ projectId?: string projectName?: string projectNameWithNamespace?: string @@ -59,6 +57,9 @@ type metadata = { productionBranch?: string } | { + /** + * Bitbucket link + */ name?: string slug?: string owner?: string @@ -138,7 +139,7 @@ export type IntegrationProjectConnection = { } export type IntegrationsVariables = { - orgSlug?: string + orgId?: number } export type IntegrationProjectConnectionPayload = { @@ -174,87 +175,12 @@ export type Integration = { export type IntegrationsResponse = Integration[] -export async function getIntegrations({ orgSlug }: IntegrationsVariables, signal?: AbortSignal) { - if (!orgSlug) { - throw new Error('orgSlug is required') +export async function getIntegrations({ orgId }: IntegrationsVariables, signal?: AbortSignal) { + if (!orgId) { + throw new Error('orgId is required') } - // const response: IntegrationsResponse = [ - // { - // id: '1', - // type: 'VERCEL', - // createdBy: 'alaister@supabase.io', - // createdAt: '2023-06-05T06:56:25.565Z', - // metadata: { - // vercelTeam: 'alaister-team', - // }, - // connections: [ - // { - // id: '1.0', - // createdAt: '2023-06-05T01:56:25.565Z', - // to: { - // name: 'www prod', - // }, - // from: { - // name: 'alaister project prod', - // }, - // }, - // { - // id: '1.1', - // createdAt: '2023-06-14T06:56:25.565Z', - // to: { - // name: 'www staging', - // }, - // from: { - // name: 'alaister project staging', - // }, - // }, - // { - // id: '1.1', - // createdAt: '2023-06-02T21:56:25.565Z', - // to: { - // name: 'bees knees', - // }, - // from: { - // name: 'jonny bee project', - // }, - // }, - // ], - // }, - // { - // id: '2', - // type: 'VERCEL', - // createdBy: 'alaister@supabase.io', - // createdAt: '2023-06-05T06:56:25.565Z', - // metadata: { - // vercelTeam: 'alaister-team', - // }, - // connections: [], - // }, - // { - // id: '3', - // type: 'GITHUB', - // createdBy: 'Alaister', - // createdAt: '2023-06-05T06:56:25.565Z', - // metadata: { - // gitHubConnectionOwner: 'alaister', - // }, - // connections: [ - // { - // id: '1.2', - // createdAt: '2023-06-05T06:56:25.565Z', - // to: { - // name: 'supabase/supabase', - // }, - // from: { - // name: 'alaister project', - // }, - // }, - // ], - // }, - // ] - - const response = await get(`${API_URL}/integrations/${orgSlug}`, { + const response = await get(`${API_URL}/integrations/${orgId}`, { signal, }) if (response.error) { @@ -264,24 +190,6 @@ export async function getIntegrations({ orgSlug }: IntegrationsVariables, signal return response as IntegrationsResponse } -// export async function getProjectIntegrationConnections( -// { orgSlug }: IntegrationsVariables, -// signal?: AbortSignal -// ) { -// if (!orgSlug) { -// throw new Error('orgSlug is required') -// } - -// const response = await get(`${API_URL}/integrations`, { -// signal, -// }) -// if (response.error) { -// throw response.error -// } - -// return response as IntegrationsResponse -// } - export type IntegrationsData = Awaited> export type ProjectIntegrationConnectionsData = Awaited< ReturnType @@ -289,11 +197,11 @@ export type ProjectIntegrationConnectionsData = Awaited< export type IntegrationsError = unknown export const useIntegrationsQuery = ( - { orgSlug }: IntegrationsVariables, + { orgId }: IntegrationsVariables, { enabled = true, ...options }: UseQueryOptions = {} ) => useQuery( - integrationKeys.list(orgSlug), - ({ signal }) => getIntegrations({ orgSlug }, signal), - { enabled: enabled && typeof orgSlug !== 'undefined', ...options } + integrationKeys.list(orgId), + ({ signal }) => getIntegrations({ orgId }, signal), + { enabled: enabled && typeof orgId !== 'undefined', ...options } ) diff --git a/studio/data/integrations/integrations-vercel-projects-query.ts b/studio/data/integrations/integrations-vercel-projects-query.ts index da159791234..493cfd83dae 100644 --- a/studio/data/integrations/integrations-vercel-projects-query.ts +++ b/studio/data/integrations/integrations-vercel-projects-query.ts @@ -25,7 +25,7 @@ export async function getVercelProjects({ orgId }: VercelProjectsVariables, sign throw new Error('orgId is required') } - const response = await get(`${API_URL}/integrations/vercel/projects/${orgId}`, { + const response = await get(`${API_URL}/integrations/vercel/connections/${orgId}`, { signal, }) if (response.error) { From 8c1d4f716297739b7f5241c5d670e89cdd0ce845 Mon Sep 17 00:00:00 2001 From: Jonathan Summers-Muir Date: Tue, 20 Jun 2023 00:13:21 +0800 Subject: [PATCH 13/59] add source and teamId to new org integration payload --- .../vercel-integration-create-mutation.ts | 10 +++++++++- studio/pages/integrations/vercel.tsx | 11 ++++++++++- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/studio/data/integrations/vercel-integration-create-mutation.ts b/studio/data/integrations/vercel-integration-create-mutation.ts index 9b8a8b21ead..04781212e39 100644 --- a/studio/data/integrations/vercel-integration-create-mutation.ts +++ b/studio/data/integrations/vercel-integration-create-mutation.ts @@ -7,6 +7,10 @@ export type VercelIntegrationCreateVariables = { configurationId: string orgId: number 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({ @@ -14,13 +18,17 @@ export async function createVercelIntegration({ configurationId, orgId, metadata, + source, + teamId, }: VercelIntegrationCreateVariables) { - console.log('payload', { code, configurationId, orgId, metadata }) + console.log('payload', { code, configurationId, orgId, metadata, source, teamId }) const response = await post(`${API_URL}/integrations/vercel`, { code, configuration_id: configurationId, organization_id: orgId, metadata, + source, + teamId, }) if (response.error) { throw response.error diff --git a/studio/pages/integrations/vercel.tsx b/studio/pages/integrations/vercel.tsx index 3c7930ca83c..0a9b9b60d89 100644 --- a/studio/pages/integrations/vercel.tsx +++ b/studio/pages/integrations/vercel.tsx @@ -14,7 +14,7 @@ import { Button } from 'ui' const VercelIntegration: NextPageWithLayout = () => { const { ui } = useStore() - const { code, configurationId, next } = useParams() + const { code, configurationId, next, teamId, source } = useParams() const [selectedOrg, setSelectedOrg] = useState(null) const [organizationIntegrationId, setOrganizationIntegrationId] = useState(null) @@ -38,6 +38,13 @@ const VercelIntegration: NextPageWithLayout = () => { return ui.setNotification({ category: 'error', message: 'Vercel Configuration ID missing' }) } + if (!source) { + return ui.setNotification({ + category: 'error', + message: 'Vercel Configuration source missing', + }) + } + const metadata = {} mutate({ @@ -45,6 +52,8 @@ const VercelIntegration: NextPageWithLayout = () => { configurationId, orgId, metadata, + source, + teamId, }) } From 321fd0818c289005b6b5604abbbdcf01a9ce1cc2 Mon Sep 17 00:00:00 2001 From: Jonathan Summers-Muir Date: Tue, 20 Jun 2023 01:59:27 +0800 Subject: [PATCH 14/59] fix visuals --- .../Integrations/IntegrationPanels.tsx | 2 +- .../integrations-vercel-projects-query.ts | 29 +++++++++++++------ studio/pages/integrations/vercel.tsx | 3 +- 3 files changed, 23 insertions(+), 11 deletions(-) diff --git a/studio/components/interfaces/Integrations/IntegrationPanels.tsx b/studio/components/interfaces/Integrations/IntegrationPanels.tsx index 46b9b59db37..6817050500b 100644 --- a/studio/components/interfaces/Integrations/IntegrationPanels.tsx +++ b/studio/components/interfaces/Integrations/IntegrationPanels.tsx @@ -91,7 +91,7 @@ const IntegrationInstallation = React.forwardRef - {connection.metadata.account.plan} + {connection.metadata.account.type}
    diff --git a/studio/data/integrations/integrations-vercel-projects-query.ts b/studio/data/integrations/integrations-vercel-projects-query.ts index 493cfd83dae..2f3307b373b 100644 --- a/studio/data/integrations/integrations-vercel-projects-query.ts +++ b/studio/data/integrations/integrations-vercel-projects-query.ts @@ -7,6 +7,7 @@ import { integrationKeys } from './keys' export type VercelProjectsVariables = { orgId?: number orgSlug?: string + organization_integration_id?: string } export type VercelProjectsResponse = { @@ -20,14 +21,20 @@ export type VercelProjectsResponse = { } } -export async function getVercelProjects({ orgId }: VercelProjectsVariables, signal?: AbortSignal) { - if (!orgId) { +export async function getVercelProjects( + { orgId, organization_integration_id }: VercelProjectsVariables, + signal?: AbortSignal +) { + if (!organization_integration_id) { throw new Error('orgId is required') } - const response = await get(`${API_URL}/integrations/vercel/connections/${orgId}`, { - signal, - }) + const response = await get( + `${API_URL}/integrations/vercel/projects/${organization_integration_id}`, + { + signal, + } + ) if (response.error) { throw response.error } @@ -39,7 +46,7 @@ export type VercelProjectsData = Awaited> export type VercelProjectsError = unknown export const useVercelProjectsQuery = ( - { orgSlug, orgId }: VercelProjectsVariables, + { orgSlug, orgId, organization_integration_id }: VercelProjectsVariables, { enabled = true, ...options @@ -47,7 +54,7 @@ export const useVercelProjectsQuery = ( ) => useQuery( integrationKeys.vercelProjectList(orgSlug), - ({ signal }) => getVercelProjects({ orgSlug, orgId }, signal), + ({ signal }) => getVercelProjects({ orgSlug, orgId, organization_integration_id }, signal), { enabled: enabled && typeof orgSlug !== 'undefined' && typeof orgId !== 'undefined', ...options, @@ -66,13 +73,17 @@ export const useVercelProjectsQuery = ( * * ) */ -export const useVercelProjectsPrefetch = ({ orgSlug, orgId }: VercelProjectsVariables) => { +export const useVercelProjectsPrefetch = ({ + orgSlug, + orgId, + organization_integration_id, +}: VercelProjectsVariables) => { const client = useQueryClient() return useCallback(() => { if (orgSlug) { client.prefetchQuery(integrationKeys.vercelProjectList(orgSlug), ({ signal }) => - getVercelProjects({ orgSlug, orgId }, signal) + getVercelProjects({ orgSlug, orgId, organization_integration_id }, signal) ) } }, [orgSlug]) diff --git a/studio/pages/integrations/vercel.tsx b/studio/pages/integrations/vercel.tsx index 0a9b9b60d89..049ad06a48e 100644 --- a/studio/pages/integrations/vercel.tsx +++ b/studio/pages/integrations/vercel.tsx @@ -53,7 +53,7 @@ const VercelIntegration: NextPageWithLayout = () => { orgId, metadata, source, - teamId, + teamId: teamId, }) } @@ -72,6 +72,7 @@ const VercelIntegration: NextPageWithLayout = () => { { orgId: selectedOrg?.id, orgSlug: selectedOrg?.slug, + organization_integration_id: organizationIntegrationId, }, { enabled: organizationIntegrationId !== null } ) From af5433acbecc543d196110b88b65c47529076139 Mon Sep 17 00:00:00 2001 From: Jonathan Summers-Muir Date: Tue, 20 Jun 2023 16:54:48 +0800 Subject: [PATCH 15/59] new UI for vercel integration marketplace flow --- packages/ui/index.tsx | 1 + .../src/components/Command/Command.utils.tsx | 2 +- .../{Command => LoadingLine}/LoadingLine.tsx | 2 +- .../ui/src/components/LoadingLine/index.tsx | 1 + .../Integrations/IntegrationPanels.tsx | 6 +- .../Integrations-Vercel.constants.ts | 52 +++ .../interfaces/Integrations/ProjectLinker.tsx | 297 ++++++++---------- .../Integrations/ProjectsLinker.tsx | 245 +++++++++++++++ studio/components/interfaces/Markdown.tsx | 2 +- .../IntegrationSettings.tsx | 8 +- .../SidePanelVercelProjectLinker.tsx | 2 +- .../layouts/IntegrationWindowLayout.tsx | 72 +++++ studio/components/layouts/Scaffold.tsx | 2 +- studio/pages/integrations/vercel.tsx | 119 +++++-- 14 files changed, 609 insertions(+), 202 deletions(-) rename packages/ui/src/components/{Command => LoadingLine}/LoadingLine.tsx (93%) create mode 100644 packages/ui/src/components/LoadingLine/index.tsx create mode 100644 studio/components/interfaces/Integrations/Integrations-Vercel.constants.ts create mode 100644 studio/components/interfaces/Integrations/ProjectsLinker.tsx create mode 100644 studio/components/layouts/IntegrationWindowLayout.tsx diff --git a/packages/ui/index.tsx b/packages/ui/index.tsx index 30d9ad7d52e..f5009a16d8d 100644 --- a/packages/ui/index.tsx +++ b/packages/ui/index.tsx @@ -63,6 +63,7 @@ export * from './src/components/Form' export * from './src/components/Command' // layout +export * from './src/components/LoadingLine' // banners export * from './src/layout/banners' diff --git a/packages/ui/src/components/Command/Command.utils.tsx b/packages/ui/src/components/Command/Command.utils.tsx index ee020395eb9..a7a44b0cc8b 100644 --- a/packages/ui/src/components/Command/Command.utils.tsx +++ b/packages/ui/src/components/Command/Command.utils.tsx @@ -7,7 +7,7 @@ import { DetailedHTMLProps, HTMLAttributes, KeyboardEventHandler } from 'react' import { Modal } from '../Modal' import { ModalProps } from '../Modal/Modal' import { useCommandMenu } from './CommandMenuProvider' -import { LoadingLine } from './LoadingLine' +import { LoadingLine } from '../LoadingLine/LoadingLine' type CommandPrimitiveElement = React.ElementRef type CommandPrimitiveProps = React.ComponentPropsWithoutRef diff --git a/packages/ui/src/components/Command/LoadingLine.tsx b/packages/ui/src/components/LoadingLine/LoadingLine.tsx similarity index 93% rename from packages/ui/src/components/Command/LoadingLine.tsx rename to packages/ui/src/components/LoadingLine/LoadingLine.tsx index 1e590e092b1..afb8522b653 100644 --- a/packages/ui/src/components/Command/LoadingLine.tsx +++ b/packages/ui/src/components/LoadingLine/LoadingLine.tsx @@ -1,5 +1,5 @@ import React from 'react' -import { cn } from './../../lib/utils' +import { cn } from '../../lib/utils' export const LoadingLine = ({ loading }: { loading: boolean }) => { return ( diff --git a/packages/ui/src/components/LoadingLine/index.tsx b/packages/ui/src/components/LoadingLine/index.tsx new file mode 100644 index 00000000000..16a23c1edfe --- /dev/null +++ b/packages/ui/src/components/LoadingLine/index.tsx @@ -0,0 +1 @@ +export * from './LoadingLine' diff --git a/studio/components/interfaces/Integrations/IntegrationPanels.tsx b/studio/components/interfaces/Integrations/IntegrationPanels.tsx index 6817050500b..9cf53225dfa 100644 --- a/studio/components/interfaces/Integrations/IntegrationPanels.tsx +++ b/studio/components/interfaces/Integrations/IntegrationPanels.tsx @@ -6,8 +6,7 @@ import Image from 'next/image' import React from 'react' -import { Badge, Button, IconArrowRight, IconGitHub, IconSquare } from 'ui' -import { cn } from 'ui/src/utils/cn' +import { Badge, Button, IconArrowRight, IconGitHub, IconSquare, cn } from 'ui' const ICON_STROKE_WIDTH = 2 const ICON_SIZE = 14 @@ -50,6 +49,7 @@ const HandleIcon = ({ type }: { type: HandleIconType }) => { } const Avatar = ({ src }: { src: string }) => { + console.log('src of avatar', src) return (
    avatar @@ -80,7 +80,7 @@ const IntegrationInstallation = React.forwardRef */}
    - +
    diff --git a/studio/components/interfaces/Integrations/Integrations-Vercel.constants.ts b/studio/components/interfaces/Integrations/Integrations-Vercel.constants.ts new file mode 100644 index 00000000000..4513c7a4aed --- /dev/null +++ b/studio/components/interfaces/Integrations/Integrations-Vercel.constants.ts @@ -0,0 +1,52 @@ +export const ENV_VAR_KEYS = { + POSTGRES_URL: { + key: 'POSTGRES_URL', + type: 'encrypted', + }, + POSTGRES_PRISMA_URL: { + key: 'POSTGRES_PRISMA_URL', + type: 'encrypted', + }, + POSTGRES_URL_NON_POOLING: { + key: 'POSTGRES_URL_NON_POOLING', + type: 'encrypted', + }, + POSTGRES_USER: { + key: 'POSTGRES_USER', + type: 'encrypted', + }, + POSTGRES_HOST: { + key: 'POSTGRES_HOST', + type: 'encrypted', + }, + POSTGRES_PASSWORD: { + key: 'POSTGRES_PASSWORD', + type: 'encrypted', + }, + POSTGRES_DATABASE: { + key: 'POSTGRES_DATABASE', + type: 'encrypted', + }, + SUPABASE_ANON_KEY: { + key: 'SUPABASE_ANON_KEY', + type: 'encrypted', + }, + SUPABASE_URL: { + key: 'SUPABASE_URL', + type: 'encrypted', + }, + SUPABASE_SERVICE_ROLE_KEY: { + key: 'SUPABASE_SERVICE_ROLE_KEY', + type: 'encrypted', + }, + NEXT_PUBLIC_SUPABASE_ANON_KEY: { + key: 'NEXT_PUBLIC_SUPABASE_ANON_KEY', + type: 'encrypted', + }, + NEXT_PUBLIC_SUPABASE_URL: { + key: 'NEXT_PUBLIC_SUPABASE_URL', + type: 'encrypted', + }, +} as const + +export const ENV_VAR_RAW_KEYS = Object.values(ENV_VAR_KEYS).map((x) => x.key) diff --git a/studio/components/interfaces/Integrations/ProjectLinker.tsx b/studio/components/interfaces/Integrations/ProjectLinker.tsx index 81e9ca7e6d2..8b8ac5f5758 100644 --- a/studio/components/interfaces/Integrations/ProjectLinker.tsx +++ b/studio/components/interfaces/Integrations/ProjectLinker.tsx @@ -1,8 +1,11 @@ -import { databaseIcon, vercelIcon } from 'components/to-be-cleaned/ListIcons' +import { ENV_VAR_RAW_KEYS } from 'components/interfaces/Integrations/Integrations-Vercel.constants' +import { Markdown } from 'components/interfaces/Markdown' +import { 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 { BASE_PATH } from 'lib/constants' import { useState } from 'react' -import { Button, IconArrowRight, IconPlus, IconX, Listbox, Select } from 'ui' +import { Button, IconArrowRight, IconPlus, IconX, Input, Listbox, Select, cn } from 'ui' interface Project { id: string @@ -30,68 +33,26 @@ const ProjectLinker = ({ onCreateConnections: _onCreateConnections, installedConnections, }: ProjectLinkerProps) => { - const [connections, setConnections] = useState( - installedConnections && installedConnections.length > 0 - ? installedConnections?.map((connection) => { - return { - foreign_project_id: connection?.foreign_project_id, - supabase_project_id: connection?.supabase_project_id, - integrationId: INTEGRATION_INTERNAL_ID, - metadata: UNDEFINED_METADATA_VALUE, - } - }) - : [ - { - foreign_project_id: UNDEFINED_SELECT_VALUE, - supabase_project_id: UNDEFINED_SELECT_VALUE, - integrationId: INTEGRATION_INTERNAL_ID, - metadata: UNDEFINED_METADATA_VALUE, - }, - ] - ) + const [supabaseProjectId, setSupabaseProjectId] = useState('') + const [vercelProjectId, setVercelProjectId] = useState('') - console.log('installedConnections', installedConnections) - console.log('connections', connections) - console.log('foreignProjects', foreignProjects) - console.log('supabaseProjects', supabaseProjects) + // function addConnection() { + // setConnections([ + // ...connections, + // { + // foreign_project_id: UNDEFINED_SELECT_VALUE, + // supabase_project_id: UNDEFINED_SELECT_VALUE, + // integrationId: INTEGRATION_INTERNAL_ID, + // metadata: UNDEFINED_METADATA_VALUE, + // }, + // ]) + // } - function onSetForeignProjectId(idx: number, id: string) { - const newConnections = [...connections] - const projectDetails = foreignProjects.filter((x) => x.id === id)[0] - newConnections[idx].metadata = { ...projectDetails } - newConnections[idx].foreign_project_id = id - newConnections[idx].supabaseConfig = { - projectEnvVars: { - write: true, - }, - } - - setConnections(newConnections) - } - - function onSetSupabaseProjectId(idx: number, id: string) { - const newConnections = [...connections] - newConnections[idx].supabase_project_id = id - setConnections(newConnections) - } - - function addConnection() { - setConnections([ - ...connections, - { - foreign_project_id: UNDEFINED_SELECT_VALUE, - supabase_project_id: UNDEFINED_SELECT_VALUE, - integrationId: INTEGRATION_INTERNAL_ID, - metadata: UNDEFINED_METADATA_VALUE, - }, - ]) - } - - function removeConnection(idx: number) { - const newConnections = [...connections] - newConnections.splice(idx, 1) - setConnections(newConnections) - } + // function removeConnection(idx: number) { + // const newConnections = [...connections] + // newConnections.splice(idx, 1) + // setConnections(newConnections) + // } const { mutate: createConnections, isLoading } = useIntegrationConnectionsCreateMutation({ onSuccess() { @@ -100,114 +61,99 @@ const ProjectLinker = ({ }) function onCreateConnections() { + const projectDetails = foreignProjects.filter((x) => x.id === vercelProjectId)[0] + createConnections({ organizationIntegrationId, - connections, + connections: [ + { + foreign_project_id: vercelProjectId, + supabase_project_id: supabaseProjectId, + integrationId: INTEGRATION_INTERNAL_ID, + metadata: { + ...projectDetails, + supabaseConfig: { + projectEnvVars: { + write: true, + }, + }, + }, + }, + ], }) } - console.log(connections) + const Panel = ({ children, className, ...props }: React.HTMLAttributes) => { + return ( +
    + {children} +
    + ) + } return (
    -
      - {connections.map((connection, i) => ( - onSetForeignProjectId(i, id)} - supabaseProjectId={connection.supabase_project_id} - setSupabaseProjectId={(id) => onSetSupabaseProjectId(i, id)} - removeConnection={() => removeConnection(i)} - canRemove={connections.length > 1} - /> - ))} -
    - - - -
    - - -
    - ) -} - -export default ProjectLinker - -interface ProjectLinkerItemProps { - foreignProjects: Project[] - supabaseProjects: Project[] - foreignProjectId: string - setForeignProjectId: (id: string) => void - supabaseProjectId: string - setSupabaseProjectId: (id: string) => void - removeConnection: () => void - canRemove: boolean - connections: any[] -} - -const ProjectLinkerItem = ({ - foreignProjects, - supabaseProjects, - foreignProjectId, - setForeignProjectId, - supabaseProjectId, - setSupabaseProjectId, - removeConnection, - canRemove, -}: ProjectLinkerItemProps) => { - console.log(supabaseProjectId) - return ( -
  • -
    -
    - -
    -
    - -
    -
    +
    + +
    + Supabase +
    setSupabaseProjectId(e)} > - Choose a project + Choose a Supabase project + + {supabaseProjects.map((project) => ( + { + return ( + <> +
    + Supabase +
    + + ) + }} + > + {project.name} +
    + ))} +
    +
    +
    + +
    + {/* integration icon */} + + + +
    + setVercelProjectId(e)} + > + + Choose a Vercel project - {foreignProjects.map((project) => ( ))} -
    - - {canRemove && ( -
    -
  • +
    + +
    +
    +

    + The following enviroment variables will be added: +

    +

    + {ENV_VAR_RAW_KEYS.map((x, idx) => { + return ( + + {x},{' '} + + ) + })} +

    +
    +
    ) } + +export default ProjectLinker diff --git a/studio/components/interfaces/Integrations/ProjectsLinker.tsx b/studio/components/interfaces/Integrations/ProjectsLinker.tsx new file mode 100644 index 00000000000..81e9ca7e6d2 --- /dev/null +++ b/studio/components/interfaces/Integrations/ProjectsLinker.tsx @@ -0,0 +1,245 @@ +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 { Button, IconArrowRight, IconPlus, IconX, Listbox, Select } from 'ui' + +interface Project { + id: string + name: string +} + +// to do: move this somewhere +const INTEGRATION_INTERNAL_ID = 1 + +export interface ProjectLinkerProps { + organizationIntegrationId: string + foreignProjects: VercelProjectsResponse[] + supabaseProjects: Project[] + onCreateConnections?: () => void + installedConnections?: any[] +} + +const UNDEFINED_SELECT_VALUE = 'undefined' +const UNDEFINED_METADATA_VALUE = {} + +const ProjectLinker = ({ + organizationIntegrationId, + foreignProjects, + supabaseProjects, + onCreateConnections: _onCreateConnections, + installedConnections, +}: ProjectLinkerProps) => { + const [connections, setConnections] = useState( + installedConnections && installedConnections.length > 0 + ? installedConnections?.map((connection) => { + return { + foreign_project_id: connection?.foreign_project_id, + supabase_project_id: connection?.supabase_project_id, + integrationId: INTEGRATION_INTERNAL_ID, + metadata: UNDEFINED_METADATA_VALUE, + } + }) + : [ + { + foreign_project_id: UNDEFINED_SELECT_VALUE, + supabase_project_id: 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) { + const newConnections = [...connections] + const projectDetails = foreignProjects.filter((x) => x.id === id)[0] + newConnections[idx].metadata = { ...projectDetails } + newConnections[idx].foreign_project_id = id + newConnections[idx].supabaseConfig = { + projectEnvVars: { + write: true, + }, + } + + setConnections(newConnections) + } + + function onSetSupabaseProjectId(idx: number, id: string) { + const newConnections = [...connections] + newConnections[idx].supabase_project_id = id + setConnections(newConnections) + } + + function addConnection() { + setConnections([ + ...connections, + { + foreign_project_id: UNDEFINED_SELECT_VALUE, + supabase_project_id: UNDEFINED_SELECT_VALUE, + integrationId: INTEGRATION_INTERNAL_ID, + metadata: UNDEFINED_METADATA_VALUE, + }, + ]) + } + + function removeConnection(idx: number) { + const newConnections = [...connections] + newConnections.splice(idx, 1) + setConnections(newConnections) + } + + const { mutate: createConnections, isLoading } = useIntegrationConnectionsCreateMutation({ + onSuccess() { + _onCreateConnections?.() + }, + }) + + function onCreateConnections() { + createConnections({ + organizationIntegrationId, + connections, + }) + } + + console.log(connections) + + return ( +
    +
      + {connections.map((connection, i) => ( + onSetForeignProjectId(i, id)} + supabaseProjectId={connection.supabase_project_id} + setSupabaseProjectId={(id) => onSetSupabaseProjectId(i, id)} + removeConnection={() => removeConnection(i)} + canRemove={connections.length > 1} + /> + ))} +
    + + + +
    + + +
    + ) +} + +export default ProjectLinker + +interface ProjectLinkerItemProps { + foreignProjects: Project[] + supabaseProjects: Project[] + foreignProjectId: string + setForeignProjectId: (id: string) => void + supabaseProjectId: string + setSupabaseProjectId: (id: string) => void + removeConnection: () => void + canRemove: boolean + connections: any[] +} + +const ProjectLinkerItem = ({ + foreignProjects, + supabaseProjects, + foreignProjectId, + setForeignProjectId, + supabaseProjectId, + setSupabaseProjectId, + removeConnection, + canRemove, +}: ProjectLinkerItemProps) => { + console.log(supabaseProjectId) + return ( +
  • +
    +
    + +
    +
    + +
    +
    + + + Choose a project + + + {foreignProjects.map((project) => ( + { + return ( + <> + {!project?.framework ? ( + vercelIcon + ) : ( + {`icon`} + )} + + ) + }} + > + {project.name} + + ))} + +
    + + {canRemove && ( +
    +
  • + ) +} diff --git a/studio/components/interfaces/Markdown.tsx b/studio/components/interfaces/Markdown.tsx index db85f97f4f3..1755f86c843 100644 --- a/studio/components/interfaces/Markdown.tsx +++ b/studio/components/interfaces/Markdown.tsx @@ -1,6 +1,6 @@ import { ReactMarkdownProps } from 'react-markdown/lib/complex-types' import { ReactMarkdown } from 'react-markdown/lib/react-markdown' -import { cn } from 'ui/src/utils/cn' +import { cn } from 'ui' interface Props extends Omit { className?: string diff --git a/studio/components/interfaces/Organization/IntegrationSettings/IntegrationSettings.tsx b/studio/components/interfaces/Organization/IntegrationSettings/IntegrationSettings.tsx index 240cce5449c..e535d1f0577 100644 --- a/studio/components/interfaces/Organization/IntegrationSettings/IntegrationSettings.tsx +++ b/studio/components/interfaces/Organization/IntegrationSettings/IntegrationSettings.tsx @@ -20,9 +20,11 @@ const IntegrationSettings = () => { vercelIntegrations?.map((x) => { let data: any = { ...x } - data['metadata']['account'][ - 'avatar' - ] = `https://vercel.com/api/www/avatar/${data.metadata.account.avatar}?w=48` + + const avatarSrc = data.metadata.account.avatar + ? `https://vercel.com/api/www/avatar/${data.metadata.account.avatar}?s=48` + : `https://vercel.com/api/www/avatar?teamId=${data.metadata.account.team_id}&s=48` + data['metadata']['account']['avatar'] = avatarSrc return data }) diff --git a/studio/components/interfaces/Organization/IntegrationSettings/SidePanelVercelProjectLinker.tsx b/studio/components/interfaces/Organization/IntegrationSettings/SidePanelVercelProjectLinker.tsx index f5c459773b5..be862353f74 100644 --- a/studio/components/interfaces/Organization/IntegrationSettings/SidePanelVercelProjectLinker.tsx +++ b/studio/components/interfaces/Organization/IntegrationSettings/SidePanelVercelProjectLinker.tsx @@ -1,5 +1,5 @@ import { useParams } from 'common' -import ProjectLinker from 'components/interfaces/Integrations/ProjectLinker' +import ProjectLinker from 'components/interfaces/Integrations/ProjectsLinker' import { Markdown } from 'components/interfaces/Markdown' import { useIntegrationsQuery } from 'data/integrations/integrations-query' import { useStore } from 'hooks' diff --git a/studio/components/layouts/IntegrationWindowLayout.tsx b/studio/components/layouts/IntegrationWindowLayout.tsx new file mode 100644 index 00000000000..98adc94be52 --- /dev/null +++ b/studio/components/layouts/IntegrationWindowLayout.tsx @@ -0,0 +1,72 @@ +import { FC } from 'react' +import Link from 'next/link' +import { IconChevronRight, IconX, cn } from 'ui' +import { withAuth, useFlag } from 'hooks' +import { observer } from 'mobx-react-lite' +import { BASE_PATH } from 'lib/constants' +import React from 'react' +import { ScaffoldContainer } from './Scaffold' + +const IntegrationWindowLayout: FC = ({ organization, project, children }) => { + const ongoingIncident = useFlag('ongoingIncident') + const maxHeight = ongoingIncident ? 'calc(100vh - 44px)' : '100vh' + + return ( +
    +
    + {children} +
    + ) +} + +const INTEGRATION_LAYOUT_MAX_WIDTH = '' // 'max-w-[720px]' + +export default withAuth(observer(IntegrationWindowLayout)) + +export const IntegrationWindowLayoutWithoutAuth = observer(IntegrationWindowLayout) + +const Header: FC = ({ organization, project }) => { + let stepNumber = organization ? 1 : project ? 2 : 0 + return ( +
    + +
    +
    +
    + Supabase +
    + +
    + {/* integration icon */} + + + +
    +
    + + Supabase + Vercel Integration Marketplace Connector + +
    +
    +
    + ) +} + +const maxWidthClasses = 'mx-auto w-full max-w-[1600px]' +const paddingClasses = 'px-6 lg:px-14 xl:px-28 2xl:px-32' + +const IntegrationScaffoldContainer = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => { + return
    +}) + +IntegrationScaffoldContainer.displayName = 'IntegrationScaffoldContainer' + +export { IntegrationScaffoldContainer } diff --git a/studio/components/layouts/Scaffold.tsx b/studio/components/layouts/Scaffold.tsx index b3adc0714f7..c0367141f76 100644 --- a/studio/components/layouts/Scaffold.tsx +++ b/studio/components/layouts/Scaffold.tsx @@ -1,5 +1,5 @@ import React from 'react' -import { cn } from 'ui/src/utils/cn' +import { cn } from 'ui' const maxWidthClasses = 'mx-auto w-full max-w-[1600px]' const paddingClasses = 'px-6 lg:px-14 xl:px-28 2xl:px-32' diff --git a/studio/pages/integrations/vercel.tsx b/studio/pages/integrations/vercel.tsx index 049ad06a48e..2133b293df6 100644 --- a/studio/pages/integrations/vercel.tsx +++ b/studio/pages/integrations/vercel.tsx @@ -2,7 +2,7 @@ import { useMemo, useState } from 'react' import { useParams } from 'common' import ProjectLinker from 'components/interfaces/Integrations/ProjectLinker' -import { WizardLayout } from 'components/layouts' + import OrganizationPicker from 'components/ui/OrganizationPicker' import { useVercelIntegrationCreateMutation } from 'data/integrations/vercel-integration-create-mutation' import { useVercelProjectsQuery } from 'data/integrations/integrations-vercel-projects-query' @@ -10,7 +10,12 @@ import { useProjectsQuery } from 'data/projects/projects-query' import { useStore } from 'hooks' import { EMPTY_ARR } from 'lib/void' import { NextPageWithLayout, Organization } from 'types' -import { Button } from 'ui' +import { Alert, Button, IconBook, IconLifeBuoy, Input, LoadingLine, cn } from 'ui' +import IntegrationWindowLayout from 'components/layouts/IntegrationWindowLayout' +import { ScaffoldContainer, ScaffoldDivider, ScaffoldSection } from 'components/layouts/Scaffold' +import { Markdown } from 'components/interfaces/Markdown' +import { BASE_PATH } from 'lib/constants' +import { ENV_VAR_RAW_KEYS } from 'components/interfaces/Integrations/Integrations-Vercel.constants' const VercelIntegration: NextPageWithLayout = () => { const { ui } = useStore() @@ -81,35 +86,95 @@ const VercelIntegration: NextPageWithLayout = () => { const vercelProjects = useMemo(() => vercelProjectsData ?? EMPTY_ARR, [vercelProjectsData]) return ( -
    -

    Vercel Integration

    + <> +
    + + {organizationIntegrationId === null && ( + <> + +

    Install Integration

    + <> + + +
    + +
    + +
    + + + + + + + )} - {organizationIntegrationId === null ? ( - <> - + {organizationIntegrationId !== null && ( + <> + +
    +

    + Link a Supabase project to a Vercel project +

    + +
    + {/* { + if (next) { + window.location.href = next + } + }} + /> */} - - - ) : ( - <> - { - if (next) { - window.location.href = next - } - }} - /> - - )} -
    + { + if (next) { + window.location.href = next + } + }} + /> + + + )} + + + +
    + Docs +
    +
    + Support +
    +
    + ) } -VercelIntegration.getLayout = (page) => {page} +VercelIntegration.getLayout = (page) => {page} export default VercelIntegration From b5561cc413cbcb1dbd097c8dcf3b199355e0e8af Mon Sep 17 00:00:00 2001 From: Jonathan Summers-Muir Date: Tue, 20 Jun 2023 20:54:39 +0800 Subject: [PATCH 16/59] update picker UI --- package-lock.json | 1 + packages/config/package.json | 3 +- packages/config/ui.config.js | 35 ++-- .../interfaces/Integrations/ProjectLinker.tsx | 193 ++++++++++-------- .../IntegrationSettings/Integration.tsx | 14 +- .../layouts/IntegrationWindowLayout.tsx | 2 +- ...el-installed-connection-delete-mutation.ts | 13 +- studio/data/integrations/keys.ts | 6 +- 8 files changed, 156 insertions(+), 111 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4fdc32b163d..2c815be09f9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -42860,6 +42860,7 @@ "eslint-config-next": "^13.3.0", "eslint-config-prettier": "^8.3.0", "eslint-plugin-react": "7.28.0", + "mini-svg-data-uri": "^1.4.3", "tailwindcss-radix": "^2.0.0" } }, diff --git a/packages/config/package.json b/packages/config/package.json index 45901f19411..b9fb4a06dab 100644 --- a/packages/config/package.json +++ b/packages/config/package.json @@ -15,6 +15,7 @@ "eslint-config-prettier": "^8.3.0", "eslint-plugin-react": "7.28.0", "tailwindcss-radix": "^2.0.0", - "@tailwindcss/typography": "^0.5.9" + "@tailwindcss/typography": "^0.5.9", + "mini-svg-data-uri": "^1.4.3" } } diff --git a/packages/config/ui.config.js b/packages/config/ui.config.js index 96cf6ae71a7..856f8ff436a 100644 --- a/packages/config/ui.config.js +++ b/packages/config/ui.config.js @@ -3,6 +3,7 @@ const forms = require('@tailwindcss/forms') const plugin = require('tailwindcss/plugin') const radixUiColors = require('@radix-ui/colors') const brandColors = require('./default-colors') +const svgToDataUri = require('mini-svg-data-uri') const { default: flattenColorPalette } = require('tailwindcss/lib/util/flattenColorPalette') @@ -371,18 +372,28 @@ const uiConfig = { highlight: (value) => ({ boxShadow: `inset 0 1px 0 0 ${value}` }), }, { values: flattenColorPalette(theme('backgroundColor')), type: 'color' } - ), - matchUtilities( - { - subhighlight: (value) => ({ - boxShadow: `inset 0 -1px 0 0 ${value}`, - }), - }, - { - values: flattenColorPalette(theme('backgroundColor')), - type: 'color', - } - ) + ) + matchUtilities( + { + subhighlight: (value) => ({ + boxShadow: `inset 0 -1px 0 0 ${value}`, + }), + }, + { + values: flattenColorPalette(theme('backgroundColor')), + type: 'color', + } + ) + matchUtilities( + { + 'bg-grid': (value) => ({ + backgroundImage: `url("${svgToDataUri( + `` + )}")`, + }), + }, + { values: flattenColorPalette(theme('backgroundColor')), type: 'color' } + ) }, require('tailwindcss-radix')(), forms, diff --git a/studio/components/interfaces/Integrations/ProjectLinker.tsx b/studio/components/interfaces/Integrations/ProjectLinker.tsx index 8b8ac5f5758..8f183b8b7c8 100644 --- a/studio/components/interfaces/Integrations/ProjectLinker.tsx +++ b/studio/components/interfaces/Integrations/ProjectLinker.tsx @@ -86,7 +86,10 @@ const ProjectLinker = ({ const Panel = ({ children, className, ...props }: React.HTMLAttributes) => { return (
    {children} @@ -96,91 +99,97 @@ const ProjectLinker = ({ return (
    -
    - -
    - Supabase -
    - setSupabaseProjectId(e)} - > - - Choose a Supabase project - - {supabaseProjects.map((project) => ( - { - return ( - <> -
    - Supabase -
    - - ) - }} - > - {project.name} -
    - ))} -
    -
    -
    - -
    - {/* integration icon */} - +
    +
    + +
    + Supabase +
    + setSupabaseProjectId(e)} > - - -
    - setVercelProjectId(e)} - > - - Choose a Vercel project - - {foreignProjects.map((project) => ( - { - return ( - <> - {!project?.framework ? ( - vercelIcon - ) : ( - {`icon`} - )} - - ) - }} - > - {project.name} + + Choose a Supabase project - ))} - - + {supabaseProjects.map((project) => ( + { + return ( + <> +
    + Supabase +
    + + ) + }} + > + {project.name} +
    + ))} + + +
    + +
    + {/* integration icon */} + + + +
    + setVercelProjectId(e)} + > + + Choose a Vercel project + + {foreignProjects.map((project) => ( + { + return ( + <> + {!project?.framework ? ( + vercelIcon + ) : ( + {`icon`} + )} + + ) + }} + > + {project.name} + + ))} + +
    +
    -
    + {/*

    The following enviroment variables will be added:

    @@ -206,7 +215,19 @@ const ProjectLinker = ({ ) })}

    -
    +
    */} + { + return ` + \n + - \`${x}\` - ${(This is the URL for the Project)} +` +})} +`} + />
    ) } diff --git a/studio/components/interfaces/Organization/IntegrationSettings/Integration.tsx b/studio/components/interfaces/Organization/IntegrationSettings/Integration.tsx index ecbd6751ea2..cf4a11985df 100644 --- a/studio/components/interfaces/Organization/IntegrationSettings/Integration.tsx +++ b/studio/components/interfaces/Organization/IntegrationSettings/Integration.tsx @@ -18,6 +18,7 @@ import { useIntegrationsQuery, } from 'data/integrations/integrations-query' import { useIntegrationsVercelInstalledConnectionDeleteMutation } from 'data/integrations/integrations-vercel-installed-connection-delete-mutation' +import { useStore } from 'hooks' import { pluralize } from 'lib/helpers' import { EMPTY_ARR } from 'lib/void' import { useMemo } from 'react' @@ -42,11 +43,11 @@ const Integration = ({ integrations = EMPTY_ARR, }: IntegrationProps) => { const githubConnectionConfigPanelShotshot = useGithubConnectionConfigPanelSnapshot() - const deleteMutation = useIntegrationsVercelInstalledConnectionDeleteMutation({ - onSuccess: (data, variables, context) => { - // Handle the success case - }, - }) + + const { ui } = useStore() + + const { mutate: deleteMutate, isLoading: isDeleteLoading } = + useIntegrationsVercelInstalledConnectionDeleteMutation() const ConnectionHeading = ({ integration }: { integration: TIntegration }) => { return ( @@ -66,9 +67,10 @@ Repository connections for ${title?.toLowerCase()} const variables = { organization_integration_id: organizationIntegrationId, id: projectIntegrationId, + orgId: ui.selectedOrganization?.id, } - deleteMutation.mutate(variables) + deleteMutate(variables) } return ( diff --git a/studio/components/layouts/IntegrationWindowLayout.tsx b/studio/components/layouts/IntegrationWindowLayout.tsx index 98adc94be52..9b4fb43bf86 100644 --- a/studio/components/layouts/IntegrationWindowLayout.tsx +++ b/studio/components/layouts/IntegrationWindowLayout.tsx @@ -29,7 +29,7 @@ const Header: FC = ({ organization, project }) => { let stepNumber = organization ? 1 : project ? 2 : 0 return (
    - +
    diff --git a/studio/data/integrations/integrations-vercel-installed-connection-delete-mutation.ts b/studio/data/integrations/integrations-vercel-installed-connection-delete-mutation.ts index 5c9825553b4..fa6d74522a8 100644 --- a/studio/data/integrations/integrations-vercel-installed-connection-delete-mutation.ts +++ b/studio/data/integrations/integrations-vercel-installed-connection-delete-mutation.ts @@ -1,9 +1,14 @@ -import { useMutation, UseMutationOptions } from '@tanstack/react-query' +import { useMutation, UseMutationOptions, useQueryClient } from '@tanstack/react-query' import { delete_ } from 'lib/common/fetch' import { API_URL } from 'lib/constants' import { UserContent } from 'types' +import { integrationKeys } from './keys' -type DeleteVariables = { organization_integration_id: string; id: string } +type DeleteVariables = { + organization_integration_id: string + id: string + orgId: number | undefined +} export async function deleteConnection( { organization_integration_id, id }: DeleteVariables, @@ -29,10 +34,14 @@ export const useIntegrationsVercelInstalledConnectionDeleteMutation = ({ onSuccess, ...options }: Omit, 'mutationFn'> = {}) => { + const queryClient = useQueryClient() return useMutation( (args) => deleteConnection(args), { async onSuccess(data, variables, context) { + console.log('variables in mutate delete onSuccess', variables) + await Promise.all([queryClient.invalidateQueries(integrationKeys.list(variables.orgId))]) + await onSuccess?.(data, variables, context) }, ...options, diff --git a/studio/data/integrations/keys.ts b/studio/data/integrations/keys.ts index be833c0d307..b25c9329d41 100644 --- a/studio/data/integrations/keys.ts +++ b/studio/data/integrations/keys.ts @@ -1,7 +1,7 @@ export const integrationKeys = { - list: (orgSlug: string | undefined) => ['organizations', orgSlug, 'integrations'] as const, - vercelProjectList: (orgSlug: string | undefined) => - ['organizations', orgSlug, 'vercel-projects'] as const, + list: (orgId: number | undefined) => ['organizations', orgId, 'integrations'] as const, + vercelProjectList: (organization_integration_id: string | undefined) => + ['organizations', organization_integration_id, 'vercel-projects'] as const, vercelConnectionsList: (organization_integration_id: string | undefined) => ['organizations', organization_integration_id, 'vercel-connections'] as const, } From 331195333bed8d5747033c963deb12ea5960e33f Mon Sep 17 00:00:00 2001 From: "joel@joellee.org" Date: Wed, 21 Jun 2023 11:47:25 +0800 Subject: [PATCH 17/59] feat: update studio config to include twilio verify --- .../components/interfaces/Auth/Auth.types.ts | 3 + studio/pages/api/auth/[ref]/config.ts | 249 +++++++++--------- .../AuthProvidersFormValidation.tsx | 50 ++++ .../stores/jsonSchema/auth_gotrue_config.json | 13 + 4 files changed, 192 insertions(+), 123 deletions(-) diff --git a/studio/components/interfaces/Auth/Auth.types.ts b/studio/components/interfaces/Auth/Auth.types.ts index 3c4118ec83b..55b756c31bd 100644 --- a/studio/components/interfaces/Auth/Auth.types.ts +++ b/studio/components/interfaces/Auth/Auth.types.ts @@ -137,6 +137,9 @@ export interface AuthConfig { SMS_TWILIO_ACCOUNT_SID: string SMS_TWILIO_AUTH_TOKEN: string SMS_TWILIO_MESSAGE_SERVICE_SID: string + SMS_TWILIO_VERIFY_ACCOUNT_SID: string + SMS_TWILIO_VERIFY_AUTH_TOKEN: string + SMS_TWILIO_VERIFY_MESSAGE_SERVICE_SID: string SMS_VONAGE_API_KEY: string SMS_VONAGE_API_SECRET: string SMS_VONAGE_FROM: string diff --git a/studio/pages/api/auth/[ref]/config.ts b/studio/pages/api/auth/[ref]/config.ts index 66545dba0ae..96d3f1a6f6e 100644 --- a/studio/pages/api/auth/[ref]/config.ts +++ b/studio/pages/api/auth/[ref]/config.ts @@ -20,135 +20,138 @@ async function handler(req: NextApiRequest, res: NextApiResponse) { const handleGetAll = async (req: NextApiRequest, res: NextApiResponse) => { // Platform only API return res.status(200).json({ - app_version: '', - config_override_id: '', - project_id: '', - jwt_secret_encrypted: '', - isFreeTier: true, - SITE_URL: '', - OPERATOR_TOKEN: null, - DISABLE_SIGNUP: false, - RATE_LIMIT_HEADER: null, - JWT_EXP: 3600, - JWT_AUD: '', - JWT_DEFAULT_GROUP_NAME: '', - URI_ALLOW_LIST: '', - MAILER_AUTOCONFIRM: false, - MAILER_OTP_EXP: 86400, - MAILER_URLPATHS_INVITE: '', - MAILER_URLPATHS_CONFIRMATION: '', - MAILER_URLPATHS_RECOVERY: '', - MAILER_URLPATHS_EMAIL_CHANGE: '', - SECURITY_UPDATE_PASSWORD_REQUIRE_REAUTHENTICATION: false, - SMTP_ADMIN_EMAIL: '', - SMTP_HOST: null, - SMTP_PORT: null, - SMTP_USER: null, - SMTP_PASS: null, - SMTP_MAX_FREQUENCY: 0, - EXTERNAL_EMAIL_ENABLED: true, - EXTERNAL_PHONE_ENABLED: true, - EXTERNAL_APPLE_ENABLED: false, - EXTERNAL_APPLE_CLIENT_ID: null, - EXTERNAL_APPLE_SECRET: null, - EXTERNAL_AZURE_ENABLED: false, - EXTERNAL_AZURE_CLIENT_ID: null, - EXTERNAL_AZURE_SECRET: null, - EXTERNAL_AZURE_URL: null, - EXTERNAL_BITBUCKET_ENABLED: false, - EXTERNAL_BITBUCKET_CLIENT_ID: null, - EXTERNAL_BITBUCKET_SECRET: null, - EXTERNAL_DISCORD_ENABLED: false, - EXTERNAL_DISCORD_CLIENT_ID: null, - EXTERNAL_DISCORD_SECRET: null, - EXTERNAL_FACEBOOK_ENABLED: false, - EXTERNAL_FACEBOOK_CLIENT_ID: null, - EXTERNAL_FACEBOOK_SECRET: null, - EXTERNAL_GITHUB_ENABLED: false, - EXTERNAL_GITHUB_CLIENT_ID: null, - EXTERNAL_GITHUB_SECRET: null, - EXTERNAL_GITLAB_ENABLED: false, - EXTERNAL_GITLAB_CLIENT_ID: null, - EXTERNAL_GITLAB_SECRET: null, - EXTERNAL_GITLAB_REDIRECT_URI: null, - EXTERNAL_GOOGLE_ENABLED: false, - EXTERNAL_GOOGLE_CLIENT_ID: null, - EXTERNAL_GOOGLE_SECRET: null, - EXTERNAL_KEYCLOAK_ENABLED: false, - EXTERNAL_KEYCLOAK_CLIENT_ID: null, - EXTERNAL_KEYCLOAK_SECRET: null, - EXTERNAL_KEYCLOAK_URL: null, - EXTERNAL_LINKEDIN_ENABLED: false, - EXTERNAL_LINKEDIN_CLIENT_ID: null, - EXTERNAL_LINKEDIN_SECRET: null, - EXTERNAL_NOTION_ENABLED: false, - EXTERNAL_NOTION_CLIENT_ID: null, - EXTERNAL_NOTION_SECRET: null, - EXTERNAL_SPOTIFY_ENABLED: false, - EXTERNAL_SPOTIFY_CLIENT_ID: null, - EXTERNAL_SPOTIFY_SECRET: null, - EXTERNAL_SLACK_ENABLED: false, - EXTERNAL_SLACK_CLIENT_ID: null, - EXTERNAL_SLACK_SECRET: null, - EXTERNAL_TWITTER_ENABLED: false, - EXTERNAL_TWITTER_CLIENT_ID: null, - EXTERNAL_TWITTER_SECRET: null, - EXTERNAL_TWITCH_ENABLED: false, - EXTERNAL_TWITCH_CLIENT_ID: null, - EXTERNAL_TWITCH_SECRET: null, - EXTERNAL_WORKOS_ENABLED: false, - EXTERNAL_WORKOS_CLIENT_ID: null, - EXTERNAL_WORKOS_SECRET: null, - EXTERNAL_WORKOS_URL: null, - EXTERNAL_ZOOM_ENABLED: false, - EXTERNAL_ZOOM_CLIENT_ID: null, - EXTERNAL_ZOOM_SECRET: null, + app_version: '', + config_override_id: '', + project_id: '', + jwt_secret_encrypted: '', + isFreeTier: true, + SITE_URL: '', + OPERATOR_TOKEN: null, + DISABLE_SIGNUP: false, + RATE_LIMIT_HEADER: null, + JWT_EXP: 3600, + JWT_AUD: '', + JWT_DEFAULT_GROUP_NAME: '', + URI_ALLOW_LIST: '', + MAILER_AUTOCONFIRM: false, + MAILER_OTP_EXP: 86400, + MAILER_URLPATHS_INVITE: '', + MAILER_URLPATHS_CONFIRMATION: '', + MAILER_URLPATHS_RECOVERY: '', + MAILER_URLPATHS_EMAIL_CHANGE: '', + SECURITY_UPDATE_PASSWORD_REQUIRE_REAUTHENTICATION: false, + SMTP_ADMIN_EMAIL: '', + SMTP_HOST: null, + SMTP_PORT: null, + SMTP_USER: null, + SMTP_PASS: null, + SMTP_MAX_FREQUENCY: 0, + EXTERNAL_EMAIL_ENABLED: true, + EXTERNAL_PHONE_ENABLED: true, + EXTERNAL_APPLE_ENABLED: false, + EXTERNAL_APPLE_CLIENT_ID: null, + EXTERNAL_APPLE_SECRET: null, + EXTERNAL_AZURE_ENABLED: false, + EXTERNAL_AZURE_CLIENT_ID: null, + EXTERNAL_AZURE_SECRET: null, + EXTERNAL_AZURE_URL: null, + EXTERNAL_BITBUCKET_ENABLED: false, + EXTERNAL_BITBUCKET_CLIENT_ID: null, + EXTERNAL_BITBUCKET_SECRET: null, + EXTERNAL_DISCORD_ENABLED: false, + EXTERNAL_DISCORD_CLIENT_ID: null, + EXTERNAL_DISCORD_SECRET: null, + EXTERNAL_FACEBOOK_ENABLED: false, + EXTERNAL_FACEBOOK_CLIENT_ID: null, + EXTERNAL_FACEBOOK_SECRET: null, + EXTERNAL_GITHUB_ENABLED: false, + EXTERNAL_GITHUB_CLIENT_ID: null, + EXTERNAL_GITHUB_SECRET: null, + EXTERNAL_GITLAB_ENABLED: false, + EXTERNAL_GITLAB_CLIENT_ID: null, + EXTERNAL_GITLAB_SECRET: null, + EXTERNAL_GITLAB_REDIRECT_URI: null, + EXTERNAL_GOOGLE_ENABLED: false, + EXTERNAL_GOOGLE_CLIENT_ID: null, + EXTERNAL_GOOGLE_SECRET: null, + EXTERNAL_KEYCLOAK_ENABLED: false, + EXTERNAL_KEYCLOAK_CLIENT_ID: null, + EXTERNAL_KEYCLOAK_SECRET: null, + EXTERNAL_KEYCLOAK_URL: null, + EXTERNAL_LINKEDIN_ENABLED: false, + EXTERNAL_LINKEDIN_CLIENT_ID: null, + EXTERNAL_LINKEDIN_SECRET: null, + EXTERNAL_NOTION_ENABLED: false, + EXTERNAL_NOTION_CLIENT_ID: null, + EXTERNAL_NOTION_SECRET: null, + EXTERNAL_SPOTIFY_ENABLED: false, + EXTERNAL_SPOTIFY_CLIENT_ID: null, + EXTERNAL_SPOTIFY_SECRET: null, + EXTERNAL_SLACK_ENABLED: false, + EXTERNAL_SLACK_CLIENT_ID: null, + EXTERNAL_SLACK_SECRET: null, + EXTERNAL_TWITTER_ENABLED: false, + EXTERNAL_TWITTER_CLIENT_ID: null, + EXTERNAL_TWITTER_SECRET: null, + EXTERNAL_TWITCH_ENABLED: false, + EXTERNAL_TWITCH_CLIENT_ID: null, + EXTERNAL_TWITCH_SECRET: null, + EXTERNAL_WORKOS_ENABLED: false, + EXTERNAL_WORKOS_CLIENT_ID: null, + EXTERNAL_WORKOS_SECRET: null, + EXTERNAL_WORKOS_URL: null, + EXTERNAL_ZOOM_ENABLED: false, + EXTERNAL_ZOOM_CLIENT_ID: null, + EXTERNAL_ZOOM_SECRET: null, - MAILER_SUBJECTS_INVITE: 'You have been invited', - MAILER_SUBJECTS_CONFIRMATION: 'Confirm Your Signup', - MAILER_SUBJECTS_RECOVERY: 'Reset Your Password', - MAILER_SUBJECTS_EMAIL_CHANGE: 'Confirm Email Change', - MAILER_SUBJECTS_MAGIC_LINK: 'Your Magic Link', - MAILER_TEMPLATES_INVITE: null, - MAILER_TEMPLATES_INVITE_CONTENT: + MAILER_SUBJECTS_INVITE: 'You have been invited', + MAILER_SUBJECTS_CONFIRMATION: 'Confirm Your Signup', + MAILER_SUBJECTS_RECOVERY: 'Reset Your Password', + MAILER_SUBJECTS_EMAIL_CHANGE: 'Confirm Email Change', + MAILER_SUBJECTS_MAGIC_LINK: 'Your Magic Link', + MAILER_TEMPLATES_INVITE: null, + MAILER_TEMPLATES_INVITE_CONTENT: '

    You have been invited

    \n\n

    You have been invited to create a user on {{ .SiteURL }}. Follow this link to accept the invite:

    \n

    Accept the invite

    ', - MAILER_TEMPLATES_CONFIRMATION: null, - MAILER_TEMPLATES_CONFIRMATION_CONTENT: + MAILER_TEMPLATES_CONFIRMATION: null, + MAILER_TEMPLATES_CONFIRMATION_CONTENT: '

    Confirm your email

    \n\n

    Follow this link to confirm your email:

    \n\n

    Confirm your email address

    ', - MAILER_TEMPLATES_RECOVERY: null, - MAILER_TEMPLATES_RECOVERY_CONTENT: + MAILER_TEMPLATES_RECOVERY: null, + MAILER_TEMPLATES_RECOVERY_CONTENT: '

    Reset Password

    \n\n

    Follow this link to reset the password for your user:

    \n

    Reset Password

    ', - MAILER_TEMPLATES_EMAIL_CHANGE: null, - MAILER_TEMPLATES_EMAIL_CHANGE_CONTENT: + MAILER_TEMPLATES_EMAIL_CHANGE: null, + MAILER_TEMPLATES_EMAIL_CHANGE_CONTENT: '

    Confirm Change of Email

    \n\n

    Follow this link to confirm the update of your email from {{ .Email }} to {{ .NewEmail }}:

    \n

    Change Email

    ', - MAILER_TEMPLATES_MAGIC_LINK: null, - MAILER_TEMPLATES_MAGIC_LINK_CONTENT: + MAILER_TEMPLATES_MAGIC_LINK: null, + MAILER_TEMPLATES_MAGIC_LINK_CONTENT: '

    Magic Link

    \n\n

    Follow this link to login:

    \n

    Log In

    ', - PASSWORD_MIN_LENGTH: 6, - SMTP_SENDER_NAME: null, - SMS_AUTOCONFIRM: false, - SMS_MAX_FREQUENCY: 0, - SMS_OTP_EXP: 60, - SMS_OTP_LENGTH: 6, - SMS_PROVIDER: 'twilio', - SMS_TWILIO_ACCOUNT_SID: null, - SMS_TWILIO_AUTH_TOKEN: null, - SMS_TWILIO_MESSAGE_SERVICE_SID: null, - SMS_TEMPLATE: 'Your code is {{ .Code }}', - SECURITY_CAPTCHA_ENABLED: false, - SECURITY_CAPTCHA_PROVIDER: 'hcaptcha', - SECURITY_CAPTCHA_SECRET: null, - SECURITY_REFRESH_TOKEN_REUSE_INTERVAL: '10', - RATE_LIMIT_EMAIL_SENT: 0, - RATE_LIMIT_SMS_SENT: 0, - MAILER_SECURE_EMAIL_CHANGE_ENABLED: true, - SMS_MESSAGEBIRD_ACCESS_KEY: null, - SMS_MESSAGEBIRD_ORIGINATOR: null, - SMS_VONAGE_API_KEY: null, - SMS_VONAGE_API_SECRET: null, - SMS_VONAGE_FROM: null, - SMS_TEXTLOCAL_API_KEY: null, - SMS_TEXTLOCAL_SENDER: null, + PASSWORD_MIN_LENGTH: 6, + SMTP_SENDER_NAME: null, + SMS_AUTOCONFIRM: false, + SMS_MAX_FREQUENCY: 0, + SMS_OTP_EXP: 60, + SMS_OTP_LENGTH: 6, + SMS_PROVIDER: 'twilio', + SMS_TWILIO_ACCOUNT_SID: null, + SMS_TWILIO_AUTH_TOKEN: null, + SMS_TWILIO_MESSAGE_SERVICE_SID: null, + SMS_TWILIO_VERIFY_ACCOUNT_SID: null, + SMS_TWILIO_VERIFY_AUTH_TOKEN: null, + SMS_TWILIO_VERIFY_MESSAGE_SERVICE_SID: null, + SMS_TEMPLATE: 'Your code is {{ .Code }}', + SECURITY_CAPTCHA_ENABLED: false, + SECURITY_CAPTCHA_PROVIDER: 'hcaptcha', + SECURITY_CAPTCHA_SECRET: null, + SECURITY_REFRESH_TOKEN_REUSE_INTERVAL: '10', + RATE_LIMIT_EMAIL_SENT: 0, + RATE_LIMIT_SMS_SENT: 0, + MAILER_SECURE_EMAIL_CHANGE_ENABLED: true, + SMS_MESSAGEBIRD_ACCESS_KEY: null, + SMS_MESSAGEBIRD_ORIGINATOR: null, + SMS_VONAGE_API_KEY: null, + SMS_VONAGE_API_SECRET: null, + SMS_VONAGE_FROM: null, + SMS_TEXTLOCAL_API_KEY: null, + SMS_TEXTLOCAL_SENDER: null, }) } diff --git a/studio/stores/authConfig/schema/AuthProviders/AuthProvidersFormValidation.tsx b/studio/stores/authConfig/schema/AuthProviders/AuthProvidersFormValidation.tsx index 750ff44fa62..4e6b7541d01 100644 --- a/studio/stores/authConfig/schema/AuthProviders/AuthProvidersFormValidation.tsx +++ b/studio/stores/authConfig/schema/AuthProviders/AuthProvidersFormValidation.tsx @@ -112,6 +112,33 @@ const PROVIDER_PHONE = { }, }, + // Twilio Verify + SMS_TWILIO_VERIFY_ACCOUNT_SID: { + type: 'string', + title: 'Twilio Account Sid', + show: { + key: 'SMS_PROVIDER', + matches: 'twilio', + }, + }, + SMS_TWILIO_VERIFY_AUTH_TOKEN: { + type: 'string', + title: 'Twilio Auth Token', + isSecret: true, + show: { + key: 'SMS_PROVIDER', + matches: 'twilio', + }, + }, + SMS_TWILIO_VERIFY_MESSAGE_SERVICE_SID: { + type: 'string', + title: 'Twilio Message Service Sid', + show: { + key: 'SMS_PROVIDER', + matches: 'twilio', + }, + }, + // Messagebird SMS_MESSAGEBIRD_ACCESS_KEY: { type: 'string', @@ -227,6 +254,29 @@ const PROVIDER_PHONE = { otherwise: (schema) => schema, }), + // Twilio Verify + SMS_TWILIO_VERIFY_ACCOUNT_SID: string().when(['EXTERNAL_PHONE_ENABLED', 'SMS_PROVIDER'], { + is: (EXTERNAL_PHONE_ENABLED: boolean, SMS_PROVIDER: string) => { + return EXTERNAL_PHONE_ENABLED && SMS_PROVIDER === 'twilio_verify' + }, + then: (schema) => schema.required('Twilio Verify Account SID is required'), + otherwise: (schema) => schema, + }), + SMS_TWILIO_VERIFY_AUTH_TOKEN: string().when(['EXTERNAL_PHONE_ENABLED', 'SMS_PROVIDER'], { + is: (EXTERNAL_PHONE_ENABLED: boolean, SMS_PROVIDER: string) => { + return EXTERNAL_PHONE_ENABLED && SMS_PROVIDER === 'twilio_verify' + }, + then: (schema) => schema.required('Twilio Verify Auth Token is required'), + otherwise: (schema) => schema, + }), + SMS_TWILIO_VERIFY_MESSAGE_SERVICE_SID: string().when(['EXTERNAL_PHONE_ENABLED', 'SMS_PROVIDER'], { + is: (EXTERNAL_PHONE_ENABLED: boolean, SMS_PROVIDER: string) => { + return EXTERNAL_PHONE_ENABLED && SMS_PROVIDER === 'twilio_verify' + }, + then: (schema) => schema.required('Twilio Verify Service SID is required'), + otherwise: (schema) => schema, + }), + // Messagebird SMS_MESSAGEBIRD_ACCESS_KEY: string().when(['EXTERNAL_PHONE_ENABLED', 'SMS_PROVIDER'], { is: (EXTERNAL_PHONE_ENABLED: boolean, SMS_PROVIDER: string) => { diff --git a/studio/stores/jsonSchema/auth_gotrue_config.json b/studio/stores/jsonSchema/auth_gotrue_config.json index a0d00a3deb2..cfd63164f12 100644 --- a/studio/stores/jsonSchema/auth_gotrue_config.json +++ b/studio/stores/jsonSchema/auth_gotrue_config.json @@ -526,6 +526,19 @@ "type": "string", "help": "Twilio message service SID or twilio phone number" }, + "SMS_TWILIO_VERIFY_ACCOUNT_SID": { + "title": "Twilio account SID", + "type": "string" + }, + "SMS_TWILIO_VERIFY_AUTH_TOKEN": { + "title": "Twilio Verify auth token", + "type": "string" + }, + "SMS_TWILIO_VERIFY_MESSAGE_SERVICE_SID": { + "title": "Twilio Verify service SID", + "type": "string", + "help": "Twilio Verify service SID" + }, "SMS_MESSAGEBIRD_ACCESS_KEY": { "title": "Messagebird access key", "type": "string" From beb159ebb01066048a9757f99205f75572ccc4c4 Mon Sep 17 00:00:00 2001 From: Jonathan Summers-Muir Date: Wed, 21 Jun 2023 15:33:14 +0800 Subject: [PATCH 18/59] fix connection issues moving away from array POST --- .../Integrations/IntegrationPanels.tsx | 8 ++++--- .../interfaces/Integrations/ProjectLinker.tsx | 22 +++++++++---------- ...integration-connections-create-mutation.ts | 8 +++---- .../data/integrations/integrations-query.ts | 2 +- 4 files changed, 20 insertions(+), 20 deletions(-) diff --git a/studio/components/interfaces/Integrations/IntegrationPanels.tsx b/studio/components/interfaces/Integrations/IntegrationPanels.tsx index 9cf53225dfa..5aa16fbbde3 100644 --- a/studio/components/interfaces/Integrations/IntegrationPanels.tsx +++ b/studio/components/interfaces/Integrations/IntegrationPanels.tsx @@ -67,6 +67,8 @@ const IntegrationInstallation = React.forwardRef
    - {projects.byId(connection.project_ref)?.name} + {projects.byId(connection.supabase_project_id)?.name} - {!connection.metadata.framework ? ( + {!connection?.metadata?.framework ? ( ) : ( {`icon`} )} - {connection.metadata.name} + {connection.metadata?.name}
    diff --git a/studio/components/interfaces/Integrations/ProjectLinker.tsx b/studio/components/interfaces/Integrations/ProjectLinker.tsx index 8f183b8b7c8..570de471499 100644 --- a/studio/components/interfaces/Integrations/ProjectLinker.tsx +++ b/studio/components/interfaces/Integrations/ProjectLinker.tsx @@ -65,21 +65,19 @@ const ProjectLinker = ({ createConnections({ organizationIntegrationId, - connections: [ - { - foreign_project_id: vercelProjectId, - supabase_project_id: supabaseProjectId, - integrationId: INTEGRATION_INTERNAL_ID, - metadata: { - ...projectDetails, - supabaseConfig: { - projectEnvVars: { - write: true, - }, + connection: { + foreign_project_id: vercelProjectId, + supabase_project_id: supabaseProjectId, + integrationId: INTEGRATION_INTERNAL_ID, + metadata: { + ...projectDetails, + supabaseConfig: { + projectEnvVars: { + write: true, }, }, }, - ], + }, }) } diff --git a/studio/data/integrations/integration-connections-create-mutation.ts b/studio/data/integrations/integration-connections-create-mutation.ts index 3c58ea49072..170a18a2404 100644 --- a/studio/data/integrations/integration-connections-create-mutation.ts +++ b/studio/data/integrations/integration-connections-create-mutation.ts @@ -4,21 +4,21 @@ import { API_URL } from 'lib/constants' export type IntegrationConnectionsCreateVariables = { organizationIntegrationId: string - connections: { + connection: { foreignProjectId: string supabaseProjectId: string integrationId: number metadata: any - }[] + } } export async function createIntegrationConnections({ organizationIntegrationId, - connections, + connection, }: IntegrationConnectionsCreateVariables) { const response = await post(`${API_URL}/integrations/vercel/connections`, { organization_integration_id: organizationIntegrationId, - connections, + connection, }) if (response.error) { throw response.error diff --git a/studio/data/integrations/integrations-query.ts b/studio/data/integrations/integrations-query.ts index 39cc1f7b7ad..1865da940d3 100644 --- a/studio/data/integrations/integrations-query.ts +++ b/studio/data/integrations/integrations-query.ts @@ -133,7 +133,7 @@ export type IntegrationProjectConnection = { created_at: string updated_at: string added_by: addedBy - project_ref: string + supabase_project_id: string organization_integration_id: string metadata: metadata } From f8d94c647abba9dd954e45f53a1cb847c14230a1 Mon Sep 17 00:00:00 2001 From: Jonathan Summers-Muir Date: Wed, 21 Jun 2023 18:37:05 +0800 Subject: [PATCH 19/59] chore: you can now add new connections via dashboard --- .../Integrations/IntegrationPanels.tsx | 1 - .../interfaces/Integrations/ProjectLinker.tsx | 82 +++--- .../IntegrationSettings/Integration.tsx | 16 +- .../IntegrationSettings.tsx | 3 +- .../SidePanelVercelProjectLinker.tsx | 67 ++--- ...integration-connections-create-mutation.ts | 6 +- .../data/integrations/integrations-query.ts | 241 +++++++++--------- ...el-installed-connection-delete-mutation.ts | 1 - .../integrations-vercel-projects-query.ts | 2 + .../state/github-connection-config-panel.ts | 10 +- 10 files changed, 233 insertions(+), 196 deletions(-) diff --git a/studio/components/interfaces/Integrations/IntegrationPanels.tsx b/studio/components/interfaces/Integrations/IntegrationPanels.tsx index 5aa16fbbde3..e8a3352fded 100644 --- a/studio/components/interfaces/Integrations/IntegrationPanels.tsx +++ b/studio/components/interfaces/Integrations/IntegrationPanels.tsx @@ -49,7 +49,6 @@ const HandleIcon = ({ type }: { type: HandleIconType }) => { } const Avatar = ({ src }: { src: string }) => { - console.log('src of avatar', src) return (
    avatar diff --git a/studio/components/interfaces/Integrations/ProjectLinker.tsx b/studio/components/interfaces/Integrations/ProjectLinker.tsx index 570de471499..3b0553124f1 100644 --- a/studio/components/interfaces/Integrations/ProjectLinker.tsx +++ b/studio/components/interfaces/Integrations/ProjectLinker.tsx @@ -2,7 +2,9 @@ import { ENV_VAR_RAW_KEYS } from 'components/interfaces/Integrations/Integration import { Markdown } from 'components/interfaces/Markdown' import { vercelIcon } from 'components/to-be-cleaned/ListIcons' import { useIntegrationConnectionsCreateMutation } from 'data/integrations/integration-connections-create-mutation' +import { Integration, IntegrationProjectConnection } from 'data/integrations/integrations-query' import { VercelProjectsResponse } from 'data/integrations/integrations-vercel-projects-query' +import { useStore } from 'hooks' import { BASE_PATH } from 'lib/constants' import { useState } from 'react' import { Button, IconArrowRight, IconPlus, IconX, Input, Listbox, Select, cn } from 'ui' @@ -20,7 +22,7 @@ export interface ProjectLinkerProps { foreignProjects: VercelProjectsResponse[] supabaseProjects: Project[] onCreateConnections?: () => void - installedConnections?: any[] + installedConnections: IntegrationProjectConnection[] | undefined } const UNDEFINED_SELECT_VALUE = 'undefined' @@ -31,10 +33,12 @@ const ProjectLinker = ({ foreignProjects, supabaseProjects, onCreateConnections: _onCreateConnections, - installedConnections, + installedConnections = [], }: ProjectLinkerProps) => { - const [supabaseProjectId, setSupabaseProjectId] = useState('') - const [vercelProjectId, setVercelProjectId] = useState('') + const { ui } = useStore() + + const [supabaseProjectId, setSupabaseProjectId] = useState(UNDEFINED_SELECT_VALUE) + const [vercelProjectId, setVercelProjectId] = useState(UNDEFINED_SELECT_VALUE) // function addConnection() { // setConnections([ @@ -54,6 +58,8 @@ const ProjectLinker = ({ // setConnections(newConnections) // } + // console.log('installed connections', installedConnections) + const { mutate: createConnections, isLoading } = useIntegrationConnectionsCreateMutation({ onSuccess() { _onCreateConnections?.() @@ -78,6 +84,7 @@ const ProjectLinker = ({ }, }, }, + orgId: ui.selectedOrganization?.id, }) } @@ -95,9 +102,22 @@ const ProjectLinker = ({ ) } + /** + * create a flat array of foreign project ids. ie, ["prj_MlkO6AiLG5ofS9ojKrkS3PhhlY3f", ..] + */ + const flatInstalledConnectionsIds = installedConnections.map((x) => x.foreign_project_id) + /** + * check that vercel project is not already installed + */ + const filteredForeignProjects: VercelProjectsResponse[] = foreignProjects.filter( + (foreignProject) => { + return !flatInstalledConnectionsIds.includes(foreignProject.id) + } + ) + return (
    -
    +
    Choose a Vercel project - {foreignProjects.map((project) => ( - { - return ( - <> - {!project?.framework ? ( - vercelIcon - ) : ( - {`icon`} - )} - - ) - }} - > - {project.name} - - ))} + {filteredForeignProjects.map((project) => { + return ( + { + return ( + <> + {!project?.framework ? ( + vercelIcon + ) : ( + {`icon`} + )} + + ) + }} + > + {project.name} + + ) + })}
    diff --git a/studio/components/interfaces/Organization/IntegrationSettings/Integration.tsx b/studio/components/interfaces/Organization/IntegrationSettings/Integration.tsx index cf4a11985df..3bd3b2434c3 100644 --- a/studio/components/interfaces/Organization/IntegrationSettings/Integration.tsx +++ b/studio/components/interfaces/Organization/IntegrationSettings/Integration.tsx @@ -1,4 +1,3 @@ -import { useParams } from 'common' import { EmptyIntegrationConnection, IntegrationConnection, @@ -12,16 +11,11 @@ import { ScaffoldSectionContent, ScaffoldSectionDetail, } from 'components/layouts/Scaffold' -import { useIntegrationConnectionsCreateMutation } from 'data/integrations/integration-connections-create-mutation' -import { - Integration as TIntegration, - useIntegrationsQuery, -} from 'data/integrations/integrations-query' +import { Integration as TIntegration } from 'data/integrations/integrations-query' import { useIntegrationsVercelInstalledConnectionDeleteMutation } from 'data/integrations/integrations-vercel-installed-connection-delete-mutation' import { useStore } from 'hooks' 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' @@ -42,7 +36,7 @@ const Integration = ({ detail, integrations = EMPTY_ARR, }: IntegrationProps) => { - const githubConnectionConfigPanelShotshot = useGithubConnectionConfigPanelSnapshot() + const snapshot = useGithubConnectionConfigPanelSnapshot() const { ui } = useStore() @@ -90,6 +84,7 @@ Repository connections for ${title?.toLowerCase()}
    {integrations.length > 0 && integrations.map((integration, i) => { + console.log('integration.id', integration?.id) return (
    )} githubConnectionConfigPanelShotshot.setVisible(true)} + onClick={() => { + snapshot.setOrganizationIntegrationId(integration.id) + snapshot.setOpen(true) + }} > Add new project connection diff --git a/studio/components/interfaces/Organization/IntegrationSettings/IntegrationSettings.tsx b/studio/components/interfaces/Organization/IntegrationSettings/IntegrationSettings.tsx index e535d1f0577..e2932027eba 100644 --- a/studio/components/interfaces/Organization/IntegrationSettings/IntegrationSettings.tsx +++ b/studio/components/interfaces/Organization/IntegrationSettings/IntegrationSettings.tsx @@ -72,8 +72,7 @@ You can change the scope of the access for Supabase by configuring here. `} integrations={githubIntegrations} /> - {/* */} - {/* */} + ) } diff --git a/studio/components/interfaces/Organization/IntegrationSettings/SidePanelVercelProjectLinker.tsx b/studio/components/interfaces/Organization/IntegrationSettings/SidePanelVercelProjectLinker.tsx index be862353f74..58ee9775500 100644 --- a/studio/components/interfaces/Organization/IntegrationSettings/SidePanelVercelProjectLinker.tsx +++ b/studio/components/interfaces/Organization/IntegrationSettings/SidePanelVercelProjectLinker.tsx @@ -1,37 +1,48 @@ -import { useParams } from 'common' -import ProjectLinker from 'components/interfaces/Integrations/ProjectsLinker' +import ProjectLinker from 'components/interfaces/Integrations/ProjectLinker' import { Markdown } from 'components/interfaces/Markdown' import { useIntegrationsQuery } from 'data/integrations/integrations-query' +import { useVercelProjectConnectionsQuery } from 'data/integrations/integrations-vercel-installed-connections-query' +import { useVercelProjectsQuery } from 'data/integrations/integrations-vercel-projects-query' +import { useProjectsQuery } from 'data/projects/projects-query' import { useStore } from 'hooks' +import { EMPTY_ARR } from 'lib/void' import { observer } from 'mobx-react-lite' -import { useMemo, useState } from 'react' +import { useMemo } 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 { data } = useIntegrationsQuery({ orgId: ui.selectedOrganization?.id }) - - const vercelIntegrations = data?.filter((integration) => integration.integration.id === 1) // vercel - const selectedOrg = ui.selectedOrganization - const [organizationIntegrationId, setOrganizationIntegrationId] = useState( - '880cb835-54b4-415b-8178-6f7920fdc40d' + const { data: integrationData } = useIntegrationsQuery({ + orgId: ui.selectedOrganization?.id, + }) + const vercelIntegrations = integrationData?.filter( + (integration) => integration.integration.name === 'Vercel' + ) // vercel + + const snapshot = useGithubConnectionConfigPanelSnapshot() + + /** + * Find the right integration + * + * we use the snapshot.organizationIntegrationId which should be set whenever this sidepanel is opened + */ + const selectedIntegration = vercelIntegrations?.find( + (x) => x.id === snapshot.organizationIntegrationId ) - const githubConnectionConfigPanelSnapshot = useGithubConnectionConfigPanelSnapshot() + const organizationIntegrationId = snapshot.organizationIntegrationId + const open = snapshot.open + /** + * Supabase projects available + */ const { data: supabaseProjectsData } = useProjectsQuery({ enabled: organizationIntegrationId !== null, }) + const supabaseProjects = useMemo( () => supabaseProjectsData @@ -47,30 +58,26 @@ const SidePanelVercelProjectLinker = () => { { enabled: organizationIntegrationId !== null } ) - const vercelProjectConnections = useMemo( - () => vercelProjectConnectionsData ?? EMPTY_ARR, - [vercelProjectConnectionsData] - ) - const { data: vercelProjectsData } = useVercelProjectsQuery( { orgId: selectedOrg?.id, orgSlug: selectedOrg?.slug, + organization_integration_id: organizationIntegrationId, }, { enabled: organizationIntegrationId !== null } ) - console.log('vercelProjectsData', vercelProjectsData) const vercelProjects = useMemo(() => vercelProjectsData ?? EMPTY_ARR, [vercelProjectsData]) return ( githubConnectionConfigPanelSnapshot.setVisible(false)} + visible={open} + hideFooter + onCancel={() => snapshot.setOpen(false)} > -
    +
    { - // if (next) { - // window.location.href = next - // } + snapshot.setOpen(false) }} - installedConnections={vercelProjectConnections} + installedConnections={selectedIntegration?.connections} /> diff --git a/studio/data/integrations/integration-connections-create-mutation.ts b/studio/data/integrations/integration-connections-create-mutation.ts index 170a18a2404..aa73ad05b9a 100644 --- a/studio/data/integrations/integration-connections-create-mutation.ts +++ b/studio/data/integrations/integration-connections-create-mutation.ts @@ -1,6 +1,7 @@ -import { useMutation, UseMutationOptions } from '@tanstack/react-query' +import { useMutation, UseMutationOptions, useQueryClient } from '@tanstack/react-query' import { post } from 'lib/common/fetch' import { API_URL } from 'lib/constants' +import { integrationKeys } from './keys' export type IntegrationConnectionsCreateVariables = { organizationIntegrationId: string @@ -10,6 +11,7 @@ export type IntegrationConnectionsCreateVariables = { integrationId: number metadata: any } + orgId: number | undefined } export async function createIntegrationConnections({ @@ -40,12 +42,14 @@ export const useIntegrationConnectionsCreateMutation = ({ >, 'mutationFn' > = {}) => { + const queryClient = useQueryClient() return useMutation< IntegrationConnectionsCreateData, unknown, IntegrationConnectionsCreateVariables >((vars) => createIntegrationConnections(vars), { async onSuccess(data, variables, context) { + await Promise.all([queryClient.invalidateQueries(integrationKeys.list(variables.orgId))]) await onSuccess?.(data, variables, context) }, ...options, diff --git a/studio/data/integrations/integrations-query.ts b/studio/data/integrations/integrations-query.ts index 1865da940d3..4467bbf9b9f 100644 --- a/studio/data/integrations/integrations-query.ts +++ b/studio/data/integrations/integrations-query.ts @@ -3,7 +3,123 @@ import { get } from 'lib/common/fetch' import { API_URL } from 'lib/constants' import { integrationKeys } from './keys' -type metadata = { +export type VercelFramework = + | ( + | 'blitzjs' + | 'nextjs' + | 'gatsby' + | 'remix' + | 'astro' + | 'hexo' + | 'eleventy' + | 'docusaurus-2' + | 'docusaurus' + | 'preact' + | 'solidstart' + | 'dojo' + | 'ember' + | 'vue' + | 'scully' + | 'ionic-angular' + | 'angular' + | 'polymer' + | 'svelte' + | 'sveltekit' + | 'sveltekit-1' + | 'ionic-react' + | 'create-react-app' + | 'gridsome' + | 'umijs' + | 'sapper' + | 'saber' + | 'stencil' + | 'nuxtjs' + | 'redwoodjs' + | 'hugo' + | 'jekyll' + | 'brunch' + | 'middleman' + | 'zola' + | 'hydrogen' + | 'vite' + | 'vitepress' + | 'vuepress' + | 'parcel' + | 'sanity' + | 'storybook' + ) + | null + +export type VercelGitLink = + | { + /** + * GitHub link + */ + org?: string + repo?: string + repoId?: number + type?: 'github' + createdAt?: number + deployHooks: { + createdAt?: number + id: string + name: string + ref: string + url: string + }[] + gitCredentialId?: string + updatedAt?: number + sourceless?: boolean + productionBranch?: string + } + | { + /** + * GitLab link + */ + projectId?: string + projectName?: string + projectNameWithNamespace?: string + projectNamespace?: string + projectUrl?: string + type?: 'gitlab' + createdAt?: number + deployHooks: { + createdAt?: number + id: string + name: string + ref: string + url: string + }[] + gitCredentialId?: string + updatedAt?: number + sourceless?: boolean + productionBranch?: string + } + | { + /** + * Bitbucket link + */ + name?: string + slug?: string + owner?: string + type?: 'bitbucket' + uuid?: string + workspaceUuid?: string + createdAt?: number + deployHooks: { + createdAt?: number + id: string + name: string + ref: string + url: string + }[] + gitCredentialId?: string + updatedAt?: number + sourceless?: boolean + productionBranch?: string + } + +type Imetadata = { metadata: { id: string supabaseConfig: { @@ -11,121 +127,9 @@ type metadata = { write: boolean } } - link?: - | { - /** - * GitHub link - */ - org?: string - repo?: string - repoId?: number - type?: 'github' - createdAt?: number - deployHooks: { - createdAt?: number - id: string - name: string - ref: string - url: string - }[] - gitCredentialId?: string - updatedAt?: number - sourceless?: boolean - productionBranch?: string - } - | { - /** - * GitLab link - */ - projectId?: string - projectName?: string - projectNameWithNamespace?: string - projectNamespace?: string - projectUrl?: string - type?: 'gitlab' - createdAt?: number - deployHooks: { - createdAt?: number - id: string - name: string - ref: string - url: string - }[] - gitCredentialId?: string - updatedAt?: number - sourceless?: boolean - productionBranch?: string - } - | { - /** - * Bitbucket link - */ - name?: string - slug?: string - owner?: string - type?: 'bitbucket' - uuid?: string - workspaceUuid?: string - createdAt?: number - deployHooks: { - createdAt?: number - id: string - name: string - ref: string - url: string - }[] - gitCredentialId?: string - updatedAt?: number - sourceless?: boolean - productionBranch?: string - } + link?: VercelGitLink name: string - framework: - | ( - | 'blitzjs' - | 'nextjs' - | 'gatsby' - | 'remix' - | 'astro' - | 'hexo' - | 'eleventy' - | 'docusaurus-2' - | 'docusaurus' - | 'preact' - | 'solidstart' - | 'dojo' - | 'ember' - | 'vue' - | 'scully' - | 'ionic-angular' - | 'angular' - | 'polymer' - | 'svelte' - | 'sveltekit' - | 'sveltekit-1' - | 'ionic-react' - | 'create-react-app' - | 'gridsome' - | 'umijs' - | 'sapper' - | 'saber' - | 'stencil' - | 'nuxtjs' - | 'redwoodjs' - | 'hugo' - | 'jekyll' - | 'brunch' - | 'middleman' - | 'zola' - | 'hydrogen' - | 'vite' - | 'vitepress' - | 'vuepress' - | 'parcel' - | 'sanity' - | 'storybook' - ) - | null + framework: VercelFramework } } export type IntegrationProjectConnection = { @@ -134,8 +138,9 @@ export type IntegrationProjectConnection = { updated_at: string added_by: addedBy supabase_project_id: string + foreign_project_id: string organization_integration_id: string - metadata: metadata + metadata: Imetadata } export type IntegrationsVariables = { @@ -146,7 +151,7 @@ export type IntegrationProjectConnectionPayload = { foreignProjectId: string supabaseProjectId: string integrationId: string - metadata: metadata + metadata: Imetadata } type userDetails = { @@ -166,7 +171,7 @@ export type Integration = { added_by: addedBy created_at: string updated_at: string - connections: IntegrationProjectConnection[] + connections: IntegrationProjectConnection[] | [] metadata?: { vercelTeam?: string gitHubConnectionOwner?: string diff --git a/studio/data/integrations/integrations-vercel-installed-connection-delete-mutation.ts b/studio/data/integrations/integrations-vercel-installed-connection-delete-mutation.ts index fa6d74522a8..dbcac04ee61 100644 --- a/studio/data/integrations/integrations-vercel-installed-connection-delete-mutation.ts +++ b/studio/data/integrations/integrations-vercel-installed-connection-delete-mutation.ts @@ -41,7 +41,6 @@ export const useIntegrationsVercelInstalledConnectionDeleteMutation = ({ async onSuccess(data, variables, context) { console.log('variables in mutate delete onSuccess', variables) await Promise.all([queryClient.invalidateQueries(integrationKeys.list(variables.orgId))]) - await onSuccess?.(data, variables, context) }, ...options, diff --git a/studio/data/integrations/integrations-vercel-projects-query.ts b/studio/data/integrations/integrations-vercel-projects-query.ts index 2f3307b373b..1e63ee1f6a3 100644 --- a/studio/data/integrations/integrations-vercel-projects-query.ts +++ b/studio/data/integrations/integrations-vercel-projects-query.ts @@ -3,6 +3,7 @@ import { get } from 'lib/common/fetch' import { API_URL } from 'lib/constants' import { useCallback } from 'react' import { integrationKeys } from './keys' +import { VercelFramework } from './integrations-query' export type VercelProjectsVariables = { orgId?: number @@ -13,6 +14,7 @@ export type VercelProjectsVariables = { export type VercelProjectsResponse = { id: string name: string + framework: VercelFramework metadata: { id: string name: string diff --git a/studio/state/github-connection-config-panel.ts b/studio/state/github-connection-config-panel.ts index 021d5c54846..915c6ec5fe8 100644 --- a/studio/state/github-connection-config-panel.ts +++ b/studio/state/github-connection-config-panel.ts @@ -1,9 +1,13 @@ import { proxy, snapshot, useSnapshot } from 'valtio' export const githubConnectionConfigPanelState = proxy({ - visible: false as boolean, - setVisible: (visible: boolean) => { - githubConnectionConfigPanelState.visible = visible + open: false as boolean, + setOpen: (open: boolean) => { + githubConnectionConfigPanelState.open = open + }, + organizationIntegrationId: '' as string, + setOrganizationIntegrationId: (organizationInterationId: string) => { + githubConnectionConfigPanelState.organizationIntegrationId = organizationInterationId }, }) From c15f0391f93ed5d3247e888241c970ed816108f4 Mon Sep 17 00:00:00 2001 From: Jonathan Summers-Muir Date: Thu, 22 Jun 2023 18:09:15 +0800 Subject: [PATCH 20/59] fix BASE_PATH issues --- .../components/interfaces/Integrations/IntegrationPanels.tsx | 3 ++- .../Organization/IntegrationSettings/Integration.tsx | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/studio/components/interfaces/Integrations/IntegrationPanels.tsx b/studio/components/interfaces/Integrations/IntegrationPanels.tsx index e8a3352fded..ae9fdbde404 100644 --- a/studio/components/interfaces/Integrations/IntegrationPanels.tsx +++ b/studio/components/interfaces/Integrations/IntegrationPanels.tsx @@ -2,6 +2,7 @@ import { Markdown } from 'components/interfaces/Markdown' import { Integration, IntegrationProjectConnection } from 'data/integrations/integrations-query' import dayjs from 'dayjs' import { useStore } from 'hooks' +import { BASE_PATH } from 'lib/constants' import Image from 'next/image' import React from 'react' @@ -142,7 +143,7 @@ const IntegrationConnection = React.forwardRef ) : ( {`icon`}} cover From c10ad8f01e95d7c3ef03a7d9bd83f72fedd79405 Mon Sep 17 00:00:00 2001 From: Jonathan Summers-Muir Date: Thu, 22 Jun 2023 19:49:52 +0800 Subject: [PATCH 21/59] updating to use slug --- .../Integrations/IntegrationPanels.tsx | 2 +- .../interfaces/Integrations/ProjectLinker.tsx | 19 ++++++++++--------- .../IntegrationSettings.tsx | 6 +----- ...integration-connections-create-mutation.ts | 6 +++--- .../data/integrations/integrations-query.ts | 18 +++++++++--------- studio/data/integrations/keys.ts | 2 +- .../vercel-integration-create-mutation.ts | 8 ++++---- studio/pages/integrations/vercel.tsx | 9 +++++---- 8 files changed, 34 insertions(+), 36 deletions(-) diff --git a/studio/components/interfaces/Integrations/IntegrationPanels.tsx b/studio/components/interfaces/Integrations/IntegrationPanels.tsx index ae9fdbde404..429a06bfc50 100644 --- a/studio/components/interfaces/Integrations/IntegrationPanels.tsx +++ b/studio/components/interfaces/Integrations/IntegrationPanels.tsx @@ -40,7 +40,7 @@ const HandleIcon = ({ type }: { type: HandleIconType }) => { break case 'Supabase': - return Supabase + return Supabase break default: diff --git a/studio/components/interfaces/Integrations/ProjectLinker.tsx b/studio/components/interfaces/Integrations/ProjectLinker.tsx index 3b0553124f1..4f384ec30be 100644 --- a/studio/components/interfaces/Integrations/ProjectLinker.tsx +++ b/studio/components/interfaces/Integrations/ProjectLinker.tsx @@ -12,6 +12,7 @@ import { Button, IconArrowRight, IconPlus, IconX, Input, Listbox, Select, cn } f interface Project { id: string name: string + ref: string } // to do: move this somewhere @@ -37,7 +38,7 @@ const ProjectLinker = ({ }: ProjectLinkerProps) => { const { ui } = useStore() - const [supabaseProjectId, setSupabaseProjectId] = useState(UNDEFINED_SELECT_VALUE) + const [supabaseProjectRef, setSupabaseProjectRef] = useState(UNDEFINED_SELECT_VALUE) const [vercelProjectId, setVercelProjectId] = useState(UNDEFINED_SELECT_VALUE) // function addConnection() { @@ -73,8 +74,8 @@ const ProjectLinker = ({ organizationIntegrationId, connection: { foreign_project_id: vercelProjectId, - supabase_project_id: supabaseProjectId, - integrationId: INTEGRATION_INTERNAL_ID, + supabase_project_ref: supabaseProjectRef, + integration_id: INTEGRATION_INTERNAL_ID, metadata: { ...projectDetails, supabaseConfig: { @@ -129,16 +130,16 @@ const ProjectLinker = ({
    setSupabaseProjectId(e)} + value={supabaseProjectRef ?? UNDEFINED_SELECT_VALUE} + onChange={(e) => setSupabaseProjectRef(e)} > - Choose a Supabase project + Choose project {supabaseProjects.map((project) => ( { return ( @@ -178,7 +179,7 @@ const ProjectLinker = ({ onChange={(e) => setVercelProjectId(e)} > - Choose a Vercel project + Choose Vercel project {filteredForeignProjects.map((project) => { return ( @@ -193,7 +194,7 @@ const ProjectLinker = ({ vercelIcon ) : ( {`icon`} { const { ui } = useStore() - const { slug } = useParams() - const { data } = useIntegrationsQuery({ orgId: ui.selectedOrganization?.id }) + const { data } = useIntegrationsQuery({ orgSlug: ui.selectedOrganization?.slug }) const org = ui.selectedOrganization diff --git a/studio/data/integrations/integration-connections-create-mutation.ts b/studio/data/integrations/integration-connections-create-mutation.ts index aa73ad05b9a..b6605601fd6 100644 --- a/studio/data/integrations/integration-connections-create-mutation.ts +++ b/studio/data/integrations/integration-connections-create-mutation.ts @@ -6,9 +6,9 @@ import { integrationKeys } from './keys' export type IntegrationConnectionsCreateVariables = { organizationIntegrationId: string connection: { - foreignProjectId: string - supabaseProjectId: string - integrationId: number + foreign_project_id: string + supabase_project_ref: string + integration_id: number metadata: any } orgId: number | undefined diff --git a/studio/data/integrations/integrations-query.ts b/studio/data/integrations/integrations-query.ts index 4467bbf9b9f..d0c01593a57 100644 --- a/studio/data/integrations/integrations-query.ts +++ b/studio/data/integrations/integrations-query.ts @@ -144,7 +144,7 @@ export type IntegrationProjectConnection = { } export type IntegrationsVariables = { - orgId?: number + orgSlug?: string } export type IntegrationProjectConnectionPayload = { @@ -180,12 +180,12 @@ export type Integration = { export type IntegrationsResponse = Integration[] -export async function getIntegrations({ orgId }: IntegrationsVariables, signal?: AbortSignal) { - if (!orgId) { - throw new Error('orgId is required') +export async function getIntegrations({ orgSlug }: IntegrationsVariables, signal?: AbortSignal) { + if (!orgSlug) { + throw new Error('orgSlug is required') } - const response = await get(`${API_URL}/integrations/${orgId}`, { + const response = await get(`${API_URL}/integrations/${orgSlug}`, { signal, }) if (response.error) { @@ -202,11 +202,11 @@ export type ProjectIntegrationConnectionsData = Awaited< export type IntegrationsError = unknown export const useIntegrationsQuery = ( - { orgId }: IntegrationsVariables, + { orgSlug }: IntegrationsVariables, { enabled = true, ...options }: UseQueryOptions = {} ) => useQuery( - integrationKeys.list(orgId), - ({ signal }) => getIntegrations({ orgId }, signal), - { enabled: enabled && typeof orgId !== 'undefined', ...options } + integrationKeys.list(orgSlug), + ({ signal }) => getIntegrations({ orgSlug }, signal), + { enabled: enabled && typeof orgSlug !== 'undefined', ...options } ) diff --git a/studio/data/integrations/keys.ts b/studio/data/integrations/keys.ts index b25c9329d41..7164ad8068f 100644 --- a/studio/data/integrations/keys.ts +++ b/studio/data/integrations/keys.ts @@ -1,5 +1,5 @@ export const integrationKeys = { - list: (orgId: number | undefined) => ['organizations', orgId, 'integrations'] as const, + list: (orgSlug: string | undefined) => ['organizations', orgSlug, 'integrations'] as const, vercelProjectList: (organization_integration_id: string | undefined) => ['organizations', organization_integration_id, 'vercel-projects'] as const, vercelConnectionsList: (organization_integration_id: string | undefined) => diff --git a/studio/data/integrations/vercel-integration-create-mutation.ts b/studio/data/integrations/vercel-integration-create-mutation.ts index 04781212e39..9165c33df2d 100644 --- a/studio/data/integrations/vercel-integration-create-mutation.ts +++ b/studio/data/integrations/vercel-integration-create-mutation.ts @@ -5,7 +5,7 @@ import { API_URL } from 'lib/constants' export type VercelIntegrationCreateVariables = { code: string configurationId: string - orgId: number + orgSlug: string metadata: { [key: string]: string } source: string // teamId is only present when a team is being installed @@ -16,16 +16,16 @@ export type VercelIntegrationCreateVariables = { export async function createVercelIntegration({ code, configurationId, - orgId, + orgSlug, metadata, source, teamId, }: VercelIntegrationCreateVariables) { - console.log('payload', { code, configurationId, orgId, metadata, source, teamId }) + console.log('payload', { code, configurationId, orgSlug, metadata, source, teamId }) const response = await post(`${API_URL}/integrations/vercel`, { code, configuration_id: configurationId, - organization_id: orgId, + organization_slug: orgSlug, metadata, source, teamId, diff --git a/studio/pages/integrations/vercel.tsx b/studio/pages/integrations/vercel.tsx index 2133b293df6..da33fc04467 100644 --- a/studio/pages/integrations/vercel.tsx +++ b/studio/pages/integrations/vercel.tsx @@ -30,8 +30,8 @@ const VercelIntegration: NextPageWithLayout = () => { }) function onInstall() { - const orgId = selectedOrg?.id - if (!orgId) { + const orgSlug = selectedOrg?.slug + if (!orgSlug) { return ui.setNotification({ category: 'error', message: 'Please select an organization' }) } @@ -55,7 +55,7 @@ const VercelIntegration: NextPageWithLayout = () => { mutate({ code, configurationId, - orgId, + orgSlug, metadata, source, teamId: teamId, @@ -69,7 +69,8 @@ const VercelIntegration: NextPageWithLayout = () => { () => supabaseProjectsData ?.filter((project) => project.organization_id === selectedOrg?.id) - .map((project) => ({ id: project.id.toString(), name: project.name })) ?? EMPTY_ARR, + .map((project) => ({ id: project.id.toString(), name: project.name, ref: project.ref })) ?? + EMPTY_ARR, [selectedOrg?.id, supabaseProjectsData] ) From 6c31d28f059c0e920486ef6f4323021264dae2fd Mon Sep 17 00:00:00 2001 From: Jonathan Summers-Muir Date: Thu, 22 Jun 2023 19:53:55 +0800 Subject: [PATCH 22/59] fixed fitler issue --- .../IntegrationSettings/IntegrationSettings.tsx | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/studio/components/interfaces/Organization/IntegrationSettings/IntegrationSettings.tsx b/studio/components/interfaces/Organization/IntegrationSettings/IntegrationSettings.tsx index 88efe9e86d9..d7d2249b047 100644 --- a/studio/components/interfaces/Organization/IntegrationSettings/IntegrationSettings.tsx +++ b/studio/components/interfaces/Organization/IntegrationSettings/IntegrationSettings.tsx @@ -11,8 +11,12 @@ const IntegrationSettings = () => { const org = ui.selectedOrganization - const vercelIntegrations = data?.filter((integration) => integration.integration.id === 1) // vercel - const githubIntegrations = data?.filter((integration) => integration.integration.id === 2) // github + const vercelIntegrations = data?.filter( + (integration) => integration.integration.name === 'Vercel' + ) // vercel + const githubIntegrations = data?.filter( + (integration) => integration.integration.name === 'GitHub' + ) // github vercelIntegrations?.map((x) => { let data: any = { ...x } From beb5d10b61dbd6d3fef218061ff8d124eebd5c7d Mon Sep 17 00:00:00 2001 From: Jonathan Summers-Muir Date: Fri, 23 Jun 2023 16:07:48 +0800 Subject: [PATCH 23/59] deploy button flow started --- packages/common/hooks/useParams.ts | 33 +- .../Database/Backups/PITR/PITRSelection.tsx | 1 - .../Integrations/IntegrationPanels.tsx | 5 +- .../interfaces/Integrations/ProjectLinker.tsx | 56 +-- .../IntegrationSettings/Integration.tsx | 2 +- .../IntegrationSettings/IntegrationGitHub.tsx | 2 +- .../IntegrationSettings.tsx | 4 +- .../SidePanelGitHubRepoSelection.tsx | 2 +- .../SidePanelVercelProjectLinker.tsx | 8 +- studio/components/ui/OrganizationPicker.tsx | 73 +++- ...integration-connections-create-mutation.ts | 11 +- .../integrations-query-org-only.ts | 35 ++ .../data/integrations/integrations-query.ts | 196 +--------- .../integrations-vercel-projects-query.ts | 31 +- .../data/integrations/integrations.types.ts | 178 ++++++++++ studio/data/integrations/keys.ts | 4 +- .../vercel-integration-create-mutation.ts | 10 +- studio/pages/integrations/vercel.tsx | 33 +- .../vercel/[slug]/new-project.tsx | 334 ++++++++++++++++++ studio/pages/integrations/vercel/install.tsx | 248 +++++++++++++ .../state/vercel-integration-installation.ts | 15 + 21 files changed, 1003 insertions(+), 278 deletions(-) create mode 100644 studio/data/integrations/integrations-query-org-only.ts create mode 100644 studio/data/integrations/integrations.types.ts create mode 100644 studio/pages/integrations/vercel/[slug]/new-project.tsx create mode 100644 studio/pages/integrations/vercel/install.tsx create mode 100644 studio/state/vercel-integration-installation.ts diff --git a/packages/common/hooks/useParams.ts b/packages/common/hooks/useParams.ts index cac30143bd9..879d3f4e50e 100644 --- a/packages/common/hooks/useParams.ts +++ b/packages/common/hooks/useParams.ts @@ -1,15 +1,46 @@ import { useRouter } from 'next/router' import { useMemo } from 'react' +/** + * Helper to convert kebab case to camel case + */ +function convertToCamelCase(key: string): string { + if (!key.includes('-')) { + return key + } + + const parts = key.split('-') + const capitalizedParts = parts.map((part, index) => { + if (index === 0) { + return part + } + return part.charAt(0).toUpperCase() + part.slice(1) + }) + return capitalizedParts.join('') +} + export function useParams(): { [k: string]: string | undefined } { const { query } = useRouter() + const modifiedQuery = { + ...query, + } + + // Convert kebab case keys to camel case + Object.keys(modifiedQuery).forEach((key) => { + const modifiedKey = convertToCamelCase(key) + if (modifiedKey !== key) { + modifiedQuery[modifiedKey] = modifiedQuery[key] + delete modifiedQuery[key] + } + }) + return useMemo( () => Object.fromEntries( - Object.entries(query).map(([key, value]) => { + Object.entries(modifiedQuery).map(([key, value]) => { if (Array.isArray(value)) { return [key, value[0]] } else { diff --git a/studio/components/interfaces/Database/Backups/PITR/PITRSelection.tsx b/studio/components/interfaces/Database/Backups/PITR/PITRSelection.tsx index eb1ecceb2f0..1517f52ff3d 100644 --- a/studio/components/interfaces/Database/Backups/PITR/PITRSelection.tsx +++ b/studio/components/interfaces/Database/Backups/PITR/PITRSelection.tsx @@ -147,7 +147,6 @@ const PITRSelection = ({}) => {
    - {/*
    -

    - The following enviroment variables will be added: -

    -

    - {ENV_VAR_RAW_KEYS.map((x, idx) => { - return ( - - {x},{' '} - - ) - })} -

    -
    */} { const { ui } = useStore() - const { data } = useIntegrationsQuery({ orgSlug: ui.selectedOrganization?.slug }) + const { data } = useOrgIntegrationsQuery({ orgSlug: ui.selectedOrganization?.slug }) const org = ui.selectedOrganization diff --git a/studio/components/interfaces/Organization/IntegrationSettings/SidePanelGitHubRepoSelection.tsx b/studio/components/interfaces/Organization/IntegrationSettings/SidePanelGitHubRepoSelection.tsx index 0b4494a00e1..9331baf205d 100644 --- a/studio/components/interfaces/Organization/IntegrationSettings/SidePanelGitHubRepoSelection.tsx +++ b/studio/components/interfaces/Organization/IntegrationSettings/SidePanelGitHubRepoSelection.tsx @@ -1,6 +1,6 @@ import { useParams } from 'common' import { Markdown } from 'components/interfaces/Markdown' -import { useIntegrationsQuery } from 'data/integrations/integrations-query' +import { useIntegrationsQuery } from 'data/integrations/integrations-query-org-only' import { useStore } from 'hooks' import { observer } from 'mobx-react-lite' import { useGithubConnectionConfigPanelSnapshot } from 'state/github-connection-config-panel' diff --git a/studio/components/interfaces/Organization/IntegrationSettings/SidePanelVercelProjectLinker.tsx b/studio/components/interfaces/Organization/IntegrationSettings/SidePanelVercelProjectLinker.tsx index 58ee9775500..9e86712d86c 100644 --- a/studio/components/interfaces/Organization/IntegrationSettings/SidePanelVercelProjectLinker.tsx +++ b/studio/components/interfaces/Organization/IntegrationSettings/SidePanelVercelProjectLinker.tsx @@ -1,6 +1,7 @@ +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 { useOrgIntegrationsQuery } from 'data/integrations/integrations-query-org-only' import { useVercelProjectConnectionsQuery } from 'data/integrations/integrations-vercel-installed-connections-query' import { useVercelProjectsQuery } from 'data/integrations/integrations-vercel-projects-query' import { useProjectsQuery } from 'data/projects/projects-query' @@ -13,10 +14,11 @@ import { SidePanel } from 'ui' const SidePanelVercelProjectLinker = () => { const { ui } = useStore() + const selectedOrg = ui.selectedOrganization - const { data: integrationData } = useIntegrationsQuery({ - orgId: ui.selectedOrganization?.id, + const { data: integrationData } = useOrgIntegrationsQuery({ + orgSlug: ui.selectedOrganization?.slug, }) const vercelIntegrations = integrationData?.filter( (integration) => integration.integration.name === 'Vercel' diff --git a/studio/components/ui/OrganizationPicker.tsx b/studio/components/ui/OrganizationPicker.tsx index 808a5166f68..4b89efa3b3e 100644 --- a/studio/components/ui/OrganizationPicker.tsx +++ b/studio/components/ui/OrganizationPicker.tsx @@ -1,19 +1,41 @@ -import { useOrganizationsQuery } from 'data/organizations/organizations-query' +import { useIntegrationsQuery } from 'data/integrations/integrations-query' +import { IntegrationName } from 'data/integrations/integrations.types' +import { + OrganizationsResponse, + useOrganizationsQuery, +} from 'data/organizations/organizations-query' +import { useStore } from 'hooks' import { useState } from 'react' import { Organization } from 'types' -import { Listbox } from 'ui' +import { Badge, IconHexagon, Listbox } from 'ui' export interface OrganizationPickerProps { label?: string onSelectedOrgChange?: (org: Organization) => void + integrationName: IntegrationName } const OrganizationPicker = ({ label = 'Choose an organization', onSelectedOrgChange, + integrationName, }: OrganizationPickerProps) => { + const { ui } = useStore() const [selectedOrg, setSelectedOrg] = useState(null) + /** + * array of integrations installed on all + */ + const { data: integrationData, isLoading: integrationDataLoading } = useIntegrationsQuery({}) + console.log('integrationData', integrationData) + + /** + * filter integrations to match integrationName + */ + const vercelIntegrationsInstalled = integrationData?.filter( + (integration) => integration.integration.name === 'Vercel' + ) + const { data, isLoading } = useOrganizationsQuery({ onSuccess(organizations) { const firstOrg = organizations?.[0] @@ -33,7 +55,7 @@ const OrganizationPicker = ({ } } - if (isLoading) { + if (isLoading || integrationDataLoading) { return ( @@ -43,12 +65,51 @@ const OrganizationPicker = ({ ) } + /** + * Organization type with `installationInstalled` added + */ + interface OrganizationsResponseWithInstalledData extends Organization { + installationInstalled?: boolean + } + + /** + * A flat array of org slugs that have integration installed + */ + const flatInstalledConnectionsIds = + integrationData && integrationData.length > 0 + ? integrationData?.map((x) => x.organization.slug) + : [] + + /** + * Organizations with extra `installationInstalled` attribute + * Used to show label/badge and allow/disallow installing + */ + const organizationsWithInstalledData: OrganizationsResponseWithInstalledData[] = data + ? data.map((org) => { + return { + ...org, + installationInstalled: !flatInstalledConnectionsIds.includes(org.slug) ? true : false, + } + }) + : [] + return ( - {data?.map((org) => { - return ( - + {organizationsWithInstalledData?.map((org) => { + const label = ( +
    {org.name} + {org.installationInstalled && Integration Installed} +
    + ) + return ( + } + > + {label} ) })} diff --git a/studio/data/integrations/integration-connections-create-mutation.ts b/studio/data/integrations/integration-connections-create-mutation.ts index b6605601fd6..491e606ea9b 100644 --- a/studio/data/integrations/integration-connections-create-mutation.ts +++ b/studio/data/integrations/integration-connections-create-mutation.ts @@ -8,10 +8,9 @@ export type IntegrationConnectionsCreateVariables = { connection: { foreign_project_id: string supabase_project_ref: string - integration_id: number metadata: any } - orgId: number | undefined + orgSlug: string | undefined } export async function createIntegrationConnections({ @@ -49,7 +48,13 @@ export const useIntegrationConnectionsCreateMutation = ({ IntegrationConnectionsCreateVariables >((vars) => createIntegrationConnections(vars), { async onSuccess(data, variables, context) { - await Promise.all([queryClient.invalidateQueries(integrationKeys.list(variables.orgId))]) + await Promise.all([ + queryClient.invalidateQueries(integrationKeys.integrationsList()), + queryClient.invalidateQueries(integrationKeys.integrationsListWithOrg(variables.orgSlug)), + queryClient.invalidateQueries( + integrationKeys.vercelProjectList(variables.organizationIntegrationId) + ), + ]) await onSuccess?.(data, variables, context) }, ...options, diff --git a/studio/data/integrations/integrations-query-org-only.ts b/studio/data/integrations/integrations-query-org-only.ts new file mode 100644 index 00000000000..664f4aced96 --- /dev/null +++ b/studio/data/integrations/integrations-query-org-only.ts @@ -0,0 +1,35 @@ +import { useQuery, useQueryClient, UseQueryOptions } from '@tanstack/react-query' +import { get } from 'lib/common/fetch' +import { API_URL } from 'lib/constants' +import { integrationKeys } from './keys' +import { IntegrationsVariables, Integration } from './integrations.types' + +export type IntegrationsResponse = Integration[] + +export async function getIntegrations({ orgSlug }: IntegrationsVariables, signal?: AbortSignal) { + if (!orgSlug) { + throw new Error('orgSlug is required') + } + const response = await get(`${API_URL}/integrations/${orgSlug}?expand=true`, { + signal, + }) + if (response.error) { + throw response.error + } + + return response as IntegrationsResponse +} + +export type IntegrationsData = Awaited> +export type ProjectIntegrationConnectionsData = Awaited> +export type IntegrationsError = unknown + +export const useOrgIntegrationsQuery = ( + { orgSlug }: IntegrationsVariables, + { enabled = true, ...options }: UseQueryOptions = {} +) => + useQuery( + integrationKeys.integrationsListWithOrg(orgSlug), + ({ signal }) => getIntegrations({ orgSlug }, signal), + { enabled: enabled && typeof orgSlug !== 'undefined', ...options } + ) diff --git a/studio/data/integrations/integrations-query.ts b/studio/data/integrations/integrations-query.ts index d0c01593a57..c43435ff32b 100644 --- a/studio/data/integrations/integrations-query.ts +++ b/studio/data/integrations/integrations-query.ts @@ -2,190 +2,12 @@ import { useQuery, useQueryClient, UseQueryOptions } from '@tanstack/react-query import { get } from 'lib/common/fetch' import { API_URL } from 'lib/constants' import { integrationKeys } from './keys' - -export type VercelFramework = - | ( - | 'blitzjs' - | 'nextjs' - | 'gatsby' - | 'remix' - | 'astro' - | 'hexo' - | 'eleventy' - | 'docusaurus-2' - | 'docusaurus' - | 'preact' - | 'solidstart' - | 'dojo' - | 'ember' - | 'vue' - | 'scully' - | 'ionic-angular' - | 'angular' - | 'polymer' - | 'svelte' - | 'sveltekit' - | 'sveltekit-1' - | 'ionic-react' - | 'create-react-app' - | 'gridsome' - | 'umijs' - | 'sapper' - | 'saber' - | 'stencil' - | 'nuxtjs' - | 'redwoodjs' - | 'hugo' - | 'jekyll' - | 'brunch' - | 'middleman' - | 'zola' - | 'hydrogen' - | 'vite' - | 'vitepress' - | 'vuepress' - | 'parcel' - | 'sanity' - | 'storybook' - ) - | null - -export type VercelGitLink = - | { - /** - * GitHub link - */ - org?: string - repo?: string - repoId?: number - type?: 'github' - createdAt?: number - deployHooks: { - createdAt?: number - id: string - name: string - ref: string - url: string - }[] - gitCredentialId?: string - updatedAt?: number - sourceless?: boolean - productionBranch?: string - } - | { - /** - * GitLab link - */ - projectId?: string - projectName?: string - projectNameWithNamespace?: string - projectNamespace?: string - projectUrl?: string - type?: 'gitlab' - createdAt?: number - deployHooks: { - createdAt?: number - id: string - name: string - ref: string - url: string - }[] - gitCredentialId?: string - updatedAt?: number - sourceless?: boolean - productionBranch?: string - } - | { - /** - * Bitbucket link - */ - name?: string - slug?: string - owner?: string - type?: 'bitbucket' - uuid?: string - workspaceUuid?: string - createdAt?: number - deployHooks: { - createdAt?: number - id: string - name: string - ref: string - url: string - }[] - gitCredentialId?: string - updatedAt?: number - sourceless?: boolean - productionBranch?: string - } - -type Imetadata = { - metadata: { - id: string - supabaseConfig: { - projectEnvVars: { - write: boolean - } - } - link?: VercelGitLink - name: string - framework: VercelFramework - } -} -export type IntegrationProjectConnection = { - id: string - created_at: string - updated_at: string - added_by: addedBy - supabase_project_id: string - foreign_project_id: string - organization_integration_id: string - metadata: Imetadata -} - -export type IntegrationsVariables = { - orgSlug?: string -} - -export type IntegrationProjectConnectionPayload = { - foreignProjectId: string - supabaseProjectId: string - integrationId: string - metadata: Imetadata -} - -type userDetails = { - username: string - id: string - primary_email: string -} -type addedBy = userDetails -type updatedBy = userDetails - -export type Integration = { - id: string - integration: { - id: string - name: 'Vercel' | 'Netlify' | 'GitHub' - } - added_by: addedBy - created_at: string - updated_at: string - connections: IntegrationProjectConnection[] | [] - metadata?: { - vercelTeam?: string - gitHubConnectionOwner?: string - } -} +import { IntegrationsVariables, Integration } from './integrations.types' export type IntegrationsResponse = Integration[] -export async function getIntegrations({ orgSlug }: IntegrationsVariables, signal?: AbortSignal) { - if (!orgSlug) { - throw new Error('orgSlug is required') - } - - const response = await get(`${API_URL}/integrations/${orgSlug}`, { +export async function getIntegrations({}: {}, signal?: AbortSignal) { + const response = await get(`${API_URL}/integrations`, { signal, }) if (response.error) { @@ -196,17 +18,15 @@ export async function getIntegrations({ orgSlug }: IntegrationsVariables, signal } export type IntegrationsData = Awaited> -export type ProjectIntegrationConnectionsData = Awaited< - ReturnType -> +export type ProjectIntegrationConnectionsData = Awaited> export type IntegrationsError = unknown export const useIntegrationsQuery = ( - { orgSlug }: IntegrationsVariables, + {}: {}, { enabled = true, ...options }: UseQueryOptions = {} ) => useQuery( - integrationKeys.list(orgSlug), - ({ signal }) => getIntegrations({ orgSlug }, signal), - { enabled: enabled && typeof orgSlug !== 'undefined', ...options } + integrationKeys.integrationsList(), + ({ signal }) => getIntegrations({}, signal), + { enabled: enabled, ...options } ) diff --git a/studio/data/integrations/integrations-vercel-projects-query.ts b/studio/data/integrations/integrations-vercel-projects-query.ts index 1e63ee1f6a3..5c6556c283f 100644 --- a/studio/data/integrations/integrations-vercel-projects-query.ts +++ b/studio/data/integrations/integrations-vercel-projects-query.ts @@ -3,12 +3,10 @@ import { get } from 'lib/common/fetch' import { API_URL } from 'lib/constants' import { useCallback } from 'react' import { integrationKeys } from './keys' -import { VercelFramework } from './integrations-query' +import { VercelFramework } from './integrations.types' export type VercelProjectsVariables = { - orgId?: number - orgSlug?: string - organization_integration_id?: string + organization_integration_id: string | undefined } export type VercelProjectsResponse = { @@ -24,11 +22,11 @@ export type VercelProjectsResponse = { } export async function getVercelProjects( - { orgId, organization_integration_id }: VercelProjectsVariables, + { organization_integration_id }: VercelProjectsVariables, signal?: AbortSignal ) { if (!organization_integration_id) { - throw new Error('orgId is required') + throw new Error('organization_integration_id is required') } const response = await get( @@ -48,17 +46,17 @@ export type VercelProjectsData = Awaited> export type VercelProjectsError = unknown export const useVercelProjectsQuery = ( - { orgSlug, orgId, organization_integration_id }: VercelProjectsVariables, + { organization_integration_id }: VercelProjectsVariables, { enabled = true, ...options }: UseQueryOptions = {} ) => useQuery( - integrationKeys.vercelProjectList(orgSlug), - ({ signal }) => getVercelProjects({ orgSlug, orgId, organization_integration_id }, signal), + integrationKeys.vercelProjectList(organization_integration_id), + ({ signal }) => getVercelProjects({ organization_integration_id }, signal), { - enabled: enabled && typeof orgSlug !== 'undefined' && typeof orgId !== 'undefined', + enabled: enabled && typeof organization_integration_id !== 'undefined', ...options, } ) @@ -76,17 +74,18 @@ export const useVercelProjectsQuery = ( * ) */ export const useVercelProjectsPrefetch = ({ - orgSlug, - orgId, + // orgSlug, + // orgId, organization_integration_id, }: VercelProjectsVariables) => { const client = useQueryClient() return useCallback(() => { - if (orgSlug) { - client.prefetchQuery(integrationKeys.vercelProjectList(orgSlug), ({ signal }) => - getVercelProjects({ orgSlug, orgId, organization_integration_id }, signal) + if (organization_integration_id) { + client.prefetchQuery( + integrationKeys.vercelProjectList(organization_integration_id), + ({ signal }) => getVercelProjects({ organization_integration_id }, signal) ) } - }, [orgSlug]) + }, [organization_integration_id]) } diff --git a/studio/data/integrations/integrations.types.ts b/studio/data/integrations/integrations.types.ts new file mode 100644 index 00000000000..c109395510d --- /dev/null +++ b/studio/data/integrations/integrations.types.ts @@ -0,0 +1,178 @@ +export type VercelFramework = + | ( + | 'blitzjs' + | 'nextjs' + | 'gatsby' + | 'remix' + | 'astro' + | 'hexo' + | 'eleventy' + | 'docusaurus-2' + | 'docusaurus' + | 'preact' + | 'solidstart' + | 'dojo' + | 'ember' + | 'vue' + | 'scully' + | 'ionic-angular' + | 'angular' + | 'polymer' + | 'svelte' + | 'sveltekit' + | 'sveltekit-1' + | 'ionic-react' + | 'create-react-app' + | 'gridsome' + | 'umijs' + | 'sapper' + | 'saber' + | 'stencil' + | 'nuxtjs' + | 'redwoodjs' + | 'hugo' + | 'jekyll' + | 'brunch' + | 'middleman' + | 'zola' + | 'hydrogen' + | 'vite' + | 'vitepress' + | 'vuepress' + | 'parcel' + | 'sanity' + | 'storybook' + ) + | null + +export type VercelGitLink = + | { + /** + * GitHub link + */ + org?: string + repo?: string + repoId?: number + type?: 'github' + createdAt?: number + deployHooks: { + createdAt?: number + id: string + name: string + ref: string + url: string + }[] + gitCredentialId?: string + updatedAt?: number + sourceless?: boolean + productionBranch?: string + } + | { + /** + * GitLab link + */ + projectId?: string + projectName?: string + projectNameWithNamespace?: string + projectNamespace?: string + projectUrl?: string + type?: 'gitlab' + createdAt?: number + deployHooks: { + createdAt?: number + id: string + name: string + ref: string + url: string + }[] + gitCredentialId?: string + updatedAt?: number + sourceless?: boolean + productionBranch?: string + } + | { + /** + * Bitbucket link + */ + name?: string + slug?: string + owner?: string + type?: 'bitbucket' + uuid?: string + workspaceUuid?: string + createdAt?: number + deployHooks: { + createdAt?: number + id: string + name: string + ref: string + url: string + }[] + gitCredentialId?: string + updatedAt?: number + sourceless?: boolean + productionBranch?: string + } + +export type Imetadata = { + metadata: { + id: string + supabaseConfig: { + projectEnvVars: { + write: boolean + } + } + link?: VercelGitLink + name: string + framework: VercelFramework + } +} +export type IntegrationProjectConnection = { + id: string + created_at: string + updated_at: string + added_by: addedBy + supabase_project_id: string + foreign_project_id: string + organization_integration_id: string + metadata: Imetadata +} + +export type IntegrationsVariables = { + orgSlug?: string +} + +export type IntegrationProjectConnectionPayload = { + foreignProjectId: string + supabaseProjectId: string + integrationId: string + metadata: Imetadata +} + +export type userDetails = { + username: string + id: string + primary_email: string +} +type addedBy = userDetails +type updatedBy = userDetails + +export type IntegrationName = 'Vercel' | 'Netlify' | 'GitHub' +export type Integration = { + id: string + integration: { + id: string + name: 'Vercel' | 'Netlify' | 'GitHub' + } + added_by: addedBy + created_at: string + updated_at: string + connections: IntegrationProjectConnection[] | [] + organization: { + slug: string + } + metadata?: { + vercelTeam?: string + gitHubConnectionOwner?: string + } +} diff --git a/studio/data/integrations/keys.ts b/studio/data/integrations/keys.ts index 7164ad8068f..c099d9d7783 100644 --- a/studio/data/integrations/keys.ts +++ b/studio/data/integrations/keys.ts @@ -1,5 +1,7 @@ export const integrationKeys = { - list: (orgSlug: string | undefined) => ['organizations', orgSlug, 'integrations'] as const, + integrationsListWithOrg: (orgSlug: string | undefined) => + ['organizations', orgSlug, 'integrations'] as const, + integrationsList: () => ['organizations', 'integrations'] as const, vercelProjectList: (organization_integration_id: string | undefined) => ['organizations', organization_integration_id, 'vercel-projects'] as const, vercelConnectionsList: (organization_integration_id: string | undefined) => diff --git a/studio/data/integrations/vercel-integration-create-mutation.ts b/studio/data/integrations/vercel-integration-create-mutation.ts index 9165c33df2d..685ee4a9545 100644 --- a/studio/data/integrations/vercel-integration-create-mutation.ts +++ b/studio/data/integrations/vercel-integration-create-mutation.ts @@ -1,6 +1,7 @@ -import { useMutation, UseMutationOptions } from '@tanstack/react-query' +import { useMutation, UseMutationOptions, useQueryClient } from '@tanstack/react-query' import { post } from 'lib/common/fetch' import { API_URL } from 'lib/constants' +import { integrationKeys } from './keys' export type VercelIntegrationCreateVariables = { code: string @@ -46,11 +47,18 @@ export const useVercelIntegrationCreateMutation = ({ UseMutationOptions, 'mutationFn' > = {}) => { + const queryClient = useQueryClient() console.log('mutating') return useMutation( (vars) => createVercelIntegration(vars), { async onSuccess(data, variables, context) { + console.log('data', data, variables) + await Promise.all([ + queryClient.invalidateQueries(integrationKeys.integrationsList()), + queryClient.invalidateQueries(integrationKeys.integrationsListWithOrg(variables.orgSlug)), + queryClient.invalidateQueries(integrationKeys.vercelProjectList(data.id)), + ]) await onSuccess?.(data, variables, context) }, ...options, diff --git a/studio/pages/integrations/vercel.tsx b/studio/pages/integrations/vercel.tsx index da33fc04467..0d6bac721bb 100644 --- a/studio/pages/integrations/vercel.tsx +++ b/studio/pages/integrations/vercel.tsx @@ -1,25 +1,36 @@ -import { useMemo, useState } from 'react' +import { useEffect, useMemo, useState } from 'react' import { useParams } from 'common' import ProjectLinker from 'components/interfaces/Integrations/ProjectLinker' +import { Markdown } from 'components/interfaces/Markdown' +import IntegrationWindowLayout from 'components/layouts/IntegrationWindowLayout' +import { ScaffoldContainer, ScaffoldDivider } from 'components/layouts/Scaffold' import OrganizationPicker from 'components/ui/OrganizationPicker' -import { useVercelIntegrationCreateMutation } from 'data/integrations/vercel-integration-create-mutation' +import { useIntegrationsQuery } from 'data/integrations/integrations-query' import { useVercelProjectsQuery } from 'data/integrations/integrations-vercel-projects-query' +import { useVercelIntegrationCreateMutation } from 'data/integrations/vercel-integration-create-mutation' import { useProjectsQuery } from 'data/projects/projects-query' import { useStore } from 'hooks' import { EMPTY_ARR } from 'lib/void' import { NextPageWithLayout, Organization } from 'types' -import { Alert, Button, IconBook, IconLifeBuoy, Input, LoadingLine, cn } from 'ui' -import IntegrationWindowLayout from 'components/layouts/IntegrationWindowLayout' -import { ScaffoldContainer, ScaffoldDivider, ScaffoldSection } from 'components/layouts/Scaffold' -import { Markdown } from 'components/interfaces/Markdown' -import { BASE_PATH } from 'lib/constants' -import { ENV_VAR_RAW_KEYS } from 'components/interfaces/Integrations/Integrations-Vercel.constants' +import { Alert, Button, IconBook, IconLifeBuoy, LoadingLine } from 'ui' +import { useRouter } from 'next/router' const VercelIntegration: NextPageWithLayout = () => { + const router = useRouter() + + useEffect(() => { + router.push({ pathname: '/integrations/vercel/install', query: router.query }) + }, [router]) + + /** + * + * remove everything here + */ const { ui } = useStore() - const { code, configurationId, next, teamId, source } = useParams() + const { code, configurationId, next, teamId, source, externalId } = useParams() + const params = useParams() const [selectedOrg, setSelectedOrg] = useState(null) const [organizationIntegrationId, setOrganizationIntegrationId] = useState(null) @@ -29,6 +40,9 @@ const VercelIntegration: NextPageWithLayout = () => { }, }) + console.log('params', params) + console.log('externalId', externalId) + function onInstall() { const orgSlug = selectedOrg?.slug if (!orgSlug) { @@ -65,6 +79,7 @@ const VercelIntegration: NextPageWithLayout = () => { const { data: supabaseProjectsData } = useProjectsQuery({ enabled: organizationIntegrationId !== null, }) + const supabaseProjects = useMemo( () => supabaseProjectsData diff --git a/studio/pages/integrations/vercel/[slug]/new-project.tsx b/studio/pages/integrations/vercel/[slug]/new-project.tsx new file mode 100644 index 00000000000..1e7d6e3e016 --- /dev/null +++ b/studio/pages/integrations/vercel/[slug]/new-project.tsx @@ -0,0 +1,334 @@ +import { useParams } from 'common' +import { Markdown } from 'components/interfaces/Markdown' +import IntegrationWindowLayout from 'components/layouts/IntegrationWindowLayout' +import { ScaffoldContainer, ScaffoldDivider } from 'components/layouts/Scaffold' +import PasswordStrengthBar from 'components/ui/PasswordStrengthBar' +import { useIntegrationConnectionsCreateMutation } from 'data/integrations/integration-connections-create-mutation' +import { useIntegrationsQuery } from 'data/integrations/integrations-query' +import { useVercelProjectsQuery } from 'data/integrations/integrations-vercel-projects-query' +import { Integration } from 'data/integrations/integrations.types' +import { useOrganizationsQuery } from 'data/organizations/organizations-query' +import generator from 'generate-password' +import { useStore } from 'hooks' +import { post } from 'lib/common/fetch' +import { + API_URL, + AWS_REGIONS, + DEFAULT_MINIMUM_PASSWORD_STRENGTH, + PRICING_TIER_PRODUCT_IDS, + PROVIDERS, +} from 'lib/constants' +import { passwordStrength } from 'lib/helpers' +import { debounce } from 'lodash' +import { useRouter } from 'next/router' +import { ChangeEvent, useRef, useState } from 'react' +import { NextPageWithLayout } from 'types' +import { Alert, Button, IconBook, IconLifeBuoy, Input, Listbox, LoadingLine } from 'ui' + +const VercelIntegration: NextPageWithLayout = () => { + const [loading, setLoading] = useState(false) + + return ( + <> +
    + + + <> + +

    New project

    + <> + + setLoading(e)} /> + +
    + + + + + + + + +
    + +
    + Docs +
    +
    + Support +
    +
    + + ) +} + +VercelIntegration.getLayout = (page) => {page} + +const CreateProject = ({ setLoading }: { setLoading: (e: boolean) => void }) => { + const router = useRouter() + const { ui } = useStore() + const [projectName, setProjectName] = useState('') + const [dbPass, setDbPass] = useState('') + const [passwordStrengthMessage, setPasswordStrengthMessage] = useState('') + const [passwordStrengthScore, setPasswordStrengthScore] = useState(-1) + const [dbRegion, setDbRegion] = useState(PROVIDERS.AWS.default_region) + // const [loading, setLoading] = useState(false) + const delayedCheckPasswordStrength = useRef( + debounce((value: string) => checkPasswordStrength(value), 300) + ).current + + const { configurationId, next, currentProjectId: foreignProjectId } = useParams() + + const { mutateAsync: createConnections, isLoading: isLoadingCreateConnections } = + useIntegrationConnectionsCreateMutation({}) + + const { data: organizationData, isLoading: isLoadingOrganizationsQuery } = useOrganizationsQuery() + const { slug } = router.query + + console.log('slug') + + const organization = organizationData?.find((x) => x.slug === slug) + + /** + * array of integrations installed + */ + const { data: integrationData, isLoading: integrationDataLoading } = useIntegrationsQuery({}) + + /** + * the vercel integration installed for organization chosen + */ + const organizationIntegration: Integration | undefined = integrationData?.find( + (x) => x.organization.slug === slug + ) + + /** + * Vercel projects available for this integration + */ + const { data: vercelProjects } = useVercelProjectsQuery( + { + organization_integration_id: organizationIntegration?.id, + }, + { enabled: organizationIntegration !== undefined } + ) + + console.log('vercelProjects near top', vercelProjects) + + const canSubmit = + projectName != '' && + passwordStrengthScore >= DEFAULT_MINIMUM_PASSWORD_STRENGTH && + dbRegion != undefined + + function onProjectNameChange(e: ChangeEvent) { + e.target.value = e.target.value.replace(/\./g, '') + setProjectName(e.target.value) + } + + function onDbPassChange(e: ChangeEvent) { + const value = e.target.value + setDbPass(value) + if (value == '') { + setPasswordStrengthScore(-1) + setPasswordStrengthMessage('') + } else delayedCheckPasswordStrength(value) + } + + async function checkPasswordStrength(value: string) { + const { message, strength } = await passwordStrength(value) + setPasswordStrengthScore(strength) + setPasswordStrengthMessage(message) + } + + function generateStrongPassword() { + const password = generator.generate({ + length: 16, + numbers: true, + uppercase: true, + }) + + setDbPass(password) + delayedCheckPasswordStrength(password) + } + + async function createSupabaseProject(dbSql?: string) { + const data = { + cloud_provider: PROVIDERS.AWS.id, // hardcoded for DB instances to be under AWS + org_id: organization?.id, + name: projectName, + db_pass: dbPass, + db_region: dbRegion, + // db_sql: dbSql || '', + db_pricing_tier_id: PRICING_TIER_PRODUCT_IDS.FREE, + // auth_site_url: _store.selectedVercelProjectUrl, + vercel_configuration_id: configurationId, + } + const project = await post(`${API_URL}/projects`, data) + return { ...project, db_host: `db.${project.ref}.supabase.co`, db_password: dbPass } + } + + async function onCreateProject() { + setLoading(true) + + if (!organizationIntegration) { + console.error('No organizationIntegration set') + return + } + + if (!foreignProjectId) { + console.error('No foreignProjectId ID set') + return + } + + if (!configurationId) { + console.error('No configurationId ID set') + return + } + + try { + const response = await createSupabaseProject() + // dbSql + + if (response.error) { + setLoading(false) + ui.setNotification({ + category: 'error', + message: `Failed to create project: ${response.error.message}`, + }) + return + } + + const project = response + + console.log('vercelProjects before projectDetails', vercelProjects) + const projectDetails = vercelProjects?.find((x) => x.id === foreignProjectId) + + console.log('projectDetails', projectDetails) + console.log(project) + console.log('supabase_project_ref', project.ref) + + // Introduce a wait of 10 seconds + try { + await new Promise((resolve) => setTimeout(resolve, 10000)) + } catch (error) { + console.error('An error occurred during the delay:', error) + } + + // Wrap the createConnections function call in a try-catch block + try { + await createConnections({ + organizationIntegrationId: organizationIntegration?.id, + connection: { + foreign_project_id: foreignProjectId, + supabase_project_ref: project.ref, + metadata: { + ...projectDetails, + supabaseConfig: { + projectEnvVars: { + write: true, + }, + }, + }, + }, + orgSlug: ui.selectedOrganization?.slug, + }) + } catch (error) { + console.error('An error occurred during createConnections:', error) + } + + // const query = new URLSearchParams(_store.queryParams).toString() + // router.push(`/vercel/complete?${query}`) + + if (next) { + window.location.href = next + } + } catch (error) { + console.error('Error', error) + setLoading(false) + } + } + + return ( +
    +

    Project details for integration

    +
    + +
    +
    + 0} + onChange={onDbPassChange} + descriptionText={ + + } + /> +
    +
    +
    + setDbRegion(region)} + descriptionText="Select a region close to your users for the best performance." + > + {Object.keys(AWS_REGIONS).map((option: string, i) => { + const label = Object.values(AWS_REGIONS)[i] + return ( + ( + region icon + )} + > + {label} + + ) + })} + +
    +
    +
    + +
    + {/* */} +
    + ) +} + +export default VercelIntegration diff --git a/studio/pages/integrations/vercel/install.tsx b/studio/pages/integrations/vercel/install.tsx new file mode 100644 index 00000000000..bac48b22523 --- /dev/null +++ b/studio/pages/integrations/vercel/install.tsx @@ -0,0 +1,248 @@ +import { useParams } from 'common' +import { Markdown } from 'components/interfaces/Markdown' +import IntegrationWindowLayout from 'components/layouts/IntegrationWindowLayout' +import { ScaffoldContainer, ScaffoldDivider } from 'components/layouts/Scaffold' +import { useIntegrationsQuery } from 'data/integrations/integrations-query' +import { IntegrationName } from 'data/integrations/integrations.types' +import { useVercelIntegrationCreateMutation } from 'data/integrations/vercel-integration-create-mutation' +import { useOrganizationsQuery } from 'data/organizations/organizations-query' +import { useStore } from 'hooks' +import { useRouter } from 'next/router' +import { useState } from 'react' +import { useVercelIntegrationInstallationState } from 'state/vercel-integration-installation' +import { NextPageWithLayout, Organization } from 'types' +import { Alert, Badge, Button, IconBook, IconHexagon, IconLifeBuoy, Listbox, LoadingLine } from 'ui' + +/** + * Organization type with `installationInstalled` added + */ +interface OrganizationsResponseWithInstalledData extends Organization { + installationInstalled?: boolean +} + +const VercelIntegration: NextPageWithLayout = () => { + const router = useRouter() + const { ui } = useStore() + const { code, configurationId, next, teamId, source, externalId } = useParams() + const [selectedOrg, setSelectedOrg] = useState(null) + const [organizationIntegrationId, setOrganizationIntegrationId] = useState(null) + + const snapshot = useVercelIntegrationInstallationState() + + /** + * array of integrations installed on all + */ + const { data: integrationData, isLoading: integrationDataLoading } = useIntegrationsQuery({}) + + const { data, isLoading: isLoadingOrganizationsQuery } = useOrganizationsQuery({ + onSuccess(organizations) { + const firstOrg = organizations?.[0] + if (firstOrg && selectedOrg === null) { + setSelectedOrg(firstOrg) + snapshot.setSelectedOrganizationSlug(firstOrg.slug) + } + }, + }) + + /** + * A flat array of org slugs that have integration installed + */ + const flatInstalledConnectionsIds = + integrationData && integrationData.length > 0 + ? integrationData?.map((x) => x.organization.slug) + : [] + + /** + * Organizations with extra `installationInstalled` attribute + * Used to show label/badge and allow/disallow installing + */ + const organizationsWithInstalledData: OrganizationsResponseWithInstalledData[] = data + ? data.map((org) => { + return { + ...org, + installationInstalled: flatInstalledConnectionsIds.includes(org.slug) ? true : false, + } + }) + : [] + + const { mutate, isLoading: isLoadingVercelIntegrationCreateMutation } = + useVercelIntegrationCreateMutation({ + onSuccess({ id }) { + setOrganizationIntegrationId(id) + }, + }) + + // console.log('params', params) + // console.log('externalId', externalId) + + function onInstall() { + const orgSlug = selectedOrg?.slug + if (!orgSlug) { + return ui.setNotification({ category: 'error', message: 'Please select an organization' }) + } + + if (!code) { + return ui.setNotification({ category: 'error', message: 'Vercel code missing' }) + } + + if (!configurationId) { + return ui.setNotification({ category: 'error', message: 'Vercel Configuration ID missing' }) + } + + if (!source) { + return ui.setNotification({ + category: 'error', + message: 'Vercel Configuration source missing', + }) + } + + const metadata = {} + + if (!flatInstalledConnectionsIds.includes(orgSlug)) { + mutate({ + code, + configurationId, + orgSlug, + metadata, + source, + teamId: teamId, + }) + } + + router.push({ pathname: `/integrations/vercel/${orgSlug}/new-project`, query: router.query }) + } + + const dataLoading = isLoadingVercelIntegrationCreateMutation || isLoadingOrganizationsQuery + + return ( + <> +
    + + {organizationIntegrationId === null && ( + <> + +

    Choose organization

    + <> + + +
    + +
    + +
    + + + + + + + )} + + +
    + +
    + Docs +
    +
    + Support +
    +
    + + ) +} + +VercelIntegration.getLayout = (page) => {page} + +export interface OrganizationPickerProps { + label?: string + onSelectedOrgChange?: (org: Organization) => void + integrationName: IntegrationName + dataLoading: boolean + organizationsWithInstalledData: OrganizationsResponseWithInstalledData[] +} + +const OrganizationPicker = ({ + label = 'Choose an organization', + onSelectedOrgChange, + integrationName, + dataLoading, + organizationsWithInstalledData, +}: OrganizationPickerProps) => { + const { ui } = useStore() + const [selectedOrg, setSelectedOrg] = useState(null) + + const { data, isLoading } = useOrganizationsQuery({ + onSuccess(organizations) { + const firstOrg = organizations?.[0] + if (firstOrg && selectedOrg === null) { + setSelectedOrg(firstOrg) + onSelectedOrgChange?.(firstOrg) + } + }, + }) + + function _onSelectedOrgChange(slug: string) { + const org = data?.find((org) => org.slug === slug) + + if (org) { + setSelectedOrg(org) + onSelectedOrgChange?.(org) + } + } + + if (dataLoading) { + return ( + + + Loading... + + + ) + } + + return ( + + {organizationsWithInstalledData?.map((org) => { + const label = ( +
    + {org.name} + {org.installationInstalled && Integration Installed} +
    + ) + return ( + } + > + {label} + + ) + })} +
    + ) +} + +export default VercelIntegration diff --git a/studio/state/vercel-integration-installation.ts b/studio/state/vercel-integration-installation.ts new file mode 100644 index 00000000000..737879f6fe1 --- /dev/null +++ b/studio/state/vercel-integration-installation.ts @@ -0,0 +1,15 @@ +import { proxy, snapshot, useSnapshot } from 'valtio' + +export const vercelIntegrationInstallationState = proxy({ + selectedOrganizationSlug: '' as string, + setSelectedOrganizationSlug: (selectedOrganizationSlug: string) => { + vercelIntegrationInstallationState.selectedOrganizationSlug = selectedOrganizationSlug + }, +}) + +export const getVercelIntegrationInstallationState = () => + snapshot(vercelIntegrationInstallationState) + +export const useVercelIntegrationInstallationState = ( + options?: Parameters[1] +) => useSnapshot(vercelIntegrationInstallationState, options) From 8459cd734d7562106cec413b0a41a1730e76283c Mon Sep 17 00:00:00 2001 From: Alaister Young Date: Fri, 23 Jun 2023 21:57:15 +1000 Subject: [PATCH 24/59] move create project to a react-query mutation --- .../data/integrations/integrations-query.ts | 8 +-- .../data/projects/project-create-mutation.ts | 61 ++++++++++++++++++ .../vercel/[slug]/new-project.tsx | 62 +++++++++---------- 3 files changed, 96 insertions(+), 35 deletions(-) create mode 100644 studio/data/projects/project-create-mutation.ts diff --git a/studio/data/integrations/integrations-query.ts b/studio/data/integrations/integrations-query.ts index c43435ff32b..a522135fa2a 100644 --- a/studio/data/integrations/integrations-query.ts +++ b/studio/data/integrations/integrations-query.ts @@ -21,10 +21,10 @@ export type IntegrationsData = Awaited> export type ProjectIntegrationConnectionsData = Awaited> export type IntegrationsError = unknown -export const useIntegrationsQuery = ( - {}: {}, - { enabled = true, ...options }: UseQueryOptions = {} -) => +export const useIntegrationsQuery = ({ + enabled = true, + ...options +}: UseQueryOptions = {}) => useQuery( integrationKeys.integrationsList(), ({ signal }) => getIntegrations({}, signal), diff --git a/studio/data/projects/project-create-mutation.ts b/studio/data/projects/project-create-mutation.ts new file mode 100644 index 00000000000..a813f4d5d64 --- /dev/null +++ b/studio/data/projects/project-create-mutation.ts @@ -0,0 +1,61 @@ +import { useMutation, UseMutationOptions, useQueryClient } from '@tanstack/react-query' +import { post } from 'lib/common/fetch' +import { API_URL, PRICING_TIER_PRODUCT_IDS, PROVIDERS } from 'lib/constants' +import { ProjectBase } from 'types' +import { projectKeys } from './keys' + +export type ProjectCreateVariables = { + name: string + organizationId: number + dbPass: string + dbRegion: string + configurationId?: string +} + +export async function createProject({ + name, + organizationId, + dbPass, + dbRegion, + configurationId, +}: ProjectCreateVariables) { + const response = await post(`${API_URL}/projects`, { + cloud_provider: PROVIDERS.AWS.id, // hardcoded for DB instances to be under AWS + org_id: organizationId, + name, + db_pass: dbPass, + db_region: dbRegion, + // db_sql: dbSql || '', + db_pricing_tier_id: PRICING_TIER_PRODUCT_IDS.FREE, + // auth_site_url: _store.selectedVercelProjectUrl, + vercel_configuration_id: configurationId, + }) + if (response.error) { + throw response.error + } + + return response as ProjectBase +} + +type ProjectCreateData = Awaited> + +export const useProjectCreateMutation = ({ + onSuccess, + ...options +}: Omit< + UseMutationOptions, + 'mutationFn' +> = {}) => { + const queryClient = useQueryClient() + + return useMutation( + (vars) => createProject(vars), + { + async onSuccess(data, variables, context) { + await queryClient.invalidateQueries(projectKeys.list()), + await onSuccess?.(data, variables, context) + }, + ...options, + } + ) +} diff --git a/studio/pages/integrations/vercel/[slug]/new-project.tsx b/studio/pages/integrations/vercel/[slug]/new-project.tsx index 1e7d6e3e016..c9bf6929328 100644 --- a/studio/pages/integrations/vercel/[slug]/new-project.tsx +++ b/studio/pages/integrations/vercel/[slug]/new-project.tsx @@ -1,3 +1,7 @@ +import { debounce } from 'lodash' +import { useRouter } from 'next/router' +import { ChangeEvent, useRef, useState } from 'react' + import { useParams } from 'common' import { Markdown } from 'components/interfaces/Markdown' import IntegrationWindowLayout from 'components/layouts/IntegrationWindowLayout' @@ -8,20 +12,11 @@ import { useIntegrationsQuery } from 'data/integrations/integrations-query' import { useVercelProjectsQuery } from 'data/integrations/integrations-vercel-projects-query' import { Integration } from 'data/integrations/integrations.types' import { useOrganizationsQuery } from 'data/organizations/organizations-query' +import { useProjectCreateMutation } from 'data/projects/project-create-mutation' import generator from 'generate-password' import { useStore } from 'hooks' -import { post } from 'lib/common/fetch' -import { - API_URL, - AWS_REGIONS, - DEFAULT_MINIMUM_PASSWORD_STRENGTH, - PRICING_TIER_PRODUCT_IDS, - PROVIDERS, -} from 'lib/constants' +import { AWS_REGIONS, DEFAULT_MINIMUM_PASSWORD_STRENGTH, PROVIDERS } from 'lib/constants' import { passwordStrength } from 'lib/helpers' -import { debounce } from 'lodash' -import { useRouter } from 'next/router' -import { ChangeEvent, useRef, useState } from 'react' import { NextPageWithLayout } from 'types' import { Alert, Button, IconBook, IconLifeBuoy, Input, Listbox, LoadingLine } from 'ui' @@ -94,7 +89,7 @@ const CreateProject = ({ setLoading }: { setLoading: (e: boolean) => void }) => /** * array of integrations installed */ - const { data: integrationData, isLoading: integrationDataLoading } = useIntegrationsQuery({}) + const { data: integrationData, isLoading: integrationDataLoading } = useIntegrationsQuery() /** * the vercel integration installed for organization chosen @@ -151,19 +146,23 @@ const CreateProject = ({ setLoading }: { setLoading: (e: boolean) => void }) => delayedCheckPasswordStrength(password) } + const { mutateAsync: createProject } = useProjectCreateMutation() + async function createSupabaseProject(dbSql?: string) { - const data = { - cloud_provider: PROVIDERS.AWS.id, // hardcoded for DB instances to be under AWS - org_id: organization?.id, - name: projectName, - db_pass: dbPass, - db_region: dbRegion, - // db_sql: dbSql || '', - db_pricing_tier_id: PRICING_TIER_PRODUCT_IDS.FREE, - // auth_site_url: _store.selectedVercelProjectUrl, - vercel_configuration_id: configurationId, + if (!organization) { + throw new Error('No organization set') } - const project = await post(`${API_URL}/projects`, data) + + const project = await createProject({ + organizationId: organization.id, + name: projectName, + dbPass, + dbRegion, + configurationId, + }) + + console.log('raw project:', project) + return { ...project, db_host: `db.${project.ref}.supabase.co`, db_password: dbPass } } @@ -189,14 +188,14 @@ const CreateProject = ({ setLoading }: { setLoading: (e: boolean) => void }) => const response = await createSupabaseProject() // dbSql - if (response.error) { - setLoading(false) - ui.setNotification({ - category: 'error', - message: `Failed to create project: ${response.error.message}`, - }) - return - } + // if (response.error) { + // setLoading(false) + // ui.setNotification({ + // category: 'error', + // message: `Failed to create project: ${response.error.message}`, + // }) + // return + // } const project = response @@ -209,6 +208,7 @@ const CreateProject = ({ setLoading }: { setLoading: (e: boolean) => void }) => // Introduce a wait of 10 seconds try { + console.log('waiting for 10 seconds') await new Promise((resolve) => setTimeout(resolve, 10000)) } catch (error) { console.error('An error occurred during the delay:', error) From 0ce58b83da5ea416c58759ce9fef2bb9d5a2213b Mon Sep 17 00:00:00 2001 From: Alaister Young Date: Fri, 23 Jun 2023 22:32:14 +1000 Subject: [PATCH 25/59] wait for project to be created before creating connections --- .../vercel/[slug]/new-project.tsx | 167 ++++++++++-------- 1 file changed, 91 insertions(+), 76 deletions(-) diff --git a/studio/pages/integrations/vercel/[slug]/new-project.tsx b/studio/pages/integrations/vercel/[slug]/new-project.tsx index c9bf6929328..538d2d3381a 100644 --- a/studio/pages/integrations/vercel/[slug]/new-project.tsx +++ b/studio/pages/integrations/vercel/[slug]/new-project.tsx @@ -17,8 +17,9 @@ import generator from 'generate-password' import { useStore } from 'hooks' import { AWS_REGIONS, DEFAULT_MINIMUM_PASSWORD_STRENGTH, PROVIDERS } from 'lib/constants' import { passwordStrength } from 'lib/helpers' -import { NextPageWithLayout } from 'types' +import { NextPageWithLayout, ProjectBase } from 'types' import { Alert, Button, IconBook, IconLifeBuoy, Input, Listbox, LoadingLine } from 'ui' +import { useProjectApiQuery } from 'data/config/project-api-query' const VercelIntegration: NextPageWithLayout = () => { const [loading, setLoading] = useState(false) @@ -33,7 +34,7 @@ const VercelIntegration: NextPageWithLayout = () => {

    New project

    <> - setLoading(e)} /> + setLoading(e)} /> @@ -61,7 +62,13 @@ const VercelIntegration: NextPageWithLayout = () => { VercelIntegration.getLayout = (page) => {page} -const CreateProject = ({ setLoading }: { setLoading: (e: boolean) => void }) => { +const CreateProject = ({ + loading, + setLoading, +}: { + loading: boolean + setLoading: (e: boolean) => void +}) => { const router = useRouter() const { ui } = useStore() const [projectName, setProjectName] = useState('') @@ -148,27 +155,8 @@ const CreateProject = ({ setLoading }: { setLoading: (e: boolean) => void }) => const { mutateAsync: createProject } = useProjectCreateMutation() - async function createSupabaseProject(dbSql?: string) { - if (!organization) { - throw new Error('No organization set') - } - - const project = await createProject({ - organizationId: organization.id, - name: projectName, - dbPass, - dbRegion, - configurationId, - }) - - console.log('raw project:', project) - - return { ...project, db_host: `db.${project.ref}.supabase.co`, db_password: dbPass } - } - + const [newProjectRef, setNewProjectRef] = useState(undefined) async function onCreateProject() { - setLoading(true) - if (!organizationIntegration) { console.error('No organizationIntegration set') return @@ -184,69 +172,96 @@ const CreateProject = ({ setLoading }: { setLoading: (e: boolean) => void }) => return } + setLoading(true) + try { - const response = await createSupabaseProject() - // dbSql - - // if (response.error) { - // setLoading(false) - // ui.setNotification({ - // category: 'error', - // message: `Failed to create project: ${response.error.message}`, - // }) - // return - // } - - const project = response - - console.log('vercelProjects before projectDetails', vercelProjects) - const projectDetails = vercelProjects?.find((x) => x.id === foreignProjectId) - - console.log('projectDetails', projectDetails) - console.log(project) - console.log('supabase_project_ref', project.ref) - - // Introduce a wait of 10 seconds - try { - console.log('waiting for 10 seconds') - await new Promise((resolve) => setTimeout(resolve, 10000)) - } catch (error) { - console.error('An error occurred during the delay:', error) + if (!organization) { + throw new Error('No organization set') } - // Wrap the createConnections function call in a try-catch block + let project: ProjectBase + try { - await createConnections({ - organizationIntegrationId: organizationIntegration?.id, - connection: { - foreign_project_id: foreignProjectId, - supabase_project_ref: project.ref, - metadata: { - ...projectDetails, - supabaseConfig: { - projectEnvVars: { - write: true, - }, - }, - }, - }, - orgSlug: ui.selectedOrganization?.slug, + project = await createProject({ + organizationId: organization.id, + name: projectName, + dbPass, + dbRegion, + configurationId, }) - } catch (error) { - console.error('An error occurred during createConnections:', error) - } - // const query = new URLSearchParams(_store.queryParams).toString() - // router.push(`/vercel/complete?${query}`) - - if (next) { - window.location.href = next + setNewProjectRef(project.ref) + } catch (error: any) { + setLoading(false) + ui.setNotification({ + category: 'error', + message: `Failed to create project: ${error.message}`, + }) + return } } catch (error) { console.error('Error', error) setLoading(false) } } + const isInstallingRef = useRef(false) + + // Wait for the new project to be created before creating the connection + useProjectApiQuery( + { projectRef: newProjectRef }, + { + enabled: newProjectRef !== undefined, + // refetch until the project is created + refetchInterval: (data) => { + return (data?.autoApiService.service_api_keys.length ?? 0) > 0 ? false : 1000 + }, + async onSuccess(data) { + const isReady = data.autoApiService.service_api_keys.length > 0 + + if ( + !isReady || + !organizationIntegration || + !foreignProjectId || + !newProjectRef || + isInstallingRef.current + ) { + return + } + isInstallingRef.current = true + + const projectDetails = vercelProjects?.find((x) => x.id === foreignProjectId) + + // Wrap the createConnections function call in a try-catch block + try { + await createConnections({ + organizationIntegrationId: organizationIntegration?.id, + connection: { + foreign_project_id: foreignProjectId, + supabase_project_ref: newProjectRef, + metadata: { + ...projectDetails, + supabaseConfig: { + projectEnvVars: { + write: true, + }, + }, + }, + }, + orgSlug: ui.selectedOrganization?.slug, + }) + } catch (error) { + console.error('An error occurred during createConnections:', error) + return + } + + setLoading(false) + + if (next) { + window.location.href = next + } + }, + } + ) return (
    @@ -317,8 +332,8 @@ const CreateProject = ({ setLoading }: { setLoading: (e: boolean) => void }) => - -
    - - -
    - ) -} - -export default ProjectLinker - -interface ProjectLinkerItemProps { - foreignProjects: Project[] - supabaseProjects: Project[] - foreignProjectId: string - setForeignProjectId: (id: string) => void - supabaseProjectId: string - setSupabaseProjectId: (id: string) => void - removeConnection: () => void - canRemove: boolean - connections: any[] -} - -const ProjectLinkerItem = ({ - foreignProjects, - supabaseProjects, - foreignProjectId, - setForeignProjectId, - supabaseProjectId, - setSupabaseProjectId, - removeConnection, - canRemove, -}: ProjectLinkerItemProps) => { - console.log(supabaseProjectId) - return ( -
  • -
    -
    - -
    -
    - -
    -
    - - - Choose a project - - - {foreignProjects.map((project) => ( - { - return ( - <> - {!project?.framework ? ( - vercelIcon - ) : ( - {`icon`} - )} - - ) - }} - > - {project.name} - - ))} - -
    - - {canRemove && ( -
    -
  • - ) -} diff --git a/studio/components/interfaces/Organization/IntegrationSettings/Integration.tsx b/studio/components/interfaces/Organization/IntegrationSettings/Integration.tsx index cddef1fdb79..39b23288760 100644 --- a/studio/components/interfaces/Organization/IntegrationSettings/Integration.tsx +++ b/studio/components/interfaces/Organization/IntegrationSettings/Integration.tsx @@ -11,8 +11,9 @@ import { ScaffoldSectionContent, ScaffoldSectionDetail, } from 'components/layouts/Scaffold' -import { Integration as TIntegration } from 'data/integrations/integrations-query-org-only' +import { Integration as TIntegration } from 'data/integrations/integrations.types' import { useIntegrationsVercelInstalledConnectionDeleteMutation } from 'data/integrations/integrations-vercel-installed-connection-delete-mutation' +import { IntegrationProjectConnection } from 'data/integrations/integrations.types' import { useStore } from 'hooks' import { BASE_PATH } from 'lib/constants' import { pluralize } from 'lib/helpers' @@ -62,7 +63,7 @@ Repository connections for ${title?.toLowerCase()} const variables = { organization_integration_id: organizationIntegrationId, id: projectIntegrationId, - orgId: ui.selectedOrganization?.id, + orgSlug: ui.selectedOrganization?.slug, } deleteMutate(variables) @@ -85,63 +86,63 @@ Repository connections for ${title?.toLowerCase()}
    {integrations.length > 0 && integrations.map((integration, i) => { - console.log('integration.id', integration?.id) return (
    - + {integration.connections.length > 0 ? ( <>
      - {integration.connections.map((connection, i) => ( - - - + {integration.connections.map( + (connection: IntegrationProjectConnection, i) => ( + + + +
    + } + > +
    Refresh Enviroment Variables
    +
    + Reapply env vars in vercel.
    - } - > -
    Refresh Enviroment Variables
    -
    - Reapply env vars in vercel. -
    - - - } - onSelect={() => - handleDelete(integration.id, connection.id) - } - > - Delete - - - } - > - - - } - /> - ))} + + + } + onSelect={() => + handleDelete(integration.id, connection.id) + } + > + Delete + + + } + > + + + } + /> + ) + )} ) : ( diff --git a/studio/components/interfaces/Organization/IntegrationSettings/IntegrationGitHub.tsx b/studio/components/interfaces/Organization/IntegrationSettings/IntegrationGitHub.tsx deleted file mode 100644 index e1b92add11b..00000000000 --- a/studio/components/interfaces/Organization/IntegrationSettings/IntegrationGitHub.tsx +++ /dev/null @@ -1,95 +0,0 @@ -import { - EmptyIntegrationConnection, - IntegrationConnection, - IntegrationConnectionHeader, - IntegrationInstallation, -} from 'components/interfaces/Integrations/IntegrationPanels' -import { Markdown } from 'components/interfaces/Markdown' -import { - ScaffoldContainer, - ScaffoldSection, - ScaffoldSectionContent, - ScaffoldSectionDetail, -} from 'components/layouts/Scaffold' -import { Integration as TIntegration } from 'data/integrations/integrations-query-org-only' -import { pluralize } from 'lib/helpers' -import { EMPTY_ARR } from 'lib/void' -import { useMemo } from 'react' - -export interface IntegrationProps { - title: string - orgName?: string - description?: string - note?: string - integrations?: TIntegration[] -} - -const Integration = ({ - title, - orgName, - description, - note, - integrations = EMPTY_ARR, -}: IntegrationProps) => { - const projectConnections = useMemo( - () => integrations.flatMap((integration) => integration.connections), - [integrations] - ) - - return ( - <> - - - -

    {title}

    -
    - - {description !== undefined && ( - - )} -
    - {integrations.length > 0 && - integrations.map((integraton, i) => { - return ( -
    - - {integraton.connections.length > 0 && ( - <> - - -
      - {integraton.connections.map((connection, i) => ( - - ))} -
    - - - Add new project connection - - - )} -
    - ) - })} -
    - - -
    -
    -
    - - ) -} - -export default Integration diff --git a/studio/components/interfaces/Organization/IntegrationSettings/SidePanelGitHubRepoSelection.tsx b/studio/components/interfaces/Organization/IntegrationSettings/SidePanelGitHubRepoSelection.tsx index 9331baf205d..4b978dd0ae2 100644 --- a/studio/components/interfaces/Organization/IntegrationSettings/SidePanelGitHubRepoSelection.tsx +++ b/studio/components/interfaces/Organization/IntegrationSettings/SidePanelGitHubRepoSelection.tsx @@ -1,26 +1,27 @@ import { useParams } from 'common' import { Markdown } from 'components/interfaces/Markdown' -import { useIntegrationsQuery } from 'data/integrations/integrations-query-org-only' +// import { useIntegrationsQuery } from 'data/integrations/integrations-query-org-only' import { useStore } from 'hooks' import { observer } from 'mobx-react-lite' import { useGithubConnectionConfigPanelSnapshot } from 'state/github-connection-config-panel' import { IconGitHub, IconSearch, Input, Select, SidePanel } from 'ui' +// TO DO + const GitHubRepoSelection = () => { const { ui } = useStore() const { slug } = useParams() - const { data } = useIntegrationsQuery({ orgSlug: slug }) + // const { data } = useIntegrationsQuery({ orgSlug: slug }) const githubConnectionConfigPanelSnapshot = useGithubConnectionConfigPanelSnapshot() - const githubIntegrations = data?.filter((integration) => integration.type === 'GITHUB') - return ( githubConnectionConfigPanelSnapshot.setVisible(false)} + visible={false} + // visible={githubConnectionConfigPanelSnapshot.visible} + // onCancel={() => githubConnectionConfigPanelSnapshot.setVisible(false)} >
    diff --git a/studio/components/interfaces/Organization/IntegrationSettings/SidePanelVercelProjectLinker.tsx b/studio/components/interfaces/Organization/IntegrationSettings/SidePanelVercelProjectLinker.tsx index 9e86712d86c..606857d6f5f 100644 --- a/studio/components/interfaces/Organization/IntegrationSettings/SidePanelVercelProjectLinker.tsx +++ b/studio/components/interfaces/Organization/IntegrationSettings/SidePanelVercelProjectLinker.tsx @@ -1,6 +1,7 @@ import { useParams } from 'common' import ProjectLinker from 'components/interfaces/Integrations/ProjectLinker' import { Markdown } from 'components/interfaces/Markdown' +import { Project } from 'data/config/project-api-query' import { useOrgIntegrationsQuery } from 'data/integrations/integrations-query-org-only' import { useVercelProjectConnectionsQuery } from 'data/integrations/integrations-vercel-installed-connections-query' import { useVercelProjectsQuery } from 'data/integrations/integrations-vercel-projects-query' @@ -49,7 +50,8 @@ const SidePanelVercelProjectLinker = () => { () => supabaseProjectsData ?.filter((project) => project.organization_id === selectedOrg?.id) - .map((project) => ({ id: project.id.toString(), name: project.name })) ?? EMPTY_ARR, + .map((project) => ({ id: project.id.toString(), name: project.name, ref: project.ref })) ?? + EMPTY_ARR, [selectedOrg?.id, supabaseProjectsData] ) @@ -62,8 +64,6 @@ const SidePanelVercelProjectLinker = () => { const { data: vercelProjectsData } = useVercelProjectsQuery( { - orgId: selectedOrg?.id, - orgSlug: selectedOrg?.slug, organization_integration_id: organizationIntegrationId, }, { enabled: organizationIntegrationId !== null } diff --git a/studio/components/ui/OrganizationPicker.tsx b/studio/components/ui/OrganizationPicker.tsx index 4b89efa3b3e..7f5da7a550e 100644 --- a/studio/components/ui/OrganizationPicker.tsx +++ b/studio/components/ui/OrganizationPicker.tsx @@ -106,6 +106,7 @@ const OrganizationPicker = ({ } > diff --git a/studio/data/integrations/integrations-github-repos-query.ts b/studio/data/integrations/integrations-github-repos-query.ts index 6498b583b2b..753d196b6f2 100644 --- a/studio/data/integrations/integrations-github-repos-query.ts +++ b/studio/data/integrations/integrations-github-repos-query.ts @@ -131,7 +131,7 @@ export const useIntegrationsQuery = ( { enabled = true, ...options }: UseQueryOptions = {} ) => useQuery( - integrationKeys.list(orgSlug), + integrationKeys.integrationsList(), ({ signal }) => getIntegrations({ orgSlug }, signal), { enabled: enabled && typeof orgSlug !== 'undefined', ...options } ) diff --git a/studio/data/integrations/integrations-vercel-installed-connection-delete-mutation.ts b/studio/data/integrations/integrations-vercel-installed-connection-delete-mutation.ts index dbcac04ee61..2f33b13ad9b 100644 --- a/studio/data/integrations/integrations-vercel-installed-connection-delete-mutation.ts +++ b/studio/data/integrations/integrations-vercel-installed-connection-delete-mutation.ts @@ -5,9 +5,9 @@ import { UserContent } from 'types' import { integrationKeys } from './keys' type DeleteVariables = { - organization_integration_id: string id: string - orgId: number | undefined + organization_integration_id: string + orgSlug: string | undefined } export async function deleteConnection( @@ -40,7 +40,13 @@ export const useIntegrationsVercelInstalledConnectionDeleteMutation = ({ { async onSuccess(data, variables, context) { console.log('variables in mutate delete onSuccess', variables) - await Promise.all([queryClient.invalidateQueries(integrationKeys.list(variables.orgId))]) + await Promise.all([ + queryClient.invalidateQueries(integrationKeys.integrationsList()), + queryClient.invalidateQueries(integrationKeys.integrationsListWithOrg(variables.orgSlug)), + queryClient.invalidateQueries( + integrationKeys.vercelProjectList(variables.organization_integration_id) + ), + ]) await onSuccess?.(data, variables, context) }, ...options, diff --git a/studio/data/integrations/integrations.types.ts b/studio/data/integrations/integrations.types.ts index c109395510d..e0a84f9fa78 100644 --- a/studio/data/integrations/integrations.types.ts +++ b/studio/data/integrations/integrations.types.ts @@ -115,24 +115,23 @@ export type VercelGitLink = } export type Imetadata = { - metadata: { - id: string - supabaseConfig: { - projectEnvVars: { - write: boolean - } + id: string + supabaseConfig: { + projectEnvVars: { + write: boolean } - link?: VercelGitLink - name: string - framework: VercelFramework } + link?: VercelGitLink + name: string + framework: VercelFramework } + export type IntegrationProjectConnection = { id: string - created_at: string + inserted_at: string updated_at: string added_by: addedBy - supabase_project_id: string + supabase_project_ref: string foreign_project_id: string organization_integration_id: string metadata: Imetadata @@ -158,14 +157,16 @@ type addedBy = userDetails type updatedBy = userDetails export type IntegrationName = 'Vercel' | 'Netlify' | 'GitHub' +export type VercelAcccountType = 'team' | 'personal' +export type VercelSource = 'marketplace' | 'deploy button' + export type Integration = { id: string integration: { - id: string - name: 'Vercel' | 'Netlify' | 'GitHub' + name: IntegrationName } added_by: addedBy - created_at: string + inserted_at: string updated_at: string connections: IntegrationProjectConnection[] | [] organization: { @@ -174,5 +175,13 @@ export type Integration = { metadata?: { vercelTeam?: string gitHubConnectionOwner?: string + account: { + name: string + type: VercelAcccountType + avatar: string + source: VercelSource + owner_id: string + } + configuration_id: string } } diff --git a/studio/pages/integrations/vercel.tsx b/studio/pages/integrations/vercel.tsx index 0d6bac721bb..a156f70e419 100644 --- a/studio/pages/integrations/vercel.tsx +++ b/studio/pages/integrations/vercel.tsx @@ -24,171 +24,7 @@ const VercelIntegration: NextPageWithLayout = () => { router.push({ pathname: '/integrations/vercel/install', query: router.query }) }, [router]) - /** - * - * remove everything here - */ - const { ui } = useStore() - const { code, configurationId, next, teamId, source, externalId } = useParams() - const params = useParams() - const [selectedOrg, setSelectedOrg] = useState(null) - const [organizationIntegrationId, setOrganizationIntegrationId] = useState(null) - - const { mutate, isLoading } = useVercelIntegrationCreateMutation({ - onSuccess({ id }) { - setOrganizationIntegrationId(id) - }, - }) - - console.log('params', params) - console.log('externalId', externalId) - - function onInstall() { - const orgSlug = selectedOrg?.slug - if (!orgSlug) { - return ui.setNotification({ category: 'error', message: 'Please select an organization' }) - } - - if (!code) { - return ui.setNotification({ category: 'error', message: 'Vercel code missing' }) - } - - if (!configurationId) { - return ui.setNotification({ category: 'error', message: 'Vercel Configuration ID missing' }) - } - - if (!source) { - return ui.setNotification({ - category: 'error', - message: 'Vercel Configuration source missing', - }) - } - - const metadata = {} - - mutate({ - code, - configurationId, - orgSlug, - metadata, - source, - teamId: teamId, - }) - } - - 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, ref: project.ref })) ?? - EMPTY_ARR, - [selectedOrg?.id, supabaseProjectsData] - ) - - const { data: vercelProjectsData } = useVercelProjectsQuery( - { - orgId: selectedOrg?.id, - orgSlug: selectedOrg?.slug, - organization_integration_id: organizationIntegrationId, - }, - { enabled: organizationIntegrationId !== null } - ) - - console.log('vercelProjectsData', vercelProjectsData) - const vercelProjects = useMemo(() => vercelProjectsData ?? EMPTY_ARR, [vercelProjectsData]) - - return ( - <> -
    - - {organizationIntegrationId === null && ( - <> - -

    Install Integration

    - <> - - -
    - -
    - -
    - - - - - - - )} - - {organizationIntegrationId !== null && ( - <> - -
    -

    - Link a Supabase project to a Vercel project -

    - -
    - {/* { - if (next) { - window.location.href = next - } - }} - /> */} - - { - if (next) { - window.location.href = next - } - }} - /> -
    - - )} - -
    - -
    - Docs -
    -
    - Support -
    -
    - - ) + return <> } VercelIntegration.getLayout = (page) => {page} diff --git a/studio/pages/integrations/vercel/[slug]/marketplace/choose-project.tsx b/studio/pages/integrations/vercel/[slug]/marketplace/choose-project.tsx index dbb54eed465..cae0c637d86 100644 --- a/studio/pages/integrations/vercel/[slug]/marketplace/choose-project.tsx +++ b/studio/pages/integrations/vercel/[slug]/marketplace/choose-project.tsx @@ -6,29 +6,24 @@ import ProjectLinker from 'components/interfaces/Integrations/ProjectLinker' import { Markdown } from 'components/interfaces/Markdown' import IntegrationWindowLayout from 'components/layouts/IntegrationWindowLayout' import { ScaffoldContainer, ScaffoldDivider } from 'components/layouts/Scaffold' +import { useOrgIntegrationsQuery } from 'data/integrations/integrations-query-org-only' import { useVercelProjectsQuery } from 'data/integrations/integrations-vercel-projects-query' -import { useVercelIntegrationCreateMutation } from 'data/integrations/vercel-integration-create-mutation' +import { useOrganizationsQuery } from 'data/organizations/organizations-query' import { useProjectsQuery } from 'data/projects/projects-query' import { useStore } from 'hooks' import { EMPTY_ARR } from 'lib/void' +import { useRouter } from 'next/router' import { NextPageWithLayout, Organization } from 'types' import { IconBook, IconLifeBuoy, LoadingLine } from 'ui' -import { useIntegrationsQuery } from 'data/integrations/integrations-github-repos-query' -import { useOrgIntegrationsQuery } from 'data/integrations/integrations-query-org-only' -import { useRouter } from 'next/router' const VercelIntegration: NextPageWithLayout = () => { - const { ui } = useStore() const router = useRouter() - const { code, configurationId, next, teamId, source, externalId } = useParams() + const { configurationId, next, organizationSlug } = useParams() const [loading, setLoading] = useState(false) - const [selectedOrg, setSelectedOrg] = useState(null) - // const [organizationIntegrationId, setOrganizationIntegrationId] = useState( - // undefined - // ) const { slug } = router.query + /** * Fetch the list of organization based integration installations for Vercel. * @@ -38,36 +33,34 @@ const VercelIntegration: NextPageWithLayout = () => { orgSlug: slug?.toString(), }) - console.log('integrationData', integrationData) + const { data, isLoading: isLoadingOrganizationsQuery } = useOrganizationsQuery({ + enabled: slug !== undefined, + }) - const organizationIntegrationId = integrationData?.find( - (x) => x.metadata?.configuration_id === configurationId - )?.id + const organization = data?.find((organization: Organization) => organization.slug === slug) - console.log('organizationIntegrationId', organizationIntegrationId) + const integration = integrationData?.find((x) => x.metadata?.configuration_id === configurationId) const { data: supabaseProjectsData } = useProjectsQuery({ - enabled: organizationIntegrationId !== null, + enabled: integration?.id !== undefined, }) const supabaseProjects = useMemo( () => supabaseProjectsData - ?.filter((project) => project.organization_id === selectedOrg?.id) + ?.filter((project) => project.organization_id === organization?.id) .map((project) => ({ id: project.id.toString(), name: project.name, ref: project.ref })) ?? EMPTY_ARR, - [selectedOrg?.id, supabaseProjectsData] + [organizationSlug, supabaseProjectsData] ) const { data: vercelProjectsData } = useVercelProjectsQuery( { - organization_integration_id: organizationIntegrationId, + organization_integration_id: integration?.id, }, - { enabled: organizationIntegrationId !== undefined } + { enabled: integration?.id !== undefined } ) - console.log('vercelProjectsData', vercelProjectsData) - const vercelProjects = useMemo(() => vercelProjectsData ?? EMPTY_ARR, [vercelProjectsData]) return ( @@ -88,7 +81,7 @@ This Supabase integration manages your envioemnt variables automatically to prov /> { @@ -96,6 +89,7 @@ This Supabase integration manages your envioemnt variables automatically to prov window.location.href = next } }} + installedConnections={integration?.connections} /> diff --git a/studio/pages/integrations/vercel/install.tsx b/studio/pages/integrations/vercel/install.tsx index 4b8dc7b38bf..72c46376e1a 100644 --- a/studio/pages/integrations/vercel/install.tsx +++ b/studio/pages/integrations/vercel/install.tsx @@ -48,15 +48,18 @@ const VercelIntegration: NextPageWithLayout = () => { */ const { data: integrationData, isLoading: integrationDataLoading } = useIntegrationsQuery({}) - const { data, isLoading: isLoadingOrganizationsQuery } = useOrganizationsQuery({ - onSuccess(organizations) { - const firstOrg = organizations?.[0] - if (firstOrg && selectedOrg === null) { - setSelectedOrg(firstOrg) - snapshot.setSelectedOrganizationSlug(firstOrg.slug) - } - }, - }) + const { data: organizationsData, isLoading: isLoadingOrganizationsQuery } = useOrganizationsQuery( + { + onSuccess(organizations) { + const firstOrg = organizations?.[0] + if (firstOrg && selectedOrg === null) { + setSelectedOrg(firstOrg) + snapshot.setSelectedOrganizationSlug(firstOrg.slug) + router.query.organizationSlug = firstOrg.slug + } + }, + } + ) /** * Flat array of org slugs that have integration installed @@ -67,14 +70,16 @@ const VercelIntegration: NextPageWithLayout = () => { ? integrationData?.map((x) => x.organization.slug) : [] + console.log('flatInstalledConnectionsIds', flatInstalledConnectionsIds) + /** * Organizations with extra `installationInstalled` attribute * * Used to show label/badge and allow/disallow installing * */ - const organizationsWithInstalledData: OrganizationsResponseWithInstalledData[] = data - ? data.map((org) => { + const organizationsWithInstalledData: OrganizationsResponseWithInstalledData[] = organizationsData + ? organizationsData.map((org) => { return { ...org, installationInstalled: flatInstalledConnectionsIds.includes(org.slug) ? true : false, @@ -91,6 +96,15 @@ const VercelIntegration: NextPageWithLayout = () => { function onInstall() { const orgSlug = selectedOrg?.slug + + const isIntegrationInstalled = organizationsWithInstalledData.find( + (x) => x.slug === orgSlug && x.installationInstalled + ) + ? true + : false + + console.log('isIntegrationInstalled', isIntegrationInstalled) + if (!orgSlug) { return ui.setNotification({ category: 'error', message: 'Please select an organization' }) } @@ -110,14 +124,15 @@ const VercelIntegration: NextPageWithLayout = () => { }) } - const metadata = {} - - if (!flatInstalledConnectionsIds.includes(orgSlug)) { + /** + * Only install if instgration hasn't already been installed + */ + if (!isIntegrationInstalled) { mutate({ code, configurationId, orgSlug, - metadata, + metadata: {}, source, teamId: teamId, }) @@ -151,7 +166,10 @@ const VercelIntegration: NextPageWithLayout = () => { { + router.query.organizationSlug = e.slug + setSelectedOrg(e) + }} dataLoading={dataLoading} />
    From b21072929edf61bac2d49c0de82f765fc992983f Mon Sep 17 00:00:00 2001 From: Alaister Young Date: Mon, 26 Jun 2023 22:36:03 +1000 Subject: [PATCH 28/59] adds basic migrations on (vercel) project creation --- .../data/projects/project-create-mutation.ts | 4 +- studio/lib/integration-utils.ts | 87 +++++++++++++++++++ .../[slug]/deploy-button/new-project.tsx | 51 ++++++++--- .../[slug]/marketplace/choose-project.tsx | 10 +-- 4 files changed, 131 insertions(+), 21 deletions(-) create mode 100644 studio/lib/integration-utils.ts diff --git a/studio/data/projects/project-create-mutation.ts b/studio/data/projects/project-create-mutation.ts index a813f4d5d64..f355ee965f4 100644 --- a/studio/data/projects/project-create-mutation.ts +++ b/studio/data/projects/project-create-mutation.ts @@ -9,6 +9,7 @@ export type ProjectCreateVariables = { organizationId: number dbPass: string dbRegion: string + dbSql?: string configurationId?: string } @@ -17,6 +18,7 @@ export async function createProject({ organizationId, dbPass, dbRegion, + dbSql, configurationId, }: ProjectCreateVariables) { const response = await post(`${API_URL}/projects`, { @@ -25,7 +27,7 @@ export async function createProject({ name, db_pass: dbPass, db_region: dbRegion, - // db_sql: dbSql || '', + db_sql: dbSql, db_pricing_tier_id: PRICING_TIER_PRODUCT_IDS.FREE, // auth_site_url: _store.selectedVercelProjectUrl, vercel_configuration_id: configurationId, diff --git a/studio/lib/integration-utils.ts b/studio/lib/integration-utils.ts new file mode 100644 index 00000000000..8336470c685 --- /dev/null +++ b/studio/lib/integration-utils.ts @@ -0,0 +1,87 @@ +import { ResponseFailure } from 'types' + +type SupaResponse = T | ResponseFailure + +async function fetchGitHub(url: string, responseJson = true): Promise> { + const response = await fetch(url) + if (!response.ok) { + return { + error: { + code: response.status, + message: response.statusText, + requestId: '', + }, + } + } + try { + return (responseJson ? await response.json() : await response.text()) as T + } catch (error: any) { + return { + error: { + message: error.message, + code: 500, + requestId: '', + }, + } + } +} + +export type File = { + name: string + download_url: string +} + +/** + * Returns the initial migration SQL from a GitHub repo. + * @param externalId An external GitHub URL for example: https://github.com/vercel/next.js/tree/canary/examples/with-supabase + */ +export async function getInitialMigrationSQLFromGitHubRepo( + externalId?: string +): Promise { + if (!externalId) return null + + const [, , , owner, repo, , branch, ...pathSegments] = externalId?.split('/') ?? [] + const path = pathSegments.join('/') + + const baseGitHubUrl = `https://api.github.com/repos/${owner}/${repo}/contents/${path}` + const supabaseFolderUrl = `${baseGitHubUrl}/supabase?ref=${branch}` + const supabaseMigrationsPath = `supabase/migrations` // TODO: read this from the `supabase/config.toml` file + const migrationsFolderUrl = `${baseGitHubUrl}/${supabaseMigrationsPath}?ref=${branch}` + + const [supabaseFilesResponse, migrationFilesResponse] = await Promise.all([ + fetchGitHub(supabaseFolderUrl), + fetchGitHub(migrationsFolderUrl), + ]) + + if ('error' in supabaseFilesResponse) { + console.warn(`Failed to fetch supabase files from GitHub: ${supabaseFilesResponse.error}`) + return null + } + if ('error' in migrationFilesResponse) { + console.warn(`Failed to fetch migration files from GitHub: ${migrationFilesResponse.error}`) + return null + } + + const seedFileUrl = supabaseFilesResponse.find((file) => file.name === 'seed.sql')?.download_url + const migrationFileDownloadUrlPromises = migrationFilesResponse + .sort((a, b) => { + // sort by name ascending + if (a.name < b.name) return -1 + if (a.name > b.name) return 1 + return 0 + }) + .map((file) => fetchGitHub(file.download_url, false)) + + const [seedFileResponse, ...migrationFileResponses] = await Promise.all([ + seedFileUrl ? fetchGitHub(seedFileUrl, false) : Promise.resolve(''), + ...migrationFileDownloadUrlPromises, + ]) + + const migrations = migrationFileResponses + .filter((response) => !(typeof response === 'object' && 'error' in response)) + .join(';') + const seed = + typeof seedFileResponse === 'object' && 'error' in seedFileResponse ? '' : seedFileResponse + + return `${migrations};${seed}` +} diff --git a/studio/pages/integrations/vercel/[slug]/deploy-button/new-project.tsx b/studio/pages/integrations/vercel/[slug]/deploy-button/new-project.tsx index 538d2d3381a..eb82bd7245f 100644 --- a/studio/pages/integrations/vercel/[slug]/deploy-button/new-project.tsx +++ b/studio/pages/integrations/vercel/[slug]/deploy-button/new-project.tsx @@ -7,6 +7,7 @@ import { Markdown } from 'components/interfaces/Markdown' import IntegrationWindowLayout from 'components/layouts/IntegrationWindowLayout' import { ScaffoldContainer, ScaffoldDivider } from 'components/layouts/Scaffold' import PasswordStrengthBar from 'components/ui/PasswordStrengthBar' +import { useProjectApiQuery } from 'data/config/project-api-query' import { useIntegrationConnectionsCreateMutation } from 'data/integrations/integration-connections-create-mutation' import { useIntegrationsQuery } from 'data/integrations/integrations-query' import { useVercelProjectsQuery } from 'data/integrations/integrations-vercel-projects-query' @@ -17,9 +18,9 @@ import generator from 'generate-password' import { useStore } from 'hooks' import { AWS_REGIONS, DEFAULT_MINIMUM_PASSWORD_STRENGTH, PROVIDERS } from 'lib/constants' import { passwordStrength } from 'lib/helpers' +import { getInitialMigrationSQLFromGitHubRepo } from 'lib/integration-utils' import { NextPageWithLayout, ProjectBase } from 'types' -import { Alert, Button, IconBook, IconLifeBuoy, Input, Listbox, LoadingLine } from 'ui' -import { useProjectApiQuery } from 'data/config/project-api-query' +import { Alert, Button, Checkbox, IconBook, IconLifeBuoy, Input, Listbox, LoadingLine } from 'ui' const VercelIntegration: NextPageWithLayout = () => { const [loading, setLoading] = useState(false) @@ -75,21 +76,25 @@ const CreateProject = ({ const [dbPass, setDbPass] = useState('') const [passwordStrengthMessage, setPasswordStrengthMessage] = useState('') const [passwordStrengthScore, setPasswordStrengthScore] = useState(-1) + const [shouldRunMigrations, setShouldRunMigrations] = useState(true) const [dbRegion, setDbRegion] = useState(PROVIDERS.AWS.default_region) // const [loading, setLoading] = useState(false) const delayedCheckPasswordStrength = useRef( debounce((value: string) => checkPasswordStrength(value), 300) ).current - const { configurationId, next, currentProjectId: foreignProjectId } = useParams() + const { + slug, + configurationId, + next, + currentProjectId: foreignProjectId, + externalId, + } = useParams() const { mutateAsync: createConnections, isLoading: isLoadingCreateConnections } = useIntegrationConnectionsCreateMutation({}) const { data: organizationData, isLoading: isLoadingOrganizationsQuery } = useOrganizationsQuery() - const { slug } = router.query - - console.log('slug') const organization = organizationData?.find((x) => x.slug === slug) @@ -115,8 +120,6 @@ const CreateProject = ({ { enabled: organizationIntegration !== undefined } ) - console.log('vercelProjects near top', vercelProjects) - const canSubmit = projectName != '' && passwordStrengthScore >= DEFAULT_MINIMUM_PASSWORD_STRENGTH && @@ -179,6 +182,23 @@ const CreateProject = ({ throw new Error('No organization set') } + let dbSql: string | undefined + if (shouldRunMigrations) { + const id = ui.setNotification({ + category: 'info', + message: `Fetching initial migrations from GitHub repo`, + }) + + dbSql = (await getInitialMigrationSQLFromGitHubRepo(externalId)) ?? undefined + + ui.setNotification({ + id, + category: 'success', + message: `Done fetching initial migrations`, + }) + } + console.log('dbSql:', dbSql) + let project: ProjectBase try { @@ -187,6 +207,7 @@ const CreateProject = ({ name: projectName, dbPass, dbRegion, + dbSql, configurationId, }) @@ -297,7 +318,7 @@ const CreateProject = ({ } />
    -
    +
    +
    + setShouldRunMigrations(e.target.checked)} + /> +
    - {/* */}
    ) } diff --git a/studio/pages/integrations/vercel/[slug]/marketplace/choose-project.tsx b/studio/pages/integrations/vercel/[slug]/marketplace/choose-project.tsx index cae0c637d86..afbbc25646e 100644 --- a/studio/pages/integrations/vercel/[slug]/marketplace/choose-project.tsx +++ b/studio/pages/integrations/vercel/[slug]/marketplace/choose-project.tsx @@ -2,7 +2,6 @@ import { useMemo, useState } from 'react' import { useParams } from 'common' import ProjectLinker from 'components/interfaces/Integrations/ProjectLinker' - import { Markdown } from 'components/interfaces/Markdown' import IntegrationWindowLayout from 'components/layouts/IntegrationWindowLayout' import { ScaffoldContainer, ScaffoldDivider } from 'components/layouts/Scaffold' @@ -10,27 +9,22 @@ import { useOrgIntegrationsQuery } from 'data/integrations/integrations-query-or import { useVercelProjectsQuery } from 'data/integrations/integrations-vercel-projects-query' import { useOrganizationsQuery } from 'data/organizations/organizations-query' import { useProjectsQuery } from 'data/projects/projects-query' -import { useStore } from 'hooks' import { EMPTY_ARR } from 'lib/void' -import { useRouter } from 'next/router' import { NextPageWithLayout, Organization } from 'types' import { IconBook, IconLifeBuoy, LoadingLine } from 'ui' const VercelIntegration: NextPageWithLayout = () => { - const router = useRouter() - const { configurationId, next, organizationSlug } = useParams() + const { slug, configurationId, next, organizationSlug } = useParams() const [loading, setLoading] = useState(false) - const { slug } = router.query - /** * Fetch the list of organization based integration installations for Vercel. * * Array of integrations installed on all */ const { data: integrationData, isLoading: integrationDataLoading } = useOrgIntegrationsQuery({ - orgSlug: slug?.toString(), + orgSlug: slug, }) const { data, isLoading: isLoadingOrganizationsQuery } = useOrganizationsQuery({ From 8d3439363bd04084e94d7c5b5b4e3d6fafd2c03a Mon Sep 17 00:00:00 2001 From: Alaister Young Date: Mon, 26 Jun 2023 23:13:44 +1000 Subject: [PATCH 29/59] adds migrations table sql --- studio/lib/integration-utils.ts | 46 +++++++++++++++---- .../[slug]/deploy-button/new-project.tsx | 1 - 2 files changed, 37 insertions(+), 10 deletions(-) diff --git a/studio/lib/integration-utils.ts b/studio/lib/integration-utils.ts index 8336470c685..63f9a93969f 100644 --- a/studio/lib/integration-utils.ts +++ b/studio/lib/integration-utils.ts @@ -63,14 +63,15 @@ export async function getInitialMigrationSQLFromGitHubRepo( } const seedFileUrl = supabaseFilesResponse.find((file) => file.name === 'seed.sql')?.download_url - const migrationFileDownloadUrlPromises = migrationFilesResponse - .sort((a, b) => { - // sort by name ascending - if (a.name < b.name) return -1 - if (a.name > b.name) return 1 - return 0 - }) - .map((file) => fetchGitHub(file.download_url, false)) + const sortedFiles = migrationFilesResponse.sort((a, b) => { + // sort by name ascending + if (a.name < b.name) return -1 + if (a.name > b.name) return 1 + return 0 + }) + const migrationFileDownloadUrlPromises = sortedFiles.map((file) => + fetchGitHub(file.download_url, false) + ) const [seedFileResponse, ...migrationFileResponses] = await Promise.all([ seedFileUrl ? fetchGitHub(seedFileUrl, false) : Promise.resolve(''), @@ -83,5 +84,32 @@ export async function getInitialMigrationSQLFromGitHubRepo( const seed = typeof seedFileResponse === 'object' && 'error' in seedFileResponse ? '' : seedFileResponse - return `${migrations};${seed}` + const migrationsTableSql = /* SQL */ ` + create schema if not exists supabase_migrations; + create table if not exists supabase_migrations.schema_migrations ( + version text not null primary key, + statements text[], + name text + ); + ${sortedFiles.map((file, i) => { + const migration = migrationFileResponses[i] + if (!migration || (typeof migration === 'object' && 'error' in migration)) return '' + + const version = file.name.split('_')[0] + const statements = JSON.stringify( + migration + .split(';') + .map((statement) => statement.trim()) + .filter(Boolean) + ) + + return /* SQL */ ` + insert into supabase_migrations.schema_migrations (version, statements, name) + select '${version}', array_agg(jsonb_statements)::text[], '${file.name}' + from jsonb_array_elements_text($statements$${statements}$statements$::jsonb) as jsonb_statements; + ` + })} + ` + + return `${migrations};${migrationsTableSql};${seed}` } diff --git a/studio/pages/integrations/vercel/[slug]/deploy-button/new-project.tsx b/studio/pages/integrations/vercel/[slug]/deploy-button/new-project.tsx index eb82bd7245f..d2162d8eadf 100644 --- a/studio/pages/integrations/vercel/[slug]/deploy-button/new-project.tsx +++ b/studio/pages/integrations/vercel/[slug]/deploy-button/new-project.tsx @@ -197,7 +197,6 @@ const CreateProject = ({ message: `Done fetching initial migrations`, }) } - console.log('dbSql:', dbSql) let project: ProjectBase From 0790cd5ca73ba3936173b88cce5709da40ab292a Mon Sep 17 00:00:00 2001 From: Jonathan Summers-Muir Date: Tue, 27 Jun 2023 16:22:46 +0800 Subject: [PATCH 30/59] fix ID issue --- .../vercel/[slug]/deploy-button/new-project.tsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/studio/pages/integrations/vercel/[slug]/deploy-button/new-project.tsx b/studio/pages/integrations/vercel/[slug]/deploy-button/new-project.tsx index d2162d8eadf..035508f2f6f 100644 --- a/studio/pages/integrations/vercel/[slug]/deploy-button/new-project.tsx +++ b/studio/pages/integrations/vercel/[slug]/deploy-button/new-project.tsx @@ -161,7 +161,11 @@ const CreateProject = ({ const [newProjectRef, setNewProjectRef] = useState(undefined) async function onCreateProject() { if (!organizationIntegration) { - console.error('No organizationIntegration set') + console.error('No organization installation details found') + } + + if (!organizationIntegration?.id) { + console.error('No organization installation ID found') return } From 75690e57aea695ce638ddd52b2549e66743fe86c Mon Sep 17 00:00:00 2001 From: Alaister Young Date: Wed, 28 Jun 2023 22:07:15 +1000 Subject: [PATCH 31/59] feature flag integrations v2 --- studio/components/layouts/OrganizationLayout.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/studio/components/layouts/OrganizationLayout.tsx b/studio/components/layouts/OrganizationLayout.tsx index 7b66373e84c..c79d90c60c2 100644 --- a/studio/components/layouts/OrganizationLayout.tsx +++ b/studio/components/layouts/OrganizationLayout.tsx @@ -12,6 +12,7 @@ const OrganizationLayout = ({ children }: PropsWithChildren<{}>) => { const { slug } = useParams() const id = router.asPath.split('/').at(-1) const showOAuthApps = useFlag('oauthApps') + const showIntegrationsV2 = useFlag('integrationsV2') return ( ) => { > - + {showIntegrationsV2 && ( + + )} {showOAuthApps && } From a310a19463123b49ab5f4905eb0ab4419b14fd4f Mon Sep 17 00:00:00 2001 From: "joel@joellee.org" Date: Wed, 28 Jun 2023 22:14:09 +0200 Subject: [PATCH 32/59] fix: update auth config --- .../schema/AuthProviders/AuthProvidersFormValidation.tsx | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/studio/stores/authConfig/schema/AuthProviders/AuthProvidersFormValidation.tsx b/studio/stores/authConfig/schema/AuthProviders/AuthProvidersFormValidation.tsx index 4e6b7541d01..42da2dd8ef8 100644 --- a/studio/stores/authConfig/schema/AuthProviders/AuthProvidersFormValidation.tsx +++ b/studio/stores/authConfig/schema/AuthProviders/AuthProvidersFormValidation.tsx @@ -77,6 +77,7 @@ const PROVIDER_PHONE = { { label: 'Messagebird', value: 'messagebird', icon: 'messagebird-icon.svg' }, { label: 'Textlocal', value: 'textlocal', icon: 'textlocal-icon.png' }, { label: 'Vonage', value: 'vonage', icon: 'vonage-icon.svg' }, + { label: 'Twilio Verify', value: 'twilio-verify', icon: 'twilio-icon.svg' } ], }, RATE_LIMIT_SMS_SENT: { @@ -118,7 +119,7 @@ const PROVIDER_PHONE = { title: 'Twilio Account Sid', show: { key: 'SMS_PROVIDER', - matches: 'twilio', + matches: 'twilio-verify', }, }, SMS_TWILIO_VERIFY_AUTH_TOKEN: { @@ -127,7 +128,7 @@ const PROVIDER_PHONE = { isSecret: true, show: { key: 'SMS_PROVIDER', - matches: 'twilio', + matches: 'twilio-verify', }, }, SMS_TWILIO_VERIFY_MESSAGE_SERVICE_SID: { @@ -135,7 +136,7 @@ const PROVIDER_PHONE = { title: 'Twilio Message Service Sid', show: { key: 'SMS_PROVIDER', - matches: 'twilio', + matches: 'twilio-verify', }, }, From af7765a3c471d308a0b7401ded08e9fef66f935c Mon Sep 17 00:00:00 2001 From: "joel@joellee.org" Date: Thu, 29 Jun 2023 06:03:37 +0200 Subject: [PATCH 33/59] fix: update frontend --- .../Auth/AuthProvidersForm/FormField.tsx | 52 +++++++++---------- .../AuthProvidersFormValidation.tsx | 12 +++++ 2 files changed, 38 insertions(+), 26 deletions(-) diff --git a/studio/components/interfaces/Auth/AuthProvidersForm/FormField.tsx b/studio/components/interfaces/Auth/AuthProvidersForm/FormField.tsx index ddb160631fb..0bbf5940fc3 100644 --- a/studio/components/interfaces/Auth/AuthProvidersForm/FormField.tsx +++ b/studio/components/interfaces/Auth/AuthProvidersForm/FormField.tsx @@ -14,7 +14,7 @@ interface Props { const FormField: FC = ({ name, properties, formValues, disabled = false }) => { const [hidden, setHidden] = useState(!!properties.isSecret) - if (properties.show && formValues[properties.show.key] !== properties.show.matches) return null + if (properties.show && !properties.show.matches.includes(formValues[properties.show.key])) return null switch (properties.type) { case 'string': @@ -28,35 +28,35 @@ const FormField: FC = ({ name, properties, formValues, disabled = false } type={hidden ? 'password' : 'text'} label={properties.title} labelOptional={ - properties.descriptionOptional ? ( - - {properties.descriptionOptional} - - ) : null + properties.descriptionOptional ? ( + + {properties.descriptionOptional} + + ) : null } descriptionText={ - properties.description ? ( - - {properties.description} - - ) : null + properties.description ? ( + + {properties.description} + + ) : null } actions={ - !!properties.isSecret ? ( -