Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(ui): integrate new provider endpoint #2348

Merged
merged 4 commits into from
Jun 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { DefaultValues, useForm, UseFormReturn } from 'react-hook-form'
import { toast } from 'sonner'
import * as z from 'zod'

import { RepositoryKind } from '@/lib/gql/generates/graphql'
import { IntegrationKind } from '@/lib/gql/generates/graphql'
import { cn } from '@/lib/utils'
import {
AlertDialog,
Expand All @@ -35,7 +35,7 @@ import {
import { IconExternalLink, IconSpinner } from '@/components/ui/icons'
import { Input } from '@/components/ui/input'

import { useRepositoryKind } from '../hooks/use-repository-kind'
import { useIntegrationKind } from '../hooks/use-repository-kind'

export const createRepositoryProviderFormSchema = z.object({
displayName: z.string().trim(),
Expand Down Expand Up @@ -77,7 +77,7 @@ export function CommonProviderForm<T extends boolean>({
cancleable = true,
deletable
}: GithubProviderFormProps<T>) {
const kind = useRepositoryKind()
const kind = useIntegrationKind()
const router = useRouter()

const [deleteAlertVisible, setDeleteAlertVisible] = React.useState(false)
Expand All @@ -104,13 +104,13 @@ export function CommonProviderForm<T extends boolean>({

const displayNamePlaceholder = React.useMemo(() => {
switch (kind) {
case RepositoryKind.Github:
case IntegrationKind.Github:
return 'e.g. GitHub'
case RepositoryKind.GithubSelfHosted:
case IntegrationKind.GithubSelfHosted:
return 'e.g. GitHub Self-Hosted'
case RepositoryKind.Gitlab:
case IntegrationKind.Gitlab:
return 'e.g. GitLab'
case RepositoryKind.GitlabSelfHosted:
case IntegrationKind.GitlabSelfHosted:
return 'e.g. GitLab Self-Hosted'
default:
return ''
Expand All @@ -120,11 +120,11 @@ export function CommonProviderForm<T extends boolean>({
const accessTokenPlaceholder = React.useMemo(() => {
if (!isNew) return new Array(36).fill('*').join('')
switch (kind) {
case RepositoryKind.Github:
case RepositoryKind.GithubSelfHosted:
case IntegrationKind.Github:
case IntegrationKind.GithubSelfHosted:
return 'e.g. github_pat_1ABCD1234ABCD1234ABCD1234ABCD1234ABCD1234'
case RepositoryKind.Gitlab:
case RepositoryKind.GitlabSelfHosted:
case IntegrationKind.Gitlab:
case IntegrationKind.GitlabSelfHosted:
return 'e.g. glpat_1ABCD1234ABCD1234ABCD1234ABCD1234'
default:
return ''
Expand All @@ -133,18 +133,18 @@ export function CommonProviderForm<T extends boolean>({

const apiBasePlaceholder = React.useMemo(() => {
switch (kind) {
case RepositoryKind.GithubSelfHosted:
case IntegrationKind.GithubSelfHosted:
return 'e.g. https://api.github.yourcompany.com'
case RepositoryKind.GitlabSelfHosted:
case IntegrationKind.GitlabSelfHosted:
return 'e.g. https://gitlab.yourcompany.com'
default:
return ''
}
}, [kind])

const showApiBase = [
RepositoryKind.GithubSelfHosted,
RepositoryKind.GitlabSelfHosted
IntegrationKind.GithubSelfHosted,
IntegrationKind.GitlabSelfHosted
].includes(kind)

return (
Expand Down Expand Up @@ -303,11 +303,11 @@ export function useRepositoryProviderForm<T extends boolean>(
}

function AccessTokenDescription() {
const kind = useRepositoryKind()
const kind = useIntegrationKind()

if (
kind === RepositoryKind.Github ||
kind === RepositoryKind.GithubSelfHosted
kind === IntegrationKind.Github ||
kind === IntegrationKind.GithubSelfHosted
) {
return (
<>
Expand All @@ -325,8 +325,8 @@ function AccessTokenDescription() {
}

if (
kind === RepositoryKind.Gitlab ||
kind === RepositoryKind.GitlabSelfHosted
kind === IntegrationKind.Gitlab ||
kind === IntegrationKind.GitlabSelfHosted
) {
return (
<>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,100 +6,39 @@ import { useParams } from 'next/navigation'
import { useQuery } from 'urql'

import {
RepositoryKind,
RepositoryProviderStatus
IntegrationKind,
IntegrationStatus,
ListIntegrationsQuery
} from '@/lib/gql/generates/graphql'
import { QueryResponseData } from '@/lib/tabby/gql'
import {
listGithubRepositoryProviders,
listGithubSelfHostedRepositoryProviders,
listGitlabRepositoryProviders,
listGitlabSelfHostedRepositoryProviders
} from '@/lib/tabby/query'
import { listIntegrations } from '@/lib/tabby/query'
import { buttonVariants } from '@/components/ui/button'
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
import LoadingWrapper from '@/components/loading-wrapper'

interface GitProvidersListProps {
kind: RepositoryKind
kind: IntegrationKind
}

type TProviderList =
| Array<{
node: {
id: string
displayName: string
status: RepositoryProviderStatus
apiBase?: string
}
}>
| undefined

export default function RepositoryProvidersPage({
kind
}: GitProvidersListProps) {
return <ProviderList kind={kind} key={kind} />
// return <div>404</div>
}

function ProviderList({ kind }: GitProvidersListProps) {
const query = React.useMemo(() => {
switch (kind) {
case RepositoryKind.Github:
return listGithubRepositoryProviders
case RepositoryKind.GithubSelfHosted:
return listGithubSelfHostedRepositoryProviders
case RepositoryKind.Gitlab:
return listGitlabRepositoryProviders
case RepositoryKind.GitlabSelfHosted:
return listGitlabSelfHostedRepositoryProviders
}
}, [kind])

const resolver = React.useMemo(() => {
// todo also return pageInfo for pagination
switch (kind) {
case RepositoryKind.Github:
return (res: QueryResponseData<typeof listGithubRepositoryProviders>) =>
res?.githubRepositoryProviders?.edges
case RepositoryKind.GithubSelfHosted:
return (
res: QueryResponseData<typeof listGithubSelfHostedRepositoryProviders>
) => res?.githubSelfHostedRepositoryProviders?.edges
case RepositoryKind.Gitlab:
return (res: QueryResponseData<typeof listGitlabRepositoryProviders>) =>
res?.gitlabRepositoryProviders?.edges
case RepositoryKind.GitlabSelfHosted:
return (
res: QueryResponseData<typeof listGitlabSelfHostedRepositoryProviders>
) => res?.gitlabSelfHostedRepositoryProviders?.edges
default:
return () => []
}
}, [kind]) as (response: any) => TProviderList

const [{ data, fetching }] = useQuery({
query: query as any,
pause: !query
query: listIntegrations,
variables: { kind }
})

const providers = resolver(data)
const providers = data?.integrations?.edges

return <RepositoryProvidersView fetching={fetching} providers={providers} />
}

interface RepositoryProvidersViewProps {
fetching: boolean
providers:
| Array<{
node: {
id: string
displayName: string
status: RepositoryProviderStatus
apiBase?: string
}
}>
| undefined
providers: ListIntegrationsQuery['integrations']['edges'] | undefined
}

function RepositoryProvidersView({
Expand Down Expand Up @@ -171,13 +110,13 @@ const CreateRepositoryProvider = () => {
)
}

function toStatusMessage(status: RepositoryProviderStatus) {
function toStatusMessage(status: IntegrationStatus) {
switch (status) {
case RepositoryProviderStatus.Ready:
case IntegrationStatus.Ready:
return 'Ready'
case RepositoryProviderStatus.Failed:
case IntegrationStatus.Failed:
return 'Processing error. Please check if the access token is still valid'
case RepositoryProviderStatus.Pending:
case IntegrationStatus.Pending:
return 'Awaiting the next data synchronization'
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@
import * as React from 'react'
import { zodResolver } from '@hookform/resolvers/zod'
import { useForm } from 'react-hook-form'
import { TypedDocumentNode } from 'urql'
import * as z from 'zod'

import {
RepositoryKind,
RepositoryProviderStatus
IntegrationKind,
IntegrationStatus,
ListIntegratedRepositoriesQuery
} from '@/lib/gql/generates/graphql'
import { QueryResponseData, useMutation } from '@/lib/tabby/gql'
import { useMutation } from '@/lib/tabby/gql'
import { cn } from '@/lib/utils'
import { Button } from '@/components/ui/button'
import {
Expand Down Expand Up @@ -39,12 +39,7 @@ import {
PopoverTrigger
} from '@/components/ui/popover'

import {
updateGithubProvidedRepositoryActiveMutation,
updateGithubSelfHostedProvidedRepositoryActiveMutation,
updateGitlabProvidedRepositoryActiveMutation,
updateGitlabSelfHostedProvidedRepositoryActiveMutation
} from '../query'
import { updateIntegratedRepositoryActiveMutation } from '../query'

const formSchema = z.object({
id: z.string()
Expand All @@ -53,27 +48,17 @@ const formSchema = z.object({
type ActivateRepositoryFormValues = z.infer<typeof formSchema>

interface ActivateRepositoryFormProps {
kind: RepositoryKind
kind: IntegrationKind
onCreated?: (id: string) => void
onCancel: () => void
providerStatus: RepositoryProviderStatus | undefined
providerStatus: IntegrationStatus | undefined
repositories:
| Array<{
cursor: string
node: {
id: string
vendorId: string
name: string
gitUrl: string
active: boolean
}
}>
| ListIntegratedRepositoriesQuery['integratedRepositories']['edges']
| undefined
fetchingRepos: boolean
}

export default function AddRepositoryForm({
kind,
onCreated,
onCancel,
repositories,
Expand All @@ -90,64 +75,21 @@ export default function AddRepositoryForm({

const emptyText = React.useMemo(() => {
switch (providerStatus) {
case RepositoryProviderStatus.Pending:
case IntegrationStatus.Pending:
return 'Awaiting the next data synchronization'
case RepositoryProviderStatus.Failed:
case IntegrationStatus.Failed:
return 'Synchronizing error. Please check if the access token is still valid'
default:
return 'No repository found'
}
}, [providerStatus])

const { mutation, resolver } = React.useMemo(() => {
switch (kind) {
case RepositoryKind.Github:
return {
mutation: updateGithubProvidedRepositoryActiveMutation,
resolver: (
res?: QueryResponseData<
typeof updateGithubProvidedRepositoryActiveMutation
>
) => res?.updateGithubProvidedRepositoryActive
}
case RepositoryKind.GithubSelfHosted:
return {
mutation: updateGithubSelfHostedProvidedRepositoryActiveMutation,
resolver: (
res?: QueryResponseData<
typeof updateGithubSelfHostedProvidedRepositoryActiveMutation
>
) => res?.updateGithubSelfHostedProvidedRepositoryActive
}
case RepositoryKind.Gitlab:
return {
mutation: updateGitlabProvidedRepositoryActiveMutation,
resolver: (
res?: QueryResponseData<
typeof updateGitlabProvidedRepositoryActiveMutation
>
) => res?.updateGitlabProvidedRepositoryActive
}
case RepositoryKind.GitlabSelfHosted:
return {
mutation: updateGitlabSelfHostedProvidedRepositoryActiveMutation,
resolver: (
res?: QueryResponseData<
typeof updateGitlabSelfHostedProvidedRepositoryActiveMutation
>
) => res?.updateGitlabSelfHostedProvidedRepositoryActive
}
default:
return {}
const updateProvidedRepositoryActive = useMutation(
updateIntegratedRepositoryActiveMutation,
{
form
}
}, [kind]) as {
mutation: TypedDocumentNode<any, any>
resolver: (data?: Record<string, boolean>) => boolean | undefined
}

const updateProvidedRepositoryActive = useMutation(mutation, {
form
})
)

const onSubmit = (values: ActivateRepositoryFormValues) => {
const id = values.id
Expand All @@ -156,7 +98,7 @@ export default function AddRepositoryForm({
id: values.id,
active: true
}).then(res => {
if (resolver?.(res?.data)) {
if (res?.data?.updateIntegratedRepositoryActive) {
form.reset({ id: undefined })
onCreated?.(id)
}
Expand Down Expand Up @@ -228,8 +170,7 @@ export default function AddRepositoryForm({
)}
</CommandEmpty>
<CommandGroup>
{providerStatus !==
RepositoryProviderStatus.Pending &&
{providerStatus !== IntegrationStatus.Pending &&
repositories?.map(repo => (
<CommandItem
key={repo.node.id}
Expand Down
Loading