mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-21 03:50:10 +00:00
194 lines
6.0 KiB
TypeScript
194 lines
6.0 KiB
TypeScript
import { Controller, useForm } from "react-hook-form";
|
|
import { zodResolver } from "@hookform/resolvers/zod";
|
|
import { z } from "zod";
|
|
|
|
import { createNotification } from "@app/components/notifications";
|
|
import {
|
|
Button,
|
|
Checkbox,
|
|
FormControl,
|
|
Input,
|
|
Modal,
|
|
ModalClose,
|
|
ModalContent,
|
|
TextArea
|
|
} from "@app/components/v2";
|
|
import { useProject } from "@app/context";
|
|
import { useCreateKmipClient, useUpdateKmipClient } from "@app/hooks/api/kmip";
|
|
import { KmipPermission, TKmipClient } from "@app/hooks/api/kmip/types";
|
|
|
|
const KMIP_PERMISSIONS_OPTIONS = [
|
|
{ value: KmipPermission.Check, label: "Check" },
|
|
{ value: KmipPermission.Create, label: "Create" },
|
|
{ value: KmipPermission.Get, label: "Get" },
|
|
{ value: KmipPermission.Locate, label: "Locate" },
|
|
{ value: KmipPermission.Destroy, label: "Destroy" },
|
|
{ value: KmipPermission.Activate, label: "Activate" },
|
|
{ value: KmipPermission.Revoke, label: "Revoke" },
|
|
{ value: KmipPermission.GetAttributes, label: "Get Attributes" },
|
|
{ value: KmipPermission.Register, label: "Register" }
|
|
] as const;
|
|
|
|
const formSchema = z.object({
|
|
name: z.string().trim().min(1),
|
|
description: z.string().max(500).optional(),
|
|
permissions: z.object({
|
|
[KmipPermission.Check]: z.boolean().optional(),
|
|
[KmipPermission.Create]: z.boolean().optional(),
|
|
[KmipPermission.Get]: z.boolean().optional(),
|
|
[KmipPermission.Locate]: z.boolean().optional(),
|
|
[KmipPermission.Destroy]: z.boolean().optional(),
|
|
[KmipPermission.Activate]: z.boolean().optional(),
|
|
[KmipPermission.GetAttributes]: z.boolean().optional(),
|
|
[KmipPermission.Revoke]: z.boolean().optional(),
|
|
[KmipPermission.Register]: z.boolean().optional()
|
|
})
|
|
});
|
|
|
|
export type FormData = z.infer<typeof formSchema>;
|
|
|
|
type Props = {
|
|
isOpen: boolean;
|
|
onOpenChange: (isOpen: boolean) => void;
|
|
kmipClient?: TKmipClient | null;
|
|
};
|
|
|
|
type FormProps = Pick<Props, "kmipClient"> & {
|
|
onComplete: () => void;
|
|
};
|
|
|
|
const KmipClientForm = ({ onComplete, kmipClient }: FormProps) => {
|
|
const createKmipClient = useCreateKmipClient();
|
|
const updateKmipClient = useUpdateKmipClient();
|
|
const { currentProject } = useProject();
|
|
const projectId = currentProject.id;
|
|
const isUpdate = !!kmipClient;
|
|
|
|
const {
|
|
control,
|
|
handleSubmit,
|
|
register,
|
|
formState: { isSubmitting, errors }
|
|
} = useForm<FormData>({
|
|
resolver: zodResolver(formSchema),
|
|
defaultValues: {
|
|
name: kmipClient?.name,
|
|
description: kmipClient?.description,
|
|
permissions: Object.fromEntries((kmipClient?.permissions || []).map((name) => [name, true]))
|
|
}
|
|
});
|
|
|
|
const handleKmipClientSubmit = async ({ permissions, name, description }: FormData) => {
|
|
const mutation = isUpdate
|
|
? updateKmipClient.mutateAsync({
|
|
id: kmipClient.id,
|
|
projectId,
|
|
name,
|
|
description,
|
|
permissions: Object.entries(permissions)
|
|
.filter(([, value]) => value)
|
|
.map(([key]) => key as KmipPermission)
|
|
})
|
|
: createKmipClient.mutateAsync({
|
|
projectId,
|
|
name,
|
|
description,
|
|
permissions: Object.entries(permissions)
|
|
.filter(([, value]) => value)
|
|
.map(([key]) => key as KmipPermission)
|
|
});
|
|
|
|
try {
|
|
await mutation;
|
|
createNotification({
|
|
text: `Successfully ${isUpdate ? "updated" : "added"} KMIP client`,
|
|
type: "success"
|
|
});
|
|
onComplete();
|
|
} catch (err) {
|
|
console.error(err);
|
|
createNotification({
|
|
text: `Failed to ${isUpdate ? "update" : "add"} KMIP client`,
|
|
type: "error"
|
|
});
|
|
}
|
|
};
|
|
|
|
return (
|
|
<form onSubmit={handleSubmit(handleKmipClientSubmit)}>
|
|
<FormControl
|
|
errorText={errors.name?.message}
|
|
isError={Boolean(errors.name?.message)}
|
|
label="Name"
|
|
>
|
|
<Input autoFocus placeholder="My KMIP Client" {...register("name")} />
|
|
</FormControl>
|
|
<FormControl
|
|
label="Description (optional)"
|
|
errorText={errors.description?.message}
|
|
isError={Boolean(errors.description?.message)}
|
|
>
|
|
<TextArea
|
|
className="max-h-80 min-h-40 max-w-full min-w-full"
|
|
{...register("description")}
|
|
/>
|
|
</FormControl>
|
|
<Controller
|
|
control={control}
|
|
name="permissions"
|
|
render={({ field: { onChange, value }, fieldState: { error } }) => {
|
|
return (
|
|
<FormControl label="Permissions" errorText={error?.message} isError={Boolean(error)}>
|
|
<div className="mt-2 mb-7 grid grid-cols-2 gap-2">
|
|
{KMIP_PERMISSIONS_OPTIONS.map(({ label, value: optionValue }) => {
|
|
return (
|
|
<Checkbox
|
|
id={optionValue}
|
|
key={optionValue}
|
|
isChecked={value[optionValue]}
|
|
onCheckedChange={(state) => {
|
|
onChange({
|
|
...value,
|
|
[optionValue]: state
|
|
});
|
|
}}
|
|
>
|
|
{label}
|
|
</Checkbox>
|
|
);
|
|
})}
|
|
</div>
|
|
</FormControl>
|
|
);
|
|
}}
|
|
/>
|
|
<div className="flex items-center">
|
|
<Button
|
|
className="mr-4"
|
|
size="sm"
|
|
type="submit"
|
|
isLoading={isSubmitting}
|
|
isDisabled={isSubmitting}
|
|
>
|
|
{isUpdate ? "Update" : "Add"} KMIP client
|
|
</Button>
|
|
<ModalClose asChild>
|
|
<Button colorSchema="secondary" variant="plain">
|
|
Cancel
|
|
</Button>
|
|
</ModalClose>
|
|
</div>
|
|
</form>
|
|
);
|
|
};
|
|
|
|
export const KmipClientModal = ({ isOpen, onOpenChange, kmipClient }: Props) => {
|
|
return (
|
|
<Modal isOpen={isOpen} onOpenChange={onOpenChange}>
|
|
<ModalContent title={`${kmipClient ? "Update" : "Add"} KMIP Client`}>
|
|
<KmipClientForm onComplete={() => onOpenChange(false)} kmipClient={kmipClient} />
|
|
</ModalContent>
|
|
</Modal>
|
|
);
|
|
};
|