"use client"; import { Divider } from "@heroui/divider"; import { zodResolver } from "@hookform/resolvers/zod"; import { SaveIcon } from "lucide-react"; import { useRouter } from "next/navigation"; import { Controller, useForm } from "react-hook-form"; import * as z from "zod"; import { updateProviderGroup } from "@/actions/manage-groups/manage-groups"; import { Button } from "@/components/shadcn"; import { useToast } from "@/components/ui"; import { CustomDropdownSelection, CustomInput } from "@/components/ui/custom"; import { Form } from "@/components/ui/form"; import { ApiError } from "@/types"; const editGroupSchema = z.object({ name: z.string().min(1, "Provider group name is required"), providers: z.array(z.object({ id: z.string(), name: z.string() })).optional(), roles: z.array(z.object({ id: z.string(), name: z.string() })).optional(), }); export type FormValues = z.infer; export const EditGroupForm = ({ providerGroupId, providerGroupData, allProviders, allRoles, }: { providerGroupId: string; providerGroupData: FormValues; allProviders: { id: string; name: string }[]; allRoles: { id: string; name: string }[]; }) => { const { toast } = useToast(); const router = useRouter(); const form = useForm({ resolver: zodResolver(editGroupSchema), defaultValues: providerGroupData, }); const isLoading = form.formState.isSubmitting; const onSubmitClient = async (values: FormValues) => { try { const updatedFields: Partial = {}; // Detect changes in the name if (values.name !== providerGroupData.name) { updatedFields.name = values.name; } // Detect changes in providers if ( JSON.stringify(values.providers) !== JSON.stringify(providerGroupData.providers) ) { updatedFields.providers = values.providers; } // Detect changes in roles if ( JSON.stringify(values.roles) !== JSON.stringify(providerGroupData.roles) ) { updatedFields.roles = values.roles; } // If no changes, notify the user and exit if (Object.keys(updatedFields).length === 0) { toast({ title: "No changes detected", description: "No updates were made to the provider group.", }); return; } // Create FormData dynamically const formData = new FormData(); if (updatedFields.name) { formData.append("name", updatedFields.name); } if (updatedFields.providers) { const providersData = updatedFields.providers.map((provider) => ({ id: provider.id, type: "providers", })); formData.append("providers", JSON.stringify(providersData)); } if (updatedFields.roles) { const rolesData = updatedFields.roles.map((role) => ({ id: role.id, type: "roles", })); formData.append("roles", JSON.stringify(rolesData)); } // Call the update action const data = await updateProviderGroup(providerGroupId, 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; case "/data/relationships/roles": form.setError("roles", { type: "server", message: errorMessage, }); break; default: toast({ variant: "destructive", title: "Oops! Something went wrong", description: errorMessage, }); } }); } else { toast({ title: "Success!", description: "The group was updated successfully.", }); router.push("/manage-groups"); } } catch (error) { toast({ variant: "destructive", title: "Error", description: "An unexpected error occurred. Please try again.", }); } }; return (
{/* Field for the name */}
{/* Providers selection */} { const combinedProviders = [ ...(providerGroupData.providers || []), ...allProviders.filter( (p) => !(providerGroupData.providers || []).some( (sp) => sp.id === p.id, ), ), ]; return ( p.id) || []} onChange={(name, selectedValues) => { const selectedProviders = combinedProviders.filter( (provider) => selectedValues.includes(provider.id), ); field.onChange(selectedProviders); }} /> ); }} /> {form.formState.errors.providers && (

{form.formState.errors.providers.message}

)}

The roles associated with the group can be edited directly here or from the Roles page.

{/* Roles selection */} { const combinedRoles = [ ...(providerGroupData.roles || []), ...allRoles.filter( (r) => !(providerGroupData.roles || []).some((sr) => sr.id === r.id), ), ]; return ( r.id) || []} onChange={(name, selectedValues) => { const selectedRoles = combinedRoles.filter((role) => selectedValues.includes(role.id), ); field.onChange(selectedRoles); }} /> ); }} /> {form.formState.errors.roles && (

{form.formState.errors.roles.message}

)}
); };