cabloy 5.1.168 → 5.1.170

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 (84) hide show
  1. package/.cabloy-version +1 -1
  2. package/CHANGELOG.md +15 -0
  3. package/package.json +1 -1
  4. package/repo-e2e/specs/cabloy-basic.spec.ts +45 -0
  5. package/vona/packages-cli/cli/package.json +1 -1
  6. package/vona/packages-cli/cli-set-api/cli/templates/tools/crudBasic/boilerplate/src/dto/{{resourceName}}SelectResItem.tsx_ +4 -0
  7. package/vona/packages-cli/cli-set-api/cli/templates/tools/crudStart/boilerplate/src/dto/{{resourceName}}SelectResItem.tsx_ +4 -0
  8. package/vona/packages-cli/cli-set-api/package.json +1 -1
  9. package/vona/pnpm-lock.yaml +83 -106
  10. package/vona/src/suite/a-training/modules/training-student/src/dto/studentSelectResItem.tsx +4 -0
  11. package/vona/src/suite/a-training/modules/training-student/test/student.test.ts +5 -0
  12. package/vona/src/suite-vendor/a-cabloy/modules/a-layoutprofile/package.json +54 -0
  13. package/vona/src/suite-vendor/a-cabloy/modules/a-layoutprofile/src/.metadata/index.ts +346 -0
  14. package/vona/src/suite-vendor/a-cabloy/modules/a-layoutprofile/src/.metadata/this.ts +2 -0
  15. package/vona/src/suite-vendor/a-cabloy/modules/a-layoutprofile/src/bean/meta.index.ts +12 -0
  16. package/vona/src/suite-vendor/a-cabloy/modules/a-layoutprofile/src/bean/meta.redlock.ts +11 -0
  17. package/vona/src/suite-vendor/a-cabloy/modules/a-layoutprofile/src/bean/meta.version.ts +20 -0
  18. package/vona/src/suite-vendor/a-cabloy/modules/a-layoutprofile/src/controller/layoutprofile.ts +38 -0
  19. package/vona/src/suite-vendor/a-cabloy/modules/a-layoutprofile/src/dto/layoutProfile.tsx +26 -0
  20. package/vona/src/suite-vendor/a-cabloy/modules/a-layoutprofile/src/dto/layoutProfileLoad.tsx +13 -0
  21. package/vona/src/suite-vendor/a-cabloy/modules/a-layoutprofile/src/dto/layoutProfileSave.tsx +31 -0
  22. package/vona/src/suite-vendor/a-cabloy/modules/a-layoutprofile/src/entity/layoutprofile.ts +20 -0
  23. package/vona/src/suite-vendor/a-cabloy/modules/a-layoutprofile/src/index.ts +2 -0
  24. package/vona/src/suite-vendor/a-cabloy/modules/a-layoutprofile/src/model/layoutprofile.ts +10 -0
  25. package/vona/src/suite-vendor/a-cabloy/modules/a-layoutprofile/src/service/layoutprofile.ts +64 -0
  26. package/vona/src/suite-vendor/a-cabloy/modules/a-layoutprofile/src/types/index.ts +1 -0
  27. package/vona/src/suite-vendor/a-cabloy/modules/a-layoutprofile/src/types/layoutprofile.ts +21 -0
  28. package/vona/src/suite-vendor/a-cabloy/modules/a-layoutprofile/test/layoutprofile.test.ts +258 -0
  29. package/vona/src/suite-vendor/a-cabloy/modules/a-layoutprofile/tsconfig.build.json +11 -0
  30. package/vona/src/suite-vendor/a-cabloy/modules/a-layoutprofile/tsconfig.json +7 -0
  31. package/vona/src/suite-vendor/a-cabloy/package.json +2 -1
  32. package/vona/src/suite-vendor/a-cabloy/tsconfig.json +3 -0
  33. package/zova/packages-zova/zova/package.json +2 -2
  34. package/zova/pnpm-lock.yaml +21 -6
  35. package/zova/src/suite/a-home/modules/home-base/src/service/ssrLayout.ts +20 -10
  36. package/zova/src/suite/cabloy-basic/modules/basic-app/src/component/routedDialog/controller.tsx +2 -0
  37. package/zova/src/suite/cabloy-basic/modules/basic-app/src/types/appModal.ts +3 -0
  38. package/zova/src/suite/cabloy-basic/modules/basic-page/src/component/blockPage/controller.tsx +44 -1
  39. package/zova/src/suite/cabloy-basic/modules/basic-page/src/component/blockTable/controller.tsx +1 -0
  40. package/zova/src/suite/cabloy-basic/modules/basic-page/src/component/blockToolbarBulk/controller.tsx +40 -25
  41. package/zova/src/suite/cabloy-basic/modules/basic-page/src/lib/selection.ts +11 -0
  42. package/zova/src/suite/cabloy-basic/modules/basic-page/test/lib/selection.test.ts +23 -0
  43. package/zova/src/suite/cabloy-basic/modules/basic-resource/src/component/formFieldResourcePicker/controller.tsx +5 -0
  44. package/zova/src/suite/cabloy-basic/modules/basic-resource/src/lib/resourcePickerPageHost.ts +64 -0
  45. package/zova/src/suite/cabloy-basic/modules/basic-resource/test/lib/resourcePickerPageHost.test.ts +94 -0
  46. package/zova/src/suite/cabloy-basic/modules/basic-table/src/.metadata/component/actionColumnConfig.ts +31 -0
  47. package/zova/src/suite/cabloy-basic/modules/basic-table/src/.metadata/index.ts +25 -12
  48. package/zova/src/suite/cabloy-basic/modules/basic-table/src/component/actionColumnConfig/controller.tsx +260 -0
  49. package/zova/src/suite/cabloy-basic/modules/basic-table/src/component/table/render.tsx +3 -3
  50. package/zova/src/suite/cabloy-basic/modules/basic-table/src/config/locale/en-us.ts +10 -0
  51. package/zova/src/suite/cabloy-basic/modules/basic-table/src/config/locale/zh-cn.ts +10 -0
  52. package/zova/src/suite-vendor/a-cabloy/modules/a-layoutprofile/cli/openapi.config.ts +9 -0
  53. package/zova/src/suite-vendor/a-cabloy/modules/a-layoutprofile/package.json +53 -0
  54. package/zova/src/suite-vendor/a-cabloy/modules/a-layoutprofile/src/.metadata/index.ts +140 -0
  55. package/zova/src/suite-vendor/a-cabloy/modules/a-layoutprofile/src/.metadata/this.ts +2 -0
  56. package/zova/src/suite-vendor/a-cabloy/modules/a-layoutprofile/src/api/layoutprofile.ts +67 -0
  57. package/zova/src/suite-vendor/a-cabloy/modules/a-layoutprofile/src/api/openapi/baseURL.ts +5 -0
  58. package/zova/src/suite-vendor/a-cabloy/modules/a-layoutprofile/src/api/openapi/index.ts +3 -0
  59. package/zova/src/suite-vendor/a-cabloy/modules/a-layoutprofile/src/api/openapi/schemas.ts +663 -0
  60. package/zova/src/suite-vendor/a-cabloy/modules/a-layoutprofile/src/api/openapi/types.ts +10150 -0
  61. package/zova/src/suite-vendor/a-cabloy/modules/a-layoutprofile/src/apiSchema/layoutprofile.ts +25 -0
  62. package/zova/src/suite-vendor/a-cabloy/modules/a-layoutprofile/src/index.ts +1 -0
  63. package/zova/src/suite-vendor/a-cabloy/modules/a-layoutprofile/src/model/layoutprofile.ts +76 -0
  64. package/zova/src/suite-vendor/a-cabloy/modules/a-layoutprofile/tsconfig.build.json +13 -0
  65. package/zova/src/suite-vendor/a-cabloy/modules/a-layoutprofile/tsconfig.json +5 -0
  66. package/zova/src/suite-vendor/a-cabloy/modules/rest-resource/package.json +1 -1
  67. package/zova/src/suite-vendor/a-cabloy/modules/rest-resource/src/lib/resourcePicker.ts +42 -0
  68. package/zova/src/suite-vendor/a-cabloy/modules/rest-resource/src/page/resourcePicker/controller.tsx +20 -79
  69. package/zova/src/suite-vendor/a-cabloy/package.json +3 -2
  70. package/zova/src/suite-vendor/a-zova/modules/a-bean/package.json +1 -1
  71. package/zova/src/suite-vendor/a-zova/modules/a-openapi/package.json +1 -1
  72. package/zova/src/suite-vendor/a-zova/modules/a-openapi/src/types/resource/tableActionBulk.ts +3 -0
  73. package/zova/src/suite-vendor/a-zova/modules/a-router/package.json +1 -1
  74. package/zova/src/suite-vendor/a-zova/modules/a-routerstack/package.json +1 -1
  75. package/zova/src/suite-vendor/a-zova/modules/a-ssr/package.json +1 -1
  76. package/zova/src/suite-vendor/a-zova/modules/a-ssr/src/lib/bodyReadyObserver.ts +13 -11
  77. package/zova/src/suite-vendor/a-zova/modules/a-table/package.json +1 -1
  78. package/zova/src/suite-vendor/a-zova/modules/a-table/src/component/table/controller.tsx +64 -2
  79. package/zova/src/suite-vendor/a-zova/modules/a-table/src/component/table/render.tsx +2 -3
  80. package/zova/src/suite-vendor/a-zova/modules/a-table/src/lib/beanControllerTableBase.ts +10 -0
  81. package/zova/src/suite-vendor/a-zova/modules/a-table/src/types/index.ts +1 -0
  82. package/zova/src/suite-vendor/a-zova/modules/a-table/src/types/tableLayout.ts +101 -0
  83. package/zova/src/suite-vendor/a-zova/modules/a-table/test/lib/tableLayout.test.ts +112 -0
  84. package/zova/src/suite-vendor/a-zova/package.json +7 -7
