cabloy 5.1.158 → 5.1.159

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 (88) hide show
  1. package/.cabloy-version +1 -1
  2. package/.claude/skills/cabloy-contract-loop/SKILL.md +24 -7
  3. package/.claude/skills/cabloy-contract-loop/evals/evals.json +12 -0
  4. package/.claude/skills/cabloy-contract-loop/references/contract-loop-map.md +28 -0
  5. package/.claude/skills/cabloy-contract-loop/references/verification-checklist.md +19 -2
  6. package/.claude/skills/cabloy-resource-field-update/SKILL.md +18 -0
  7. package/.claude/skills/cabloy-zova-source-reading/SKILL.md +14 -0
  8. package/.claude/skills/cabloy-zova-source-reading/references/core-reading-paths.md +10 -0
  9. package/.github/workflows/docs-pages.yml +18 -2
  10. package/CHANGELOG.md +19 -0
  11. package/package.json +2 -1
  12. package/repo-docs/.vitepress/config.mjs +34 -4
  13. package/repo-docs/.vitepress/theme/components/GitHubRepositoriesNav.vue +255 -0
  14. package/repo-docs/.vitepress/theme/custom.css +21 -0
  15. package/repo-docs/.vitepress/theme/index.js +7 -1
  16. package/repo-docs/backend/resource-field-update.md +48 -1
  17. package/repo-docs/blogs/index.md +2 -0
  18. package/repo-docs/frontend/form-layout-guide.md +6 -6
  19. package/repo-docs/frontend/page-guide.md +12 -0
  20. package/repo-docs/frontend/page-meta-guide.md +27 -0
  21. package/repo-docs/frontend/ssr-architecture-overview.md +4 -0
  22. package/repo-docs/frontend/ssr-build-deploy-guide.md +1 -1
  23. package/repo-docs/frontend/zova-form-source-reading-map.md +2 -2
  24. package/repo-docs/frontend/zova-form-under-the-hood.md +1 -1
  25. package/repo-docs/frontend/zova-reactivity-under-the-hood.md +65 -9
  26. package/repo-docs/fullstack/contract-loop-playbook.md +2 -0
  27. package/repo-docs/fullstack/ssr-site-and-flavor-setup.md +198 -0
  28. package/repo-docs/fullstack/vona-zova-integration.md +2 -0
  29. package/repo-e2e/docs/playwright.config.ts +37 -0
  30. package/repo-e2e/docs/specs/blogs-index.spec.ts +180 -0
  31. package/repo-e2e/docs/specs/github-repositories-nav.spec.ts +69 -0
  32. package/repo-e2e/docs/test-results/.last-run.json +4 -0
  33. package/repo-e2e/specs/cabloy-basic.spec.ts +136 -2
  34. package/vona/packages-cli/cli/package.json +1 -1
  35. package/vona/packages-cli/cli-set-api/cli/templates/tools/crudBasic/boilerplate/src/entity/{{resourceName}}.tsx_ +1 -1
  36. package/vona/packages-cli/cli-set-api/cli/templates/tools/crudStart/boilerplate/src/entity/{{resourceName}}.tsx_ +1 -1
  37. package/vona/packages-cli/cli-set-api/package.json +1 -1
  38. package/vona/packages-vona/vona/package.json +1 -1
  39. package/vona/pnpm-lock.yaml +21 -80
  40. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/config/locale/en-us.ts +3 -0
  41. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/config/locale/zh-cn.ts +3 -0
  42. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/dto/productCreate.tsx +2 -0
  43. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/dto/productUpdate.tsx +2 -0
  44. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/dto/productView.tsx +2 -0
  45. package/vona/src/suite/a-training/modules/training-record/src/dto/recordCreate.tsx +1 -0
  46. package/vona/src/suite/a-training/modules/training-record/src/dto/recordSelectReq.tsx +3 -7
  47. package/vona/src/suite/a-training/modules/training-record/src/dto/recordUpdate.tsx +1 -0
  48. package/vona/src/suite/a-training/modules/training-record/src/dto/recordView.tsx +1 -0
  49. package/vona/src/suite/a-training/modules/training-record/src/entity/record.tsx +8 -0
  50. package/vona/src/suite/a-training/modules/training-record/test/record.test.ts +51 -0
  51. package/vona/src/suite/a-training/modules/training-student/src/config/locale/en-us.ts +3 -0
  52. package/vona/src/suite/a-training/modules/training-student/src/config/locale/zh-cn.ts +3 -0
  53. package/vona/src/suite/a-training/modules/training-student/src/dto/studentCreate.tsx +1 -0
  54. package/vona/src/suite/a-training/modules/training-student/src/dto/studentSelectResItem.tsx +1 -0
  55. package/vona/src/suite/a-training/modules/training-student/src/dto/studentUpdate.tsx +1 -0
  56. package/vona/src/suite/a-training/modules/training-student/src/dto/studentView.tsx +1 -0
  57. package/vona/src/suite/a-training/modules/training-student/src/entity/student.tsx +10 -1
  58. package/vona/src/suite/a-training/modules/training-student/test/student.test.ts +99 -1
  59. package/vona/src/suite-vendor/a-cabloy/modules/a-rbac/package.json +1 -1
  60. package/vona/src/suite-vendor/a-cabloy/package.json +2 -2
  61. package/vona/src/suite-vendor/a-vona/modules/a-permission/package.json +1 -1
  62. package/vona/src/suite-vendor/a-vona/modules/a-web/package.json +1 -1
  63. package/vona/src/suite-vendor/a-vona/modules/a-web/src/bean/pipe.filter.ts +85 -57
  64. package/vona/src/suite-vendor/a-vona/package.json +1 -1
  65. package/zova/packages-cli/cli/package.json +2 -2
  66. package/zova/packages-cli/cli-set-front/cli/templates/rest/render.ts +2 -0
  67. package/zova/packages-cli/cli-set-front/cli/templates/rest/rest.ts +13 -3
  68. package/zova/packages-cli/cli-set-front/package.json +1 -1
  69. package/zova/packages-zova/zova/package.json +2 -2
  70. package/zova/src/suite/cabloy-basic/modules/basic-page/src/component/blockPage/controller.tsx +31 -11
  71. package/zova/src/suite/cabloy-basic/modules/basic-page/src/component/blockTable/controller.tsx +3 -0
  72. package/zova/src/suite/cabloy-basic/modules/basic-pageentry/src/component/blockPageEntry/controller.tsx +1 -1
  73. package/zova/src/suite/cabloy-basic/modules/basic-table/src/component/table/render.tsx +68 -8
  74. package/zova/src/suite-vendor/a-cabloy/modules/rest-resource/package.json +1 -1
  75. package/zova/src/suite-vendor/a-cabloy/modules/rest-resource/src/model/resource.ts +4 -0
  76. package/zova/src/suite-vendor/a-cabloy/package.json +2 -2
  77. package/zova/src/suite-vendor/a-zova/modules/a-form/package.json +1 -1
  78. package/zova/src/suite-vendor/a-zova/modules/a-form/src/lib/formLayout.ts +0 -6
  79. package/zova/src/suite-vendor/a-zova/modules/a-form/test/lib/formLayout.test.ts +16 -9
  80. package/zova/src/suite-vendor/a-zova/modules/a-openapi/package.json +1 -1
  81. package/zova/src/suite-vendor/a-zova/modules/a-openapi/src/model/sdk.ts +4 -0
  82. package/zova/src/suite-vendor/a-zova/modules/a-openapi/src/types/rest.ts +13 -2
  83. package/zova/src/suite-vendor/a-zova/modules/a-openapi/src/types/schema.ts +1 -0
  84. package/zova/src/suite-vendor/a-zova/modules/a-table/package.json +1 -1
  85. package/zova/src/suite-vendor/a-zova/modules/a-table/src/component/table/controller.tsx +50 -0
  86. package/zova/src/suite-vendor/a-zova/modules/a-table/src/component/table/render.tsx +60 -7
  87. package/zova/src/suite-vendor/a-zova/modules/a-table/src/types/table.ts +6 -4
  88. package/zova/src/suite-vendor/a-zova/package.json +4 -4
