diff --git a/ui/actions/invitations/invitation.ts b/ui/actions/invitations/invitation.ts index 56aefc74e1..c9871dcde0 100644 --- a/ui/actions/invitations/invitation.ts +++ b/ui/actions/invitations/invitation.ts @@ -53,6 +53,7 @@ export const sendInvite = async (formData: FormData) => { const keyServer = process.env.API_BASE_URL; const email = formData.get("email"); + const role = formData.get("role"); const url = new URL(`${keyServer}/tenants/invitations`); const body = JSON.stringify({ @@ -61,7 +62,18 @@ export const sendInvite = async (formData: FormData) => { attributes: { email, }, - relationships: {}, + relationships: { + roles: { + data: role + ? [ + { + id: role, + type: "role", + }, + ] + : [], + }, + }, }, }); diff --git a/ui/app/(prowler)/invitations/(send-invite)/new/page.tsx b/ui/app/(prowler)/invitations/(send-invite)/new/page.tsx index 87a2e33acd..520760092b 100644 --- a/ui/app/(prowler)/invitations/(send-invite)/new/page.tsx +++ b/ui/app/(prowler)/invitations/(send-invite)/new/page.tsx @@ -1,7 +1,31 @@ import React from "react"; +import { Suspense } from "react"; +import { getRoles } from "@/actions/roles"; +import { SkeletonInvitationInfo } from "@/components/invitations/workflow"; import { SendInvitationForm } from "@/components/invitations/workflow/forms/send-invitation-form"; -export default function SendInvitationPage() { - return ; +export default async function SendInvitationPage() { + const rolesData = await getRoles({}); + + return ( + }> + + + ); } + +const SSRSendInvitation = ({ rolesData }: { rolesData: Array }) => { + const hasRoles = rolesData && rolesData.length > 0; + + return ( + ({ + id: role.id, + name: role.attributes.name, + }))} + defaultRole={!hasRoles ? "admin" : undefined} + isSelectorDisabled={!hasRoles} + /> + ); +}; diff --git a/ui/components/invitations/workflow/forms/send-invitation-form.tsx b/ui/components/invitations/workflow/forms/send-invitation-form.tsx index a75c6a60c6..150db0c70c 100644 --- a/ui/components/invitations/workflow/forms/send-invitation-form.tsx +++ b/ui/components/invitations/workflow/forms/send-invitation-form.tsx @@ -1,9 +1,10 @@ "use client"; import { zodResolver } from "@hookform/resolvers/zod"; +import { Select, SelectItem } from "@nextui-org/react"; import { SaveIcon } from "lucide-react"; import { useRouter } from "next/navigation"; -import { useForm } from "react-hook-form"; +import { Controller, useForm } from "react-hook-form"; import * as z from "zod"; import { sendInvite } from "@/actions/invitations/invitation"; @@ -14,11 +15,20 @@ import { ApiError } from "@/types"; const sendInvitationFormSchema = z.object({ email: z.string().email("Please enter a valid email"), + roleId: z.string().nonempty("Role is required"), }); export type FormValues = z.infer; -export const SendInvitationForm = () => { +export const SendInvitationForm = ({ + roles = [], + defaultRole = "admin", + isSelectorDisabled = false, +}: { + roles: Array<{ id: string; name: string }>; + defaultRole?: string; + isSelectorDisabled: boolean; +}) => { const { toast } = useToast(); const router = useRouter(); @@ -26,6 +36,7 @@ export const SendInvitationForm = () => { resolver: zodResolver(sendInvitationFormSchema), defaultValues: { email: "", + roleId: isSelectorDisabled ? defaultRole : "", }, }); @@ -34,6 +45,7 @@ export const SendInvitationForm = () => { const onSubmitClient = async (values: FormValues) => { const formData = new FormData(); formData.append("email", values.email); + formData.append("role", values.roleId); try { const data = await sendInvite(formData); @@ -48,6 +60,12 @@ export const SendInvitationForm = () => { message: errorMessage, }); break; + case "/data/relationships/roles": + form.setError("roleId", { + type: "server", + message: errorMessage, + }); + break; default: toast({ variant: "destructive", @@ -75,6 +93,7 @@ export const SendInvitationForm = () => { onSubmit={form.handleSubmit(onSubmitClient)} className="flex flex-col space-y-4" > + {/* Email Field */} { isInvalid={!!form.formState.errors.email} /> + ( + <> + + {form.formState.errors.roleId && ( +

+ {form.formState.errors.roleId.message} +

+ )} + + )} + /> + + {/* Submit Button */}