From 5e79c6906cc7b93fba9ea5537258dfdfa6d81e94 Mon Sep 17 00:00:00 2001 From: Oliver Date: Sun, 29 Dec 2024 17:00:27 +1100 Subject: [PATCH] [UI] Permission Enhancements (#8785) * Update page permissions - Add permission check to - HIde breadcrumbs and tree for part - Hide breadcrumbs and tree for stock * Additional permissions checks --- .../src/components/nav/InstanceDetail.tsx | 17 ++++++++- src/frontend/src/pages/build/BuildDetail.tsx | 6 +++- .../src/pages/company/SupplierPartDetail.tsx | 6 +++- .../src/pages/part/CategoryDetail.tsx | 1 + src/frontend/src/pages/part/PartDetail.tsx | 36 ++++++++++++------- .../pages/purchasing/PurchaseOrderDetail.tsx | 6 +++- .../src/pages/purchasing/PurchasingIndex.tsx | 5 +-- .../src/pages/sales/ReturnOrderDetail.tsx | 6 +++- src/frontend/src/pages/sales/SalesIndex.tsx | 8 +++-- .../src/pages/sales/SalesOrderDetail.tsx | 6 +++- .../pages/sales/SalesOrderShipmentDetail.tsx | 1 + .../src/pages/stock/LocationDetail.tsx | 1 + src/frontend/src/pages/stock/StockDetail.tsx | 28 +++++++++------ 13 files changed, 93 insertions(+), 34 deletions(-) diff --git a/src/frontend/src/components/nav/InstanceDetail.tsx b/src/frontend/src/components/nav/InstanceDetail.tsx index 98ed5d0292..1fc966e106 100644 --- a/src/frontend/src/components/nav/InstanceDetail.tsx +++ b/src/frontend/src/components/nav/InstanceDetail.tsx @@ -1,17 +1,24 @@ import { LoadingOverlay } from '@mantine/core'; +import type { ModelType } from '../../enums/ModelType'; +import type { UserRoles } from '../../enums/Roles'; import { useUserState } from '../../states/UserState'; import ClientError from '../errors/ClientError'; +import PermissionDenied from '../errors/PermissionDenied'; import ServerError from '../errors/ServerError'; export default function InstanceDetail({ status, loading, - children + children, + requiredRole, + requiredPermission }: Readonly<{ status: number; loading: boolean; children: React.ReactNode; + requiredRole?: UserRoles; + requiredPermission?: ModelType; }>) { const user = useUserState(); @@ -27,5 +34,13 @@ export default function InstanceDetail({ return ; } + if (requiredRole && !user.hasViewRole(requiredRole)) { + return ; + } + + if (requiredPermission && !user.hasViewPermission(requiredPermission)) { + return ; + } + return <>{children}; } diff --git a/src/frontend/src/pages/build/BuildDetail.tsx b/src/frontend/src/pages/build/BuildDetail.tsx index a3cd447de0..ec0bbecd4d 100644 --- a/src/frontend/src/pages/build/BuildDetail.tsx +++ b/src/frontend/src/pages/build/BuildDetail.tsx @@ -519,7 +519,11 @@ export default function BuildDetail() { {holdOrder.modal} {issueOrder.modal} {completeOrder.modal} - + + diff --git a/src/frontend/src/pages/part/PartDetail.tsx b/src/frontend/src/pages/part/PartDetail.tsx index d47191501f..6b23a647e1 100644 --- a/src/frontend/src/pages/part/PartDetail.tsx +++ b/src/frontend/src/pages/part/PartDetail.tsx @@ -970,18 +970,24 @@ export default function PartDetail() { {editPart.modal} {deletePart.modal} {orderPartsWizard.wizard} - + - { - setTreeOpen(false); - }} - selectedId={part?.category} - /> + {user.hasViewRole(UserRoles.part_category) && ( + { + setTreeOpen(false); + }} + selectedId={part?.category} + /> + )} { - setTreeOpen(true); // Open the category tree + setTreeOpen(true); }} editAction={editPart.open} editEnabled={user.hasChangeRole(UserRoles.part)} diff --git a/src/frontend/src/pages/purchasing/PurchaseOrderDetail.tsx b/src/frontend/src/pages/purchasing/PurchaseOrderDetail.tsx index f557b0886d..22ec2225b4 100644 --- a/src/frontend/src/pages/purchasing/PurchaseOrderDetail.tsx +++ b/src/frontend/src/pages/purchasing/PurchaseOrderDetail.tsx @@ -483,7 +483,11 @@ export default function PurchaseOrderDetail() { {completeOrder.modal} {editPurchaseOrder.modal} {duplicatePurchaseOrder.modal} - + , - content: + content: , + hidden: !user.hasViewRole(UserRoles.purchase_order) }, { name: 'suppliers', @@ -49,7 +50,7 @@ export default function PurchasingIndex() { ) } ]; - }, []); + }, [user]); if (!user.isLoggedIn() || !user.hasViewRole(UserRoles.purchase_order)) { return ; diff --git a/src/frontend/src/pages/sales/ReturnOrderDetail.tsx b/src/frontend/src/pages/sales/ReturnOrderDetail.tsx index 0320c949d7..bbba1340c5 100644 --- a/src/frontend/src/pages/sales/ReturnOrderDetail.tsx +++ b/src/frontend/src/pages/sales/ReturnOrderDetail.tsx @@ -470,7 +470,11 @@ export default function ReturnOrderDetail() { {holdOrder.modal} {completeOrder.modal} {duplicateReturnOrder.modal} - + , - content: + content: , + hidden: !user.hasViewRole(UserRoles.sales_order) }, { name: 'returnorders', label: t`Return Orders`, icon: , - content: + content: , + hidden: !user.hasViewRole(UserRoles.return_order) }, { name: 'suppliers', @@ -42,7 +44,7 @@ export default function PurchasingIndex() { ) } ]; - }, []); + }, [user]); if (!user.isLoggedIn() || !user.hasViewRole(UserRoles.sales_order)) { return ; diff --git a/src/frontend/src/pages/sales/SalesOrderDetail.tsx b/src/frontend/src/pages/sales/SalesOrderDetail.tsx index 7484d9be0f..c02627361c 100644 --- a/src/frontend/src/pages/sales/SalesOrderDetail.tsx +++ b/src/frontend/src/pages/sales/SalesOrderDetail.tsx @@ -534,7 +534,11 @@ export default function SalesOrderDetail() { {completeOrder.modal} {editSalesOrder.modal} {duplicateSalesOrder.modal} - + + - setTreeOpen(false)} - selectedId={stockitem?.location} - /> + {user.hasViewRole(UserRoles.stock_location) && ( + setTreeOpen(false)} + selectedId={stockitem?.location} + /> + )} { setTreeOpen(true); }}