mirror of
https://github.com/prowler-cloud/prowler.git
synced 2025-12-19 05:17:47 +00:00
Co-authored-by: Alan Buscaglia <alanbuscaglia@MacBook-Pro.local> Co-authored-by: alejandrobailo <alejandrobailo94@gmail.com> Co-authored-by: César Arroba <cesar@prowler.com> Co-authored-by: Alejandro Bailo <59607668+alejandrobailo@users.noreply.github.com>
121 lines
3.3 KiB
TypeScript
121 lines
3.3 KiB
TypeScript
import { Spacer } from "@heroui/spacer";
|
|
import React, { Suspense } from "react";
|
|
|
|
import { getInvitations } from "@/actions/invitations/invitation";
|
|
import { getRoles } from "@/actions/roles";
|
|
import { FilterControls } from "@/components/filters";
|
|
import { filterInvitations } from "@/components/filters/data-filters";
|
|
import { SendInvitationButton } from "@/components/invitations";
|
|
import {
|
|
ColumnsInvitation,
|
|
SkeletonTableInvitation,
|
|
} from "@/components/invitations/table";
|
|
import { ContentLayout } from "@/components/ui";
|
|
import { DataTable, DataTableFilterCustom } from "@/components/ui/table";
|
|
import { InvitationProps, Role, SearchParamsProps } from "@/types";
|
|
|
|
export default async function Invitations({
|
|
searchParams,
|
|
}: {
|
|
searchParams: Promise<SearchParamsProps>;
|
|
}) {
|
|
const resolvedSearchParams = await searchParams;
|
|
const searchParamsKey = JSON.stringify(resolvedSearchParams || {});
|
|
|
|
return (
|
|
<ContentLayout title="Invitations" icon="lucide:mail">
|
|
<FilterControls search />
|
|
<Spacer y={8} />
|
|
<SendInvitationButton />
|
|
<Spacer y={4} />
|
|
<DataTableFilterCustom filters={filterInvitations || []} />
|
|
<Spacer y={8} />
|
|
|
|
<Suspense key={searchParamsKey} fallback={<SkeletonTableInvitation />}>
|
|
<SSRDataTable searchParams={resolvedSearchParams} />
|
|
</Suspense>
|
|
</ContentLayout>
|
|
);
|
|
}
|
|
|
|
const SSRDataTable = async ({
|
|
searchParams,
|
|
}: {
|
|
searchParams: SearchParamsProps;
|
|
}) => {
|
|
const page = parseInt(searchParams.page?.toString() || "1", 10);
|
|
const sort = searchParams.sort?.toString();
|
|
const pageSize = parseInt(searchParams.pageSize?.toString() || "10", 10);
|
|
|
|
// Extract all filter parameters
|
|
const filters = Object.fromEntries(
|
|
Object.entries(searchParams).filter(([key]) => key.startsWith("filter[")),
|
|
);
|
|
|
|
// Extract query from filters
|
|
const query = (filters["filter[search]"] as string) || "";
|
|
|
|
// Fetch invitations and roles
|
|
const invitationsData = await getInvitations({
|
|
query,
|
|
page,
|
|
sort,
|
|
filters,
|
|
pageSize,
|
|
});
|
|
const rolesData = await getRoles({});
|
|
|
|
// Create a dictionary for roles by invitation ID
|
|
const roleDict = (rolesData?.data || []).reduce(
|
|
(acc: Record<string, Role>, role: Role) => {
|
|
role.relationships.invitations.data.forEach((invitation: any) => {
|
|
acc[invitation.id] = role;
|
|
});
|
|
return acc;
|
|
},
|
|
{},
|
|
);
|
|
|
|
// Generate the array of roles with all the roles available
|
|
const roles = Array.from(
|
|
new Map(
|
|
(rolesData?.data || []).map((role: Role) => [
|
|
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
|
|
};
|
|
},
|
|
);
|
|
|
|
// Create the expanded response
|
|
const expandedResponse = {
|
|
...invitationsData,
|
|
data: expandedInvitations,
|
|
roles,
|
|
};
|
|
|
|
return (
|
|
<DataTable
|
|
key={Date.now()}
|
|
columns={ColumnsInvitation}
|
|
data={expandedResponse?.data || []}
|
|
metadata={invitationsData?.meta}
|
|
/>
|
|
);
|
|
};
|