mirror of
https://github.com/prowler-cloud/prowler.git
synced 2026-01-25 02:08:11 +00:00
WIP: add change role to the user's invitations
This commit is contained in:
@@ -98,15 +98,19 @@ export const sendInvite = async (formData: FormData) => {
|
||||
};
|
||||
|
||||
export const updateInvite = async (formData: FormData) => {
|
||||
console.log(formData, "formData from updateInvite");
|
||||
const session = await auth();
|
||||
const keyServer = process.env.API_BASE_URL;
|
||||
|
||||
const invitationId = formData.get("invitationId");
|
||||
const invitationEmail = formData.get("invitationEmail");
|
||||
const expiresAt = formData.get("expires_at");
|
||||
const role = formData.get("role");
|
||||
const roleId = formData.get("role");
|
||||
const expiresAt =
|
||||
formData.get("expires_at") ||
|
||||
new Date(Date.now() + 7 * 24 * 60 * 60 * 1000).toISOString();
|
||||
|
||||
const url = new URL(`${keyServer}/tenants/invitations/${invitationId}`);
|
||||
console.log(url, "url");
|
||||
|
||||
const body = JSON.stringify({
|
||||
data: {
|
||||
@@ -114,23 +118,23 @@ export const updateInvite = async (formData: FormData) => {
|
||||
id: invitationId,
|
||||
attributes: {
|
||||
email: invitationEmail,
|
||||
...(expiresAt && { expires_at: expiresAt }),
|
||||
expires_at: expiresAt,
|
||||
},
|
||||
relationships: {
|
||||
roles: {
|
||||
data: role
|
||||
? [
|
||||
{
|
||||
id: role,
|
||||
type: "role",
|
||||
},
|
||||
]
|
||||
: [],
|
||||
data: [
|
||||
{
|
||||
id: roleId,
|
||||
type: "role",
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
console.log("Payload send to server", JSON.stringify(body, null, 2));
|
||||
|
||||
try {
|
||||
const response = await fetch(url.toString(), {
|
||||
method: "PATCH",
|
||||
@@ -141,6 +145,13 @@ export const updateInvite = async (formData: FormData) => {
|
||||
},
|
||||
body,
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const error = await response.json();
|
||||
console.error("API Error:", error);
|
||||
return { error };
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
revalidatePath("/invitations");
|
||||
return parseStringify(data);
|
||||
|
||||
@@ -70,16 +70,28 @@ const SSRDataTable = async ({
|
||||
{},
|
||||
);
|
||||
|
||||
// Expand invitations with role information
|
||||
// Generate the array of roles with all the roles available
|
||||
const roles = Array.from(
|
||||
new Map(
|
||||
rolesData.data.map((role: any) => [
|
||||
role.id,
|
||||
{ id: role.id, name: role.attributes?.name || "Unnamed Role" },
|
||||
]),
|
||||
).values(),
|
||||
);
|
||||
|
||||
// Expand the invitations
|
||||
const expandedInvitations = invitationsData?.data?.map(
|
||||
(invitation: InvitationProps) => {
|
||||
const role = roleDict[invitation.id];
|
||||
|
||||
return {
|
||||
...invitation,
|
||||
relationships: {
|
||||
...invitation.relationships,
|
||||
role,
|
||||
},
|
||||
roles, // Include all roles here for each invitation
|
||||
};
|
||||
},
|
||||
);
|
||||
@@ -88,6 +100,7 @@ const SSRDataTable = async ({
|
||||
const expandedResponse = {
|
||||
...invitationsData,
|
||||
data: expandedInvitations,
|
||||
roles,
|
||||
};
|
||||
|
||||
return (
|
||||
|
||||
@@ -15,13 +15,13 @@ export const EditForm = ({
|
||||
invitationId,
|
||||
invitationEmail,
|
||||
roles = [],
|
||||
defaultRole = "",
|
||||
currentRole = "",
|
||||
setIsOpen,
|
||||
}: {
|
||||
invitationId: string;
|
||||
invitationEmail?: string;
|
||||
roles: Array<{ id: string; name: string }>;
|
||||
defaultRole?: string;
|
||||
currentRole?: string;
|
||||
setIsOpen: Dispatch<SetStateAction<boolean>>;
|
||||
}) => {
|
||||
const formSchema = editInviteFormSchema;
|
||||
@@ -31,7 +31,7 @@ export const EditForm = ({
|
||||
defaultValues: {
|
||||
invitationId,
|
||||
invitationEmail: invitationEmail || "",
|
||||
role: defaultRole,
|
||||
role: roles.find((role) => role.name === currentRole)?.id || "",
|
||||
},
|
||||
});
|
||||
|
||||
@@ -40,6 +40,7 @@ export const EditForm = ({
|
||||
const isLoading = form.formState.isSubmitting;
|
||||
|
||||
const onSubmitClient = async (values: z.infer<typeof formSchema>) => {
|
||||
console.log(values, " from edit form");
|
||||
const formData = new FormData();
|
||||
|
||||
Object.entries(values).forEach(
|
||||
@@ -49,11 +50,10 @@ export const EditForm = ({
|
||||
const data = await updateInvite(formData);
|
||||
|
||||
if (data?.error) {
|
||||
const errorMessage = `${data.error}`;
|
||||
toast({
|
||||
variant: "destructive",
|
||||
title: "Oops! Something went wrong",
|
||||
description: errorMessage,
|
||||
description: `${data.error}`,
|
||||
});
|
||||
} else {
|
||||
toast({
|
||||
@@ -70,9 +70,12 @@ export const EditForm = ({
|
||||
onSubmit={form.handleSubmit(onSubmitClient)}
|
||||
className="flex flex-col space-y-4"
|
||||
>
|
||||
<div className="text-md">
|
||||
<div className="text-small">
|
||||
Current email: <span className="font-bold">{invitationEmail}</span>
|
||||
</div>
|
||||
<div className="text-small">
|
||||
Current role: <span className="font-bold">{currentRole}</span>
|
||||
</div>
|
||||
<div>
|
||||
<CustomInput
|
||||
control={form.control}
|
||||
@@ -96,7 +99,7 @@ export const EditForm = ({
|
||||
label="Role"
|
||||
placeholder="Select a role"
|
||||
variant="bordered"
|
||||
selectedKeys={[field.value]}
|
||||
selectedKeys={[field.value || ""]}
|
||||
onSelectionChange={(selected) =>
|
||||
field.onChange(selected?.currentKey || "")
|
||||
}
|
||||
@@ -107,6 +110,7 @@ export const EditForm = ({
|
||||
</Select>
|
||||
)}
|
||||
/>
|
||||
|
||||
{form.formState.errors.role && (
|
||||
<p className="mt-2 text-sm text-red-600">
|
||||
{form.formState.errors.role.message}
|
||||
|
||||
@@ -74,7 +74,8 @@ export const ColumnsInvitation: ColumnDef<InvitationProps>[] = [
|
||||
header: () => <div className="text-right">Actions</div>,
|
||||
id: "actions",
|
||||
cell: ({ row }) => {
|
||||
return <DataTableRowActions row={row} />;
|
||||
const roles = row.original.roles;
|
||||
return <DataTableRowActions row={row} roles={roles} />;
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
@@ -24,28 +24,34 @@ import { DeleteForm, EditForm } from "../forms";
|
||||
|
||||
interface DataTableRowActionsProps<InvitationProps> {
|
||||
row: Row<InvitationProps>;
|
||||
roles?: { id: string; name: string }[];
|
||||
}
|
||||
const iconClasses =
|
||||
"text-2xl text-default-500 pointer-events-none flex-shrink-0";
|
||||
|
||||
export function DataTableRowActions<InvitationProps>({
|
||||
row,
|
||||
roles,
|
||||
}: DataTableRowActionsProps<InvitationProps>) {
|
||||
const [isEditOpen, setIsEditOpen] = useState(false);
|
||||
const [isDeleteOpen, setIsDeleteOpen] = useState(false);
|
||||
const invitationId = (row.original as { id: string }).id;
|
||||
const invitationEmail = (row.original as any).attributes?.email;
|
||||
const invitationRole = (row.original as any).relationships?.role?.attributes
|
||||
?.name;
|
||||
|
||||
return (
|
||||
<>
|
||||
<CustomAlertModal
|
||||
isOpen={isEditOpen}
|
||||
onOpenChange={setIsEditOpen}
|
||||
title="Edit Invitation"
|
||||
description={"Edit the invitation details"}
|
||||
>
|
||||
<EditForm
|
||||
invitationId={invitationId}
|
||||
invitationEmail={invitationEmail}
|
||||
currentRole={invitationRole}
|
||||
roles={roles || []}
|
||||
setIsOpen={setIsEditOpen}
|
||||
/>
|
||||
</CustomAlertModal>
|
||||
|
||||
@@ -242,6 +242,10 @@ export interface InvitationProps {
|
||||
links: {
|
||||
self: string;
|
||||
};
|
||||
roles?: {
|
||||
id: string;
|
||||
name: string;
|
||||
}[];
|
||||
}
|
||||
|
||||
export interface Role {
|
||||
|
||||
Reference in New Issue
Block a user