@appcorp/fusion-storybook 0.1.72 → 0.1.74
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -1,10 +1,10 @@
|
|
|
1
|
+
import { type RowAction, type TableRow } from "@appcorp/shadcn/components/enhanced-table";
|
|
1
2
|
import { PermissionBE, RoleBE, RolePermissionBE } from "../../type";
|
|
2
3
|
export declare const RBAC_DRAWER: {
|
|
3
4
|
readonly FILTER_DRAWER: string;
|
|
4
5
|
readonly FORM_DRAWER: string;
|
|
5
6
|
readonly VIEW_DRAWER: string;
|
|
6
7
|
readonly MORE_ACTIONS_DRAWER: string;
|
|
7
|
-
readonly ASSIGN_PERMISSIONS_DRAWER: string;
|
|
8
8
|
};
|
|
9
9
|
export declare const RBAC_ACTION_TYPES: {
|
|
10
10
|
readonly RESET_FORM: "RESET_FORM";
|
|
@@ -106,24 +106,6 @@ export declare const RBAC_ACTION_TYPES: {
|
|
|
106
106
|
drawer: null;
|
|
107
107
|
modal: null;
|
|
108
108
|
}>;
|
|
109
|
-
/**
|
|
110
|
-
* Extended action types for permission-specific state mutations.
|
|
111
|
-
*/
|
|
112
|
-
export declare const RBAC_EXTENDED_ACTION_TYPES: {
|
|
113
|
-
readonly SET_AVAILABLE_PERMISSIONS: "SET_AVAILABLE_PERMISSIONS";
|
|
114
|
-
readonly SET_TOGGLING_PERMISSION: "SET_TOGGLING_PERMISSION";
|
|
115
|
-
readonly RESET_FORM: "RESET_FORM";
|
|
116
|
-
readonly SET_CURRENT_PAGE: "SET_CURRENT_PAGE";
|
|
117
|
-
readonly SET_PAGE_LIMIT: "SET_PAGE_LIMIT";
|
|
118
|
-
readonly SET_SEARCH_QUERY: "SET_SEARCH_QUERY";
|
|
119
|
-
readonly SET_DRAWER: "SET_DRAWER";
|
|
120
|
-
readonly SET_ITEMS: "SET_ITEMS";
|
|
121
|
-
readonly SET_FORM_DATA: "SET_FORM_DATA";
|
|
122
|
-
readonly SET_DISABLE_SAVE_BUTTON: "SET_DISABLE_SAVE_BUTTON";
|
|
123
|
-
readonly SET_INPUT_FIELD: "SET_INPUT_FIELD";
|
|
124
|
-
readonly SET_ERRORS: "SET_ERRORS";
|
|
125
|
-
readonly SET_FILTERS: "SET_FILTERS";
|
|
126
|
-
};
|
|
127
109
|
/**
|
|
128
110
|
* Backward-compatible alias used by dashboard-providers.tsx
|
|
129
111
|
*/
|
|
@@ -139,10 +121,9 @@ export declare const useRbacModule: () => {
|
|
|
139
121
|
deleteLoading: boolean;
|
|
140
122
|
handleChange: (key: string, value: string | number | boolean | undefined) => void;
|
|
141
123
|
handleCreate: () => void;
|
|
142
|
-
handleDelete: (row?:
|
|
143
|
-
handleEdit: (row?:
|
|
124
|
+
handleDelete: (row?: TableRow) => void;
|
|
125
|
+
handleEdit: (row?: TableRow) => Promise<void>;
|
|
144
126
|
handleFilters: () => void;
|
|
145
|
-
handleManagePermissions: (row?: unknown) => Promise<void>;
|
|
146
127
|
handleMoreActions: () => void;
|
|
147
128
|
handleNextClick: () => void;
|
|
148
129
|
handlePageChange: (page: number) => void;
|
|
@@ -151,7 +132,7 @@ export declare const useRbacModule: () => {
|
|
|
151
132
|
handleSearch: (query: string) => void;
|
|
152
133
|
handleSubmit: () => void;
|
|
153
134
|
handleTogglePermission: (permissionId: string) => Promise<void>;
|
|
154
|
-
handleView: (row?:
|
|
135
|
+
handleView: (row?: TableRow) => void;
|
|
155
136
|
headerActions: {
|
|
156
137
|
enabled: boolean;
|
|
157
138
|
handleOnClick: () => void;
|
|
@@ -161,12 +142,7 @@ export declare const useRbacModule: () => {
|
|
|
161
142
|
listError: Error | undefined;
|
|
162
143
|
listFetchNow: (url?: string, config?: import("@react-pakistan/util-functions/hooks/use-fetch").FetchConfig) => void;
|
|
163
144
|
listLoading: boolean;
|
|
164
|
-
rowActions:
|
|
165
|
-
enabled: boolean;
|
|
166
|
-
handleOnClick: (row?: unknown) => void;
|
|
167
|
-
label: string;
|
|
168
|
-
order: number;
|
|
169
|
-
}[];
|
|
145
|
+
rowActions: RowAction[];
|
|
170
146
|
updateLoading: boolean;
|
|
171
147
|
state: {
|
|
172
148
|
description: string;
|
|
@@ -15,7 +15,6 @@
|
|
|
15
15
|
* - `RbacProvider` — provider component used by the page
|
|
16
16
|
* - `RbacStateContextProvider` — backward-compat alias
|
|
17
17
|
* - `RBAC_ACTION_TYPES` — action type constants (from factory)
|
|
18
|
-
* - `RBAC_EXTENDED_ACTION_TYPES` — extended action types for permissions
|
|
19
18
|
* - `RBAC_DRAWER` — drawer type constants
|
|
20
19
|
* - `useRbacModule()` — hook that returns state, dispatch, and handlers
|
|
21
20
|
*/
|
|
@@ -39,7 +38,6 @@ export const RBAC_DRAWER = {
|
|
|
39
38
|
FORM_DRAWER: DRAWER_TYPES.FORM_DRAWER,
|
|
40
39
|
VIEW_DRAWER: DRAWER_TYPES.VIEW_DRAWER,
|
|
41
40
|
MORE_ACTIONS_DRAWER: DRAWER_TYPES.MORE_ACTIONS_DRAWER,
|
|
42
|
-
ASSIGN_PERMISSIONS_DRAWER: "ASSIGN_PERMISSIONS_DRAWER",
|
|
43
41
|
};
|
|
44
42
|
const rbacConfig = {
|
|
45
43
|
name: "Rbac",
|
|
@@ -73,10 +71,6 @@ const rbacConfig = {
|
|
|
73
71
|
// 1.3 CREATE RBAC MODULE
|
|
74
72
|
// ============================================================================
|
|
75
73
|
export const { actionTypes: RBAC_ACTION_TYPES, config: rbacModuleConfig, initialState: initialRbacState, Provider: RbacProvider, reducer: rbacReducer, useContext: useRbacContext, } = createGenericModule(rbacConfig);
|
|
76
|
-
/**
|
|
77
|
-
* Extended action types for permission-specific state mutations.
|
|
78
|
-
*/
|
|
79
|
-
export const RBAC_EXTENDED_ACTION_TYPES = Object.assign(Object.assign({}, RBAC_ACTION_TYPES), { SET_AVAILABLE_PERMISSIONS: "SET_AVAILABLE_PERMISSIONS", SET_TOGGLING_PERMISSION: "SET_TOGGLING_PERMISSION" });
|
|
80
74
|
/**
|
|
81
75
|
* Backward-compatible alias used by dashboard-providers.tsx
|
|
82
76
|
*/
|
|
@@ -260,26 +254,27 @@ export const useRbacModule = () => {
|
|
|
260
254
|
}, [dispatch]);
|
|
261
255
|
// row actions
|
|
262
256
|
const handleView = useCallback((row) => {
|
|
263
|
-
|
|
264
|
-
byIdFetchNow === null || byIdFetchNow === void 0 ? void 0 : byIdFetchNow(undefined, { params: { id: record === null || record === void 0 ? void 0 : record.id } });
|
|
257
|
+
byIdFetchNow === null || byIdFetchNow === void 0 ? void 0 : byIdFetchNow(undefined, { params: { id: row === null || row === void 0 ? void 0 : row.id } });
|
|
265
258
|
dispatch({
|
|
266
259
|
type: RBAC_ACTION_TYPES.SET_DRAWER,
|
|
267
260
|
payload: { drawer: RBAC_DRAWER.VIEW_DRAWER },
|
|
268
261
|
});
|
|
269
262
|
}, [byIdFetchNow, dispatch]);
|
|
270
|
-
const handleEdit = useCallback((row) => {
|
|
271
|
-
|
|
272
|
-
|
|
263
|
+
const handleEdit = useCallback(async (row) => {
|
|
264
|
+
byIdFetchNow === null || byIdFetchNow === void 0 ? void 0 : byIdFetchNow(undefined, { params: { id: row === null || row === void 0 ? void 0 : row.id } });
|
|
265
|
+
// loadAvailablePermissions is declared below in 1.4.7
|
|
266
|
+
// await loadAvailablePermissions();
|
|
273
267
|
dispatch({
|
|
274
268
|
type: RBAC_ACTION_TYPES.SET_DRAWER,
|
|
275
269
|
payload: { drawer: RBAC_DRAWER.FORM_DRAWER },
|
|
276
270
|
});
|
|
277
271
|
}, [byIdFetchNow, dispatch]);
|
|
278
272
|
const handleDelete = useCallback((row) => {
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
273
|
+
if (!confirm(t("messagesDeleteConfirmation")))
|
|
274
|
+
return;
|
|
275
|
+
deleteFetchNow === null || deleteFetchNow === void 0 ? void 0 : deleteFetchNow(undefined, {
|
|
276
|
+
body: JSON.stringify({ id: row === null || row === void 0 ? void 0 : row.id }),
|
|
277
|
+
});
|
|
283
278
|
}, [deleteFetchNow, t]);
|
|
284
279
|
// header actions
|
|
285
280
|
const handleCreate = useCallback(() => {
|
|
@@ -361,40 +356,34 @@ export const useRbacModule = () => {
|
|
|
361
356
|
},
|
|
362
357
|
});
|
|
363
358
|
}, [dispatch, showToast, t, updateFetchNow, updateParams]);
|
|
364
|
-
const loadAvailablePermissions = useCallback(async () => {
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
await loadAvailablePermissions();
|
|
388
|
-
dispatch({
|
|
389
|
-
type: RBAC_ACTION_TYPES.SET_DRAWER,
|
|
390
|
-
payload: { drawer: RBAC_DRAWER.ASSIGN_PERMISSIONS_DRAWER },
|
|
391
|
-
});
|
|
392
|
-
}, [byIdFetchNow, dispatch, loadAvailablePermissions]);
|
|
359
|
+
// const loadAvailablePermissions = useCallback(async () => {
|
|
360
|
+
// try {
|
|
361
|
+
// const res = await fetch(
|
|
362
|
+
// `${RBAC_API_ROUTES.PERMISSIONS_LIST}?pageLimit=1000`,
|
|
363
|
+
// {
|
|
364
|
+
// headers: {
|
|
365
|
+
// "Content-Type": "application/json",
|
|
366
|
+
// "x-api-token": process.env.NEXT_PUBLIC_API_KEY!,
|
|
367
|
+
// },
|
|
368
|
+
// }
|
|
369
|
+
// );
|
|
370
|
+
// if (!res.ok) throw new Error("Failed to load permissions");
|
|
371
|
+
// const data = (await res.json()) as { items: PermissionBE[] };
|
|
372
|
+
// // Use SET_INPUT_FIELD — the generic reducer handles it via state[key] = value.
|
|
373
|
+
// // Custom action types hit the reducer's default case and are silently ignored.
|
|
374
|
+
// dispatch({
|
|
375
|
+
// type: RBAC_ACTION_TYPES.SET_INPUT_FIELD,
|
|
376
|
+
// payload: { key: "availablePermissions", value: data.items },
|
|
377
|
+
// });
|
|
378
|
+
// } catch {
|
|
379
|
+
// showToast(t("messagesFetchFailed"), TOAST_VARIANT.ERROR);
|
|
380
|
+
// }
|
|
381
|
+
// }, [dispatch, showToast, t]);
|
|
393
382
|
const handleTogglePermission = useCallback(async (permissionId) => {
|
|
394
383
|
const existing = state.rolePermissions.find((rp) => rp.permissionId === permissionId);
|
|
395
384
|
dispatch({
|
|
396
|
-
type:
|
|
397
|
-
payload: {
|
|
385
|
+
type: RBAC_ACTION_TYPES.SET_INPUT_FIELD,
|
|
386
|
+
payload: { key: "togglingPermission", value: true },
|
|
398
387
|
});
|
|
399
388
|
try {
|
|
400
389
|
if (existing) {
|
|
@@ -426,8 +415,8 @@ export const useRbacModule = () => {
|
|
|
426
415
|
}
|
|
427
416
|
finally {
|
|
428
417
|
dispatch({
|
|
429
|
-
type:
|
|
430
|
-
payload: {
|
|
418
|
+
type: RBAC_ACTION_TYPES.SET_INPUT_FIELD,
|
|
419
|
+
payload: { key: "togglingPermission", value: false },
|
|
431
420
|
});
|
|
432
421
|
}
|
|
433
422
|
}, [byIdFetchNow, dispatch, showToast, state.id, state.rolePermissions, t]);
|
|
@@ -436,7 +425,7 @@ export const useRbacModule = () => {
|
|
|
436
425
|
// ============================================================================
|
|
437
426
|
const headerActions = useMemo(() => [
|
|
438
427
|
{
|
|
439
|
-
enabled:
|
|
428
|
+
enabled: false,
|
|
440
429
|
handleOnClick: handleMoreActions,
|
|
441
430
|
label: t("actionsButtonMoreActions"),
|
|
442
431
|
order: 0,
|
|
@@ -467,19 +456,13 @@ export const useRbacModule = () => {
|
|
|
467
456
|
label: t("actionsButtonEdit"),
|
|
468
457
|
order: 2,
|
|
469
458
|
},
|
|
470
|
-
{
|
|
471
|
-
enabled: true,
|
|
472
|
-
handleOnClick: handleManagePermissions,
|
|
473
|
-
label: t("actionsButtonManagePermissions"),
|
|
474
|
-
order: 3,
|
|
475
|
-
},
|
|
476
459
|
{
|
|
477
460
|
enabled: true,
|
|
478
461
|
handleOnClick: handleDelete,
|
|
479
462
|
label: t("actionsButtonDelete"),
|
|
480
463
|
order: 4,
|
|
481
464
|
},
|
|
482
|
-
], [handleDelete, handleEdit,
|
|
465
|
+
], [handleDelete, handleEdit, handleView, t]);
|
|
483
466
|
// ============================================================================
|
|
484
467
|
// 1.4.9 EFFECTS
|
|
485
468
|
// ============================================================================
|
|
@@ -520,7 +503,6 @@ export const useRbacModule = () => {
|
|
|
520
503
|
handleDelete,
|
|
521
504
|
handleEdit,
|
|
522
505
|
handleFilters,
|
|
523
|
-
handleManagePermissions,
|
|
524
506
|
handleMoreActions,
|
|
525
507
|
handleNextClick,
|
|
526
508
|
handlePageChange,
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
3
|
/**
|
|
4
4
|
* RBAC Form Component
|
|
5
5
|
*
|
|
6
6
|
* Create/edit form for roles.
|
|
7
7
|
*/
|
|
8
8
|
import { EnhancedInput } from "@appcorp/shadcn/components/enhanced-input";
|
|
9
|
+
import { Separator } from "@appcorp/shadcn/components/ui/separator";
|
|
9
10
|
import { useRbacModule } from "./context";
|
|
11
|
+
import { AssignPermissions } from "./assign-permissions";
|
|
10
12
|
export const RbacForm = () => {
|
|
11
13
|
const { state, handleChange } = useRbacModule();
|
|
12
|
-
return (
|
|
14
|
+
return (_jsxs("div", { className: "space-y-4", children: [_jsxs("div", { className: "grid grid-cols-1 gap-4", children: [_jsx(EnhancedInput, { id: "name", label: "Role Name", required: true, type: "text", value: state.name || "", onChange: (e) => handleChange("name", e.target.value), error: state.errors.name, placeholder: "e.g. Class Teacher, Admin, Accountant", info: "A unique, descriptive name for this role" }), _jsx(EnhancedInput, { id: "description", label: "Description", type: "text", value: state.description || "", onChange: (e) => handleChange("description", e.target.value || undefined), error: state.errors.description, placeholder: "Brief description of what this role can do", info: "Optional description to clarify the role's purpose" })] }), state.id && (_jsxs(_Fragment, { children: [_jsx(Separator, {}), _jsxs("div", { className: "space-y-2", children: [_jsx("p", { className: "text-sm font-medium", children: "Permissions" }), _jsx(AssignPermissions, {})] })] }))] }));
|
|
13
15
|
};
|
|
@@ -16,16 +16,15 @@
|
|
|
16
16
|
* - `RbacPage` — root component that wraps with RbacProvider
|
|
17
17
|
*/
|
|
18
18
|
"use client";
|
|
19
|
-
import { jsx as _jsx
|
|
19
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
20
20
|
import { useMemo } from "react";
|
|
21
21
|
import { COMPONENT_TYPE } from "@appcorp/shadcn/components/enhanced-table";
|
|
22
22
|
import { createGenericModulePage, } from "@react-pakistan/util-functions/factory/generic-component-factory";
|
|
23
|
-
import { RBAC_ACTION_TYPES, RbacProvider, useRbacModule
|
|
23
|
+
import { RBAC_ACTION_TYPES, RbacProvider, useRbacModule } from "./context";
|
|
24
24
|
import { RbacFilter } from "./filter";
|
|
25
25
|
import { RbacForm } from "./form";
|
|
26
26
|
import { RbacMoreActions } from "./more-actions";
|
|
27
27
|
import { RbacView } from "./view";
|
|
28
|
-
import { AssignPermissions } from "./assign-permissions";
|
|
29
28
|
import { resolveRbacPermissions } from "../../utils/resolve-rbac-permissions";
|
|
30
29
|
import { RbacNoAccess } from "../../components/rbac-no-access";
|
|
31
30
|
// ============================================================================
|
|
@@ -61,7 +60,6 @@ const createComponentInstances = () => ({
|
|
|
61
60
|
form: _jsx(RbacForm, {}),
|
|
62
61
|
moreActions: _jsx(RbacMoreActions, {}),
|
|
63
62
|
view: _jsx(RbacView, {}),
|
|
64
|
-
assignPermissions: _jsx(AssignPermissions, {}),
|
|
65
63
|
});
|
|
66
64
|
const createRbacConfig = ({ dispatch, drawerButtonCancel, drawerButtonSave, drawerTitleRbac, tableColumnHeaderActions, tableColumnHeaderDescription, tableColumnHeaderId, tableColumnHeaderName, tableColumnHeaderPermissions, tableDescription, tableSearchPlaceholder, tableTitle, }) => {
|
|
67
65
|
const components = createComponentInstances();
|
|
@@ -93,9 +91,6 @@ const createRbacConfig = ({ dispatch, drawerButtonCancel, drawerButtonSave, draw
|
|
|
93
91
|
// STABLE PAGE COMPONENT (created once, outside render)
|
|
94
92
|
// ============================================================================
|
|
95
93
|
const GenericRbacPage = createGenericModulePage();
|
|
96
|
-
// ============================================================================
|
|
97
|
-
// INNER PAGE (requires RbacProvider context)
|
|
98
|
-
// ============================================================================
|
|
99
94
|
const RbacPageInner = (props) => {
|
|
100
95
|
const context = useRbacModule();
|
|
101
96
|
// Memoize config creation — destructure props to avoid object reference changes
|
|
@@ -133,10 +128,9 @@ const RbacPageInner = (props) => {
|
|
|
133
128
|
if (!hasPermission) {
|
|
134
129
|
return _jsx(RbacNoAccess, { moduleName: "Workspace" });
|
|
135
130
|
}
|
|
136
|
-
// If the assign-permissions drawer is open, render it inline instead
|
|
137
|
-
if (context.state.drawer === RBAC_DRAWER.ASSIGN_PERMISSIONS_DRAWER) {
|
|
138
|
-
return (_jsxs("div", { className: "p-4", children: [_jsx("div", { className: "mb-4 flex items-center gap-2", children: _jsx("button", { className: "text-muted-foreground text-sm underline", onClick: () => context.closeDrawer(), children: "\u2190 Back to roles" }) }), _jsx(AssignPermissions, {})] }));
|
|
139
|
-
}
|
|
140
131
|
return (_jsx("div", { className: "p-4", children: _jsx(GenericRbacPage, { context: context, overrideConfig: rbacConfig, tableBodyCols: tableBodyCols }) }));
|
|
141
132
|
};
|
|
133
|
+
// ============================================================================
|
|
134
|
+
// PAGE EXPORTS
|
|
135
|
+
// ============================================================================
|
|
142
136
|
export const RbacPage = (props) => (_jsx(RbacProvider, { children: _jsx(RbacPageInner, Object.assign({}, props)) }));
|