Updated permissions to have a key to group them

This commit is contained in:
Joao Ramos
2024-08-14 18:44:35 +01:00
parent 859d9283a7
commit cb75ba6056
4 changed files with 197 additions and 109 deletions

View File

@@ -1,5 +1,12 @@
import React from "react";
import { Permission } from "@/interfaces/permissions";
import {createColumnHelper, flexRender, getCoreRowModel, useReactTable} from "@tanstack/react-table";
import {
createColumnHelper,
flexRender,
getCoreRowModel,
useReactTable,
Row,
} from "@tanstack/react-table";
import Link from "next/link";
import { convertCamelCaseToReadable } from "@/utils/string";
@@ -16,7 +23,8 @@ const defaultColumns = [
<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">
className="underline text-mti-purple-light hover:text-mti-purple-dark transition ease-in-out duration-300 cursor-pointer"
>
{convertCamelCaseToReadable(getValue() as string)}
</Link>
),
@@ -29,6 +37,18 @@ export default function PermissionList({permissions}: Props) {
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">
@@ -38,22 +58,45 @@ export default function PermissionList({permissions}: Props) {
<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())}
{header.isPlaceholder
? null
: flexRender(
header.column.columnDef.header,
header.getContext()
)}
</th>
))}
</tr>
))}
</thead>
<tbody className="px-2">
{table.getRowModel().rows.map((row) => (
<tr className="odd:bg-white even:bg-mti-purple-ultralight/40 rounded-lg py-2" key={row.id}>
{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
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>

View File

@@ -1,58 +1,89 @@
export const markets = ["au", "br", "de"] as const;
export interface PermissionTopic {
topic: string;
list: string[];
}
export const permissions = [
// generate codes are basicly invites
"createCodeStudent",
"createCodeTeacher",
{
topic: "Manage Corporate",
list: [
"viewCorporate",
"editCorporate",
"deleteCorporate",
"createCodeCorporate",
],
},
{
topic: "Manage Admin",
list: ["viewAdmin", "editAdmin", "deleteAdmin", "createCodeAdmin"],
},
{
topic: "Manage Student",
list: ["viewStudent", "editStudent", "deleteStudent", "createCodeStudent"],
},
{
topic: "Manage Teacher",
list: ["viewTeacher", "editTeacher", "deleteTeacher", "createCodeTeacher"],
},
{
topic: "Manage Country Manager",
list: [
"viewCountryManager",
"editCountryManager",
"deleteCountryManager",
"createCodeCountryManager",
"createCodeAdmin",
// exams
],
},
{
topic: "Manage Exams",
list: [
"createReadingExam",
"createListeningExam",
"createWritingExam",
"createSpeakingExam",
"createLevelExam",
// view pages
],
},
{
topic: "View Pages",
list: [
"viewExams",
"viewExercises",
"viewRecords",
"viewStats",
"viewTickets",
"viewPaymentRecords",
// view data
"viewStudent",
"viewTeacher",
"viewCorporate",
"viewCountryManager",
"viewAdmin",
"viewGroup",
"viewCodes",
// edit data
"editStudent",
"editTeacher",
"editCorporate",
"editCountryManager",
"editAdmin",
"editGroup",
// delete data
"deleteStudent",
"deleteTeacher",
"deleteCorporate",
"deleteCountryManager",
"deleteAdmin",
"deleteGroup",
"deleteCodes",
// create options
"createGroup",
"createCodes",
"all",
],
},
{
topic: "Manage Group",
list: ["viewGroup", "editGroup", "deleteGroup", "createGroup"],
},
{
topic: "Manage Codes",
list: ["viewCodes", "deleteCodes", "createCodes"],
},
{
topic: "Others",
list: ["all"],
},
] as const;
export type PermissionType = (typeof permissions)[keyof typeof permissions];
const permissionsList = [
...new Set(
permissions.reduce(
(accm: string[], permission) => [...accm, ...permission.list],
[]
)
),
];
export type PermissionType =
(typeof permissionsList)[keyof typeof permissionsList];
export interface Permission {
id: string;
type: PermissionType;
topic: string;
users: string[];
}

View File

@@ -55,9 +55,7 @@ interface Props {
}
export default function Page(props: Props) {
const { permissions, user } = props;
return (
<>
<Head>

View File

@@ -16,12 +16,13 @@ import {
Permission,
PermissionType,
permissions,
PermissionTopic,
} from "@/interfaces/permissions";
import { v4 } from "uuid";
const db = getFirestore(app);
async function createPermission(type: string) {
async function createPermission(topic: string, type: string) {
const permData = doc(db, "permissions", v4());
const permDoc = await getDoc(permData);
if (permDoc.exists()) {
@@ -30,9 +31,14 @@ async function createPermission(type: string) {
await setDoc(permData, {
type,
topic,
users: [],
});
}
interface PermissionsHelperList {
topic: string;
type: string;
}
export function getPermissions(userId: string | undefined, docs: Permission[]) {
if (!userId) {
return [];
@@ -52,8 +58,18 @@ export function getPermissions(userId: string | undefined, docs: Permission[]) {
}
export async function bootstrap() {
await permissions.forEach(async (type) => {
await createPermission(type);
await permissions
.reduce((accm: PermissionsHelperList[], permissionData) => {
return [
...accm,
...permissionData.list.map((type) => ({
topic: permissionData.topic,
type,
})),
];
}, [])
.forEach(async ({ topic, type }) => {
await createPermission(topic, type);
});
}