@@ -15,13 +15,24 @@ export type TypeFormFieldOnEffect = (value: any) => void;
15
15
 
16
16
  export interface ISchemaRenderComponentPresetRecord extends IResourceFormFieldRecord {}
17
17
 
18
- export interface ISchemaObjectExtensionFieldRest {
18
+ export type TypeTableColumnAlign = 'left' | 'center' | 'right';
19
+ export type TypeTableColumnFixed = 'left' | 'right';
20
+
21
+ export interface ITableColumnOptions {
22
+ order?: number;
23
+ align?: TypeTableColumnAlign;
24
+ width?: number;
25
+ fixed?: TypeTableColumnFixed;
26
+ enableSorting?: boolean;
27
+ sortDescFirst?: boolean;
28
+ }
29
+
30
+ export interface ISchemaObjectExtensionFieldRest extends ITableColumnOptions {
19
31
  'blocks'?: IResourceRenderBlockOptionsBlock[];
20
32
  'schemaScene'?: TypeSchemaScene;
21
33
  //
22
34
  'fieldSource'?: string;
23
35
  'visible'?: boolean;
24
- 'order'?: number;
25
36
  'disableNotifyChanged'?: boolean;
26
37
  'readonly'?: boolean;
27
38
  'onEffect'?: TypeFormFieldOnEffect;
@@ -16,6 +16,7 @@ export interface IOpenapiSchemas {
16
16
  sdk: TypeOpenapiSchemasSdk;
17
17
  query?: SchemaObject;
18
18
  filter?: SchemaObject;
19
+ order?: SchemaObject;
19
20
  requestBody?: SchemaObject;
20
21
  responseBody?: SchemaObject;
21
22
  paged?: SchemaObject;
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zova-module-a-table",
3
- "version": "5.1.38",
3
+ "version": "5.1.39",
4
4
  "gitHead": "09d901d17140a80ee0764211b441cda72fd94663",
5
5
  "description": "",
6
6
  "keywords": [
@@ -10,8 +10,11 @@ import { celEnvBase, isNilOrEmptyString } from '@cabloy/utils';
10
10
  import {
11
11
  CellContext,
12
12
  createColumnHelper,
13
+ functionalUpdate,
13
14
  getCoreRowModel,
15
+ OnChangeFn,
14
16
  Row,
17
+ SortingState,
15
18
  TableOptionsWithReactiveData,
16
19
  } from '@tanstack/vue-table';
17
20
  import { SchemaObject } from 'openapi3-ts/oas31';
@@ -48,6 +51,9 @@ import { ITableCellRenderColumnOptions } from '../../types/tableColumn.js';
48
51
  export interface ControllerTableProps<TData extends {} = {}> {
49
52
  data?: TData[];
50
53
  schema?: SchemaObject;
54
+ schemaOrder?: SchemaObject;
55
+ sorting?: SortingState;
56
+ onSortingChange?: OnChangeFn<SortingState>;
51
57
  tableScope?: ITableScope;
52
58
  getColumns?: TypeTableGetColumns<TData>;
53
59
  slotDefault?: (table: ControllerTable<TData>) => VNode;
@@ -95,9 +101,14 @@ export class ControllerTable<TData extends {} = {}> extends BeanControllerTableB
95
101
  return this.$props.data;
96
102
  }
97
103
 
104
+ public get sorting() {
105
+ return this.$props.sorting ?? [];
106
+ }
107
+
98
108
  public async refreshMeta() {
99
109
  this.tableMeta = await this._createTableMeta();
100
110
  this.columns = await this._createColumns();
111
+ this.table?.setColumnPinning(this._getColumnPinning());
101
112
  }
102
113
 
103
114
  private _createTable() {
@@ -108,6 +119,22 @@ export class ControllerTable<TData extends {} = {}> extends BeanControllerTableB
108
119
  getCoreRowModel: getCoreRowModel(),
109
120
  renderFallbackValue: this.scope.config.renderFallbackValue,
110
121
  manualPagination: true,
122
+ manualSorting: true,
123
+ enableMultiSort: false,
124
+ enableSortingRemoval: false,
125
+ state: {
126
+ get sorting() {
127
+ return self.sorting;
128
+ },
129
+ },
130
+ onSortingChange: updater => {
131
+ const sorting = functionalUpdate(updater, self.sorting).slice(0, 1);
132
+ self.$props.onSortingChange?.(sorting);
133
+ },
134
+ get initialState() {
135
+ const columnPinning = self._getColumnPinning();
136
+ return { columnPinning };
137
+ },
111
138
  get data() {
112
139
  return self.data || [];
113
140
  },
@@ -116,6 +143,7 @@ export class ControllerTable<TData extends {} = {}> extends BeanControllerTableB
116
143
  },
117
144
  };
118
145
  this.table = this.$useTable(tableOptions);
146
+ this.table.setColumnPinning(this._getColumnPinning());
119
147
  }
120
148
 
121
149
  private async _createColumns() {
@@ -162,12 +190,34 @@ export class ControllerTable<TData extends {} = {}> extends BeanControllerTableB
162
190
  return property?.title || key;
163
191
  },
164
192
  cell: props => tableMeta.renders[key](props),
193
+ size: property.rest?.width,
194
+ enableSorting: property.rest?.enableSorting === true && this._isOrderable(property),
195
+ sortDescFirst: property.rest?.sortDescFirst === true,
196
+ meta: { rest: property.rest },
165
197
  }),
