@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?: unknown) => void;
143
- handleEdit: (row?: unknown) => void;
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?: unknown) => void;
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
- const record = row;
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
- const record = row;
272
- byIdFetchNow === null || byIdFetchNow === void 0 ? void 0 : byIdFetchNow(undefined, { params: { id: record === null || record === void 0 ? void 0 : record.id } });
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
- const record = row;
280
- if (confirm(t("messagesDeleteConfirmation"))) {
281
- deleteFetchNow === null || deleteFetchNow === void 0 ? void 0 : deleteFetchNow(undefined, { params: { id: record === null || record === void 0 ? void 0 : record.id } });
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
- try {
366
- const res = await fetch(`${RBAC_API_ROUTES.PERMISSIONS_LIST}?pageLimit=1000`, {
367
- headers: {
368
- "Content-Type": "application/json",
369
- "x-api-token": process.env.NEXT_PUBLIC_API_KEY,
370
- },
371
- });
372
- if (!res.ok)
373
- throw new Error("Failed to load permissions");
374
- const data = (await res.json());
375
- dispatch({
376
- type: RBAC_EXTENDED_ACTION_TYPES.SET_AVAILABLE_PERMISSIONS,
377
- payload: { permissions: data.items },
378
- });
379
- }
380
- catch (_a) {
381
- showToast(t("messagesFetchFailed"), TOAST_VARIANT.ERROR);
382
- }
383
- }, [dispatch, showToast, t]);
384
- const handleManagePermissions = useCallback(async (row) => {
385
- const record = row;
386
- await (byIdFetchNow === null || byIdFetchNow === void 0 ? void 0 : byIdFetchNow(undefined, { params: { id: record === null || record === void 0 ? void 0 : record.id } }));
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: RBAC_EXTENDED_ACTION_TYPES.SET_TOGGLING_PERMISSION,
397
- payload: { toggling: true },
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: RBAC_EXTENDED_ACTION_TYPES.SET_TOGGLING_PERMISSION,
430
- payload: { toggling: false },
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: true,
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, handleManagePermissions, handleView, t]);
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 (_jsx("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" })] }) }));
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, jsxs as _jsxs } from "react/jsx-runtime";
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, RBAC_DRAWER, } from "./context";
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)) }));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@appcorp/fusion-storybook",
3
- "version": "0.1.72",
3
+ "version": "0.1.74",
4
4
  "scripts": {
5
5
  "build-storybook": "storybook build",
6
6
  "build:next": "next build",