"use client"; import { Checkbox } from "@heroui/checkbox"; import { Divider } from "@heroui/divider"; import { Tooltip } from "@heroui/tooltip"; import { zodResolver } from "@hookform/resolvers/zod"; import clsx from "clsx"; import { InfoIcon, SaveIcon } from "lucide-react"; import { useRouter } from "next/navigation"; import { useEffect } from "react"; import { Controller, useForm } from "react-hook-form"; import { z } from "zod"; import { addRole } from "@/actions/roles/roles"; import { useToast } from "@/components/ui"; import { CustomButton, CustomDropdownSelection, CustomInput, } from "@/components/ui/custom"; import { Form } from "@/components/ui/form"; import { getErrorMessage, permissionFormFields } from "@/lib"; import { addRoleFormSchema, ApiError } from "@/types"; type FormValues = z.input; export const AddRoleForm = ({ groups, }: { groups: { id: string; name: string }[]; }) => { const { toast } = useToast(); const router = useRouter(); const form = useForm({ resolver: zodResolver(addRoleFormSchema), defaultValues: { name: "", manage_users: false, manage_providers: false, manage_integrations: false, manage_scans: false, unlimited_visibility: false, groups: [], ...(process.env.NEXT_PUBLIC_IS_CLOUD_ENV === "true" && { manage_billing: false, }), }, }); const { watch, setValue } = form; const manageProviders = watch("manage_providers"); const unlimitedVisibility = watch("unlimited_visibility"); useEffect(() => { if (manageProviders && !unlimitedVisibility) { setValue("unlimited_visibility", true, { shouldValidate: true, shouldDirty: true, shouldTouch: true, }); } }, [manageProviders, unlimitedVisibility, setValue]); const isLoading = form.formState.isSubmitting; const onSelectAllChange = (checked: boolean) => { const permissions = [ "manage_users", "manage_account", "manage_billing", "manage_providers", "manage_integrations", "manage_scans", "unlimited_visibility", ]; permissions.forEach((permission) => { form.setValue(permission as keyof FormValues, checked, { shouldValidate: true, shouldDirty: true, shouldTouch: true, }); }); }; const onSubmitClient = async (values: FormValues) => { const formData = new FormData(); formData.append("name", values.name); formData.append("manage_users", String(values.manage_users)); formData.append("manage_providers", String(values.manage_providers)); formData.append("manage_integrations", String(values.manage_integrations)); formData.append("manage_scans", String(values.manage_scans)); formData.append("manage_account", String(values.manage_account)); formData.append( "unlimited_visibility", String(values.unlimited_visibility), ); // Conditionally append manage_account and manage_billing if (process.env.NEXT_PUBLIC_IS_CLOUD_ENV === "true") { formData.append("manage_billing", String(values.manage_billing)); } if (values.groups && values.groups.length > 0) { values.groups.forEach((group) => { formData.append("groups[]", group); }); } try { const data = await addRole(formData); if (data?.errors && data.errors.length > 0) { data.errors.forEach((error: ApiError) => { const errorMessage = error.detail; const pointer = error.source?.pointer; switch (pointer) { case "/data/attributes/name": form.setError("name", { type: "server", message: errorMessage, }); break; default: toast({ variant: "destructive", title: "Error", description: errorMessage, }); } }); } else { toast({ title: "Role Added", description: "The role was added successfully.", }); router.push("/roles"); } } catch (error) { toast({ variant: "destructive", title: "Error", description: getErrorMessage(error), }); } }; return (
Admin Permissions {/* Select All Checkbox */} form.watch(perm.field as keyof FormValues), )} onChange={(e) => onSelectAllChange(e.target.checked)} classNames={{ label: "text-small", wrapper: "checkbox-update", }} > Grant all admin permissions {/* Permissions Grid */}
{permissionFormFields .filter( (permission) => permission.field !== "manage_billing" || process.env.NEXT_PUBLIC_IS_CLOUD_ENV === "true", ) .map(({ field, label, description }) => (
{label}
))}
{!unlimitedVisibility && (
Groups and Account Visibility

Select the groups this role will have access to. If no groups are selected and unlimited visibility is not enabled, the role will not have access to any accounts.

( field.onChange(selectedValues) } /> )} /> {form.formState.errors.groups && (

{form.formState.errors.groups.message}

)}
)}
} > {isLoading ? <>Loading : Add Role}
); };