166
198
  );
167
199
  }
168
200
  return columns;
169
201
  }
170
202
 
203
+ private _getColumnPinning() {
204
+ const left: string[] = [];
205
+ const right: string[] = [];
206
+ for (const property of this.tableMeta?.properties ?? []) {
207
+ const fixed = property.rest?.fixed;
208
+ if (fixed === 'left') left.push(property.key!);
209
+ if (fixed === 'right') right.push(property.key!);
210
+ }
211
+ return { left, right };
212
+ }
213
+
214
+ private _isOrderable(property: ISchemaObjectExtensionField) {
215
+ const properties = this.$props.schemaOrder?.properties;
216
+ if (!properties) return false;
217
+ const keys = [property.key, property.schemaKey, ...(property.schemaKeys ?? [])];
218
+ return keys.some(key => key && Object.prototype.hasOwnProperty.call(properties, key));
219
+ }
220
+
171
221
  private _createProperties() {
172
222
  this.properties = this.$computed(() => {
173
223
  return this.$sdk.loadSchemaProperties(this.schema, 'table');
@@ -1,9 +1,26 @@
1
+ import type { AriaAttributes, CSSProperties } from 'vue';
2
+
1
3
  import { FlexRender } from '@tanstack/vue-table';
2
4
  import { BeanRenderBase } from 'zova';
3
5
  import { Render } from 'zova-module-a-bean';
4
6
 
5
7
  @Render()
6
8
  export class RenderTable extends BeanRenderBase {
9
+ private _getColumnStyle(column: any): CSSProperties {
10
+ const rest = (column.columnDef.meta as any)?.rest;
11
+ const fixed = column.getIsPinned();
12
+ const width = rest?.width ? `${rest.width}px` : undefined;
13
+ return {
14
+ width,
15
+ minWidth: width,
16
+ textAlign: rest?.align,
17
+ position: fixed ? ('sticky' as const) : undefined,
18
+ left: fixed === 'left' ? `${column.getStart('left')}px` : undefined,
19
+ right: fixed === 'right' ? `${column.getAfter('right')}px` : undefined,
20
+ zIndex: fixed ? 1 : undefined,
21
+ };
22
+ }
23
+
7
24
  private _renderTableDefault() {
8
25
  const table = this.table;
9
26
  return (
@@ -11,12 +28,43 @@ export class RenderTable extends BeanRenderBase {
11
28
  <thead>
12
29
  <tr>
13
30
  {table.getFlatHeaders().map(header => {
31
+ const column = header.column;
32
+ const canSort = column.getCanSort();
33
+ const sorted = column.getIsSorted();
34
+ const fixed = column.getIsPinned();
35
+ const headerDefinition = column.columnDef.header;
36
+ const headerContent = (
37
+ <FlexRender render={headerDefinition} props={header.getContext()}></FlexRender>
38
+ );
39
+ let sortAria: AriaAttributes['aria-sort'] = 'none';
40
+ let sortIcon: '▲' | '▼' | '↕' = '↕';
41
+ if (sorted === 'asc') {
42
+ sortAria = 'ascending';
43
+ sortIcon = '▲';
44
+ } else if (sorted === 'desc') {
45
+ sortAria = 'descending';
46
+ sortIcon = '▼';
47
+ }
14
48
  return (
15
- <th key={header.id}>
16
- <FlexRender
17
- render={header.column.columnDef.header}
18
- props={header.getContext()}
19
- ></FlexRender>
49
+ <th
50
+ key={header.id}
51
+ class={fixed ? 'bg-base-100' : undefined}
52
+ style={this._getColumnStyle(column)}
53
+ aria-sort={sortAria}
54
+ >
55
+ {canSort ? (
56
+ <button
57
+ type="button"
58
+ class="inline-flex w-full items-center gap-1"
59
+ onClick={column.getToggleSortingHandler()}
60
+ aria-label={`Sort by ${column.id}`}
61
+ >
62
+ {headerContent}
63
+ <span aria-hidden="true">{sortIcon}</span>
64
+ </button>
65
+ ) : (
66
+ headerContent
67
+ )}
20
68
  </th>
21
69
  );
22
70
  })}
@@ -27,10 +75,15 @@ export class RenderTable extends BeanRenderBase {
27
75
  return (
28
76
  <tr key={row.id}>
29
77
  {row.getVisibleCells().map(cell => {
78
+ const column = cell.column;
30
79
  return (
31
- <td key={cell.id}>
80
+ <td
81
+ key={cell.id}
82
+ class={column.getIsPinned() ? 'bg-base-100' : undefined}
83
+ style={this._getColumnStyle(column)}
84
+ >
32
85
  <FlexRender
33
- render={cell.column.columnDef.cell}
86
+ render={column.columnDef.cell}
34
87
  props={cell.getContext()}
35
88
  ></FlexRender>
36
89
  </td>
@@ -1,6 +1,8 @@
1
1
  import type { ColumnDef, useVueTable } from '@tanstack/vue-table';
2
- import type { SchemaObject } from 'openapi3-ts/oas31';
3
- import type { TypeTableCellRenderComponent } from 'zova-module-a-openapi';
2
+ import type {
3
+ ISchemaObjectExtensionField,
4
+ TypeTableCellRenderComponent,
5
+ } from 'zova-module-a-openapi';
4
6
 
5
7
  import type { ControllerTable } from '../component/table/controller.jsx';
6
8
  import type { TypeTableCellRender } from './tableColumn.js';
@@ -10,12 +12,12 @@ export type TypeTable<TData extends {} = {}> = ReturnType<typeof useVueTable<TDa
10
12
  export type TypeColumn<TData extends {} = {}> = ColumnDef<TData, any>;
11
13
 
12
14
  export interface ITableMeta<TData extends {} = {}> {
13
- properties: SchemaObject[];
15
+ properties: ISchemaObjectExtensionField[];
14
16
  renders: Record<string, TypeTableCellRender<TData>>;
15
17
  }
16
18
 
17
19
  export type TypeTableGetColumnsNext<TData extends {} = {}> = (
18
- properties?: SchemaObject[],
20
+ properties?: ISchemaObjectExtensionField[],
19
21
  ) => Promise<TypeColumn<TData>[]>;
20
22
 
21
23
  export type TypeTableCreateColumnRender<TData extends {} = {}> = (
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zova-suite-a-zova",
3
- "version": "5.1.154",
3
+ "version": "5.1.155",
4
4
  "gitHead": "2c5c19284bab738e492856189acb6fad74b8a7b7",
5
5
  "description": "zova",
6
6
  "license": "MIT",
@@ -16,13 +16,13 @@
16
16
  "zova-module-a-boundary": "^5.1.22",
17
17
  "zova-module-a-command": "^5.1.34",
18
18
  "zova-module-a-fetch": "^5.1.25",
19
- "zova-module-a-form": "^5.1.50",
19
+ "zova-module-a-form": "^5.1.51",
20
20
  "zova-module-a-icon": "^5.1.27",
21
21
  "zova-module-a-interceptor": "^5.1.31",
22
22
  "zova-module-a-logger": "^5.1.28",
23
23
  "zova-module-a-meta": "^5.1.22",
24
24
  "zova-module-a-model": "^5.1.36",
25
- "zova-module-a-openapi": "^5.1.51",
25
+ "zova-module-a-openapi": "^5.1.52",
26
26
  "zova-module-a-router": "^5.1.34",
27
27
  "zova-module-a-routerstack": "^5.1.27",
28
28
  "zova-module-a-routertabs": "^5.1.34",
@@ -30,7 +30,7 @@
30
30
  "zova-module-a-ssrhmr": "^5.1.23",
31
31
  "zova-module-a-ssrserver": "^5.1.26",
32
32
  "zova-module-a-style": "^5.1.35",
33
- "zova-module-a-table": "^5.1.38",
33
+ "zova-module-a-table": "^5.1.39",
34
34
  "zova-module-a-zod": "^5.1.37",
35
35
  "zova-module-a-zova": "^5.1.103"
36
36
  },