Change role into action-service pattern
This commit is contained in:
parent
e33a7b5e9c
commit
b94f2c6aad
|
|
@ -1,6 +1,6 @@
|
|||
import checkMultiplePermissions from "@/modules/auth/utils/checkMultiplePermissions";
|
||||
import unauthorized from "@/modules/dashboard/utils/unauthorized";
|
||||
import getAllRoles from "@/modules/role/actions/getAllRoles";
|
||||
import getAllRoles from "@/modules/role/services/getAllRoles";
|
||||
import RolesTable from "@/modules/role/tables/RolesTable/RolesTable";
|
||||
import { Card, Stack, Title } from "@mantine/core";
|
||||
import { Metadata } from "next";
|
||||
|
|
@ -21,14 +21,13 @@ export default async function RolesPage() {
|
|||
|
||||
if (!permissions.readAll) unauthorized()
|
||||
|
||||
const res = await getAllRoles();
|
||||
if (!res.success) throw new Error("Error while fetch roles");
|
||||
const roles = await getAllRoles();
|
||||
|
||||
return (
|
||||
<Stack>
|
||||
<Title order={1}>Roles</Title>
|
||||
<Card>
|
||||
<RolesTable permissions={permissions} roles={res.data} />
|
||||
<RolesTable permissions={permissions} data={roles} />
|
||||
</Card>
|
||||
</Stack>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1,45 +0,0 @@
|
|||
import getCurrentUser from "@/modules/auth/utils/getCurrentUser";
|
||||
import "server-only";
|
||||
|
||||
/**
|
||||
* Checks if the current user has the specified permissions.
|
||||
*
|
||||
* Deprecated. Use `checkPermission()` from auth module instead.
|
||||
*
|
||||
* @deprecated
|
||||
* @param permission - The specific permission to check. If it's "guest-only", the function returns true if the user is not authenticated. If it's "authenticated-only", it returns true if the user is authenticated. For other permissions, it checks against the user's roles and direct permissions.
|
||||
* @param currentUser - Optional. The current user object. If not provided, the function retrieves the current user.
|
||||
* @returns true if the user has the required permission, otherwise false.
|
||||
*/
|
||||
export default async function checkPermission(
|
||||
permission?: "guest-only" | "authenticated-only" | (string & {}),
|
||||
currentUser?: Awaited<ReturnType<typeof getCurrentUser>>
|
||||
): Promise<boolean> {
|
||||
// Allow if no specific permission is required.
|
||||
if (!permission) return true;
|
||||
|
||||
// Retrieve current user if not provided.
|
||||
const user = currentUser ?? (await getCurrentUser());
|
||||
|
||||
// Handle non-authenticated users.
|
||||
if (!user) {
|
||||
return permission === "guest-only";
|
||||
}
|
||||
|
||||
// Allow authenticated users if the permission is 'authenticated-only'.
|
||||
if (permission === "authenticated-only") {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Short-circuit for super-admin role to allow all permissions.
|
||||
if (user.roles.some((role) => role.code === "super-admin")) return true;
|
||||
|
||||
// Aggregate all role codes and direct permissions into a set for efficient lookup.
|
||||
const permissions = new Set<string>([
|
||||
...user.roles.map((role) => role.code),
|
||||
...user.directPermissions.map((dp) => dp.code),
|
||||
]);
|
||||
|
||||
// Check if the user has the required permission.
|
||||
return permissions.has(permission);
|
||||
}
|
||||
|
|
@ -1,22 +1,19 @@
|
|||
"use server";
|
||||
|
||||
import db from "@/core/db";
|
||||
import prisma from "@/db";
|
||||
import checkPermission from "@/modules/dashboard/services/checkPermission";
|
||||
import checkPermission from "@/modules/auth/utils/checkPermission";
|
||||
import ServerResponseAction from "@/modules/dashboard/types/ServerResponseAction";
|
||||
import handleCatch from "@/modules/dashboard/utils/handleCatch";
|
||||
import unauthorized from "@/modules/dashboard/utils/unauthorized";
|
||||
import { revalidatePath } from "next/cache";
|
||||
import { notFound } from "next/navigation";
|
||||
import deleteRole from "../services/deleteRole";
|
||||
|
||||
export default async function deleteRole(
|
||||
export default async function deleteRoleAction(
|
||||
id: string
|
||||
): Promise<ServerResponseAction> {
|
||||
try {
|
||||
if (!(await checkPermission("roles.delete"))) return unauthorized();
|
||||
const role = await db.role.delete({
|
||||
where: { id },
|
||||
});
|
||||
|
||||
await deleteRole(id);
|
||||
|
||||
revalidatePath(".");
|
||||
|
||||
|
|
@ -1,58 +0,0 @@
|
|||
"use server";
|
||||
import prisma from "@/db";
|
||||
import checkPermission from "@/modules/dashboard/services/checkPermission";
|
||||
import ServerResponseAction from "@/modules/dashboard/types/ServerResponseAction";
|
||||
import handleCatch from "@/modules/dashboard/utils/handleCatch";
|
||||
import unauthorized from "@/modules/dashboard/utils/unauthorized";
|
||||
import "server-only";
|
||||
import Role from "../types/Role";
|
||||
import db from "@/core/db";
|
||||
|
||||
/**
|
||||
* Retrieves all roles along with the count of associated permissions and users.
|
||||
* Authorization check is performed for the operation.
|
||||
*
|
||||
* @returns An array of role objects each including details and counts of related permissions and users.
|
||||
*/
|
||||
export default async function getAllRoles(): Promise<
|
||||
ServerResponseAction<Role[]>
|
||||
> {
|
||||
try {
|
||||
// Authorization check
|
||||
if (!(await checkPermission("roles.getAll"))) {
|
||||
unauthorized();
|
||||
}
|
||||
|
||||
// Fetch roles from the database
|
||||
const roles = await db.role.findMany({
|
||||
include: {
|
||||
_count: {
|
||||
select: {
|
||||
permissions: true,
|
||||
users: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
// Transform the data into the desired format
|
||||
const result = roles.map(
|
||||
({ id, code, name, description, isActive, _count }) => ({
|
||||
id,
|
||||
code,
|
||||
name,
|
||||
description,
|
||||
isActive,
|
||||
permissionCount: _count.permissions,
|
||||
userCount: _count.users,
|
||||
})
|
||||
);
|
||||
|
||||
return {
|
||||
success: true,
|
||||
data: result
|
||||
}
|
||||
} catch (error) {
|
||||
return handleCatch(error)
|
||||
}
|
||||
}
|
||||
34
src/modules/role/actions/getAllRolesAction.ts
Normal file
34
src/modules/role/actions/getAllRolesAction.ts
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
"use server";
|
||||
import ServerResponseAction from "@/modules/dashboard/types/ServerResponseAction";
|
||||
import handleCatch from "@/modules/dashboard/utils/handleCatch";
|
||||
import unauthorized from "@/modules/dashboard/utils/unauthorized";
|
||||
import Role from "../types/Role";
|
||||
import checkPermission from "@/modules/auth/utils/checkPermission";
|
||||
import getAllRoles from "../services/getAllRoles";
|
||||
|
||||
/**
|
||||
* Retrieves all roles along with the count of associated permissions and users.
|
||||
* Authorization check is performed for the operation.
|
||||
*
|
||||
* @returns An array of role objects each including details and counts of related permissions and users.
|
||||
*/
|
||||
export default async function getAllRolesAction(): Promise<
|
||||
ServerResponseAction<Role[]>
|
||||
> {
|
||||
try {
|
||||
// Authorization check
|
||||
if (!(await checkPermission("roles.readAll"))) {
|
||||
return unauthorized();
|
||||
}
|
||||
|
||||
// Fetch roles from the database
|
||||
const roles = await getAllRoles()
|
||||
|
||||
return {
|
||||
success: true,
|
||||
data: roles
|
||||
}
|
||||
} catch (error) {
|
||||
return handleCatch(error)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,58 +0,0 @@
|
|||
"use server";
|
||||
|
||||
import db from "@/core/db";
|
||||
import prisma from "@/db";
|
||||
import checkPermission from "@/modules/dashboard/services/checkPermission";
|
||||
import ServerResponseAction from "@/modules/dashboard/types/ServerResponseAction";
|
||||
import handleCatch from "@/modules/dashboard/utils/handleCatch";
|
||||
import unauthorized from "@/modules/dashboard/utils/unauthorized";
|
||||
|
||||
type RoleData = {
|
||||
id: string;
|
||||
code: string;
|
||||
name: string;
|
||||
description: string;
|
||||
isActive: boolean;
|
||||
permissions: {
|
||||
id: string;
|
||||
code: string;
|
||||
name: string;
|
||||
}[]
|
||||
}
|
||||
|
||||
export default async function getRoleById(id: string): Promise<ServerResponseAction<RoleData>>{
|
||||
try{
|
||||
|
||||
if (!(await checkPermission("roles.read"))) return unauthorized();
|
||||
|
||||
const role = await db.role.findFirst({
|
||||
where: { id },
|
||||
select: {
|
||||
code: true,
|
||||
description: true,
|
||||
id: true,
|
||||
isActive: true,
|
||||
name: true,
|
||||
permissions: {
|
||||
select: {
|
||||
id: true,
|
||||
code: true,
|
||||
name: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
if (!role) {
|
||||
throw new Error("Permission not found")
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
message: "Role fetched successfully",
|
||||
data: role,
|
||||
};
|
||||
} catch (e){
|
||||
return handleCatch(e)
|
||||
}
|
||||
}
|
||||
24
src/modules/role/actions/getRoleByIdAction.ts
Normal file
24
src/modules/role/actions/getRoleByIdAction.ts
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
"use server";
|
||||
|
||||
import checkPermission from "@/modules/auth/utils/checkPermission";
|
||||
import ServerResponseAction from "@/modules/dashboard/types/ServerResponseAction";
|
||||
import handleCatch from "@/modules/dashboard/utils/handleCatch";
|
||||
import unauthorized from "@/modules/dashboard/utils/unauthorized";
|
||||
import getRoleById from "../services/getRoleById";
|
||||
|
||||
export default async function getRoleByIdAction(id: string): Promise<ServerResponseAction<Awaited<ReturnType<typeof getRoleById>>>>{
|
||||
try{
|
||||
|
||||
if (!(await checkPermission("roles.read"))) return unauthorized();
|
||||
|
||||
const role = await getRoleById(id)
|
||||
|
||||
return {
|
||||
success: true,
|
||||
message: "Role fetched successfully",
|
||||
data: role,
|
||||
};
|
||||
} catch (e){
|
||||
return handleCatch(e)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,99 +0,0 @@
|
|||
"use server";
|
||||
|
||||
import roleFormDataSchema, { RoleFormData } from "../formSchemas/RoleFormData";
|
||||
import mapObjectToFirstValue from "@/utils/mapObjectToFirstValue";
|
||||
import prisma from "@/db";
|
||||
import { revalidatePath } from "next/cache";
|
||||
import ServerResponseAction from "@/modules/dashboard/types/ServerResponseAction";
|
||||
import checkPermission from "@/modules/dashboard/services/checkPermission";
|
||||
import unauthorized from "@/modules/dashboard/utils/unauthorized";
|
||||
import DashboardError from "@/modules/dashboard/errors/DashboardError";
|
||||
import handleCatch from "@/modules/dashboard/utils/handleCatch";
|
||||
import db from "@/core/db";
|
||||
|
||||
/**
|
||||
* Upserts a role based on the provided RoleFormData.
|
||||
* If the role already exists (determined by `id`), it updates the role; otherwise, it creates a new role.
|
||||
* Authorization checks are performed based on whether it's a create or update operation.
|
||||
*
|
||||
* @param data - The data for creating or updating the role.
|
||||
* @returns An object containing the success status, message, and any errors.
|
||||
*/
|
||||
export default async function upsertRole(
|
||||
data: RoleFormData
|
||||
): Promise<ServerResponseAction> {
|
||||
try {
|
||||
const isInsert = !data.id;
|
||||
|
||||
// Authorization check
|
||||
const permissionType = isInsert ? "role.create" : "role.update";
|
||||
if (!(await checkPermission(permissionType))) {
|
||||
return unauthorized();
|
||||
}
|
||||
|
||||
// Validate form data
|
||||
const validatedFields = roleFormDataSchema.safeParse(data);
|
||||
if (!validatedFields.success) {
|
||||
throw new DashboardError({
|
||||
errorCode: "INVALID_FORM_DATA",
|
||||
formErrors: mapObjectToFirstValue(
|
||||
validatedFields.error.flatten().fieldErrors
|
||||
),
|
||||
});
|
||||
}
|
||||
const roleData = {
|
||||
code: validatedFields.data.code,
|
||||
description: validatedFields.data.description,
|
||||
name: validatedFields.data.name,
|
||||
isActive: validatedFields.data.isActive,
|
||||
};
|
||||
|
||||
const permissionIds = validatedFields.data.permissions.map(
|
||||
(permission) => ({ code: permission })
|
||||
);
|
||||
|
||||
// Database operation
|
||||
if (isInsert) {
|
||||
if (
|
||||
await db.role.findFirst({
|
||||
where: {
|
||||
code: roleData.code,
|
||||
},
|
||||
})
|
||||
) {
|
||||
throw new DashboardError({
|
||||
errorCode: "INVALID_FORM_DATA",
|
||||
formErrors: {
|
||||
code: "The code is already exists",
|
||||
},
|
||||
});
|
||||
}
|
||||
await db.role.create({
|
||||
data: {
|
||||
...roleData,
|
||||
permissions: {
|
||||
connect: permissionIds,
|
||||
},
|
||||
},
|
||||
});
|
||||
} else {
|
||||
await db.role.update({
|
||||
where: { id: validatedFields.data.id! },
|
||||
data: { ...roleData, permissions: { connect: permissionIds } },
|
||||
});
|
||||
}
|
||||
|
||||
// Revalidate the cache
|
||||
revalidatePath(".");
|
||||
|
||||
// Return success message
|
||||
return {
|
||||
success: true,
|
||||
message: `Role ${validatedFields.data.name} has been successfully ${
|
||||
isInsert ? "created" : "updated"
|
||||
}.`,
|
||||
};
|
||||
} catch (error) {
|
||||
return handleCatch(error);
|
||||
}
|
||||
}
|
||||
50
src/modules/role/actions/upsertRoleAction.ts
Normal file
50
src/modules/role/actions/upsertRoleAction.ts
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
"use server";
|
||||
|
||||
import roleFormDataSchema, { RoleFormData } from "../formSchemas/RoleFormData";
|
||||
import mapObjectToFirstValue from "@/utils/mapObjectToFirstValue";
|
||||
import { revalidatePath } from "next/cache";
|
||||
import ServerResponseAction from "@/modules/dashboard/types/ServerResponseAction";
|
||||
import unauthorized from "@/modules/dashboard/utils/unauthorized";
|
||||
import DashboardError from "@/modules/dashboard/errors/DashboardError";
|
||||
import handleCatch from "@/modules/dashboard/utils/handleCatch";
|
||||
import db from "@/core/db";
|
||||
import checkPermission from "@/modules/auth/utils/checkPermission";
|
||||
import upsertRole from "../services/upsertRole";
|
||||
|
||||
/**
|
||||
* Upserts a role based on the provided RoleFormData.
|
||||
* If the role already exists (determined by `id`), it updates the role; otherwise, it creates a new role.
|
||||
* Authorization checks are performed based on whether it's a create or update operation.
|
||||
*
|
||||
* @param data - The data for creating or updating the role.
|
||||
* @returns An object containing the success status, message, and any errors.
|
||||
*/
|
||||
export default async function upsertRoleAction(
|
||||
data: RoleFormData
|
||||
): Promise<ServerResponseAction> {
|
||||
try {
|
||||
const isInsert = !data.id;
|
||||
|
||||
// Authorization check
|
||||
const permissionType = isInsert ? "roles.create" : "roles.update";
|
||||
if (!(await checkPermission(permissionType))) {
|
||||
return unauthorized();
|
||||
}
|
||||
|
||||
// Validate form data
|
||||
const result = await upsertRole(data);
|
||||
|
||||
// Revalidate the cache
|
||||
revalidatePath(".");
|
||||
|
||||
// Return success message
|
||||
return {
|
||||
success: true,
|
||||
message: `Role ${result.name} has been successfully ${
|
||||
isInsert ? "created" : "updated"
|
||||
}.`,
|
||||
};
|
||||
} catch (error) {
|
||||
return handleCatch(error);
|
||||
}
|
||||
}
|
||||
|
|
@ -9,7 +9,7 @@ import {
|
|||
} from "@mantine/core";
|
||||
import { showNotification } from "@/utils/notifications";
|
||||
import withServerAction from "@/modules/dashboard/utils/withServerAction";
|
||||
import deleteRole from "../actions/deleteRole";
|
||||
import deleteRoleAction from "../actions/deleteRoleAction";
|
||||
import ClientError from "@/core/error/ClientError";
|
||||
|
||||
export interface DeleteModalProps {
|
||||
|
|
@ -38,7 +38,7 @@ export default function DeleteModal(props: DeleteModalProps) {
|
|||
if (!props.data?.id) return;
|
||||
setSubmitting(true);
|
||||
|
||||
withServerAction(deleteRole, props.data!.id)
|
||||
withServerAction(deleteRoleAction, props.data!.id)
|
||||
.then((response) => {
|
||||
showNotification(
|
||||
response.message ?? "Role deleted successfully"
|
||||
|
|
|
|||
|
|
@ -21,8 +21,8 @@ import { TbDeviceFloppy } from "react-icons/tb";
|
|||
import roleFormDataSchema, { RoleFormData } from "../formSchemas/RoleFormData";
|
||||
import getAllPermissions from "@/modules/permission/actions/getAllPermissions";
|
||||
import withServerAction from "@/modules/dashboard/utils/withServerAction";
|
||||
import getRoleById from "../actions/getRoleById";
|
||||
import upsertRole from "../actions/upsertRole";
|
||||
import getRoleByIdAction from "../actions/getRoleByIdAction";
|
||||
import upsertRoleAction from "../actions/upsertRoleAction";
|
||||
import ClientError from "@/core/error/ClientError";
|
||||
|
||||
export interface ModalProps {
|
||||
|
|
@ -96,7 +96,7 @@ export default function FormModal(props: ModalProps) {
|
|||
}
|
||||
|
||||
setFetching(true);
|
||||
withServerAction(getRoleById, props.id)
|
||||
withServerAction(getRoleByIdAction, props.id)
|
||||
.then((response) => {
|
||||
const data = response.data;
|
||||
form.setValues({
|
||||
|
|
@ -133,7 +133,7 @@ export default function FormModal(props: ModalProps) {
|
|||
|
||||
const handleSubmit = (values: RoleFormData) => {
|
||||
setSubmitting(true);
|
||||
withServerAction(upsertRole, values)
|
||||
withServerAction(upsertRoleAction, values)
|
||||
.then((response) => {
|
||||
showNotification(response.message!, "success");
|
||||
closeModal();
|
||||
|
|
|
|||
12
src/modules/role/services/deleteRole.ts
Normal file
12
src/modules/role/services/deleteRole.ts
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
import db from "@/core/db";
|
||||
import notFound from "@/modules/dashboard/utils/notFound";
|
||||
|
||||
export default async function deleteRole(id: string) {
|
||||
const role = await db.role.delete({
|
||||
where: { id },
|
||||
});
|
||||
|
||||
if (!role) notFound({message: "The role doesn't exists"})
|
||||
|
||||
return true as const;
|
||||
}
|
||||
32
src/modules/role/services/getAllRoles.ts
Normal file
32
src/modules/role/services/getAllRoles.ts
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
import db from "@/core/db";
|
||||
import "server-only"
|
||||
import Role from "../types/Role";
|
||||
|
||||
export default async function getAllRoles(): Promise<Role[]>{
|
||||
|
||||
const roles = await db.role.findMany({
|
||||
include: {
|
||||
_count: {
|
||||
select: {
|
||||
permissions: true,
|
||||
users: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
//data transformation
|
||||
const result = roles.map(
|
||||
({ id, code, name, description, isActive, _count }) => ({
|
||||
id,
|
||||
code,
|
||||
name,
|
||||
description,
|
||||
isActive,
|
||||
permissionCount: _count.permissions,
|
||||
userCount: _count.users,
|
||||
})
|
||||
);
|
||||
|
||||
return result;
|
||||
}
|
||||
40
src/modules/role/services/getRoleById.ts
Normal file
40
src/modules/role/services/getRoleById.ts
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
import "server-only";
|
||||
import db from "@/core/db";
|
||||
import notFound from "@/modules/dashboard/utils/notFound";
|
||||
|
||||
type RoleData = {
|
||||
id: string;
|
||||
code: string;
|
||||
name: string;
|
||||
description: string;
|
||||
isActive: boolean;
|
||||
permissions: {
|
||||
id: string;
|
||||
code: string;
|
||||
name: string;
|
||||
}[];
|
||||
};
|
||||
|
||||
export default async function getRoleById(id: string): Promise<RoleData> {
|
||||
const role = await db.role.findFirst({
|
||||
where: { id },
|
||||
select: {
|
||||
code: true,
|
||||
description: true,
|
||||
id: true,
|
||||
isActive: true,
|
||||
name: true,
|
||||
permissions: {
|
||||
select: {
|
||||
id: true,
|
||||
code: true,
|
||||
name: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
if (!role) return notFound({ message: "Role doesn't exists" });
|
||||
|
||||
return role;
|
||||
}
|
||||
59
src/modules/role/services/upsertRole.ts
Normal file
59
src/modules/role/services/upsertRole.ts
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
import DashboardError from "@/modules/dashboard/errors/DashboardError";
|
||||
import roleFormDataSchema, { RoleFormData } from "../formSchemas/RoleFormData";
|
||||
import mapObjectToFirstValue from "@/utils/mapObjectToFirstValue";
|
||||
import db from "@/core/db";
|
||||
|
||||
export default async function upsertRole(data: RoleFormData) {
|
||||
const isInsert = !data.id;
|
||||
|
||||
const validatedFields = roleFormDataSchema.safeParse(data);
|
||||
if (!validatedFields.success) {
|
||||
throw new DashboardError({
|
||||
errorCode: "INVALID_FORM_DATA",
|
||||
formErrors: mapObjectToFirstValue(
|
||||
validatedFields.error.flatten().fieldErrors
|
||||
),
|
||||
});
|
||||
}
|
||||
const roleData = {
|
||||
code: validatedFields.data.code,
|
||||
description: validatedFields.data.description,
|
||||
name: validatedFields.data.name,
|
||||
isActive: validatedFields.data.isActive,
|
||||
};
|
||||
|
||||
const permissionIds = validatedFields.data.permissions.map(
|
||||
(permission) => ({ code: permission })
|
||||
);
|
||||
|
||||
// Database operation
|
||||
if (isInsert) {
|
||||
if (
|
||||
await db.role.findFirst({
|
||||
where: {
|
||||
code: roleData.code,
|
||||
},
|
||||
})
|
||||
) {
|
||||
throw new DashboardError({
|
||||
errorCode: "INVALID_FORM_DATA",
|
||||
formErrors: {
|
||||
code: "The code is already exists",
|
||||
},
|
||||
});
|
||||
}
|
||||
return await db.role.create({
|
||||
data: {
|
||||
...roleData,
|
||||
permissions: {
|
||||
connect: permissionIds,
|
||||
},
|
||||
},
|
||||
});
|
||||
} else {
|
||||
return await db.role.update({
|
||||
where: { id: validatedFields.data.id! },
|
||||
data: { ...roleData, permissions: { connect: permissionIds } },
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -12,7 +12,7 @@ import Role from "../../types/Role";
|
|||
|
||||
interface Props {
|
||||
permissions: Partial<CrudPermissions>;
|
||||
roles: Role[];
|
||||
data: Role[];
|
||||
}
|
||||
|
||||
export default function RolesTable(props: Props) {
|
||||
|
|
@ -28,7 +28,7 @@ export default function RolesTable(props: Props) {
|
|||
});
|
||||
|
||||
const table = useReactTable({
|
||||
data: props.roles,
|
||||
data: props.data,
|
||||
columns: createColumns({
|
||||
permissions: props.permissions,
|
||||
actions: {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user