cabloy 5.1.190 → 5.1.191

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.
Files changed (23) hide show
  1. package/.cabloy-version +1 -1
  2. package/CHANGELOG.md +10 -0
  3. package/README.md +2 -2
  4. package/package.json +1 -1
  5. package/repo-docs/.vitepress/config.mjs +1 -0
  6. package/repo-docs/demo.md +12 -0
  7. package/repo-docs/index.md +3 -0
  8. package/zova/packages-zova/zova/package.json +2 -2
  9. package/zova/src/suite/a-home/modules/home-passport/src/model/passport.ts +2 -7
  10. package/zova/src/suite/cabloy-basic/modules/basic-details/src/bean/tableCell.actionOperationsRow.tsx +19 -13
  11. package/zova/src/suite/cabloy-basic/modules/basic-details/src/component/blockDetails/controller.tsx +11 -0
  12. package/zova/src/suite/cabloy-basic/modules/basic-details/src/component/blockToolbarBulk/controller.tsx +7 -4
  13. package/zova/src/suite/cabloy-basic/modules/basic-details/src/component/formFieldDetails/controller.tsx +14 -0
  14. package/zova/src/suite/cabloy-basic/modules/basic-details/src/lib/detailsPermissions.ts +65 -0
  15. package/zova/src/suite/cabloy-basic/modules/basic-details/src/lib/index.ts +1 -0
  16. package/zova/src/suite/cabloy-basic/modules/basic-details/src/lib/utils.ts +3 -3
  17. package/zova/src/suite/cabloy-basic/modules/basic-details/src/types/details.ts +6 -1
  18. package/zova/src/suite/cabloy-basic/modules/basic-details/test/lib/detailsPermissions.test.ts +125 -0
  19. package/zova/src/suite-vendor/a-zova/modules/a-openapi/package.json +1 -1
  20. package/zova/src/suite-vendor/a-zova/modules/a-openapi/src/types/permissions.ts +2 -8
  21. package/zova/src/suite-vendor/a-zova/modules/a-table/package.json +1 -1
  22. package/zova/src/suite-vendor/a-zova/modules/a-table/src/component/table/controller.tsx +2 -1
  23. package/zova/src/suite-vendor/a-zova/package.json +3 -3
package/.cabloy-version CHANGED
@@ -1 +1 @@
1
- 5.1.190
1
+ 5.1.191
package/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # Changelog
2
2
 
3
+ ## 5.1.191
4
+
5
+ ### Features
6
+
7
+ - Update functionality with the latest enhancements.
8
+
9
+ ### Improvements
10
+
11
+ - Refresh the demo and documentation in the README and index pages.
12
+
3
13
  ## 5.1.190
4
14
 
5
15
  ### Features