@@ -0,0 +1,25 @@
1
+ import type { IApiSchemaOptions } from 'zova-module-a-api';
2
+
3
+ import { BeanBase } from 'zova';
4
+ import { ApiSchema } from 'zova-module-a-api';
5
+
6
+ import {
7
+ ApiApiLayoutprofileloadPath,
8
+ ApiApiLayoutprofilesavePath,
9
+ ApiApiLayoutprofileresetPath,
10
+ } from '../api/layoutprofile.js';
11
+
12
+ @ApiSchema()
13
+ export class ApiSchemaLayoutprofile extends BeanBase {
14
+ load(options?: IApiSchemaOptions) {
15
+ return this.$sdk.createApiSchemas(ApiApiLayoutprofileloadPath, 'get', options);
16
+ }
17
+
18
+ save(options?: IApiSchemaOptions) {
19
+ return this.$sdk.createApiSchemas(ApiApiLayoutprofilesavePath, 'post', options);
20
+ }
21
+
22
+ reset(options?: IApiSchemaOptions) {
23
+ return this.$sdk.createApiSchemas(ApiApiLayoutprofileresetPath, 'delete', options);
24
+ }
25
+ }
@@ -0,0 +1 @@
1
+ export * from './.metadata/index.js';
@@ -0,0 +1,76 @@
1
+ import type { IDecoratorModelOptions } from 'zova-module-a-model';
2
+
3
+ import { BeanModelBase, Model } from 'zova-module-a-model';
4
+
5
+ import type {
6
+ ApiApiLayoutprofileloadResponseBody,
7
+ ApiApiLayoutprofileresetResponseBody,
8
+ ApiApiLayoutprofilesaveRequestBody,
9
+ ApiApiLayoutprofilesaveResponseBody,
10
+ } from '../api/layoutprofile.js';
11
+
12
+ export interface IModelOptionsLayoutProfile extends IDecoratorModelOptions {
13
+ enableSelector: true;
14
+ }
15
+
16
+ @Model<IModelOptionsLayoutProfile>({
17
+ enableSelector: true,
18
+ })
19
+ export class ModelLayoutProfile extends BeanModelBase {
20
+ layoutKey: string;
21
+
22
+ protected async __init__(layoutKey: string) {
23
+ if (!layoutKey) throw new Error('layout key not specified');
24
+ await super.__init__(layoutKey);
25
+ this.layoutKey = layoutKey;
26
+ }
27
+
28
+ load() {
29
+ if (this.$ssr.cookieDisabledOnServer || !this.$passport.isAuthenticated) return;
30
+ if (process.env.CLIENT && this.$ssr.profile === 'public' && this.$ssr.isRuntimeSsrPreHydration)
31
+ return;
32
+ return this.$useStateData<ApiApiLayoutprofileloadResponseBody>({
33
+ queryKey: ['load'],
34
+ queryFn: async () => {
35
+ return await this.scope.api.layoutprofile.load({
36
+ query: { layoutKey: this.layoutKey },
37
+ });
38
+ },
39
+ meta: {
40
+ disableErrorEffect: true,
41
+ },
42
+ });
43
+ }
44
+
45
+ save() {
46
+ return this.$useMutationData<
47
+ ApiApiLayoutprofilesaveResponseBody,
48
+ ApiApiLayoutprofilesaveRequestBody['profile']
49
+ >({
50
+ mutationKey: ['save'],
51
+ mutationFn: async profile => {
52
+ return await this.scope.api.layoutprofile.save({
53
+ layoutKey: this.layoutKey,
54
+ profile,
55
+ });
56
+ },
57
+ onSuccess: profile => {
58
+ this.$setQueryData<ApiApiLayoutprofilesaveResponseBody>(['load'], profile);
59
+ },
60
+ });
61
+ }
62
+
63
+ reset() {
64
+ return this.$useMutationData<ApiApiLayoutprofileresetResponseBody>({
65
+ mutationKey: ['reset'],
66
+ mutationFn: async () => {
67
+ return await this.scope.api.layoutprofile.reset({
68
+ query: { layoutKey: this.layoutKey },
69
+ });
70
+ },
71
+ onSuccess: async () => {
72
+ this.$setQueryData<ApiApiLayoutprofileloadResponseBody>(['load'], undefined);
73
+ },
74
+ });
75
+ }
76
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "extends": "../../tsconfig.base",
3
+ "compilerOptions": {
4
+ "rootDir": "src",
5
+ "outDir": "dist",
6
+ "declaration": true,
7
+ "declarationMap": true,
8
+ "emitDeclarationOnly": true,
9
+ "allowImportingTsExtensions": true,
10
+ "noEmit": false
11
+ },
12
+ "include": ["src", "src/.metadata/**/*"]
13
+ }
@@ -0,0 +1,5 @@
1
+ {
2
+ "extends": "../../tsconfig.base",
3
+ "compilerOptions": {},
4
+ "include": ["src", "src/.metadata/**/*"]
5
+ }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zova-module-rest-resource",
3
- "version": "5.1.53",
3
+ "version": "5.1.54",
4
4
  "gitHead": "4dece229b6d3f4735930e833afcb4b95ec51bf86",
