Address PR comment for terraform sync integration

This commit is contained in:
carlosmonastyrski
2025-04-11 16:23:07 -03:00
parent e19c3630d9
commit 4b0e5fa05b
91 changed files with 1463 additions and 40 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@@ -0,0 +1,80 @@
import { useEffect } from "react";
import { Controller, useFormContext, useWatch } from "react-hook-form";
import { SingleValue } from "react-select";
import { faCircleInfo } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { SecretSyncConnectionField } from "@app/components/secret-syncs/forms/SecretSyncConnectionField";
import { FilterableSelect, FormControl, Tooltip } from "@app/components/v2";
import { useCamundaConnectionListClusters } from "@app/hooks/api/appConnections/camunda";
import { TCamundaCluster } from "@app/hooks/api/appConnections/camunda/types";
import { SecretSync } from "@app/hooks/api/secretSyncs";
import { CamundaSyncScope } from "@app/hooks/api/secretSyncs/types/camunda-sync";
import { TSecretSyncForm } from "../schemas";
export const CamundaSyncFields = () => {
const { control, setValue } = useFormContext<
TSecretSyncForm & { destination: SecretSync.Camunda }
>();
const connectionId = useWatch({ name: "connection.id", control });
const { data: clusters, isPending } = useCamundaConnectionListClusters(connectionId, {
enabled: Boolean(connectionId)
});
useEffect(() => {
setValue("destinationConfig.scope", CamundaSyncScope.Cluster);
}, []);
return (
<>
<SecretSyncConnectionField
onChange={() => {
setValue("destinationConfig.clusterUUID", "");
}}
/>
<Controller
name="destinationConfig.clusterUUID"
control={control}
render={({ field: { value, onChange }, fieldState: { error } }) => (
<FormControl
isError={Boolean(error)}
errorText={error?.message}
label="Cluster"
helperText={
<Tooltip
className="max-w-md"
content="Ensure that your credential has been granted access to the cluster"
>
<div>
<span>Don&#39;t see the cluster you&#39;re looking for?</span>{" "}
<FontAwesomeIcon icon={faCircleInfo} className="text-mineshaft-400" />
</div>
</Tooltip>
}
>
<FilterableSelect
menuPlacement="top"
isLoading={isPending && Boolean(connectionId)}
isDisabled={!connectionId}
value={clusters?.find((cluster) => cluster.uuid === value) ?? null}
onChange={(option) => {
onChange((option as SingleValue<TCamundaCluster>)?.uuid ?? null);
setValue(
"destinationConfig.clusterName",
(option as SingleValue<TCamundaCluster>)?.name ?? ""
);
}}
options={clusters}
placeholder="Select a cluster..."
getOptionLabel={(option) => option.name}
getOptionValue={(option) => option.uuid}
/>
</FormControl>
)}
/>
</>
);
};

View File