package/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
  [![npm version](https://img.shields.io/npm/v/cabloy.svg?style=flat-square&label=cabloy)](https://www.npmjs.com/package/cabloy)
5
5
  [![npm downloads](https://img.shields.io/npm/dm/cabloy?color=orange&label=downloads)](https://www.npmjs.com/package/cabloy)
6
6
  [![Docs](https://img.shields.io/badge/docs-cabloy-4f46e5.svg?style=flat-square)](https://cabloy.com)
7
- [![Demo](https://img.shields.io/badge/demo-cabloy.com-059669.svg?style=flat-square)](https://cabloy.com)
7
+ [![Demo](https://img.shields.io/badge/demo-cabloy.com-059669.svg?style=flat-square)](https://cabloy.com/demo)
8
8
 
9
9
  Cabloy is a Node.js fullstack framework for AI vibe coding, with AI Spec-Driven Development for traceable, evidence-backed delivery.
10
10
 
@@ -12,7 +12,7 @@ Cabloy is a Node.js fullstack framework for AI vibe coding, with AI Spec-Driven
12
12
 
13
13
  Instead of stitching separate backend and frontend stacks together, Cabloy keeps their contracts, tooling, and guidance connected in one repository. [AI Spec-Driven Development](https://cabloy.com/ai/ai-spec-driven-development) provides the disciplined path from confirmed Specs to evidence-backed delivery; its precise engineering method is Traceable Spec Delivery. Vona is its backend framework and runtime layer, and Zova is its frontend framework and application layer. Cabloy Basic and Cabloy Start are related, complete edition baselines built on that shared architecture; see [Editions Overview](https://cabloy.com/editions/overview) for their deliberate differences.
14
14
 
15
- [Documentation](https://cabloy.com) · [npm](https://www.npmjs.com/package/cabloy) · [Web Demo](https://cabloy.com) · [Admin Demo](https://cabloy.com/admin) · [GitHub](https://github.com/cabloy/cabloy)
15
+ [Documentation](https://cabloy.com) · [npm](https://www.npmjs.com/package/cabloy) · [Demo](https://cabloy.com/demo) · [GitHub](https://github.com/cabloy/cabloy)
16
16
 
17
17
  ## Fullstack Principles
18
18
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cabloy",
3
- "version": "5.1.190",
3
+ "version": "5.1.191",
4
4
  "gitHead": "2c5c19284bab738e492856189acb6fad74b8a7b7",
5
5
  "description": "A Node.js fullstack framework",
6
6
  "keywords": [
@@ -245,6 +245,7 @@ export default defineConfig({
245
245
  { text: 'Frontend (Zova)', link: '/frontend/introduction', activeMatch: '^/frontend/' },
246
246
  ],
247
247
  },
248
+ { text: 'Demo', link: '/demo' },
248
249
  { text: 'Blogs', link: '/blogs/', activeMatch: '^/blogs/' },
249
250
  { text: 'Editions', link: '/editions/overview', activeMatch: '^/editions/' },
250
251
  { text: 'AI Development', link: '/ai/introduction', activeMatch: '^/ai/' },
@@ -0,0 +1,12 @@
1
+ ---
2
+ title: Demo
3
+ ---
4
+
5
+ # Demo
6
+
7
+ Explore the Cabloy demonstration sites:
8
+
9
+ | Site | URL |
10
+ | ---------- | ---------------------------------------------------------------- |
11
+ | Web site | [https://demo.cabloy.com/](https://demo.cabloy.com/) |
12
+ | Admin site | [https://demo.cabloy.com/admin/](https://demo.cabloy.com/admin/) |
@@ -9,6 +9,9 @@ hero:
9
9
  - theme: brand
10
10
  text: Get Started
11
11
  link: /fullstack/quickstart
12
+ - theme: alt
13
+ text: Demo
14
+ link: /demo
12
15
  - theme: alt
13
16
  text: Editions
14
17
  link: /editions/overview
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zova",
3
- "version": "5.1.166",
3
+ "version": "5.1.167",
4
4
  "gitHead": "2c5c19284bab738e492856189acb6fad74b8a7b7",
5
5
  "description": "A vue3 framework with ioc",
6
6
  "keywords": [
@@ -46,7 +46,7 @@
46
46
  },
47
47
  "dependencies": {
48
48
  "zova-core": "^5.1.92",
49
- "zova-suite-a-zova": "^5.1.165"
49
+ "zova-suite-a-zova": "^5.1.166"
50
50
  },
51
51
  "devDependencies": {
52
52
  "clean-package": "^2.2.0",
@@ -10,12 +10,7 @@ import type {
10
10
  import { combineQueries, isNil } from '@cabloy/utils';
11
11
  import { SchemaObject } from 'openapi3-ts/oas31';
12
12
  import { $QueryEnsureFresh, $QueryGetFresh, BeanModelBase, Model } from 'zova-module-a-model';
13
- import {
14
- IPermissionHintGeneral,
15
- IResourceFormActionRowNameRecord,
16
- IResourceTableActionNameRecord,
17
- TypeOpenapiPermissions,
18
- } from 'zova-module-a-openapi';
13
+ import { IPermissionHintGeneral, TypeOpenapiPermissions } from 'zova-module-a-openapi';
19
14
  import { ApiApiHomeUserPassportloginOauthPath, OpenApiBaseURL } from 'zova-module-home-api';
20
15
  import { isRoleSiteAdmitted } from 'zova-module-home-base';
21
16
 
@@ -272,7 +267,7 @@ export class ModelPassport extends BeanModelBase {
272
267
 
273
268
  public checkPermission(
274
269
  permissions: TypeOpenapiPermissions | undefined,
275
- actionName?: keyof (IResourceTableActionNameRecord & IResourceFormActionRowNameRecord),
270
+ actionName?: string,
276
271
  permissionHint?: IPermissionHintGeneral,
277
272
  currentData?: Record<string, unknown> | readonly Record<string, unknown>[],
278
273
  ): boolean {
@@ -14,7 +14,8 @@ import { VNode } from 'vue';
14
14
  import { BeanBase } from 'zova';
15
15
  import { TableCell } from 'zova-module-a-table';
16
16
 
17
- import { checkPermission } from '../lib/utils.js';
17
+ import { filterDetailsRowActions } from '../lib/detailsPermissions.js';
18
+ import { checkFormScene } from '../lib/utils.js';
18
19
 
19
20
  declare module 'zova-module-a-openapi' {
20
21
  export interface IResourceDetailsActionRowRecord {
@@ -37,16 +38,16 @@ export class TableCellActionOperationsRow extends BeanBase implements ITableCell
37
38
  const { $celScope, $$table } = renderContext;
38
39
  const actions = options.actions;
39
40
  if (!actions || actions.length === 0) return false;
40
- // renders
41
+ const $$details = $celScope.$$details!;
42
+ const actionsVisible = actions.filter(action => {
43
+ return checkFormScene($$details.formScene, action.options?.permission);
44
+ });
41
45
  const renders: TypeTableCellRenderComponent[] = [];
42
- for (const action of actions) {
46
+ for (const action of actionsVisible) {
43
47
  const actionName = action.name;
44
48
  const actionRender = action.render;
45
- const permissionHint = action.options?.permission;
46
- if (checkPermission($celScope.formMeta!.formScene!, permissionHint)) {
47
- if (!actionRender) throw new Error(`should specify action render: ${actionName}`);
48
- renders.push(actionRender);
49
- }
49
+ if (!actionRender) throw new Error(`should specify action render: ${actionName}`);
50
+ renders.push(actionRender);
50
51
  }
51
52
  await $$table.cellRenderPrepare(renders);
52
53
  return renders.length > 0;
@@ -60,13 +61,18 @@ export class TableCellActionOperationsRow extends BeanBase implements ITableCell
60
61
  const { $celScope, $$table } = renderContext;
61
62
  const actions = options.actions;
62
63
  if (!actions || actions.length === 0) return;
64
+ const $$details = $celScope.$$details!;
65
+ const actionsAllowed = filterDetailsRowActions(
66
+ $$details.formScene,
67
+ $$details.checkPermission.bind($$details),
68
+ actions,
69
+ );
63
70
  const domActions: VNode[] = [];
64
- actions.forEach((action, index) => {
65
- const permissionHint = action.options?.permission;
66
- if (!checkPermission($celScope.formMeta!.formScene!, permissionHint)) return;
67
- const options2 = Object.assign({ key: index }, action.options);
68
- domActions.push($$table.cellRender(action.render!, options2, renderContext));
71
+ actionsAllowed.forEach((action, index) => {
72
+ const actionOptions = Object.assign({ key: index }, action.options);
73
+ domActions.push($$table.cellRender(action.render!, actionOptions, renderContext));
69
74
  });
75
+ if (domActions.length === 0) return;
70
76
  return <div class={options.class}>{domActions}</div>;
71
77
  }
72
78
  }
@@ -13,6 +13,8 @@ import {
13
13
  } from 'zova-module-a-openapi';
14
14
  import { BeanControllerTableBase } from 'zova-module-a-table';
15
15
 
16
+ import type { TypeDetailsCheckPermission } from '../../types/details.js';
17
+
16
18
  declare module 'zova-module-a-openapi' {
17
19
  export interface IResourceBlockRecord {
18
20
  'basic-details:blockDetails'?: ControllerBlockDetailsProps;
@@ -26,6 +28,7 @@ export interface ControllerBlockDetailsProps<
26
28
  formMeta?: IFormMeta;
27
29
  schemaRow?: ISchemaObjectExtensionField;
28
30
  schemaForm?: ISchemaObjectExtensionField;
31
+ checkPermission?: TypeDetailsCheckPermission;
29
32
  getDetailItems?: () => TData[] | undefined;
30
33
  setDetailItems?: (detailItems: TData[]) => void;
31
34
  }
@@ -70,6 +73,14 @@ export class ControllerBlockDetails<TData extends {} = {}> extends BeanControlle
70
73
  return this.$props.schemaForm!;
71
74
  }
72
75
 
76
+ checkPermission(...args: Parameters<TypeDetailsCheckPermission>) {
77
+ const checkPermission = this.$props.checkPermission;
78
+ if (!checkPermission) {
79
+ throw new Error('should provide enclosing Resource permission checker for details');
80
+ }
81
+ return checkPermission(...args);
82
+ }
83
+
73
84
  public async setTableRef(tableRef: BeanControllerTableBase<TData> | undefined) {
74
85
  this.tableRef = tableRef;
75
86
  }
@@ -9,7 +9,7 @@ import { VNode } from 'vue';
9
9
  import { BeanControllerBase, Use } from 'zova';
10
10
  import { Controller } from 'zova-module-a-bean';
11
11
 
12
- import { checkPermission } from '../../lib/utils.js';
12
+ import { filterDetailsBulkActions } from '../../lib/detailsPermissions.js';
13
13
 
14
14
  declare module 'zova-module-a-openapi' {
15
15
  export interface IResourceBlockRecord {
@@ -46,9 +46,12 @@ export class ControllerBlockToolbarBulk extends BeanControllerBase {
46
46
  const actions = this.$props.actions;
47
47
  if (!actions || actions.length === 0) return;
48
48
  const domActions: VNode[] = [];
49
- actions.forEach((action, index) => {
50
- const permissionHint = action.options?.permission;
51
- if (!checkPermission($$details.formScene, permissionHint)) return;
49
+ const allowedActions = filterDetailsBulkActions(
50
+ $$details.formScene,
51
+ $$details.checkPermission.bind($$details),
52
+ actions,
53
+ );
54
+ allowedActions.forEach((action, index) => {
52
55
  const options = Object.assign({ key: index }, action.options);
53
56
  const domAction = $jsx.render(action.render!, options, $celScope, this.$$renderContext);
54
57
  if (!domAction) return;
@@ -8,6 +8,7 @@ import type {
8
8
  IResourceFormFieldOptionsBase,
9
9
  ISchemaObjectExtensionField,
10
10
  TypeFormScene,
11
+ TypeOpenapiPermissions,
11
12
  } from 'zova-module-a-openapi';
12
13
 
13
14
  import { VNode } from 'vue';
@@ -16,6 +17,10 @@ import { ZovaJsx } from 'zova-jsx';
16
17
  import { Controller } from 'zova-module-a-bean';
17
18
  import { formMetaFromFormScene, ZFormField } from 'zova-module-a-form';
18
19
 
20
+ import type { TypeDetailsCheckPermission } from '../../types/details.js';
21
+
22
+ import { createDetailsPermissionChecker } from '../../lib/detailsPermissions.js';
23
+
19
24
  declare module 'zova-module-a-openapi' {
20
25
  export interface IResourceFormFieldRecord {
21
26
  'basic-details:formFieldDetails'?: IResourceFormFieldDetailsOptions;
@@ -76,6 +81,14 @@ export class ControllerFormFieldDetails extends BeanControllerBase {
76
81
  // blocks
77
82
  const blocks = schemaRow?.rest?.blocks;
78
83
  if (!blocks || blocks.length === 0) return;
84
+ const checkPermission: TypeDetailsCheckPermission = createDetailsPermissionChecker(
85
+ () =>
86
+ (formFieldRenderContext.celScope as { permissions?: TypeOpenapiPermissions }).permissions,
87
+ () => $$formField.$$form.formState.values as Record<string, unknown>,
88
+ (permissions, actionName, permissionHint, currentData) => {
89
+ return this.$passport.checkPermission(permissions, actionName, permissionHint, currentData);
90
+ },
91
+ );
79
92
  const domBlocks: VNode[] = [];
80
93
  blocks.forEach((block, index) => {
81
94
  const options = deepExtend(
@@ -92,6 +105,7 @@ export class ControllerFormFieldDetails extends BeanControllerBase {
92
105
  },
93
106
  },
94
107
  block.options,
108
+ { checkPermission },
95
109
  );
96
110
  const domBlock = this.jsxZova.render(block.render!, options);
97
111
  if (!domBlock) return;
@@ -0,0 +1,65 @@
1
+ import type {
2
+ IPermissionHintGeneral,
3
+ IResourceRenderDetailsActionBulkOptionsAction,
4
+ IResourceRenderDetailsActionRowOptionsAction,
5
+ TypeFormScene,
6
+ TypeOpenapiPermissions,
7
+ } from 'zova-module-a-openapi';
8
+
9
+ import type { TypeDetailsCheckPermission } from '../types/details.js';
10
+
11
+ import { checkFormScene } from './utils.js';
12
+
13
+ export interface IDetailsPermissionAction {
14
+ name?: string;
15
+ options?: { permission?: IPermissionHintGeneral };
16
+ }
17
+
18
+ export function createDetailsPermissionChecker(
19
+ getPermissions: () => TypeOpenapiPermissions | undefined,
20
+ getCurrentData: () => Record<string, unknown> | undefined,
21
+ checkPermission: (
22
+ permissions: TypeOpenapiPermissions | undefined,
23
+ actionName?: string,
24
+ permissionHint?: IPermissionHintGeneral,
25
+ currentData?: Record<string, unknown>,
26
+ ) => boolean,
27
+ ): TypeDetailsCheckPermission {
28
+ return (actionName, permissionHint) => {
29
+ return checkPermission(getPermissions(), actionName, permissionHint, getCurrentData());
30
+ };
31
+ }
32
+
33
+ export function isDetailsActionAllowed(
34
+ formScene: TypeFormScene,
35
+ checkPermission: TypeDetailsCheckPermission,
36
+ action: IDetailsPermissionAction,
37
+ ): boolean {
38
+ const permissionHint = action.options?.permission;
39
+ return checkFormScene(formScene, permissionHint) && checkPermission(action.name, permissionHint);
40
+ }
41
+
42
+ export function filterDetailsActions<TAction extends IDetailsPermissionAction>(
43
+ formScene: TypeFormScene,
44
+ checkPermission: TypeDetailsCheckPermission,
45
+ actions: TAction[] | undefined,
46
+ ): TAction[] {
47
+ if (!actions || actions.length === 0) return [];
48
+ return actions.filter(action => isDetailsActionAllowed(formScene, checkPermission, action));
49
+ }
50
+
51
+ export function filterDetailsBulkActions(
52
+ formScene: TypeFormScene,
53
+ checkPermission: TypeDetailsCheckPermission,
54
+ actions: IResourceRenderDetailsActionBulkOptionsAction[] | undefined,
55
+ ) {
56
+ return filterDetailsActions(formScene, checkPermission, actions);
57
+ }
58
+
59
+ export function filterDetailsRowActions(
60
+ formScene: TypeFormScene,
61
+ checkPermission: TypeDetailsCheckPermission,
62
+ actions: IResourceRenderDetailsActionRowOptionsAction[] | undefined,
63
+ ) {
64
+ return filterDetailsActions(formScene, checkPermission, actions);
65
+ }
@@ -1 +1,2 @@
1
+ export * from './detailsPermissions.js';
1
2
  export * from './utils.js';
@@ -1,8 +1,8 @@
1
- import { IPermissionHintDetailsActionBulk, TypeFormScene } from 'zova-module-a-openapi';
1
+ import type { IPermissionHintGeneral, TypeFormScene } from 'zova-module-a-openapi';
2
2
 
3
- export function checkPermission(
3
+ export function checkFormScene(
4
4
  formScene: TypeFormScene,
5
- permissionHint?: IPermissionHintDetailsActionBulk,
5
+ permissionHint?: IPermissionHintGeneral,
6
6
  ): boolean {
7
7
  const formSceneHint = permissionHint?.formScene;
8
8
  if (!formSceneHint) return true;
@@ -1,9 +1,14 @@
1
1
  import 'zova-module-a-table';
2
2
  import 'zova-module-a-openapi';
3
- import type { IDetailsScope } from 'zova-module-a-openapi';
3
+ import type { IDetailsScope, IPermissionHintGeneral } from 'zova-module-a-openapi';
4
4
 
5
5
  import { ControllerBlockDetails } from '../component/blockDetails/controller.jsx';
6
6
 
7
+ export type TypeDetailsCheckPermission = (
8
+ actionName?: string,
9
+ permissionHint?: IPermissionHintGeneral,
10
+ ) => boolean;
11
+
7
12
  declare module 'zova-module-a-openapi' {
8
13
  export interface IJsxRenderContextDetails<TData extends {} = {}> {
9
14
  $$details: ControllerBlockDetails<TData>;
@@ -0,0 +1,125 @@
1
+ import type { IPermissionHintGeneral, TypeOpenapiPermissions } from 'zova-module-a-openapi';
2
+
3
+ import assert from 'node:assert/strict';
4
+ import test from 'node:test';
5
+
6
+ import {
7
+ createDetailsPermissionChecker,
8
+ filterDetailsBulkActions,
9
+ filterDetailsRowActions,
10
+ } from '../../src/lib/detailsPermissions.js';
11
+
12
+ test('details permission checker lazily reads the current enclosing Resource projection', () => {
13
+ let permissions: TypeOpenapiPermissions | undefined = true;
14
+ let currentData: Record<string, unknown> = { departmentId: 7 };
15
+ const calls: unknown[][] = [];
16
+ const checkPermission = createDetailsPermissionChecker(
17
+ () => permissions,
18
+ () => currentData,
19
+ (...args) => {
20
+ calls.push(args);
21
+ return true;
22
+ },
23
+ );
24
+ const permissionHint: IPermissionHintGeneral = { actionInherit: 'view' };
25
+
26
+ const firstPermissions = permissions;
27
+ const firstCurrentData = currentData;
28
+ assert.equal(checkPermission('grantSystemAdmin', permissionHint), true);
29
+ permissions = false;
30
+ currentData = { departmentId: 8 };
31
+ assert.equal(checkPermission('grantSystemAdmin', permissionHint), true);
32
+
33
+ assert.equal(calls.length, 2);
34
+ assert.strictEqual(calls[0][0], firstPermissions);
35
+ assert.strictEqual(calls[1][0], permissions);
36
+ assert.strictEqual(calls[0][3], firstCurrentData);
37
+ assert.strictEqual(calls[1][3], currentData);
38
+ assert.deepEqual(
39
+ calls.map(call => call.slice(1, 3)),
40
+ [
41
+ ['grantSystemAdmin', permissionHint],
42
+ ['grantSystemAdmin', permissionHint],
43
+ ],
44
+ );
45
+ assert.equal(
46
+ calls.every(call => call.length === 4),
47
+ true,
48
+ );
49
+ });
50
+
51
+ test('bulk details actions apply form-scene filtering before the enclosing Resource checker', () => {
52
+ const calls: Array<[string | undefined, IPermissionHintGeneral | undefined]> = [];
53
+ const grantHint = { actionInherit: 'view', formScene: ['view'] };
54
+ const actions = [
55
+ {
56
+ name: 'hiddenInView',
57
+ render: 'test:hiddenInView',
58
+ options: { permission: { formScene: ['edit'] } },
59
+ },
60
+ {
61
+ name: 'denied',
62
+ render: 'test:denied',
63
+ options: { permission: { formScene: ['view'] } },
64
+ },
65
+ {
66
+ name: 'grantSystemAdmin',
67
+ render: 'test:grantSystemAdmin',
68
+ options: { permission: grantHint },
69
+ },
70
+ ];
71
+
72
+ const allowed = filterDetailsBulkActions(
73
+ 'view',
74
+ (actionName, permissionHint) => {
75
+ calls.push([actionName, permissionHint]);
76
+ return actionName === 'grantSystemAdmin';
77
+ },
78
+ actions as any,
79
+ );
80
+
81
+ assert.deepEqual(
82
+ allowed.map(action => action.name),
83
+ ['grantSystemAdmin'],
84
+ );
85
+ assert.deepEqual(
86
+ calls.map(([actionName]) => actionName),
87
+ ['denied', 'grantSystemAdmin'],
88
+ );
89
+ assert.strictEqual(calls[1][1], grantHint);
90
+ });
91
+
92
+ test('row details actions use the same enclosing Resource checker and form-scene gate', () => {
93
+ const calls: string[] = [];
94
+ const actions = [
95
+ {
96
+ name: 'hiddenInView',
97
+ render: 'test:hiddenInView',
98
+ options: { permission: { formScene: ['edit'] } },
99
+ },
100
+ {
101
+ name: 'allowed',
102
+ render: 'test:allowed',
103
+ options: { permission: { public: true } },
104
+ },
105
+ {
106
+ name: 'denied',
107
+ render: 'test:denied',
108
+ },
109
+ ];
110
+
111
+ const allowed = filterDetailsRowActions(
112
+ 'view',
113
+ actionName => {
114
+ calls.push(actionName!);
115
+ return actionName === 'allowed';
116
+ },
117
+ actions as any,
118
+ );
119
+
120
+ assert.deepEqual(
121
+ allowed.map(action => action.name),
122
+ ['allowed'],
123
+ );
124
+ assert.deepEqual(calls, ['allowed', 'denied']);
125
+ });
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zova-module-a-openapi",
3
- "version": "5.1.54",
3
+ "version": "5.1.55",
4
4
  "gitHead": "09d901d17140a80ee0764211b441cda72fd94663",
5
5
  "description": "",
6
6
  "keywords": [
@@ -52,12 +52,6 @@ export interface IPermissionHintTableActionBulk {
52
52
  public?: boolean;
53
53
  }
54
54
 
55
- export interface IPermissionHintDetailsActionRow {
56
- formScene?: TypeFormScene | TypeFormScene[];
57
- }
55
+ export interface IPermissionHintDetailsActionRow extends IPermissionHintGeneral {}
58
56
 
59
- export interface IPermissionHintDetailsActionBulk {
60
- // actionInherit?: keyof IResourceDetailsActionBulkNameRecord;
61
- // public?: boolean;
62
- formScene?: TypeFormScene | TypeFormScene[];
63
- }
57
+ export interface IPermissionHintDetailsActionBulk extends IPermissionHintGeneral {}
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zova-module-a-table",
3
- "version": "5.1.43",
3
+ "version": "5.1.44",
4
4
  "gitHead": "09d901d17140a80ee0764211b441cda72fd94663",
5
5
  "description": "",
6
6
  "keywords": [
@@ -1,4 +1,5 @@
1
1
  import type {
2
+ IResourceDetailsActionRowOptionsBase,
2
3
  IResourceTableActionRowOptionsBase,
3
4
  ISchemaObjectExtensionField,
4
5
  ISchemaObjectExtensionFieldRest,
@@ -466,7 +467,7 @@ export class ControllerTable<TData extends {} = {}> extends BeanControllerTableB
466
467
 
467
468
  public cellRender(
468
469
  render: TypeTableCellRenderComponent,
469
- columnProps: IResourceTableActionRowOptionsBase,
470
+ columnProps: IResourceTableActionRowOptionsBase | IResourceDetailsActionRowOptionsBase,
470
471
  renderContext: IJsxRenderContextTableCell,
471
472
  ) {
472
473
  // render
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zova-suite-a-zova",
3
- "version": "5.1.165",
3
+ "version": "5.1.166",
4
4
  "gitHead": "2c5c19284bab738e492856189acb6fad74b8a7b7",
5
5
  "description": "zova",
6
6
  "license": "MIT",
@@ -21,7 +21,7 @@
21
21
  "zova-module-a-logger": "^5.1.28",
22
22
  "zova-module-a-meta": "^5.1.22",
23
23
  "zova-module-a-model": "^5.1.37",
24
- "zova-module-a-openapi": "^5.1.54",
24
+ "zova-module-a-openapi": "^5.1.55",
25
25
  "zova-module-a-router": "^5.1.41",
26
26
  "zova-module-a-routerstack": "^5.1.29",
27
27
  "zova-module-a-routertabs": "^5.1.34",
@@ -29,7 +29,7 @@
29
29
  "zova-module-a-ssrhmr": "^5.1.23",
30
30
  "zova-module-a-ssrserver": "^5.1.26",
31
31
  "zova-module-a-style": "^5.1.35",
32
- "zova-module-a-table": "^5.1.43",
32
+ "zova-module-a-table": "^5.1.44",
33
33
  "zova-module-a-zod": "^5.1.37",
34
34
  "zova-module-a-zova": "^5.1.108"
35
35
  },