5
5
  "description": "",
6
6
  "keywords": [
@@ -1 +1,43 @@
1
+ import type { TableIdentity } from 'table-identity';
2
+ import type {
3
+ IResourceRenderBlockOptionsBlock,
4
+ IResourceTableSelectionPayload,
5
+ ITableQuery,
6
+ } from 'zova-module-a-openapi';
7
+
1
8
  export const resourcePickerPageContextKey = '$resourcePickerPageContext';
9
+ export const resourcePickerPageHostKey = '$resourcePickerPageHost';
10
+
11
+ export interface IResourcePickerPageOptions extends Record<string, unknown> {
12
+ resource: string;
13
+ actionPath?: string;
14
+ query?: ITableQuery;
15
+ selectionMode: 'single' | 'multiple';
16
+ selectionMax?: number;
17
+ selectedIds?: readonly TableIdentity[];
18
+ }
19
+
20
+ export interface IResourcePickerPageSession {
21
+ selectedIds: TableIdentity[];
22
+ selectedRows: Record<string, unknown>[];
23
+ }
24
+
25
+ export interface IResourcePickerPageDialog {
26
+ resolve(value: IResourceTableSelectionPayload): void;
27
+ cancel(): void;
28
+ }
29
+
30
+ export interface IResourcePickerPageContext {
31
+ options: IResourcePickerPageOptions;
32
+ session: IResourcePickerPageSession;
33
+ dialog: IResourcePickerPageDialog;
34
+ }
35
+
36
+ export interface IResourcePickerPageHost extends IResourcePickerPageDialog {
37
+ options: IResourcePickerPageOptions;
38
+ session: IResourcePickerPageSession;
39
+ prepareBlocks(
40
+ blocks: IResourceRenderBlockOptionsBlock[] | undefined,
41
+ context: IResourcePickerPageContext,
42
+ ): IResourceRenderBlockOptionsBlock[] | undefined;
43
+ }
@@ -1,53 +1,25 @@
1
- import type { TableIdentity } from 'table-identity';
2
1
  import type { VNode } from 'vue';
3
- import type {
4
- IResourceBlockOptionsBase,
5
- IResourceRenderBlockOptionsBlock,
6
- IResourceTableSelectionPayload,
7
- ITableQuery,
8
- } from 'zova-module-a-openapi';
9
- import type { IRoutedDialogContext } from 'zova-module-basic-app';
10
2
 
11
3
  import { z } from 'zod';
12
4
  import { BeanControllerPageBase, deepExtend, Use, usePrepareArg } from 'zova';
13
5
  import { ZovaJsx } from 'zova-jsx';
14
6
  import { Controller } from 'zova-module-a-bean';
15
7
  import { $QueryEnsureLoaded } from 'zova-module-a-model';
16
- import { routedDialogContextKey } from 'zova-module-basic-app';
17
8
  import { ZPage } from 'zova-module-home-base';
18
9
 
10
+ import type {
11
+ IResourcePickerPageContext,
12
+ IResourcePickerPageHost,
13
+ } from '../../lib/resourcePicker.js';
19
14
  import type { ModelResource } from '../../model/resource.js';
20
15
 
21
16
  import { ZResourcePickerContext } from '../../.metadata/component/resourcePickerContext.js';
17
+ import { resourcePickerPageHostKey } from '../../lib/resourcePicker.js';
22
18
 
23
19
  export const ControllerPageResourcePickerSchemaParams = z.object({
24
20
  resource: z.string(),
25
21
  });
26
22
 
27
- export interface IResourcePickerPageOptions extends Record<string, unknown> {
28
- resource: string;
29
- actionPath?: string;
30
- query?: ITableQuery;
31
- selectionMode: 'single' | 'multiple';
32
- selectionMax?: number;
33
- selectedIds?: readonly TableIdentity[];
34
- }
35
-
36
- export interface IResourcePickerPageSession {
37
- selectedIds: TableIdentity[];
38
- selectedRows: Record<string, unknown>[];
39
- }
40
-
41
- export interface IResourcePickerPageContext {
42
- options: IResourcePickerPageOptions;
43
- session: IResourcePickerPageSession;
44
- dialog: IRoutedDialogContext<
45
- IResourceTableSelectionPayload,
46
- IResourcePickerPageOptions,
47
- IResourcePickerPageSession
48
- >;
49
- }
50
-
51
23
  @Controller()
52
24
  export class ControllerPageResourcePicker extends BeanControllerPageBase {
53
25
  jsxZova: ZovaJsx;
@@ -57,27 +29,27 @@ export class ControllerPageResourcePicker extends BeanControllerPageBase {
57
29
  return usePrepareArg(this.resource, true);
58
30
  }
59
31
 
60
- @Use({ name: routedDialogContextKey, injectionScope: 'host' })
61
- $$routedDialogContext: IRoutedDialogContext<
62
- IResourceTableSelectionPayload,
63
- IResourcePickerPageOptions,
64
- IResourcePickerPageSession
65
- >;
32
+ @Use({ name: resourcePickerPageHostKey, injectionScope: 'host' })
33
+ $$pickerHost: IResourcePickerPageHost | undefined;
66
34
 
67
35
  get resource() {
68
36
  return this.$params.resource;
69
37
  }
70
38
 
71
39
  get pickerContext(): IResourcePickerPageContext {
72
- const options = this.$$routedDialogContext.props;
73
- const session = this.$$routedDialogContext.session;
74
- if (!options || !session || options.resource !== this.resource) {
40
+ const host = this.$$pickerHost;
41
+ if (!host) {
42
+ throw new Error('resource picker requires a page host');
43
+ }
44
+ const options = host.options;
45
+ const session = host.session;
46
+ if (options.resource !== this.resource) {
75
47
  throw new Error('resource picker context does not match route resource');
76
48
  }
77
49
  return {
78
50
  options,
79
51
  session,
80
- dialog: this.$$routedDialogContext,
52
+ dialog: host,
81
53
  };
82
54
  }
83
55
 
@@ -91,7 +63,8 @@ export class ControllerPageResourcePicker extends BeanControllerPageBase {
91
63
  }
92
64
 
93
65
  public render() {
94
- const blocks = this._prepareBlocks(this.schemaRow?.rest?.blocks);
66
+ const pickerContext = this.pickerContext;
67
+ const blocks = this.$$pickerHost!.prepareBlocks(this.schemaRow?.rest?.blocks, pickerContext);
95
68
  if (!blocks || blocks.length === 0) return;
96
69
  const domBlocks: VNode[] = [];
97
70
  blocks.forEach((block, index) => {
@@ -102,43 +75,11 @@ export class ControllerPageResourcePicker extends BeanControllerPageBase {
102
75
  else domBlocks.push(domBlock);
103
76
  });
104
77
  return (
105
- <ZResourcePickerContext context={this.pickerContext}>
78
+ <ZResourcePickerContext context={pickerContext}>
106
79
  <ZPage>{domBlocks}</ZPage>
107
80
  </ZResourcePickerContext>
108
81
  );
109
82
  }
110
-
111
- private _prepareBlocks(blocks: IResourceRenderBlockOptionsBlock[] | undefined) {
112
- if (!blocks) return;
113
- return blocks.map(block => {
114
- if (block.render !== 'basic-page:blockPage') return block;
115
- const pickerContext = this.pickerContext;
116
- return {
117
- ...block,
118
- options: deepExtend({}, block.options, {
119
- actionPath: pickerContext.options.actionPath,
120
- queryFixed: pickerContext.options.query,
121
- selectionPolicy: 'always',
122
- selectionMode: pickerContext.options.selectionMode,
123
- selectionMax: pickerContext.options.selectionMax,
124
- selectedIds: pickerContext.session.selectedIds,
125
- selectedRows: pickerContext.session.selectedRows,
126
- onSelectionChange: (selection: IResourceTableSelectionPayload) => {
127
- pickerContext.session.selectedIds = [...selection.ids];
128
- pickerContext.session.selectedRows = selection.rows.map(row => ({ ...row }));
129
- },
130
- blocks: [
131
- ...((
132
- block.options as IResourceBlockOptionsBase & {
133
- blocks?: IResourceRenderBlockOptionsBlock[];
134
- }
135
- ).blocks ?? []),
136
- {
137
- render: 'basic-resource:blockResourcePickerActions',
138
- },
139
- ],
140
- }),
141
- };
142
- });
143
- }
144
83
  }
84
+
85
+ export type { IResourcePickerPageContext } from '../../lib/resourcePicker.js';
@@ -1,14 +1,15 @@
1
1
  {
2
2
  "name": "zova-suite-a-cabloy",
3
- "version": "5.1.54",
3
+ "version": "5.1.56",
4
4
  "gitHead": "4dece229b6d3f4735930e833afcb4b95ec51bf86",
5
5
  "description": "",
6
6
  "author": "",
7
7
  "files": [],
8
8
  "type": "module",
9
9
  "dependencies": {
10
+ "zova-module-a-layoutprofile": "^5.0.2",
10
11
  "zova-module-a-rbac": "^5.0.1",
11
- "zova-module-rest-resource": "^5.1.53"
12
+ "zova-module-rest-resource": "^5.1.54"
12
13
  },
13
14
  "title": "a-cabloy"
14
15
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zova-module-a-bean",
3
- "version": "5.1.34",
3
+ "version": "5.1.35",
4
4
  "gitHead": "09d901d17140a80ee0764211b441cda72fd94663",
5
5
  "description": "",
6
6
  "keywords": [
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zova-module-a-openapi",
3
- "version": "5.1.53",
3
+ "version": "5.1.54",
4
4
  "gitHead": "09d901d17140a80ee0764211b441cda72fd94663",
5
5
  "description": "",
6
6
  "keywords": [
@@ -20,9 +20,12 @@ export interface IResourceTableSelectionPayload<TData extends {} = Record<string
20
20
  }
21
21
 
22
22
  /** Declarative bulk-action metadata authored by a resource schema. */
23
+ export type TypeResourceTableActionBulkPlacement = 'start' | 'end';
24
+
23
25
  export interface IResourceTableActionBulkOptionsBase {
24
26
  class?: any;
25
27
  style?: types.NestedCSSProperties;
28
+ placement?: TypeResourceTableActionBulkPlacement;
26
29
  resource?: string;
27
30
  permission?: IPermissionHintTableActionBulk;
28
31
  requiresSelection?: boolean;
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zova-module-a-router",
3
- "version": "5.1.36",
3
+ "version": "5.1.37",
4
4
  "gitHead": "09d901d17140a80ee0764211b441cda72fd94663",
5
5
  "description": "router",
6
6
  "keywords": [
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zova-module-a-routerstack",
3
- "version": "5.1.28",
3
+ "version": "5.1.29",
4
4
  "gitHead": "09d901d17140a80ee0764211b441cda72fd94663",
5
5
  "description": "",
6
6
  "keywords": [
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zova-module-a-ssr",
3
- "version": "5.1.38",
3
+ "version": "5.1.39",
4
4
  "gitHead": "09d901d17140a80ee0764211b441cda72fd94663",
5
5
  "description": "",
6
6
  "keywords": [
@@ -1,19 +1,21 @@
1
1
  export function getBodyReadyObserverScript() {
2
2
  return `<script id="ssr-body-ready-observer">
3
3
  window.ssr_bodyReadyObserverClear=()=>{
4
- if(window.ssr_bodyReadyObserver){
5
- window.ssr_body_ready_condition=undefined;
6
- window.ssr_body_ready_callback=undefined;
7
- window.ssr_bodyReadyObserver.disconnect();
8
- window.ssr_bodyReadyObserver=undefined;
9
- document.body.style.display='block';
10
- document.querySelector('#ssr-body-ready-observer').remove();
11
- }
4
+ window.ssr_body_ready_condition=undefined;
5
+ window.ssr_body_ready_callback=undefined;
6
+ window.ssr_bodyReadyObserver?.disconnect();
7
+ window.ssr_bodyReadyObserver=undefined;
8
+ document.body.style.display='block';
9
+ document.querySelector('#ssr-body-ready-observer')?.remove();
12
10
  };
13
11
  window.ssr_bodyReadyObserver = new MutationObserver(() => {
14
- if(window.ssr_body_ready_condition && window.ssr_body_ready_condition()){
15
- window.ssr_body_ready_callback();
16
- window.ssr_bodyReadyObserverClear();
12
+ const __targets=window.ssr_body_ready_condition?.();
13
+ if(__targets){
14
+ try{
15
+ window.ssr_body_ready_callback?.(__targets);
16
+ }finally{
17
+ window.ssr_bodyReadyObserverClear();
18
+ }
17
19
  }
18
20
  });
19
21
  window.ssr_bodyReadyObserver.observe(document.body, {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zova-module-a-table",
3
- "version": "5.1.41",
3
+ "version": "5.1.43",
4
4
  "gitHead": "09d901d17140a80ee0764211b441cda72fd94663",
5
5
  "description": "",
6
6
  "keywords": [
@@ -45,13 +45,16 @@ import type {
45
45
  ITableScope,
46
46
  TypeTableCellRender,
47
47
  } from '../../types/tableColumn.js';
48
+ import type { ITableLayout } from '../../types/tableLayout.js';
48
49
 
49
50
  import { BeanControllerTableBase } from '../../lib/beanControllerTableBase.js';
50
51
  import { TableColumnIdSelection } from '../../types/table.js';
51
52
  import { ITableCellRenderColumnOptions } from '../../types/tableColumn.js';
53
+ import { reconcileTableLayout } from '../../types/tableLayout.js';
52
54
 
53
55
  export interface ControllerTableProps<TData extends {} = {}> {
54
56
  data?: TData[];
57
+ layout?: ITableLayout;
55
58
  schema?: SchemaObject;
56
59
  schemaOrder?: SchemaObject;
57
60
  sorting?: SortingState;
@@ -102,6 +105,13 @@ export class ControllerTable<TData extends {} = {}> extends BeanControllerTableB
102
105
  await this.refreshMeta();
103
106
  },
104
107
  );
108
+ this.$watch(
109
+ () => this.$props.layout,
110
+ async (newValue, oldValue) => {
111
+ if (deepEqual(newValue, oldValue)) return;
112
+ await this.refreshMeta();
113
+ },
114
+ );
105
115
  // table
106
116
  this._createTable();
107
117
  }
@@ -122,6 +132,14 @@ export class ControllerTable<TData extends {} = {}> extends BeanControllerTableB
122
132
  return this.$props.rowSelection ?? {};
123
133
  }
124
134
 
135
+ public get layout(): ITableLayout {
136
+ return reconcileTableLayout(this.layoutProperties, this.$props.layout);
137
+ }
138
+
139
+ public get layoutProperties(): readonly ISchemaObjectExtensionField[] {
140
+ return this.tableMeta?.properties ?? [];
141
+ }
142
+
125
143
  public async refreshMeta() {
126
144
  this.tableMeta = await this._createTableMeta();
127
145
  this.columns = await this._createColumns();
@@ -148,6 +166,15 @@ export class ControllerTable<TData extends {} = {}> extends BeanControllerTableB
148
166
  get rowSelection() {
149
167
  return self.rowSelection;
150
168
  },
169
+ get columnVisibility() {
170
+ return self._getColumnVisibility();
171
+ },
172
+ get columnOrder() {
173
+ return self._getColumnOrder();
174
+ },
175
+ get columnSizing() {
176
+ return self._getColumnSizing();
177
+ },
151
178
  },
152
179
  onSortingChange: updater => {
153
180
  const sorting = functionalUpdate(updater, self.sorting).slice(0, 1);
@@ -235,10 +262,15 @@ export class ControllerTable<TData extends {} = {}> extends BeanControllerTableB
235
262
  return property?.title || key;
236
263
  },
237
264
  cell: props => tableMeta.renders[key](props),
238
- size: property.rest?.width,
265
+ size: this._getLayoutWidth(key),
239
266
  enableSorting: property.rest?.enableSorting === true && this._isOrderable(property),
240
267
  sortDescFirst: property.rest?.sortDescFirst === true,
241
- meta: { rest: property.rest },
268
+ meta: {
269
+ rest: {
270
+ ...property.rest,
271
+ width: this._getLayoutWidth(key),
272
+ },
273
+ },
242
274
  }),
243
275
  );
244
276
  }
@@ -262,6 +294,36 @@ export class ControllerTable<TData extends {} = {}> extends BeanControllerTableB
262
294
  return typeof enableRowSelection === 'function' ? enableRowSelection(row) : true;
263
295
  }
264
296
 
297
+ private _getLayoutColumn(key: string) {
298
+ return this.layout.columns.find(column => column.key === key);
299
+ }
300
+
301
+ private _getLayoutWidth(key: string) {
302
+ const width = this._getLayoutColumn(key)?.width;
303
+ return typeof width === 'number' ? width : undefined;
304
+ }
305
+
306
+ private _getColumnVisibility() {
307
+ return Object.fromEntries(
308
+ this.layout.columns
309
+ .filter(column => column.key !== TableColumnIdSelection)
310
+ .map(column => [column.key, column.visible]),
311
+ );
312
+ }
313
+
314
+ private _getColumnOrder() {
315
+ const keys = this.layout.columns.map(column => column.key);
316
+ return this.$props.enableRowSelection ? [TableColumnIdSelection, ...keys] : keys;
317
+ }
318
+
319
+ private _getColumnSizing() {
320
+ return Object.fromEntries(
321
+ this.layout.columns
322
+ .filter(column => typeof column.width === 'number')
323
+ .map(column => [column.key, column.width as number]),
324
+ );
325
+ }
326
+
265
327
  private _getColumnPinning() {
266
328
  const left: string[] = this.$props.enableRowSelection ? [TableColumnIdSelection] : [];
267
329
  const right: string[] = [];
@@ -11,10 +11,9 @@ export class RenderTable extends BeanRenderBase {
11
11
  private _getColumnStyle(column: any): CSSProperties {
12
12
  const rest = (column.columnDef.meta as any)?.rest;
13
13
  const fixed = column.getIsPinned();
14
- const width = rest?.width ? `${rest.width}px` : undefined;
14
+ const width = column.getSize();
15
15
  return {
16
- width,
17
- minWidth: width,
16
+ ...(typeof rest?.width === 'number' ? { width: `${width}px`, minWidth: `${width}px` } : {}),
18
17
  textAlign: rest?.align,
19
18
  position: fixed ? ('sticky' as const) : undefined,
20
19
  left: fixed === 'left' ? `${column.getStart('left')}px` : undefined,
@@ -1,15 +1,25 @@
1
1
  import type { Table } from '@tanstack/table-core';
2
2
  import type { TableOptionsWithReactiveData } from '@tanstack/vue-table';
3
+ import type { ISchemaObjectExtensionField } from 'zova-module-a-openapi';
3
4
 
4
5
  import { useVueTable } from '@tanstack/vue-table';
5
6
  import { markRaw } from 'vue';
6
7
  import { BeanControllerBase } from 'zova';
7
8
 
8
9
  import { TypeTable } from '../types/table.js';
10
+ import { ITableLayout } from '../types/tableLayout.js';
9
11
 
10
12
  export class BeanControllerTableBase<TData extends {} = {}> extends BeanControllerBase {
11
13
  table: TypeTable<TData>;
12
14
 
15
+ public get layout(): ITableLayout {
16
+ throw new Error('should implement layout');
17
+ }
18
+
19
+ public get layoutProperties(): readonly ISchemaObjectExtensionField[] {
20
+ throw new Error('should implement layoutProperties');
21
+ }
22
+
13
23
  public $useTable(initialOptions: TableOptionsWithReactiveData<TData>): Table<TData> {
14
24
  return this.ctx.util.instanceScope(() => {
15
25
  return markRaw(useVueTable(initialOptions));
@@ -1,3 +1,4 @@
1
1
  export * from './table.js';
2
2
  export * from './tableCell.js';
3
3
  export * from './tableColumn.js';
4
+ export * from './tableLayout.js';