@@ -7,6 +7,7 @@ import { AwsParameterStoreSyncFields } from "./AwsParameterStoreSyncFields";
import { AwsSecretsManagerSyncFields } from "./AwsSecretsManagerSyncFields";
import { AzureAppConfigurationSyncFields } from "./AzureAppConfigurationSyncFields";
import { AzureKeyVaultSyncFields } from "./AzureKeyVaultSyncFields";
import { CamundaSyncFields } from "./CamundaSyncFields";
import { DatabricksSyncFields } from "./DatabricksSyncFields";
import { GcpSyncFields } from "./GcpSyncFields";
import { GitHubSyncFields } from "./GitHubSyncFields";
@@ -38,6 +39,8 @@ export const SecretSyncDestinationFields = () => {
return <HumanitecSyncFields />;
case SecretSync.TerraformCloud:
return <TerraformCloudSyncFields />;
case SecretSync.Camunda:
return <CamundaSyncFields />;
case SecretSync.Vercel:
return <VercelSyncFields />;
default:

View File

@@ -40,6 +40,7 @@ export const SecretSyncOptionsFields = ({ hideInitialSync }: Props) => {
case SecretSync.Databricks:
case SecretSync.Humanitec:
case SecretSync.TerraformCloud:
case SecretSync.Camunda:
case SecretSync.Vercel:
AdditionalSyncOptionsFieldsComponent = null;
break;

View File

@@ -0,0 +1,20 @@
import { useFormContext } from "react-hook-form";
import { GenericFieldLabel } from "@app/components/secret-syncs";
import { TSecretSyncForm } from "@app/components/secret-syncs/forms/schemas";
import { SecretSync } from "@app/hooks/api/secretSyncs";
export const CamundaSyncReviewFields = () => {
const { watch } = useFormContext<TSecretSyncForm & { destination: SecretSync.Camunda }>();
const scope = watch("destinationConfig.scope");
const clusterName = watch("destinationConfig.clusterName");
const clusterUUID = watch("destinationConfig.clusterUUID");
return (
<>
<GenericFieldLabel label="Secret Scope">{scope}</GenericFieldLabel>
<GenericFieldLabel label="Cluster">
{clusterName} (id:{clusterUUID})
</GenericFieldLabel>
</>
);
};

View File

@@ -17,6 +17,7 @@ import {
} from "./AwsSecretsManagerSyncReviewFields";
import { AzureAppConfigurationSyncReviewFields } from "./AzureAppConfigurationSyncReviewFields";
import { AzureKeyVaultSyncReviewFields } from "./AzureKeyVaultSyncReviewFields";
import { CamundaSyncReviewFields } from "./CamundaSyncReviewFields";
import { DatabricksSyncReviewFields } from "./DatabricksSyncReviewFields";
import { GcpSyncReviewFields } from "./GcpSyncReviewFields";
import { GitHubSyncReviewFields } from "./GitHubSyncReviewFields";
@@ -77,6 +78,9 @@ export const SecretSyncReviewFields = () => {
case SecretSync.TerraformCloud:
DestinationFieldsComponent = <TerraformCloudSyncReviewFields />;
break;
case SecretSync.Camunda:
DestinationFieldsComponent = <CamundaSyncReviewFields />;
break;
case SecretSync.Vercel:
DestinationFieldsComponent = <VercelSyncReviewFields />;
break;

View File

@@ -0,0 +1,15 @@
import { z } from "zod";
import { BaseSecretSyncSchema } from "@app/components/secret-syncs/forms/schemas/base-secret-sync-schema";
import { SecretSync } from "@app/hooks/api/secretSyncs";
export const CamundaSyncDestinationSchema = BaseSecretSyncSchema().merge(
z.object({
destination: z.literal(SecretSync.Camunda),
destinationConfig: z.object({
scope: z.string().trim().min(1, "Camunda scope required"),
clusterUUID: z.string().trim().min(1, "Camunda cluster UUID required"),
clusterName: z.string().optional()
})
})
);

View File

@@ -7,6 +7,7 @@ import { GitHubSyncDestinationSchema } from "@app/components/secret-syncs/forms/
import { AwsParameterStoreSyncDestinationSchema } from "./aws-parameter-store-sync-destination-schema";
import { AzureAppConfigurationSyncDestinationSchema } from "./azure-app-configuration-sync-destination-schema";
import { AzureKeyVaultSyncDestinationSchema } from "./azure-key-vault-sync-destination-schema";
import { CamundaSyncDestinationSchema } from "./camunda-sync-destination-schema";
import { GcpSyncDestinationSchema } from "./gcp-sync-destination-schema";
import { HumanitecSyncDestinationSchema } from "./humanitec-sync-destination-schema";
import { TerraformCloudSyncDestinationSchema } from "./terraform-cloud-destination-schema";
@@ -22,6 +23,7 @@ const SecretSyncUnionSchema = z.discriminatedUnion("destination", [
DatabricksSyncDestinationSchema,
HumanitecSyncDestinationSchema,
TerraformCloudSyncDestinationSchema,
CamundaSyncDestinationSchema,
VercelSyncDestinationSchema
]);

View File

@@ -6,6 +6,7 @@ import {
AwsConnectionMethod,
AzureAppConfigurationConnectionMethod,
AzureKeyVaultConnectionMethod,
CamundaConnectionMethod,
DatabricksConnectionMethod,
GcpConnectionMethod,
GitHubConnectionMethod,
@@ -34,7 +35,8 @@ export const APP_CONNECTION_MAP: Record<AppConnection, { name: string; image: st
[AppConnection.TerraformCloud]: { name: "Terraform Cloud", image: "Terraform Cloud.png" },
[AppConnection.Vercel]: { name: "Vercel", image: "Vercel.png" },
[AppConnection.Postgres]: { name: "PostgreSQL", image: "Postgres.png" },
[AppConnection.MsSql]: { name: "Microsoft SQL Server", image: "MsSql.png" }
[AppConnection.MsSql]: { name: "Microsoft SQL Server", image: "MsSql.png" },
[AppConnection.Camunda]: { name: "Camunda", image: "Camunda.png" }
};
export const getAppConnectionMethodDetails = (method: TAppConnection["method"]) => {
@@ -53,6 +55,8 @@ export const getAppConnectionMethodDetails = (method: TAppConnection["method"])
return { name: "Service Account Impersonation", icon: faUser };
case DatabricksConnectionMethod.ServicePrincipal:
return { name: "Service Principal", icon: faUser };
case CamundaConnectionMethod.ClientCredentials:
return { name: "Client Credentials", icon: faKey };
case HumanitecConnectionMethod.ApiToken:
case TerraformCloudConnectionMethod.ApiToken:
case VercelConnectionMethod.ApiToken:

View File

@@ -28,6 +28,10 @@ export const SECRET_SYNC_MAP: Record<SecretSync, { name: string; image: string }
name: "Terraform Cloud",
image: "Terraform Cloud.png"
},
[SecretSync.Camunda]: {
name: "Camunda",
image: "Camunda.png"
},
[SecretSync.Vercel]: {
name: "Vercel",
image: "Vercel.png"
@@ -44,6 +48,7 @@ export const SECRET_SYNC_CONNECTION_MAP: Record<SecretSync, AppConnection> = {
[SecretSync.Databricks]: AppConnection.Databricks,
[SecretSync.Humanitec]: AppConnection.Humanitec,
[SecretSync.TerraformCloud]: AppConnection.TerraformCloud,
[SecretSync.Camunda]: AppConnection.Camunda,
[SecretSync.Vercel]: AppConnection.Vercel
};

View File

@@ -0,0 +1 @@
export * from "./queries";

View File

@@ -0,0 +1,37 @@
import { useQuery, UseQueryOptions } from "@tanstack/react-query";
import { apiRequest } from "@app/config/request";
import { appConnectionKeys } from "../queries";
import { TCamundaCluster } from "./types";
const camundaConnectionKeys = {
all: [...appConnectionKeys.all, "camunda"] as const,
listClusters: (connectionId: string) =>
[...camundaConnectionKeys.all, "clusters", connectionId] as const
};
export const useCamundaConnectionListClusters = (
connectionId: string,
options?: Omit<
UseQueryOptions<
TCamundaCluster[],
unknown,
TCamundaCluster[],
ReturnType<typeof camundaConnectionKeys.listClusters>
>,
"queryKey" | "queryFn"
>
) => {
return useQuery({
queryKey: camundaConnectionKeys.listClusters(connectionId),
queryFn: async () => {
const { data } = await apiRequest.get<{ clusters: TCamundaCluster[] }>(
`/api/v1/app-connections/camunda/${connectionId}/clusters`
);
return data.clusters;
},
...options
});
};

View File

@@ -0,0 +1,4 @@
export type TCamundaCluster = {
name: string;
uuid: string;
};

View File

@@ -9,5 +9,6 @@ export enum AppConnection {
TerraformCloud = "terraform-cloud",
Vercel = "vercel",
Postgres = "postgres",
MsSql = "mssql"
MsSql = "mssql",
Camunda = "camunda"
}

View File

@@ -55,6 +55,10 @@ export type TMsSqlConnectionOption = TAppConnectionOptionBase & {
app: AppConnection.MsSql;
};
export type TCamundaConnectionOption = TAppConnectionOptionBase & {
app: AppConnection.Camunda;
};
export type TAppConnectionOption =
| TAwsConnectionOption
| TGitHubConnectionOption
@@ -66,7 +70,8 @@ export type TAppConnectionOption =
| TTerraformCloudConnectionOption
| TVercelConnectionOption
| TPostgresConnectionOption
| TMsSqlConnectionOption;
| TMsSqlConnectionOption
| TCamundaConnectionOption;
export type TAppConnectionOptionMap = {
[AppConnection.AWS]: TAwsConnectionOption;
@@ -80,4 +85,5 @@ export type TAppConnectionOptionMap = {
[AppConnection.Vercel]: TVercelConnectionOption;
[AppConnection.Postgres]: TPostgresConnectionOption;
[AppConnection.MsSql]: TMsSqlConnectionOption;
[AppConnection.Camunda]: TCamundaConnectionOption;
};

View File

@@ -0,0 +1,14 @@
import { AppConnection } from "../enums";
import { TRootAppConnection } from "./root-connection";
export enum CamundaConnectionMethod {
ClientCredentials = "client-credentials"
}
export type TCamundaConnection = TRootAppConnection & { app: AppConnection.Camunda } & {
method: CamundaConnectionMethod.ClientCredentials;
credentials: {
clientId: string;
clientSecret: string;
};
};

View File

@@ -3,6 +3,7 @@ import { TAppConnectionOption } from "./app-options";
import { TAwsConnection } from "./aws-connection";
import { TAzureAppConfigurationConnection } from "./azure-app-configuration-connection";
import { TAzureKeyVaultConnection } from "./azure-key-vault-connection";
import { TCamundaConnection } from "./camunda-connection";
import { TDatabricksConnection } from "./databricks-connection";
import { TGcpConnection } from "./gcp-connection";
import { TGitHubConnection } from "./github-connection";
@@ -15,6 +16,7 @@ import { TVercelConnection } from "./vercel-connection";
export * from "./aws-connection";
export * from "./azure-app-configuration-connection";
export * from "./azure-key-vault-connection";
export * from "./camunda-connection";
export * from "./databricks-connection";
export * from "./gcp-connection";
export * from "./github-connection";
@@ -35,7 +37,8 @@ export type TAppConnection =
| TTerraformCloudConnection
| TVercelConnection
| TPostgresConnection
| TMsSqlConnection;
| TMsSqlConnection
| TCamundaConnection;
export type TAvailableAppConnection = Pick<TAppConnection, "name" | "id">;
@@ -74,4 +77,5 @@ export type TAppConnectionMap = {
[AppConnection.Vercel]: TVercelConnection;
[AppConnection.Postgres]: TPostgresConnection;
[AppConnection.MsSql]: TMsSqlConnection;
[AppConnection.Camunda]: TCamundaConnection;
};

View File

@@ -8,6 +8,7 @@ export enum SecretSync {
Databricks = "databricks",
Humanitec = "humanitec",
TerraformCloud = "terraform-cloud",
Camunda = "camunda",
Vercel = "vercel"
}

View File

@@ -0,0 +1,21 @@
import { AppConnection } from "@app/hooks/api/appConnections/enums";
import { SecretSync } from "@app/hooks/api/secretSyncs";
import { TRootSecretSync } from "@app/hooks/api/secretSyncs/types/root-sync";
export enum CamundaSyncScope {
Cluster = "cluster"
}
export type TCamundaSync = TRootSecretSync & {
destination: SecretSync.Camunda;
destinationConfig: {
scope: string;
clusterUUID: string;
clusterName?: string;
};
connection: {
app: AppConnection.Camunda;
name: string;
id: string;
};
};

View File

@@ -7,6 +7,7 @@ import { DiscriminativePick } from "@app/types";
import { TAwsSecretsManagerSync } from "./aws-secrets-manager-sync";
import { TAzureAppConfigurationSync } from "./azure-app-configuration-sync";
import { TAzureKeyVaultSync } from "./azure-key-vault-sync";
import { TCamundaSync } from "./camunda-sync";
import { TGcpSync } from "./gcp-sync";
import { THumanitecSync } from "./humanitec-sync";
import { TTerraformCloudSync } from "./terraform-cloud-sync";
@@ -28,6 +29,7 @@ export type TSecretSync =
| TDatabricksSync
| THumanitecSync
| TTerraformCloudSync
| TCamundaSync
| TVercelSync;
export type TListSecretSyncs = { secretSyncs: TSecretSync[] };

View File

@@ -12,6 +12,7 @@ import { AppConnectionHeader } from "../AppConnectionHeader";
import { AwsConnectionForm } from "./AwsConnectionForm";
import { AzureAppConfigurationConnectionForm } from "./AzureAppConfigurationConnectionForm";
import { AzureKeyVaultConnectionForm } from "./AzureKeyVaultConnectionForm";
import { CamundaConnectionForm } from "./CamundaConnectionForm";
import { DatabricksConnectionForm } from "./DatabricksConnectionForm";
import { GcpConnectionForm } from "./GcpConnectionForm";
import { GitHubConnectionForm } from "./GitHubConnectionForm";
@@ -80,6 +81,8 @@ const CreateForm = ({ app, onComplete }: CreateFormProps) => {
return <PostgresConnectionForm onSubmit={onSubmit} />;
case AppConnection.MsSql:
return <MsSqlConnectionForm onSubmit={onSubmit} />;
case AppConnection.Camunda:
return <CamundaConnectionForm onSubmit={onSubmit} />;
default:
throw new Error(`Unhandled App ${app}`);
}
@@ -138,6 +141,8 @@ const UpdateForm = ({ appConnection, onComplete }: UpdateFormProps) => {
return <PostgresConnectionForm onSubmit={onSubmit} appConnection={appConnection} />;
case AppConnection.MsSql:
return <MsSqlConnectionForm onSubmit={onSubmit} appConnection={appConnection} />;
case AppConnection.Camunda:
return <CamundaConnectionForm onSubmit={onSubmit} appConnection={appConnection} />;
default:
throw new Error(`Unhandled App ${(appConnection as TAppConnection).app}`);
}

View File

@@ -0,0 +1,148 @@
import { Controller, FormProvider, useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { z } from "zod";
import {
Button,
FormControl,
Input,
ModalClose,
SecretInput,
Select,
SelectItem
} from "@app/components/v2";
import { APP_CONNECTION_MAP, getAppConnectionMethodDetails } from "@app/helpers/appConnections";
import { CamundaConnectionMethod, TCamundaConnection } from "@app/hooks/api/appConnections";
import { AppConnection } from "@app/hooks/api/appConnections/enums";
import {
genericAppConnectionFieldsSchema,
GenericAppConnectionsFields
} from "./GenericAppConnectionFields";
type Props = {
appConnection?: TCamundaConnection;
onSubmit: (formData: FormData) => Promise<void>;
};
const rootSchema = genericAppConnectionFieldsSchema.extend({
app: z.literal(AppConnection.Camunda)
});
const formSchema = z.discriminatedUnion("method", [
rootSchema.extend({
method: z.literal(CamundaConnectionMethod.ClientCredentials),
credentials: z.object({
clientId: z.string().trim().min(1, "Client ID required"),
clientSecret: z.string().trim().min(1, "Client secret required")
})
})
]);
type FormData = z.infer<typeof formSchema>;
export const CamundaConnectionForm = ({ appConnection, onSubmit }: Props) => {
const isUpdate = Boolean(appConnection);
const form = useForm<FormData>({
resolver: zodResolver(formSchema),
defaultValues: appConnection ?? {
app: AppConnection.Camunda,
method: CamundaConnectionMethod.ClientCredentials
}
});
const {
handleSubmit,
control,
formState: { isSubmitting, isDirty }
} = form;
return (
<FormProvider {...form}>
<form onSubmit={handleSubmit(onSubmit)}>
{!isUpdate && <GenericAppConnectionsFields />}
<Controller
name="method"
control={control}
render={({ field: { value, onChange }, fieldState: { error } }) => (
<FormControl
tooltipText={`The method you would like to use to connect with ${
APP_CONNECTION_MAP[AppConnection.Camunda].name
}. This field cannot be changed after creation.`}
errorText={error?.message}
isError={Boolean(error?.message)}
label="Method"
>
<Select
isDisabled={isUpdate}
value={value}
onValueChange={(val) => onChange(val)}
className="w-full border border-mineshaft-500"
position="popper"
dropdownContainerClassName="max-w-none"
>
{Object.values(CamundaConnectionMethod).map((method) => {
return (
<SelectItem value={method} key={method}>
{getAppConnectionMethodDetails(method).name}
</SelectItem>
);
})}
</Select>
</FormControl>
)}
/>
<Controller
name="credentials.clientId"
control={control}
shouldUnregister
render={({ field, fieldState: { error } }) => (
<FormControl
errorText={error?.message}
isError={Boolean(error?.message)}
label="Client ID"
>
<Input {...field} placeholder="YrBDnQYLevSe40PJ" />
</FormControl>
)}
/>
<Controller
name="credentials.clientSecret"
control={control}
shouldUnregister
render={({ field: { value, onChange }, fieldState: { error } }) => (
<FormControl
errorText={error?.message}
isError={Boolean(error?.message)}
label="Client Secret"
>
<SecretInput
containerClassName="text-gray-400 group-focus-within:!border-primary-400/50 border border-mineshaft-500 bg-mineshaft-900 px-2.5 py-1.5"
value={value}
onChange={(e) => onChange(e.target.value)}
/>
</FormControl>
)}
/>
<div className="mt-8 flex items-center">
<Button
className="mr-4"
size="sm"
type="submit"
colorSchema="secondary"
isLoading={isSubmitting}
isDisabled={isSubmitting || !isDirty}
>
{isUpdate ? "Update Credentials" : "Connect to Camunda"}
</Button>
<ModalClose asChild>
<Button colorSchema="secondary" variant="plain">
Cancel
</Button>
</ModalClose>
</div>
</form>
</FormProvider>
);
};

View File

@@ -0,0 +1,29 @@
import { useCamundaConnectionListClusters } from "@app/hooks/api/appConnections/camunda";
import { TCamundaSync } from "@app/hooks/api/secretSyncs/types/camunda-sync";
import { getSecretSyncDestinationColValues } from "../helpers";
import { SecretSyncTableCell } from "../SecretSyncTableCell";
type Props = {
secretSync: TCamundaSync;
};
export const CamundaSyncDestinationCol = ({ secretSync }: Props) => {
const { data: clusters, isPending } = useCamundaConnectionListClusters(secretSync.connectionId);
const { primaryText, secondaryText } = getSecretSyncDestinationColValues({
...secretSync,
destinationConfig: {
...secretSync.destinationConfig,
clusterName: clusters?.find(
(cluster) => cluster.uuid === secretSync.destinationConfig.clusterUUID
)?.name
}
});
if (isPending) {
return <SecretSyncTableCell primaryText="Loading cluster info..." secondaryText="Cluster" />;
}
return <SecretSyncTableCell primaryText={primaryText} secondaryText={secondaryText} />;
};

View File

@@ -4,6 +4,7 @@ import { AwsParameterStoreSyncDestinationCol } from "./AwsParameterStoreSyncDest
import { AwsSecretsManagerSyncDestinationCol } from "./AwsSecretsManagerSyncDestinationCol";
import { AzureAppConfigurationDestinationSyncCol } from "./AzureAppConfigurationDestinationSyncCol";
import { AzureKeyVaultDestinationSyncCol } from "./AzureKeyVaultDestinationSyncCol";
import { CamundaSyncDestinationCol } from "./CamundaSyncDestinationCol";
import { DatabricksSyncDestinationCol } from "./DatabricksSyncDestinationCol";
import { GcpSyncDestinationCol } from "./GcpSyncDestinationCol";
import { GitHubSyncDestinationCol } from "./GitHubSyncDestinationCol";
@@ -35,6 +36,8 @@ export const SecretSyncDestinationCol = ({ secretSync }: Props) => {
return <HumanitecSyncDestinationCol secretSync={secretSync} />;
case SecretSync.TerraformCloud:
return <TerraformCloudSyncDestinationCol secretSync={secretSync} />;
case SecretSync.Camunda:
return <CamundaSyncDestinationCol secretSync={secretSync} />;
case SecretSync.Vercel:
return <VercelSyncDestinationCol secretSync={secretSync} />;
default:

View File

@@ -82,6 +82,10 @@ export const getSecretSyncDestinationColValues = (secretSync: TSecretSync) => {
secondaryText = destinationConfig.workspaceName;
}
break;
case SecretSync.Camunda:
primaryText = destinationConfig.clusterName ?? destinationConfig.clusterUUID;
secondaryText = "Cluster";
break;
case SecretSync.Vercel:
primaryText = destinationConfig.appName || destinationConfig.app;
secondaryText = destinationConfig.env;

View File

@@ -0,0 +1,21 @@
import { GenericFieldLabel } from "@app/components/secret-syncs";
import { useCamundaConnectionListClusters } from "@app/hooks/api/appConnections/camunda";
import { TCamundaSync } from "@app/hooks/api/secretSyncs/types/camunda-sync";
type Props = {
secretSync: TCamundaSync;
};
export const CamundaSyncDestinationSection = ({ secretSync }: Props) => {
const { data: clusters, isPending } = useCamundaConnectionListClusters(secretSync.connectionId);
const {
destinationConfig: { clusterUUID }
} = secretSync;
if (isPending) {
return <GenericFieldLabel label="Cluster">Loading...</GenericFieldLabel>;
}
const clusterName = clusters?.find((cluster) => cluster.uuid === clusterUUID)?.name;
return <GenericFieldLabel label="Cluster">{clusterName ?? clusterUUID}</GenericFieldLabel>;
};

View File

@@ -16,6 +16,7 @@ import { GitHubSyncDestinationSection } from "@app/pages/secret-manager/SecretSy
import { AzureAppConfigurationSyncDestinationSection } from "./AzureAppConfigurationSyncDestinationSection";
import { AzureKeyVaultSyncDestinationSection } from "./AzureKeyVaultSyncDestinationSection";
import { CamundaSyncDestinationSection } from "./CamundaSyncDestinationSection";
import { GcpSyncDestinationSection } from "./GcpSyncDestinationSection";
import { HumanitecSyncDestinationSection } from "./HumanitecSyncDestinationSection";
import { TerraformCloudSyncDestinationSection } from "./TerraformCloudSyncDestinationSection";
@@ -62,6 +63,9 @@ export const SecretSyncDestinationSection = ({ secretSync, onEditDestination }:
case SecretSync.TerraformCloud:
DestinationComponents = <TerraformCloudSyncDestinationSection secretSync={secretSync} />;
break;
case SecretSync.Camunda:
DestinationComponents = <CamundaSyncDestinationSection secretSync={secretSync} />;
break;
case SecretSync.Vercel:
DestinationComponents = <VercelSyncDestinationSection secretSync={secretSync} />;
break;

View File

@@ -1,6 +1,7 @@
import { ReactNode } from "react";
import { GenericFieldLabel } from "@app/components/secret-syncs";
import { TerraformCloudSyncCategory } from "@app/hooks/api/appConnections/terraform-cloud";
import {
TerraformCloudSyncScope,
TTerraformCloudSync
@@ -22,6 +23,13 @@ export const TerraformCloudSyncDestinationSection = ({ secretSync }: Props) => {
<GenericFieldLabel label="Variable Set">
{destinationConfig.variableSetName}
</GenericFieldLabel>
<GenericFieldLabel label="Category">
{Object.keys(TerraformCloudSyncCategory).find(
(key) =>
TerraformCloudSyncCategory[key as keyof typeof TerraformCloudSyncCategory] ===
destinationConfig.category
)}
</GenericFieldLabel>
</>
);
break;
@@ -30,6 +38,13 @@ export const TerraformCloudSyncDestinationSection = ({ secretSync }: Props) => {
<>
<GenericFieldLabel label="Organization">{destinationConfig.org}</GenericFieldLabel>
<GenericFieldLabel label="Workspace">{destinationConfig.workspaceName}</GenericFieldLabel>
<GenericFieldLabel label="Category">
{Object.keys(TerraformCloudSyncCategory).find(
(key) =>
TerraformCloudSyncCategory[key as keyof typeof TerraformCloudSyncCategory] ===
destinationConfig.category
)}
</GenericFieldLabel>
</>
);
break;

View File

@@ -49,6 +49,7 @@ export const SecretSyncOptionsSection = ({ secretSync, onEditOptions }: Props) =
case SecretSync.Databricks:
case SecretSync.Humanitec:
case SecretSync.TerraformCloud:
case SecretSync.Camunda:
case SecretSync.Vercel:
AdditionalSyncOptionsComponent = null;
break;