cabloy 5.1.171 → 5.1.172

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.
package/.cabloy-version CHANGED
@@ -1 +1 @@
1
- 5.1.171
1
+ 5.1.172
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # Changelog
2
2
 
3
+ ## 5.1.172
4
+
5
+ ### Features
6
+
7
+ - Add action refresh capabilities.
8
+ - Add update functionality.
9
+
10
+ ### Improvements
11
+
12
+ - Update the table guide documentation.
13
+ - Improve REST build handling in the CLI.
14
+
3
15
  ## 5.1.171
4
16
 
5
17
  ### Features
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cabloy",
3
- "version": "5.1.171",
3
+ "version": "5.1.172",
4
4
  "gitHead": "2c5c19284bab738e492856189acb6fad74b8a7b7",
5
5
  "description": "A Node.js fullstack framework",
6
6
  "keywords": [
@@ -245,6 +245,32 @@ In the shared table CEL scope, `getValue(name)` reads the current row value and
245
245
 
246
246
  For the schema side of that contract, also see [API Schema Guide](/frontend/api-schema-guide).
247
247
 
248
+ ## Persisted per-user column layouts
249
+
250
+ `ZovaRender.column(...)` defines the schema defaults for column visibility, order, width, and fixed regions. On a standard resource list page, an authenticated user can personalize those defaults through the **Column Configuration** toolbar action. The saved layout is scoped to that user and the current page route path, then restored on later visits.
251
+
252
+ | Edition | Toolbar block | Column-configuration action |
253
+ | ------------ | ----------------------------- | -------------------------------- |
254
+ | Cabloy Basic | `basic-page:blockToolbarBulk` | `basic-table:actionColumnConfig` |
255
+ | Cabloy Start | `start-page:blockToolbarBulk` | `start-table:actionColumnConfig` |
256
+
257
+ For example, in Cabloy Basic:
258
+
259
+ ```ts
260
+ ZovaRender.tableActionBulk('basic-table:actionColumnConfig', {
261
+ permission: { public: true },
262
+ placement: 'end',
263
+ });
264
+ ```
265
+
266
+ In Cabloy Start, use `start-table:actionColumnConfig` in the corresponding `start-page:blockToolbarBulk`. `permission: { public: true }` controls action discoverability in the toolbar; loading and saving a personal layout still require an authenticated user.
267
+
268
+ The dialog lets the user show or hide eligible columns, choose a numeric or automatic width, and reorder columns within their schema-defined left, center, or right fixed region. **Save** persists the layout. **Reset** removes the saved profile and restores the current schema defaults.
269
+
270
+ Schema metadata remains authoritative. When the schema changes, stale or malformed saved entries are discarded, newly eligible schema columns are appended with their defaults, fixed regions are preserved, and the synthetic row-selection column is never persisted.
271
+
272
+ Automatic loading, saving, and resetting belong to the standard resource-page `blockPage` flow. A direct `ZTable` consumer can pass a `layout`, but it owns any persistence workflow itself. Current CRUD generators add the edition-appropriate column-configuration action.
273
+
248
274
  ## Step 5: Use built-in or custom `tableCell` render resources
249
275
 
250
276
  A column render is usually chosen through schema metadata such as:
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vona-cli",
3
- "version": "1.1.148",
3
+ "version": "1.1.149",
4
4
  "gitHead": "a79189b882c17af5911573896a781bbb0046d37d",
5
5
  "description": "vona cli",
6
6
  "keywords": [
@@ -44,6 +44,10 @@ export interface IDtoOptions<%=argv.resourceNameCapitalize%>SelectResItem extend
44
44
  requiresSelection: true,
45
45
  selectedMaxIds: 100,
46
46
  }),
47
+ ZovaRender.tableActionBulk('basic-table:actionRefresh', {
48
+ permission: { public: true },
49
+ placement: 'end',
50
+ }),
47
51
  ZovaRender.tableActionBulk('basic-table:actionColumnConfig', {
48
52
  permission: { public: true },
49
53
  placement: 'end',
@@ -44,6 +44,10 @@ export interface IDtoOptions<%=argv.resourceNameCapitalize%>SelectResItem extend
44
44
  requiresSelection: true,
45
45
  selectedMaxIds: 100,
46
46
  }),
