import { Controller, useForm } from "react-hook-form"; import { faArrowUpRightFromSquare, faBookOpen } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { zodResolver } from "@hookform/resolvers/zod"; import { useNavigate, useSearch } from "@tanstack/react-router"; import { z } from "zod"; import { createNotification } from "@app/components/notifications"; import { Button, Card, CardTitle, FilterableSelect, FormControl, Select, SelectItem, Spinner } from "@app/components/v2"; import { SecretPathInput } from "@app/components/v2/SecretPathInput"; import { ROUTE_PATHS } from "@app/const/routes"; import { useWorkspace } from "@app/context"; import { useCreateIntegration, useGetIntegrationAuthCircleCIOrganizations } from "@app/hooks/api"; import { CircleCiScope } from "@app/hooks/api/integrationAuth/types"; import { IntegrationsListPageTabs } from "@app/types/integrations"; const formSchema = z.discriminatedUnion("scope", [ z.object({ scope: z.literal(CircleCiScope.Context), secretPath: z.string().default("/"), sourceEnvironment: z.object({ name: z.string(), slug: z.string() }), targetOrg: z.object({ name: z.string().min(1), slug: z.string().min(1) }), targetContext: z.object({ name: z.string().min(1), id: z.string().min(1) }) }), z.object({ scope: z.literal(CircleCiScope.Project), secretPath: z.string().default("/"), sourceEnvironment: z.object({ name: z.string(), slug: z.string() }), targetOrg: z.object({ name: z.string().min(1), slug: z.string().min(1) }), targetProject: z.object({ name: z.string().min(1), id: z.string().min(1) }) }) ]); type TFormData = z.infer; export const CircleCIConfigurePage = () => { const navigate = useNavigate(); const { mutateAsync, isPending: isCreatingIntegration } = useCreateIntegration(); const { currentWorkspace } = useWorkspace(); const integrationAuthId = useSearch({ from: ROUTE_PATHS.SecretManager.Integratons.CircleConfigurePage.id, select: (el) => el.integrationAuthId }); const { control, watch, handleSubmit, setValue } = useForm({ resolver: zodResolver(formSchema), defaultValues: { secretPath: "/", sourceEnvironment: currentWorkspace?.environments[0], scope: CircleCiScope.Project } }); const selectedScope = watch("scope"); const selectedOrg = watch("targetOrg"); const selectedEnvironment = watch("sourceEnvironment"); const { data: circleCIOrganizations, isPending: isCircleCIOrganizationsLoading } = useGetIntegrationAuthCircleCIOrganizations(integrationAuthId); const selectedOrganizationEntry = selectedOrg ? circleCIOrganizations?.find((org) => org.slug === selectedOrg.slug) : undefined; const onSubmit = async (data: TFormData) => { try { if (data.scope === CircleCiScope.Context) { await mutateAsync({ scope: data.scope, integrationAuthId, isActive: true, sourceEnvironment: data.sourceEnvironment.slug, app: data.targetContext.name, appId: data.targetContext.id, owner: data.targetOrg.name, secretPath: data.secretPath }); } else { await mutateAsync({ scope: data.scope, integrationAuthId, isActive: true, app: data.targetProject.name, // project name owner: data.targetOrg.name, // organization name appId: data.targetProject.id, // project id (used for syncing) sourceEnvironment: data.sourceEnvironment.slug, secretPath: data.secretPath }); } createNotification({ type: "success", text: "Successfully created integration" }); navigate({ to: "/projects/$projectId/secret-manager/integrations", params: { projectId: currentWorkspace.id }, search: { selectedTab: IntegrationsListPageTabs.NativeIntegrations } }); } catch (err) { createNotification({ type: "error", text: "Failed to create integration" }); console.error(err); } }; if (isCircleCIOrganizationsLoading) return (
); return (
CircleCI logo CircleCI Context Integration
Docs
( option.slug} value={value} getOptionLabel={(option) => option.name} onChange={onChange} options={currentWorkspace?.environments} placeholder="Select a project environment" isDisabled={!currentWorkspace?.environments.length} /> )} /> ( )} /> ( option.slug} value={value} getOptionLabel={(option) => option.name} onChange={(e) => { setValue("targetProject", { name: "", id: "" }); setValue("targetContext", { name: "", id: "" }); onChange(e); }} options={circleCIOrganizations} placeholder={ circleCIOrganizations?.length ? "Select an organization..." : "No organizations found..." } isDisabled={!circleCIOrganizations?.length} /> )} /> ( )} /> {selectedScope === CircleCiScope.Context && selectedOrganizationEntry && ( ( option.id!} getOptionLabel={(option) => option.name} onChange={onChange} options={selectedOrganizationEntry?.contexts} placeholder={ selectedOrganizationEntry.contexts?.length ? "Select a context..." : "No contexts found..." } isDisabled={!selectedOrganizationEntry.contexts?.length} /> )} /> )} {selectedScope === CircleCiScope.Project && selectedOrganizationEntry && ( ( option.id!} getOptionLabel={(option) => option.name} onChange={onChange} options={selectedOrganizationEntry?.projects} placeholder={ selectedOrganizationEntry.projects?.length ? "Select a project..." : "No projects found..." } isDisabled={!selectedOrganizationEntry.projects?.length} /> )} /> )}
); };