feat: add privileges management module with CRUD functionality
- Introduced a new Privileges module, including routes for creating, editing, and viewing privileges. - Implemented a detailed permissions matrix for managing actions (view, create, update, delete, import) associated with each privilege. - Added validation schema for privilege creation and editing. - Developed UI components for displaying and managing privilege details and permissions. - Integrated language support for English and Indonesian in the privileges module. - Created unit tests for the privileges remote data service and transformer to ensure functionality. This commit enhances the application by providing a comprehensive privileges management system, improving user role management and permissions handling.
This commit is contained in:
@@ -23,6 +23,7 @@ export enum STATUS_DATA {
|
||||
|
||||
INACTIVE = 'inactive',
|
||||
DEACTIVATED = 'deactivated',
|
||||
ARCHIVED = 'archived',
|
||||
|
||||
REQUEST = 'request',
|
||||
REQUESTING = 'requesting',
|
||||
@@ -198,6 +199,7 @@ export const DEFAULT_STATUS_MAP: Record<string, BadgeProps> = {
|
||||
[STATUS_DATA.TODO]: { color: STATUS_COLOR.TODO, leftSection: getIcon(Clock) },
|
||||
|
||||
[STATUS_DATA.INACTIVE]: { color: STATUS_COLOR.INACTIVE, leftSection: getIcon(XCircle) },
|
||||
[STATUS_DATA.ARCHIVED]: { color: STATUS_COLOR.INACTIVE, leftSection: getIcon(XCircle) },
|
||||
[STATUS_DATA.DEACTIVATED]: { color: STATUS_COLOR.DEACTIVATED, leftSection: getIcon(XCircle) },
|
||||
[STATUS_DATA.CLOSE]: { color: STATUS_COLOR.CLOSE, leftSection: getIcon(XCircle) },
|
||||
[STATUS_DATA.CLOSED]: { color: STATUS_COLOR.CLOSED, leftSection: getIcon(XCircle) },
|
||||
|
||||
+1
-1
@@ -63,7 +63,7 @@ export function BulkActionMenu({
|
||||
|
||||
const hasActive = selectedRows.some((row) => row[statusKey]?.toLowerCase() === 'active');
|
||||
const hasInactive = selectedRows.some(
|
||||
(row) => row[statusKey]?.toLowerCase() === 'inactive' || row[statusKey]?.toLowerCase() === 'draft',
|
||||
(row) => row[statusKey]?.toLowerCase() === 'inactive' || row[statusKey]?.toLowerCase() === 'draft' || row[statusKey]?.toLowerCase() === 'archived',
|
||||
);
|
||||
|
||||
const defaultActions: PageActionProps[] = [];
|
||||
|
||||
@@ -6,6 +6,7 @@ export const defaultPrivileges: PrivilegeEntity = {
|
||||
ALLOW_CREATE: true,
|
||||
ALLOW_EDIT: true,
|
||||
ALLOW_DELETE: true,
|
||||
ALLOW_IMPORT: true,
|
||||
|
||||
ALLOW_PRINT: true,
|
||||
ALLOW_PRINT_COPY: true,
|
||||
@@ -29,6 +30,7 @@ export const noPrivileges: PrivilegeEntity = {
|
||||
ALLOW_CREATE: false,
|
||||
ALLOW_EDIT: false,
|
||||
ALLOW_DELETE: false,
|
||||
ALLOW_IMPORT: false,
|
||||
|
||||
ALLOW_PRINT: false,
|
||||
ALLOW_PRINT_COPY: false,
|
||||
|
||||
@@ -299,6 +299,7 @@ export interface PrivilegeEntity {
|
||||
ALLOW_CREATE: boolean;
|
||||
ALLOW_EDIT: boolean;
|
||||
ALLOW_DELETE: boolean;
|
||||
ALLOW_IMPORT: boolean;
|
||||
|
||||
ALLOW_PRINT: boolean;
|
||||
ALLOW_PRINT_COPY: boolean;
|
||||
|
||||
@@ -504,7 +504,7 @@ export function EnterpriseDetailPageProvider<E extends BaseEntity = BaseEntity>(
|
||||
const isMasterData = moduleType === 'MASTER_DATA';
|
||||
|
||||
const isDataActive = detailData && ['active'].includes(detailData[statusKey]?.toLowerCase());
|
||||
const isDataInActive = detailData && ['inactive', 'draft'].includes(detailData[statusKey]?.toLowerCase());
|
||||
const isDataInActive = detailData && ['inactive', 'draft', 'archived'].includes(detailData[statusKey]?.toLowerCase());
|
||||
|
||||
// 1. Declare action with Privilege & Module Type conditions directly
|
||||
const rawActions = [
|
||||
|
||||
@@ -21,7 +21,7 @@ import {
|
||||
} from '../hooks/use-module.context';
|
||||
import { StatusPage } from '../../../components';
|
||||
import { useEnterpriseStorage } from '../hooks/enterprise-storage.context';
|
||||
import { defaultPrivileges, noPrivileges } from '../constant';
|
||||
import { noPrivileges } from '../constant';
|
||||
|
||||
export interface EnterpriseModuleProviderProps<
|
||||
E extends BaseEntity,
|
||||
@@ -47,7 +47,8 @@ export function EnterpriseModuleProvider<
|
||||
// Config Slice (Static)
|
||||
// ---------------------------------------------------------------------------
|
||||
const storage = useEnterpriseStorage();
|
||||
const [parsedPrivileges, setParsedPrivileges] = useState<PrivilegeEntity>(defaultPrivileges);
|
||||
const [arePrivilegesReady, setArePrivilegesReady] = useState(false);
|
||||
const [parsedPrivileges, setParsedPrivileges] = useState<PrivilegeEntity>(noPrivileges);
|
||||
|
||||
useEffect(() => {
|
||||
const fetchPrivilegeData = async () => {
|
||||
@@ -63,6 +64,8 @@ export function EnterpriseModuleProvider<
|
||||
} catch (error) {
|
||||
setParsedPrivileges(noPrivileges);
|
||||
console.error('Failed to retrieve privilege data:', error);
|
||||
} finally {
|
||||
setArePrivilegesReady(true);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -176,6 +179,10 @@ export function EnterpriseModuleProvider<
|
||||
|
||||
const { ALLOW_VIEW } = configSlice.privileges ?? {};
|
||||
|
||||
if (!arePrivilegesReady) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!ALLOW_VIEW) {
|
||||
return (
|
||||
<StatusPage
|
||||
|
||||
Reference in New Issue
Block a user