47
+ ZovaRender.tableActionBulk('start-table:actionRefresh', {
48
+ permission: { public: true },
49
+ placement: 'end',
50
+ }),
47
51
  ZovaRender.tableActionBulk('start-table:actionColumnConfig', {
48
52
  permission: { public: true },
49
53
  placement: 'end',
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vona-cli-set-api",
3
- "version": "1.1.146",
3
+ "version": "1.1.147",
4
4
  "gitHead": "a79189b882c17af5911573896a781bbb0046d37d",
5
5
  "description": "vona cli-set-api",
6
6
  "keywords": [
@@ -46,6 +46,10 @@ export interface IDtoOptionsStudentSelectResItem extends IDecoratorDtoOptions {}
46
46
  requiresSelection: true,
47
47
  selectedMaxIds: 100,
48
48
  }),
49
+ ZovaRender.tableActionBulk('basic-table:actionRefresh', {
50
+ permission: { public: true },
51
+ placement: 'end',
52
+ }),
49
53
  ZovaRender.tableActionBulk('basic-table:actionColumnConfig', {
50
54
  permission: { public: true },
51
55
  placement: 'end',
@@ -103,6 +103,11 @@ describe('student.test.ts', { concurrency: false }, () => {
103
103
  );
104
104
  assert.equal(deleteBulkAction?.options?.requiresSelection, true);
105
105
  assert.equal(deleteBulkAction?.options?.selectedMaxIds, 100);
106
+ const refreshAction = toolbarBlock?.options?.actions?.find(
107
+ (action: any) => action.render === 'basic-table:actionRefresh',
108
+ );
109
+ assert.equal(refreshAction?.options?.requiresSelection, undefined);
110
+ assert.equal(refreshAction?.options?.selectedMaxIds, undefined);
106
111
  const columnConfigAction = toolbarBlock?.options?.actions?.find(
107
112
  (action: any) => action.render === 'basic-table:actionColumnConfig',
108
113
  );
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zova-cli",
3
- "version": "1.2.108",
3
+ "version": "1.2.109",
4
4
  "gitHead": "6f675a8cc46d596142c591c28a40cc4d82fcc6cc",
5
5
  "description": "zova cli",
6
6
  "keywords": [
@@ -44,7 +44,7 @@
44
44
  "@cabloy/process-helper": "^3.1.8",
45
45
  "fs-extra": "^11.3.5",
46
46
  "semver": "^7.6.2",
47
- "zova-cli-set-front": "^1.2.106"
47
+ "zova-cli-set-front": "^1.2.107"
48
48
  },
49
49
  "devDependencies": {
50
50
  "clean-package": "^2.2.0",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zova-cli-set-front",
3
- "version": "1.2.106",
3
+ "version": "1.2.107",
4
4
  "gitHead": "6f675a8cc46d596142c591c28a40cc4d82fcc6cc",
5
5
  "description": "zova cli-set-front",
6
6
  "keywords": [
@@ -45,6 +45,13 @@ declare module '@cabloy/cli' {
45
45
  }
46
46
  }
47
47
 
48
+ interface IBinBuildRestPackageJson {
49
+ name: string;
50
+ version: string;
51
+ dependencies?: Record<string, string>;
52
+ [key: string]: unknown;
53
+ }
54
+
48
55
  interface IBinBuildRestContext {
49
56
  projectPath: string;
50
57
  flavor: ZovaMetaFlavor;
@@ -54,6 +61,7 @@ interface IBinBuildRestContext {
54
61
  outDir: string;
55
62
  bundleModules?: string[];
56
63
  sideEffectImportModuleNames?: string[];
64
+ packageJson?: IBinBuildRestPackageJson;
57
65
  }
58
66
 
59
67
  export class CliBinBuildRest extends BeanCliBase {
@@ -129,6 +137,7 @@ export class CliBinBuildRest extends BeanCliBase {
129
137
  const templateDir = this.template.resolveTemplatePath(__ThisSetName__, 'rest');
130
138
  // render
131
139
  await this.template.renderDir(srcDir, templateDir);
140
+ context.packageJson = await loadJSONFile(path.join(srcDir, 'package.json'));
132
141
  }
133
142
 
134
143
  async _buildTs({ srcDir, outDir }: IBinBuildRestContext) {
@@ -204,7 +213,7 @@ export class CliBinBuildRest extends BeanCliBase {
204
213
  }
205
214
 
206
215
  async _build(buildContext: IBinBuildRestContext) {
207
- const { projectPath, flavor, bundleNameCopy, srcDir, outDir } = buildContext;
216
+ const { projectPath, flavor, bundleNameCopy, outDir, packageJson } = buildContext;
208
217
  // build
209
218
  await this._buildTs(buildContext);
210
219
  await this._buildDts(buildContext);
@@ -212,8 +221,10 @@ export class CliBinBuildRest extends BeanCliBase {
212
221
  const deps = await _extractDeps(path.join(outDir, 'index.d.mts'));
213
222
  const depsVersion = await _extractDepsVersion(projectPath, deps);
214
223
  // package.json
215
- const pkgContent = await loadJSONFile(path.join(srcDir, 'package.json'));
216
- pkgContent.dependencies = depsVersion;
224
+ const pkgContent = {
225
+ ...packageJson!,
226
+ dependencies: depsVersion,
227
+ };
217
228
  await saveJSONFile(path.join(outDir, 'package.json'), pkgContent);
218
229
  // await fse.copyFile(path.join(srcDir, 'package.json'), path.join(outDir, 'package.json'));
219
230
  // release
@@ -0,0 +1,31 @@
1
+ import type { TypeControllerInnerProps } from 'zova';
2
+
3
+ import { defineComponent } from 'vue';
4
+ import { prepareComponentOptions, useController } from 'zova';
5
+
6
+ import type { ControllerActionRefreshProps } from '../../component/actionRefresh/controller.jsx';
7
+
8
+ import { ControllerActionRefresh } from '../../component/actionRefresh/controller.jsx';
9
+ export type ZActionRefreshProps = {
10
+ controllerRef?: (ref: ControllerActionRefresh) => void;
11
+ } & ControllerActionRefreshProps;
12
+
13
+ type ControllerInnerProps = TypeControllerInnerProps<
14
+ ControllerActionRefreshProps,
15
+ keyof typeof ControllerActionRefresh.$propsDefault
16
+ >;
17
+ declare module 'zova-module-basic-table' {
18
+ export interface ControllerActionRefresh {
19
+ $props: ControllerInnerProps;
20
+ }
21
+ }
22
+
23
+ export const ZActionRefresh = defineComponent((_props: ZActionRefreshProps) => {
24
+ useController(ControllerActionRefresh, undefined, undefined);
25
+ return () => {};
26
+ }, prepareComponentOptions(ControllerActionRefresh.$componentOptions));
27
+ declare module 'zova-module-a-bean' {
28
+ export interface IVonaComponentRecord {
29
+ 'basic-table:actionRefresh': ControllerActionRefreshProps;
30
+ }
31
+ }
@@ -3,6 +3,7 @@
3
3
  export * from '../component/actionColumnConfig/controller.jsx';
4
4
  export * from '../component/actionCreate/controller.jsx';
5
5
  export * from '../component/actionDeleteBulk/controller.jsx';
6
+ export * from '../component/actionRefresh/controller.jsx';
6
7
  export * from '../component/table/controller.jsx';
7
8
 
8
9
  import 'zova';
@@ -27,6 +28,11 @@ declare module 'zova-module-basic-table' {
27
28
  get scope(): ScopeModuleBasicTable;
28
29
  }
29
30
 
31
+ export interface ControllerActionRefresh {
32
+ /** @internal */
33
+ get scope(): ScopeModuleBasicTable;
34
+ }
35
+
30
36
  export interface ControllerTable {
31
37
  /** @internal */
32
38
  get scope(): ScopeModuleBasicTable;
@@ -37,6 +43,7 @@ declare module 'zova-module-basic-table' {
37
43
  import type { ControllerActionColumnConfig } from '../component/actionColumnConfig/controller.jsx';
38
44
  import type { ControllerActionCreate } from '../component/actionCreate/controller.jsx';
39
45
  import type { ControllerActionDeleteBulk } from '../component/actionDeleteBulk/controller.jsx';
46
+ import type { ControllerActionRefresh } from '../component/actionRefresh/controller.jsx';
40
47
  import type { ControllerTable } from '../component/table/controller.jsx';
41
48
  import 'zova';
42
49
  declare module 'zova' {
@@ -44,6 +51,7 @@ declare module 'zova' {
44
51
  'basic-table.controller.actionColumnConfig': ControllerActionColumnConfig;
45
52
  'basic-table.controller.actionCreate': ControllerActionCreate;
46
53
  'basic-table.controller.actionDeleteBulk': ControllerActionDeleteBulk;
54
+ 'basic-table.controller.actionRefresh': ControllerActionRefresh;
47
55
  'basic-table.controller.table': ControllerTable;
48
56
  }
49
57
  }
@@ -56,12 +64,15 @@ export * from './component/actionCreate.js';
56
64
  import { ZActionCreate } from './component/actionCreate.js';
57
65
  export * from './component/actionDeleteBulk.js';
58
66
  import { ZActionDeleteBulk } from './component/actionDeleteBulk.js';
67
+ export * from './component/actionRefresh.js';
68
+ import { ZActionRefresh } from './component/actionRefresh.js';
59
69
  export * from './component/table.js';
60
70
  import { ZTable } from './component/table.js';
61
71
  export const components = {
62
72
  'actionColumnConfig': ZActionColumnConfig,
63
73
  'actionCreate': ZActionCreate,
64
74
  'actionDeleteBulk': ZActionDeleteBulk,
75
+ 'actionRefresh': ZActionRefresh,
65
76
  'table': ZTable,
66
77
  };
67
78
  import 'zova';
@@ -70,12 +81,14 @@ export interface IComponentRecord {
70
81
  'basic-table:actionColumnConfig': ControllerActionColumnConfig;
71
82
  'basic-table:actionCreate': ControllerActionCreate;
72
83
  'basic-table:actionDeleteBulk': ControllerActionDeleteBulk;
84
+ 'basic-table:actionRefresh': ControllerActionRefresh;
73
85
  'basic-table:table': ControllerTable;
74
86
  }
75
87
  export interface IZovaComponentRecord {
76
88
  'basic-table:actionColumnConfig': typeof ZActionColumnConfig;
77
89
  'basic-table:actionCreate': typeof ZActionCreate;
78
90
  'basic-table:actionDeleteBulk': typeof ZActionDeleteBulk;
91
+ 'basic-table:actionRefresh': typeof ZActionRefresh;
79
92
  'basic-table:table': typeof ZTable;
80
93
  }
81
94
  }
@@ -0,0 +1,42 @@
1
+ import type { IComponentOptions } from 'zova';
2
+ import type {
3
+ IJsxRenderContextPage,
4
+ IResourceTableActionBulkPropsBase,
5
+ } from 'zova-module-a-openapi';
6
+
7
+ import { BeanControllerBase, Use } from 'zova';
8
+ import { Controller } from 'zova-module-a-bean';
9
+
10
+ declare module 'zova-module-a-openapi' {
11
+ export interface IResourceTableActionBulkRecord {
12
+ 'basic-table:actionRefresh'?: ControllerActionRefreshProps;
13
+ }
14
+ }
15
+
16
+ export interface ControllerActionRefreshProps extends IResourceTableActionBulkPropsBase {}
17
+
18
+ @Controller()
19
+ export class ControllerActionRefresh extends BeanControllerBase {
20
+ static $propsDefault = { class: 'btn join-item' };
21
+ static $componentOptions: IComponentOptions = { inheritAttrs: false, deepExtendDefault: true };
22
+
23
+ @Use({ injectionScope: 'host' })
24
+ $$renderContext: IJsxRenderContextPage;
25
+
26
+ protected render() {
27
+ const disabled = this.$props.disabled === true || this.$props.dynamicDisabled === true;
28
+ return (
29
+ <button
30
+ class={this.$props.class}
31
+ type="button"
32
+ disabled={disabled}
33
+ onClick={async () => {
34
+ if (disabled) return;
35
+ await this.$$renderContext.$$page.queryData.refetch();
36
+ }}
37
+ >
38
+ {this.scope.locale.Refresh() as string}
39
+ </button>
40
+ );
41
+ }
42
+ }
@@ -5,6 +5,7 @@ export default {
5
5
  SelectRow: 'Select row %s',
6
6
  DeleteBulk: 'Bulk Delete',
7
7
  DeleteBulkConfirm: 'Are you sure you want to bulk delete %d selected items?',
8
+ Refresh: 'Refresh',
8
9
  ColumnConfiguration: 'Column configuration',
9
10
  Columns: 'Columns',
10
11
  Visible: 'Visible',
@@ -5,6 +5,7 @@ export default {
5
5
  SelectRow: '选择行 %s',
6
6
  DeleteBulk: '批量删除',
7
7
  DeleteBulkConfirm: '您确认要批量删除已选择的 %d 项吗?',
8
+ Refresh: '刷新',
8
9
  ColumnConfiguration: '列配置',
9
10
  Columns: '字段',
10
11
  Visible: '显示',