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.
- package/.cabloy-version +1 -1
- package/CHANGELOG.md +15 -0
- package/package.json +1 -1
- package/repo-e2e/specs/cabloy-basic.spec.ts +45 -0
- package/vona/packages-cli/cli/package.json +1 -1
- package/vona/packages-cli/cli-set-api/cli/templates/tools/crudBasic/boilerplate/src/dto/{{resourceName}}SelectResItem.tsx_ +4 -0
- package/vona/packages-cli/cli-set-api/cli/templates/tools/crudStart/boilerplate/src/dto/{{resourceName}}SelectResItem.tsx_ +4 -0
- package/vona/packages-cli/cli-set-api/package.json +1 -1
- package/vona/pnpm-lock.yaml +83 -106
- package/vona/src/suite/a-training/modules/training-student/src/dto/studentSelectResItem.tsx +4 -0
- package/vona/src/suite/a-training/modules/training-student/test/student.test.ts +5 -0
- package/vona/src/suite-vendor/a-cabloy/modules/a-layoutprofile/package.json +54 -0
- package/vona/src/suite-vendor/a-cabloy/modules/a-layoutprofile/src/.metadata/index.ts +346 -0
- package/vona/src/suite-vendor/a-cabloy/modules/a-layoutprofile/src/.metadata/this.ts +2 -0
- package/vona/src/suite-vendor/a-cabloy/modules/a-layoutprofile/src/bean/meta.index.ts +12 -0
- package/vona/src/suite-vendor/a-cabloy/modules/a-layoutprofile/src/bean/meta.redlock.ts +11 -0
- package/vona/src/suite-vendor/a-cabloy/modules/a-layoutprofile/src/bean/meta.version.ts +20 -0
- package/vona/src/suite-vendor/a-cabloy/modules/a-layoutprofile/src/controller/layoutprofile.ts +38 -0
- package/vona/src/suite-vendor/a-cabloy/modules/a-layoutprofile/src/dto/layoutProfile.tsx +26 -0
- package/vona/src/suite-vendor/a-cabloy/modules/a-layoutprofile/src/dto/layoutProfileLoad.tsx +13 -0
- package/vona/src/suite-vendor/a-cabloy/modules/a-layoutprofile/src/dto/layoutProfileSave.tsx +31 -0
- package/vona/src/suite-vendor/a-cabloy/modules/a-layoutprofile/src/entity/layoutprofile.ts +20 -0
- package/vona/src/suite-vendor/a-cabloy/modules/a-layoutprofile/src/index.ts +2 -0
- package/vona/src/suite-vendor/a-cabloy/modules/a-layoutprofile/src/model/layoutprofile.ts +10 -0
- package/vona/src/suite-vendor/a-cabloy/modules/a-layoutprofile/src/service/layoutprofile.ts +64 -0
- package/vona/src/suite-vendor/a-cabloy/modules/a-layoutprofile/src/types/index.ts +1 -0
- package/vona/src/suite-vendor/a-cabloy/modules/a-layoutprofile/src/types/layoutprofile.ts +21 -0
- package/vona/src/suite-vendor/a-cabloy/modules/a-layoutprofile/test/layoutprofile.test.ts +258 -0
- package/vona/src/suite-vendor/a-cabloy/modules/a-layoutprofile/tsconfig.build.json +11 -0
- package/vona/src/suite-vendor/a-cabloy/modules/a-layoutprofile/tsconfig.json +7 -0
- package/vona/src/suite-vendor/a-cabloy/package.json +2 -1
- package/vona/src/suite-vendor/a-cabloy/tsconfig.json +3 -0
- package/zova/packages-zova/zova/package.json +2 -2
- package/zova/pnpm-lock.yaml +21 -6
- package/zova/src/suite/a-home/modules/home-base/src/service/ssrLayout.ts +20 -10
- package/zova/src/suite/cabloy-basic/modules/basic-app/src/component/routedDialog/controller.tsx +2 -0
- package/zova/src/suite/cabloy-basic/modules/basic-app/src/types/appModal.ts +3 -0
- package/zova/src/suite/cabloy-basic/modules/basic-page/src/component/blockPage/controller.tsx +44 -1
- package/zova/src/suite/cabloy-basic/modules/basic-page/src/component/blockTable/controller.tsx +1 -0
- package/zova/src/suite/cabloy-basic/modules/basic-page/src/component/blockToolbarBulk/controller.tsx +40 -25
- package/zova/src/suite/cabloy-basic/modules/basic-page/src/lib/selection.ts +11 -0
- package/zova/src/suite/cabloy-basic/modules/basic-page/test/lib/selection.test.ts +23 -0
- package/zova/src/suite/cabloy-basic/modules/basic-resource/src/component/formFieldResourcePicker/controller.tsx +5 -0
- package/zova/src/suite/cabloy-basic/modules/basic-resource/src/lib/resourcePickerPageHost.ts +64 -0
- package/zova/src/suite/cabloy-basic/modules/basic-resource/test/lib/resourcePickerPageHost.test.ts +94 -0
- package/zova/src/suite/cabloy-basic/modules/basic-table/src/.metadata/component/actionColumnConfig.ts +31 -0
- package/zova/src/suite/cabloy-basic/modules/basic-table/src/.metadata/index.ts +25 -12
- package/zova/src/suite/cabloy-basic/modules/basic-table/src/component/actionColumnConfig/controller.tsx +260 -0
- package/zova/src/suite/cabloy-basic/modules/basic-table/src/component/table/render.tsx +3 -3
- package/zova/src/suite/cabloy-basic/modules/basic-table/src/config/locale/en-us.ts +10 -0
- package/zova/src/suite/cabloy-basic/modules/basic-table/src/config/locale/zh-cn.ts +10 -0
- package/zova/src/suite-vendor/a-cabloy/modules/a-layoutprofile/cli/openapi.config.ts +9 -0
- package/zova/src/suite-vendor/a-cabloy/modules/a-layoutprofile/package.json +53 -0
- package/zova/src/suite-vendor/a-cabloy/modules/a-layoutprofile/src/.metadata/index.ts +140 -0
- package/zova/src/suite-vendor/a-cabloy/modules/a-layoutprofile/src/.metadata/this.ts +2 -0
- package/zova/src/suite-vendor/a-cabloy/modules/a-layoutprofile/src/api/layoutprofile.ts +67 -0
- package/zova/src/suite-vendor/a-cabloy/modules/a-layoutprofile/src/api/openapi/baseURL.ts +5 -0
- package/zova/src/suite-vendor/a-cabloy/modules/a-layoutprofile/src/api/openapi/index.ts +3 -0
- package/zova/src/suite-vendor/a-cabloy/modules/a-layoutprofile/src/api/openapi/schemas.ts +663 -0
- package/zova/src/suite-vendor/a-cabloy/modules/a-layoutprofile/src/api/openapi/types.ts +10150 -0
- package/zova/src/suite-vendor/a-cabloy/modules/a-layoutprofile/src/apiSchema/layoutprofile.ts +25 -0
- package/zova/src/suite-vendor/a-cabloy/modules/a-layoutprofile/src/index.ts +1 -0
- package/zova/src/suite-vendor/a-cabloy/modules/a-layoutprofile/src/model/layoutprofile.ts +76 -0
- package/zova/src/suite-vendor/a-cabloy/modules/a-layoutprofile/tsconfig.build.json +13 -0
- package/zova/src/suite-vendor/a-cabloy/modules/a-layoutprofile/tsconfig.json +5 -0
- package/zova/src/suite-vendor/a-cabloy/modules/rest-resource/package.json +1 -1
- package/zova/src/suite-vendor/a-cabloy/modules/rest-resource/src/lib/resourcePicker.ts +42 -0
- package/zova/src/suite-vendor/a-cabloy/modules/rest-resource/src/page/resourcePicker/controller.tsx +20 -79
- package/zova/src/suite-vendor/a-cabloy/package.json +3 -2
- package/zova/src/suite-vendor/a-zova/modules/a-bean/package.json +1 -1
- package/zova/src/suite-vendor/a-zova/modules/a-openapi/package.json +1 -1
- package/zova/src/suite-vendor/a-zova/modules/a-openapi/src/types/resource/tableActionBulk.ts +3 -0
- package/zova/src/suite-vendor/a-zova/modules/a-router/package.json +1 -1
- package/zova/src/suite-vendor/a-zova/modules/a-routerstack/package.json +1 -1
- package/zova/src/suite-vendor/a-zova/modules/a-ssr/package.json +1 -1
- package/zova/src/suite-vendor/a-zova/modules/a-ssr/src/lib/bodyReadyObserver.ts +13 -11
- package/zova/src/suite-vendor/a-zova/modules/a-table/package.json +1 -1
- package/zova/src/suite-vendor/a-zova/modules/a-table/src/component/table/controller.tsx +64 -2
- package/zova/src/suite-vendor/a-zova/modules/a-table/src/component/table/render.tsx +2 -3
- package/zova/src/suite-vendor/a-zova/modules/a-table/src/lib/beanControllerTableBase.ts +10 -0
- package/zova/src/suite-vendor/a-zova/modules/a-table/src/types/index.ts +1 -0
- package/zova/src/suite-vendor/a-zova/modules/a-table/src/types/tableLayout.ts +101 -0
- package/zova/src/suite-vendor/a-zova/modules/a-table/test/lib/tableLayout.test.ts +112 -0
- package/zova/src/suite-vendor/a-zova/package.json +7 -7
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import type { ISchemaObjectExtensionField } from 'zova-module-a-openapi';
|
|
2
|
+
|
|
3
|
+
import { TableColumnIdSelection } from './table.js';
|
|
4
|
+
|
|
5
|
+
export type TypeTableLayoutWidth = number | 'auto';
|
|
6
|
+
|
|
7
|
+
export interface ITableLayoutColumn {
|
|
8
|
+
key: string;
|
|
9
|
+
visible: boolean;
|
|
10
|
+
width: TypeTableLayoutWidth;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface ITableLayout {
|
|
14
|
+
version: 1;
|
|
15
|
+
schemaFingerprint?: string;
|
|
16
|
+
columns: ITableLayoutColumn[];
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface ITableLayoutProfileLike {
|
|
20
|
+
version?: unknown;
|
|
21
|
+
schemaFingerprint?: unknown;
|
|
22
|
+
columns?: unknown;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function isWidth(value: unknown): value is TypeTableLayoutWidth {
|
|
26
|
+
return (
|
|
27
|
+
value === 'auto' ||
|
|
28
|
+
(typeof value === 'number' && Number.isInteger(value) && value >= 1 && value <= 2000)
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Reconciles a persisted layout with the currently eligible schema columns.
|
|
34
|
+
* Schema visibility and fixed regions always remain authoritative.
|
|
35
|
+
*/
|
|
36
|
+
export function reconcileTableLayout(
|
|
37
|
+
properties: readonly ISchemaObjectExtensionField[],
|
|
38
|
+
profile?: ITableLayoutProfileLike | ITableLayout,
|
|
39
|
+
): ITableLayout {
|
|
40
|
+
const entries = new Map<string, ITableLayoutColumn>();
|
|
41
|
+
const profileColumns = Array.isArray(profile?.columns) ? profile.columns : [];
|
|
42
|
+
for (const item of profileColumns) {
|
|
43
|
+
if (!item || typeof item !== 'object') continue;
|
|
44
|
+
const column = item as Record<string, unknown>;
|
|
45
|
+
const key = typeof column.key === 'string' ? column.key.trim() : '';
|
|
46
|
+
if (!key || entries.has(key)) continue;
|
|
47
|
+
if (typeof column.visible !== 'boolean' || !isWidth(column.width)) continue;
|
|
48
|
+
entries.set(key, { key, visible: column.visible, width: column.width });
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const eligible = properties.filter(
|
|
52
|
+
property =>
|
|
53
|
+
typeof property.key === 'string' && property.key && property.key !== TableColumnIdSelection,
|
|
54
|
+
);
|
|
55
|
+
const schemaKeys = new Set(eligible.map(property => property.key!));
|
|
56
|
+
const regions = new Map<'left' | 'center' | 'right', ISchemaObjectExtensionField[]>();
|
|
57
|
+
regions.set('left', []);
|
|
58
|
+
regions.set('center', []);
|
|
59
|
+
regions.set('right', []);
|
|
60
|
+
for (const property of eligible) {
|
|
61
|
+
const fixed = property.rest?.fixed;
|
|
62
|
+
regions.get(fixed === 'left' ? 'left' : fixed === 'right' ? 'right' : 'center')!.push(property);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const result: ITableLayoutColumn[] = [];
|
|
66
|
+
for (const region of ['left', 'center', 'right'] as const) {
|
|
67
|
+
const regionProperties = regions.get(region)!;
|
|
68
|
+
const regionKeys = new Set(regionProperties.map(property => property.key!));
|
|
69
|
+
const ordered = profileColumns
|
|
70
|
+
.map(item =>
|
|
71
|
+
item && typeof item === 'object' ? (item as Record<string, unknown>) : undefined,
|
|
72
|
+
)
|
|
73
|
+
.filter(item => {
|
|
74
|
+
const key = typeof item?.key === 'string' ? item.key.trim() : '';
|
|
75
|
+
return !!key && regionKeys.has(key) && schemaKeys.has(key) && entries.get(key)?.key === key;
|
|
76
|
+
})
|
|
77
|
+
.map(item => item!.key as string);
|
|
78
|
+
const seen = new Set<string>();
|
|
79
|
+
for (const key of [...ordered, ...regionProperties.map(property => property.key!)]) {
|
|
80
|
+
if (seen.has(key)) continue;
|
|
81
|
+
seen.add(key);
|
|
82
|
+
const property = regionProperties.find(item => item.key === key)!;
|
|
83
|
+
const entry = entries.get(key);
|
|
84
|
+
const schemaWidth = property.rest?.width;
|
|
85
|
+
result.push({
|
|
86
|
+
key,
|
|
87
|
+
visible: entry?.visible ?? true,
|
|
88
|
+
width:
|
|
89
|
+
entry?.width ??
|
|
90
|
+
(typeof schemaWidth === 'number' && schemaWidth > 0 ? schemaWidth : 'auto'),
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return {
|
|
95
|
+
version: 1,
|
|
96
|
+
...(typeof profile?.schemaFingerprint === 'string'
|
|
97
|
+
? { schemaFingerprint: profile.schemaFingerprint }
|
|
98
|
+
: {}),
|
|
99
|
+
columns: result,
|
|
100
|
+
};
|
|
101
|
+
}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import type { ISchemaObjectExtensionField } from 'zova-module-a-openapi';
|
|
2
|
+
|
|
3
|
+
import assert from 'node:assert/strict';
|
|
4
|
+
import test from 'node:test';
|
|
5
|
+
|
|
6
|
+
import { TableColumnIdSelection } from '../../src/types/table.js';
|
|
7
|
+
import { reconcileTableLayout } from '../../src/types/tableLayout.js';
|
|
8
|
+
|
|
9
|
+
function createProperties(...properties: ISchemaObjectExtensionField[]) {
|
|
10
|
+
return properties;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
test('table layout drops stale and malformed profile columns while preserving schema defaults', () => {
|
|
14
|
+
const layout = reconcileTableLayout(
|
|
15
|
+
createProperties(
|
|
16
|
+
{ key: 'id', type: 'number', rest: { width: 60, fixed: 'left' } },
|
|
17
|
+
{ key: 'name', type: 'string' },
|
|
18
|
+
{ key: 'level', type: 'string', rest: { width: 120 } },
|
|
19
|
+
{ key: 'operations', type: 'string', rest: { width: 360, fixed: 'right' } },
|
|
20
|
+
),
|
|
21
|
+
{
|
|
22
|
+
version: 1,
|
|
23
|
+
schemaFingerprint: 'student-v1',
|
|
24
|
+
columns: [
|
|
25
|
+
{ key: 'name', visible: false, width: 480 },
|
|
26
|
+
{ key: 'obsolete', visible: true, width: 80 },
|
|
27
|
+
{ key: 'level', visible: true, width: 0 },
|
|
28
|
+
{ key: 'operations', visible: true, width: 'auto' },
|
|
29
|
+
{ key: '', visible: false, width: 90 },
|
|
30
|
+
],
|
|
31
|
+
},
|
|
32
|
+
);
|
|
33
|
+
|
|
34
|
+
assert.deepEqual(layout, {
|
|
35
|
+
version: 1,
|
|
36
|
+
schemaFingerprint: 'student-v1',
|
|
37
|
+
columns: [
|
|
38
|
+
{ key: 'id', visible: true, width: 60 },
|
|
39
|
+
{ key: 'name', visible: false, width: 480 },
|
|
40
|
+
{ key: 'level', visible: true, width: 120 },
|
|
41
|
+
{ key: 'operations', visible: true, width: 'auto' },
|
|
42
|
+
],
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
test('table layout retains the first valid duplicate and appends new schema fields', () => {
|
|
47
|
+
const layout = reconcileTableLayout(
|
|
48
|
+
createProperties(
|
|
49
|
+
{ key: 'name', type: 'string' },
|
|
50
|
+
{ key: 'level', type: 'string' },
|
|
51
|
+
{ key: 'createdAt', type: 'string', rest: { width: 180 } },
|
|
52
|
+
),
|
|
53
|
+
{
|
|
54
|
+
columns: [
|
|
55
|
+
{ key: 'level', visible: false, width: 240 },
|
|
56
|
+
{ key: 'name', visible: true, width: 'auto' },
|
|
57
|
+
{ key: 'level', visible: true, width: 300 },
|
|
58
|
+
],
|
|
59
|
+
},
|
|
60
|
+
);
|
|
61
|
+
|
|
62
|
+
assert.deepEqual(layout.columns, [
|
|
63
|
+
{ key: 'level', visible: false, width: 240 },
|
|
64
|
+
{ key: 'name', visible: true, width: 'auto' },
|
|
65
|
+
{ key: 'createdAt', visible: true, width: 180 },
|
|
66
|
+
]);
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
test('table layout permits ordering only within schema fixed regions', () => {
|
|
70
|
+
const layout = reconcileTableLayout(
|
|
71
|
+
createProperties(
|
|
72
|
+
{ key: 'leftFirst', type: 'string', rest: { fixed: 'left' } },
|
|
73
|
+
{ key: 'leftSecond', type: 'string', rest: { fixed: 'left' } },
|
|
74
|
+
{ key: 'centerFirst', type: 'string' },
|
|
75
|
+
{ key: 'centerSecond', type: 'string' },
|
|
76
|
+
{ key: 'rightFirst', type: 'string', rest: { fixed: 'right' } },
|
|
77
|
+
{ key: 'rightSecond', type: 'string', rest: { fixed: 'right' } },
|
|
78
|
+
),
|
|
79
|
+
{
|
|
80
|
+
columns: [
|
|
81
|
+
{ key: 'rightSecond', visible: true, width: 'auto' },
|
|
82
|
+
{ key: 'centerSecond', visible: true, width: 'auto' },
|
|
83
|
+
{ key: 'leftSecond', visible: true, width: 'auto' },
|
|
84
|
+
{ key: 'rightFirst', visible: true, width: 'auto' },
|
|
85
|
+
{ key: 'centerFirst', visible: true, width: 'auto' },
|
|
86
|
+
{ key: 'leftFirst', visible: true, width: 'auto' },
|
|
87
|
+
],
|
|
88
|
+
},
|
|
89
|
+
);
|
|
90
|
+
|
|
91
|
+
assert.deepEqual(
|
|
92
|
+
layout.columns.map(column => column.key),
|
|
93
|
+
['leftSecond', 'leftFirst', 'centerSecond', 'centerFirst', 'rightSecond', 'rightFirst'],
|
|
94
|
+
);
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
test('table layout excludes synthetic selection state from persistence', () => {
|
|
98
|
+
const layout = reconcileTableLayout(
|
|
99
|
+
createProperties(
|
|
100
|
+
{ key: TableColumnIdSelection, type: 'boolean' },
|
|
101
|
+
{ key: 'name', type: 'string' },
|
|
102
|
+
),
|
|
103
|
+
{
|
|
104
|
+
columns: [
|
|
105
|
+
{ key: TableColumnIdSelection, visible: false, width: 40 },
|
|
106
|
+
{ key: 'name', visible: true, width: 'auto' },
|
|
107
|
+
],
|
|
108
|
+
},
|
|
109
|
+
);
|
|
110
|
+
|
|
111
|
+
assert.deepEqual(layout.columns, [{ key: 'name', visible: true, width: 'auto' }]);
|
|
112
|
+
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zova-suite-a-zova",
|
|
3
|
-
"version": "5.1.
|
|
3
|
+
"version": "5.1.161",
|
|
4
4
|
"gitHead": "2c5c19284bab738e492856189acb6fad74b8a7b7",
|
|
5
5
|
"description": "zova",
|
|
6
6
|
"license": "MIT",
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"dependencies": {
|
|
11
11
|
"zova-module-a-api": "^5.1.22",
|
|
12
12
|
"zova-module-a-app": "^5.1.26",
|
|
13
|
-
"zova-module-a-bean": "^5.1.
|
|
13
|
+
"zova-module-a-bean": "^5.1.35",
|
|
14
14
|
"zova-module-a-behavior": "^5.1.26",
|
|
15
15
|
"zova-module-a-behaviors": "^5.1.22",
|
|
16
16
|
"zova-module-a-boundary": "^5.1.22",
|
|
@@ -22,15 +22,15 @@
|
|
|
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.
|
|
26
|
-
"zova-module-a-router": "^5.1.
|
|
27
|
-
"zova-module-a-routerstack": "^5.1.
|
|
25
|
+
"zova-module-a-openapi": "^5.1.54",
|
|
26
|
+
"zova-module-a-router": "^5.1.37",
|
|
27
|
+
"zova-module-a-routerstack": "^5.1.29",
|
|
28
28
|
"zova-module-a-routertabs": "^5.1.34",
|
|
29
|
-
"zova-module-a-ssr": "^5.1.
|
|
29
|
+
"zova-module-a-ssr": "^5.1.39",
|
|
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.
|
|
33
|
+
"zova-module-a-table": "^5.1.43",
|
|
34
34
|
"zova-module-a-zod": "^5.1.37",
|
|
35
35
|
"zova-module-a-zova": "^5.1.104"
|
|
36
36
|
},
|