106 lines
3.2 KiB
TypeScript
106 lines
3.2 KiB
TypeScript
import React from "react";
|
|
import { Permission } from "@/interfaces/permissions";
|
|
import {
|
|
createColumnHelper,
|
|
flexRender,
|
|
getCoreRowModel,
|
|
useReactTable,
|
|
Row,
|
|
} from "@tanstack/react-table";
|
|
import Link from "next/link";
|
|
import { convertCamelCaseToReadable } from "@/utils/string";
|
|
|
|
interface Props {
|
|
permissions: Permission[];
|
|
}
|
|
|
|
const columnHelper = createColumnHelper<Permission>();
|
|
|
|
const defaultColumns = [
|
|
columnHelper.accessor("type", {
|
|
header: () => <span>Type</span>,
|
|
cell: ({ row, getValue }) => (
|
|
<Link
|
|
href={`/permissions/${row.original.id}`}
|
|
key={row.id}
|
|
className="underline text-mti-purple-light hover:text-mti-purple-dark transition ease-in-out duration-300 cursor-pointer"
|
|
>
|
|
{convertCamelCaseToReadable(getValue() as string)}
|
|
</Link>
|
|
),
|
|
}),
|
|
];
|
|
|
|
export default function PermissionList({ permissions }: Props) {
|
|
const table = useReactTable({
|
|
data: permissions,
|
|
columns: defaultColumns,
|
|
getCoreRowModel: getCoreRowModel(),
|
|
});
|
|
|
|
const groupedData: { [key: string]: Row<Permission>[] } = table
|
|
.getRowModel()
|
|
.rows.reduce((groups: { [key: string]: Row<Permission>[] }, row) => {
|
|
const parent = row.original.topic;
|
|
if (!groups[parent]) {
|
|
groups[parent] = [];
|
|
}
|
|
groups[parent].push(row);
|
|
return groups;
|
|
}, {});
|
|
|
|
return (
|
|
<div className="w-full">
|
|
<div className="w-full flex flex-col gap-2">
|
|
<table className="rounded-xl bg-mti-purple-ultralight/40 w-full">
|
|
<thead>
|
|
{table.getHeaderGroups().map((headerGroup) => (
|
|
<tr key={headerGroup.id}>
|
|
{headerGroup.headers.map((header) => (
|
|
<th className="py-4 px-4 text-left" key={header.id}>
|
|
{header.isPlaceholder
|
|
? null
|
|
: flexRender(
|
|
header.column.columnDef.header,
|
|
header.getContext()
|
|
)}
|
|
</th>
|
|
))}
|
|
</tr>
|
|
))}
|
|
</thead>
|
|
<tbody className="px-2">
|
|
{Object.keys(groupedData).map((parent) => (
|
|
<React.Fragment key={parent}>
|
|
<tr>
|
|
<td className="px-2 py-2 items-center w-fit">
|
|
<strong>{parent}</strong>
|
|
</td>
|
|
</tr>
|
|
{groupedData[parent].map((row, i) => (
|
|
<tr
|
|
className="odd:bg-white even:bg-mti-purple-ultralight/40 rounded-lg py-2"
|
|
key={row.id}
|
|
>
|
|
{row.getVisibleCells().map((cell) => (
|
|
<td
|
|
className="px-4 py-2 items-center w-fit"
|
|
key={cell.id}
|
|
>
|
|
{flexRender(
|
|
cell.column.columnDef.cell,
|
|
cell.getContext()
|
|
)}
|
|
</td>
|
|
))}
|
|
</tr>
|
|
))}
|
|
</React.Fragment>
|
|
))}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|