cabloy 5.1.167 → 5.1.169
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 +13 -0
- package/package.json +1 -1
- package/repo-e2e/specs/cabloy-basic.spec.ts +75 -0
- package/vona/pnpm-lock.yaml +267 -53
- package/vona/src/suite/a-training/modules/training-record/src/entity/record.tsx +2 -0
- package/zova/packages-zova/zova/package.json +2 -2
- package/zova/pnpm-lock.yaml +113 -84
- package/zova/src/suite/cabloy-basic/modules/basic-app/src/.metadata/component/routedDialog.ts +2 -1
- package/zova/src/suite/cabloy-basic/modules/basic-app/src/component/routedDialog/controller.tsx +8 -2
- package/zova/src/suite/cabloy-basic/modules/basic-app/src/service/appModal.ts +60 -8
- package/zova/src/suite/cabloy-basic/modules/basic-app/src/types/appModal.ts +43 -8
- package/zova/src/suite/cabloy-basic/modules/basic-page/src/.metadata/index.ts +6 -6
- package/zova/src/suite/cabloy-basic/modules/basic-page/src/component/blockPage/controller.tsx +95 -10
- 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/config/locale/en-us.ts +1 -0
- package/zova/src/suite/cabloy-basic/modules/basic-page/src/config/locale/zh-cn.ts +1 -0
- package/zova/src/suite/cabloy-basic/modules/basic-page/src/index.ts +1 -0
- package/zova/src/suite/cabloy-basic/modules/basic-page/src/lib/selection.ts +35 -0
- package/zova/src/suite/cabloy-basic/modules/basic-page/test/lib/selection.test.ts +24 -0
- package/zova/src/suite/cabloy-basic/modules/basic-resource/src/.metadata/component/blockResourcePickerActions.ts +34 -0
- package/zova/src/suite/cabloy-basic/modules/basic-resource/src/.metadata/index.ts +30 -8
- package/zova/src/suite/cabloy-basic/modules/basic-resource/src/.metadata/locales.ts +7 -0
- package/zova/src/suite/cabloy-basic/modules/basic-resource/src/component/blockResourcePickerActions/controller.tsx +92 -0
- package/zova/src/suite/cabloy-basic/modules/basic-resource/src/component/formFieldResourcePicker/controller.tsx +224 -11
- package/zova/src/suite/cabloy-basic/modules/basic-resource/src/config/locale/en-us.ts +8 -0
- package/zova/src/suite/cabloy-basic/modules/basic-resource/src/config/locale/zh-cn.ts +7 -0
- package/zova/src/suite/cabloy-basic/modules/basic-resource/src/index.ts +2 -0
- package/zova/src/suite/cabloy-basic/modules/basic-resource/src/lib/resourcePicker.ts +29 -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/resourcePicker.test.ts +32 -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/component/table/render.tsx +18 -12
- 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/.metadata/component/resourcePickerContext.ts +31 -0
- package/zova/src/suite-vendor/a-cabloy/modules/rest-resource/src/.metadata/index.ts +48 -5
- package/zova/src/suite-vendor/a-cabloy/modules/rest-resource/src/.metadata/page/resourcePicker.ts +16 -0
- package/zova/src/suite-vendor/a-cabloy/modules/rest-resource/src/component/resourcePickerContext/controller.tsx +26 -0
- package/zova/src/suite-vendor/a-cabloy/modules/rest-resource/src/index.ts +2 -0
- package/zova/src/suite-vendor/a-cabloy/modules/rest-resource/src/lib/resourcePicker.ts +43 -0
- package/zova/src/suite-vendor/a-cabloy/modules/rest-resource/src/page/resourcePicker/controller.tsx +85 -0
- package/zova/src/suite-vendor/a-cabloy/modules/rest-resource/src/routes.ts +9 -0
- package/zova/src/suite-vendor/a-cabloy/package.json +2 -2
- package/zova/src/suite-vendor/a-zova/modules/a-bean/cli/controller/metadata/generateFileComponent.ts +40 -1
- package/zova/src/suite-vendor/a-zova/modules/a-bean/package.json +1 -1
- package/zova/src/suite-vendor/a-zova/modules/a-router/package.json +1 -1
- package/zova/src/suite-vendor/a-zova/modules/a-router/src/lib/routerViewBase.tsx +5 -0
- package/zova/src/suite-vendor/a-zova/modules/a-routerstack/package.json +1 -1
- package/zova/src/suite-vendor/a-zova/modules/a-routerstack/src/component/routerViewStack/controller.tsx +7 -1
- 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 +2 -0
- package/zova/src/suite-vendor/a-zova/modules/a-table/src/component/table/render.tsx +13 -10
- package/zova/src/suite-vendor/a-zova/package.json +5 -5
package/zova/src/suite/cabloy-basic/modules/basic-resource/test/lib/resourcePickerPageHost.test.ts
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import type { IResourceRenderBlockOptionsBlock } from 'zova-module-a-openapi';
|
|
2
|
+
|
|
3
|
+
import assert from 'node:assert/strict';
|
|
4
|
+
import test from 'node:test';
|
|
5
|
+
|
|
6
|
+
import { createResourcePickerPageHost } from '../../src/lib/resourcePickerPageHost.ts';
|
|
7
|
+
|
|
8
|
+
function createDialog() {
|
|
9
|
+
const resolved: unknown[] = [];
|
|
10
|
+
let cancelled = false;
|
|
11
|
+
const dialog = {
|
|
12
|
+
id: 1,
|
|
13
|
+
props: {
|
|
14
|
+
resource: 'training-student:student',
|
|
15
|
+
selectionMode: 'multiple' as const,
|
|
16
|
+
selectionMax: 2,
|
|
17
|
+
},
|
|
18
|
+
session: {
|
|
19
|
+
selectedIds: [1],
|
|
20
|
+
selectedRows: [{ id: 1, name: 'One' }],
|
|
21
|
+
},
|
|
22
|
+
resolve(value: unknown) {
|
|
23
|
+
resolved.push(value);
|
|
24
|
+
},
|
|
25
|
+
cancel() {
|
|
26
|
+
cancelled = true;
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
return {
|
|
30
|
+
dialog,
|
|
31
|
+
resolved,
|
|
32
|
+
get cancelled() {
|
|
33
|
+
return cancelled;
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
test('Basic picker host adapts only the Basic page block and preserves picker state', () => {
|
|
39
|
+
const { dialog } = createDialog();
|
|
40
|
+
const host = createResourcePickerPageHost(dialog);
|
|
41
|
+
const unrelated: IResourceRenderBlockOptionsBlock = {
|
|
42
|
+
render: 'other:block' as never,
|
|
43
|
+
options: { class: 'other' },
|
|
44
|
+
};
|
|
45
|
+
const basicPage: IResourceRenderBlockOptionsBlock = {
|
|
46
|
+
render: 'basic-page:blockPage' as never,
|
|
47
|
+
options: {
|
|
48
|
+
blocks: [{ render: 'basic-page:blockTable' as never }],
|
|
49
|
+
} as any,
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
const context = {
|
|
53
|
+
options: dialog.props,
|
|
54
|
+
session: dialog.session,
|
|
55
|
+
dialog: host,
|
|
56
|
+
};
|
|
57
|
+
const blocks = host.prepareBlocks([unrelated, basicPage], context)!;
|
|
58
|
+
|
|
59
|
+
assert.equal(blocks[0], unrelated);
|
|
60
|
+
assert.deepEqual(blocks[1].options, {
|
|
61
|
+
actionPath: undefined,
|
|
62
|
+
queryFixed: undefined,
|
|
63
|
+
selectionPolicy: 'always',
|
|
64
|
+
selectionMode: 'multiple',
|
|
65
|
+
selectionMax: 2,
|
|
66
|
+
selectedIds: [1],
|
|
67
|
+
selectedRows: [{ id: 1, name: 'One' }],
|
|
68
|
+
blocks: [
|
|
69
|
+
{ render: 'basic-page:blockTable' },
|
|
70
|
+
{ render: 'basic-resource:blockResourcePickerActions' },
|
|
71
|
+
],
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
const onSelectionChange = (blocks[1].options as any).onSelectionChange as (
|
|
75
|
+
selection: any,
|
|
76
|
+
) => void;
|
|
77
|
+
onSelectionChange({ ids: [2], rows: [{ id: 2, name: 'Two' }], count: 1 });
|
|
78
|
+
assert.deepEqual(dialog.session, {
|
|
79
|
+
selectedIds: [2],
|
|
80
|
+
selectedRows: [{ id: 2, name: 'Two' }],
|
|
81
|
+
});
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
test('Basic picker host forwards resolve and cancel', () => {
|
|
85
|
+
const { dialog, resolved, cancelled } = createDialog();
|
|
86
|
+
const host = createResourcePickerPageHost(dialog);
|
|
87
|
+
const selection = { ids: [1], rows: [{ id: 1 }], count: 1 };
|
|
88
|
+
|
|
89
|
+
host.resolve(selection);
|
|
90
|
+
host.cancel();
|
|
91
|
+
|
|
92
|
+
assert.deepEqual(resolved, [selection]);
|
|
93
|
+
assert.equal(cancelled, true);
|
|
94
|
+
});
|
|
@@ -16,6 +16,7 @@ export class RenderTable<TData extends {} = {}> extends BeanRenderBase {
|
|
|
16
16
|
sorting={this.$props.sorting}
|
|
17
17
|
onSortingChange={this.$props.onSortingChange}
|
|
18
18
|
enableRowSelection={this.$props.enableRowSelection}
|
|
19
|
+
selectionMode={this.$props.selectionMode}
|
|
19
20
|
rowSelection={this.$props.rowSelection}
|
|
20
21
|
onRowSelectionChange={this.$props.onRowSelectionChange}
|
|
21
22
|
tableScope={this.$props.tableScope}
|
|
@@ -48,6 +49,7 @@ export class RenderTable<TData extends {} = {}> extends BeanRenderBase {
|
|
|
48
49
|
|
|
49
50
|
public _renderTable($$table: ControllerTable<TData>) {
|
|
50
51
|
const table = $$table.table;
|
|
52
|
+
const selectionMode = this.$props.selectionMode ?? 'multiple';
|
|
51
53
|
const selectionEnabled = $$table.columns.some(column => column.id === TableColumnIdSelection);
|
|
52
54
|
return (
|
|
53
55
|
<table class="table">
|
|
@@ -61,16 +63,18 @@ export class RenderTable<TData extends {} = {}> extends BeanRenderBase {
|
|
|
61
63
|
const headerDefinition = column.columnDef.header;
|
|
62
64
|
const selection = selectionEnabled && column.id === TableColumnIdSelection;
|
|
63
65
|
const headerContent = selection ? (
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
66
|
+
selectionMode === 'single' ? null : (
|
|
67
|
+
<input
|
|
68
|
+
type="checkbox"
|
|
69
|
+
class="checkbox checkbox-sm"
|
|
70
|
+
checked={table.getIsAllPageRowsSelected()}
|
|
71
|
+
indeterminate={table.getIsSomePageRowsSelected()}
|
|
72
|
+
aria-checked={table.getIsSomePageRowsSelected() ? 'mixed' : undefined}
|
|
73
|
+
aria-label={this.scope.locale.SelectAllPageRows()}
|
|
74
|
+
disabled={table.getRowModel().rows.every(row => !row.getCanSelect())}
|
|
75
|
+
onChange={table.getToggleAllPageRowsSelectedHandler()}
|
|
76
|
+
/>
|
|
77
|
+
)
|
|
74
78
|
) : (
|
|
75
79
|
<FlexRender render={headerDefinition} props={header.getContext()}></FlexRender>
|
|
76
80
|
);
|
|
@@ -123,8 +127,10 @@ export class RenderTable<TData extends {} = {}> extends BeanRenderBase {
|
|
|
123
127
|
>
|
|
124
128
|
{selection ? (
|
|
125
129
|
<input
|
|
126
|
-
type=
|
|
127
|
-
class=
|
|
130
|
+
type={selectionMode === 'single' ? 'radio' : 'checkbox'}
|
|
131
|
+
class={
|
|
132
|
+
selectionMode === 'single' ? 'radio radio-sm' : 'checkbox checkbox-sm'
|
|
133
|
+
}
|
|
128
134
|
checked={row.getIsSelected()}
|
|
129
135
|
disabled={!row.getCanSelect()}
|
|
130
136
|
aria-label={this.scope.locale.SelectRow(row.id)}
|
|
@@ -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 { ControllerResourcePickerContextProps } from '../../component/resourcePickerContext/controller.jsx';
|
|
7
|
+
|
|
8
|
+
import { ControllerResourcePickerContext } from '../../component/resourcePickerContext/controller.jsx';
|
|
9
|
+
export type ZResourcePickerContextProps = {
|
|
10
|
+
controllerRef?: (ref: ControllerResourcePickerContext) => void;
|
|
11
|
+
} & ControllerResourcePickerContextProps;
|
|
12
|
+
|
|
13
|
+
type ControllerInnerProps = TypeControllerInnerProps<
|
|
14
|
+
ControllerResourcePickerContextProps,
|
|
15
|
+
keyof typeof ControllerResourcePickerContext.$propsDefault
|
|
16
|
+
>;
|
|
17
|
+
declare module 'zova-module-rest-resource' {
|
|
18
|
+
export interface ControllerResourcePickerContext {
|
|
19
|
+
$props: ControllerInnerProps;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export const ZResourcePickerContext = defineComponent((_props: ZResourcePickerContextProps) => {
|
|
24
|
+
useController(ControllerResourcePickerContext, undefined, undefined);
|
|
25
|
+
return () => {};
|
|
26
|
+
}, prepareComponentOptions());
|
|
27
|
+
declare module 'zova-module-a-bean' {
|
|
28
|
+
export interface IVonaComponentRecord {
|
|
29
|
+
'rest-resource:resourcePickerContext': ControllerResourcePickerContextProps;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -26,7 +26,7 @@ declare module 'zova-module-rest-resource' {
|
|
|
26
26
|
}
|
|
27
27
|
/** model: end */
|
|
28
28
|
/** model: begin */
|
|
29
|
-
import { ModelResource } from '../model/resource.js';
|
|
29
|
+
import type { ModelResource } from '../model/resource.js';
|
|
30
30
|
import 'zova';
|
|
31
31
|
declare module 'zova' {
|
|
32
32
|
export interface IBeanRecordGeneral {
|
|
@@ -35,9 +35,11 @@ declare module 'zova' {
|
|
|
35
35
|
}
|
|
36
36
|
/** model: end */
|
|
37
37
|
/** controller: begin */
|
|
38
|
+
export * from '../component/resourcePickerContext/controller.jsx';
|
|
38
39
|
export * from '../page/entry/controller.jsx';
|
|
39
40
|
export * from '../page/entryCreate/controller.jsx';
|
|
40
41
|
export * from '../page/resource/controller.jsx';
|
|
42
|
+
export * from '../page/resourcePicker/controller.jsx';
|
|
41
43
|
|
|
42
44
|
import 'zova';
|
|
43
45
|
declare module 'zova' {
|
|
@@ -46,6 +48,11 @@ declare module 'zova' {
|
|
|
46
48
|
}
|
|
47
49
|
declare module 'zova-module-rest-resource' {
|
|
48
50
|
|
|
51
|
+
export interface ControllerResourcePickerContext {
|
|
52
|
+
/** @internal */
|
|
53
|
+
get scope(): ScopeModuleRestResource;
|
|
54
|
+
}
|
|
55
|
+
|
|
49
56
|
export interface ControllerPageEntry {
|
|
50
57
|
/** @internal */
|
|
51
58
|
get scope(): ScopeModuleRestResource;
|
|
@@ -55,18 +62,27 @@ declare module 'zova-module-rest-resource' {
|
|
|
55
62
|
/** @internal */
|
|
56
63
|
get scope(): ScopeModuleRestResource;
|
|
57
64
|
}
|
|
65
|
+
|
|
66
|
+
export interface ControllerPageResourcePicker {
|
|
67
|
+
/** @internal */
|
|
68
|
+
get scope(): ScopeModuleRestResource;
|
|
69
|
+
}
|
|
58
70
|
}
|
|
59
71
|
/** controller: end */
|
|
60
72
|
/** controller: begin */
|
|
61
|
-
import {
|
|
62
|
-
import {
|
|
63
|
-
import {
|
|
73
|
+
import type { ControllerResourcePickerContext } from '../component/resourcePickerContext/controller.jsx';
|
|
74
|
+
import type { ControllerPageEntry } from '../page/entry/controller.jsx';
|
|
75
|
+
import type { ControllerPageEntryCreate } from '../page/entryCreate/controller.jsx';
|
|
76
|
+
import type { ControllerPageResource } from '../page/resource/controller.jsx';
|
|
77
|
+
import type { ControllerPageResourcePicker } from '../page/resourcePicker/controller.jsx';
|
|
64
78
|
import 'zova';
|
|
65
79
|
declare module 'zova' {
|
|
66
80
|
export interface IBeanRecordLocal {
|
|
67
|
-
'rest-resource.controller.
|
|
81
|
+
'rest-resource.controller.resourcePickerContext': ControllerResourcePickerContext;
|
|
82
|
+
'rest-resource.controller.pageEntry': ControllerPageEntry;
|
|
68
83
|
'rest-resource.controller.pageEntryCreate': ControllerPageEntryCreate;
|
|
69
84
|
'rest-resource.controller.pageResource': ControllerPageResource;
|
|
85
|
+
'rest-resource.controller.pageResourcePicker': ControllerPageResourcePicker;
|
|
70
86
|
}
|
|
71
87
|
}
|
|
72
88
|
/** controller: end */
|
|
@@ -77,6 +93,8 @@ export * from './page/entryCreate.js';
|
|
|
77
93
|
import { NSControllerPageEntryCreate } from './page/entryCreate.js';
|
|
78
94
|
export * from './page/resource.js';
|
|
79
95
|
import { NSControllerPageResource } from './page/resource.js';
|
|
96
|
+
export * from './page/resourcePicker.js';
|
|
97
|
+
import { NSControllerPageResourcePicker } from './page/resourcePicker.js';
|
|
80
98
|
export * from '../routes.js';
|
|
81
99
|
import { TypePagePathSchema } from 'zova-module-a-router';
|
|
82
100
|
import 'zova';
|
|
@@ -85,11 +103,13 @@ export interface IPagePathRecord {
|
|
|
85
103
|
'/rest/resource/:resource/:id/:formScene?': TypePagePathSchema<NSControllerPageEntry.ParamsInput,undefined>;
|
|
86
104
|
'/rest/resource/:resource/create': TypePagePathSchema<NSControllerPageEntryCreate.ParamsInput,undefined>;
|
|
87
105
|
'/rest/resource/:resource': TypePagePathSchema<NSControllerPageResource.ParamsInput,undefined>;
|
|
106
|
+
'/rest/resource/:resource/picker': TypePagePathSchema<NSControllerPageResourcePicker.ParamsInput,undefined>;
|
|
88
107
|
}
|
|
89
108
|
export interface IPageNameRecord {
|
|
90
109
|
'rest-resource:entry': TypePagePathSchema<NSControllerPageEntry.ParamsInput,undefined>;
|
|
91
110
|
'rest-resource:entryCreate': TypePagePathSchema<NSControllerPageEntryCreate.ParamsInput,undefined>;
|
|
92
111
|
'rest-resource:resource': TypePagePathSchema<NSControllerPageResource.ParamsInput,undefined>;
|
|
112
|
+
'rest-resource:resourcePicker': TypePagePathSchema<NSControllerPageResourcePicker.ParamsInput,undefined>;
|
|
93
113
|
}
|
|
94
114
|
}
|
|
95
115
|
export const pagePathSchemas = {
|
|
@@ -107,6 +127,10 @@ export const pageNameSchemas = {
|
|
|
107
127
|
'rest-resource:resource': {
|
|
108
128
|
params: NSControllerPageResource.paramsSchema,
|
|
109
129
|
|
|
130
|
+
},
|
|
131
|
+
'rest-resource:resourcePicker': {
|
|
132
|
+
params: NSControllerPageResourcePicker.paramsSchema,
|
|
133
|
+
|
|
110
134
|
},
|
|
111
135
|
};
|
|
112
136
|
declare module 'zova-module-rest-resource' {
|
|
@@ -119,9 +143,28 @@ export interface ControllerPageEntryCreate {
|
|
|
119
143
|
export interface ControllerPageResource {
|
|
120
144
|
$params: NSControllerPageResource.ParamsOutput;
|
|
121
145
|
}
|
|
146
|
+
export interface ControllerPageResourcePicker {
|
|
147
|
+
$params: NSControllerPageResourcePicker.ParamsOutput;
|
|
148
|
+
}
|
|
122
149
|
}
|
|
123
150
|
/** pages: end */
|
|
124
151
|
|
|
152
|
+
/** components: begin */
|
|
153
|
+
export * from './component/resourcePickerContext.js';
|
|
154
|
+
import { ZResourcePickerContext } from './component/resourcePickerContext.js';
|
|
155
|
+
export const components = {
|
|
156
|
+
'resourcePickerContext': ZResourcePickerContext,
|
|
157
|
+
};
|
|
158
|
+
import 'zova';
|
|
159
|
+
declare module 'zova' {
|
|
160
|
+
export interface IComponentRecord {
|
|
161
|
+
'rest-resource:resourcePickerContext': ControllerResourcePickerContext;
|
|
162
|
+
}
|
|
163
|
+
export interface IZovaComponentRecord {
|
|
164
|
+
'rest-resource:resourcePickerContext': typeof ZResourcePickerContext;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
/** components: end */
|
|
125
168
|
/** scope: begin */
|
|
126
169
|
import { BeanScopeBase, type BeanScopeUtil } from 'zova';
|
|
127
170
|
import { Scope } from 'zova-module-a-bean';
|
package/zova/src/suite-vendor/a-cabloy/modules/rest-resource/src/.metadata/page/resourcePicker.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { createZovaComponentPage } from 'zova';
|
|
3
|
+
|
|
4
|
+
import { ControllerPageResourcePicker } from '../../page/resourcePicker/controller.jsx';
|
|
5
|
+
import { ControllerPageResourcePickerSchemaParams } from '../../page/resourcePicker/controller.jsx';
|
|
6
|
+
export namespace NSControllerPageResourcePicker {
|
|
7
|
+
export const paramsSchema = ControllerPageResourcePickerSchemaParams;
|
|
8
|
+
export type ParamsInput = z.input<typeof ControllerPageResourcePickerSchemaParams>;
|
|
9
|
+
export type ParamsOutput = z.output<typeof ControllerPageResourcePickerSchemaParams>;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export const ZPageResourcePicker = createZovaComponentPage(
|
|
13
|
+
ControllerPageResourcePicker,
|
|
14
|
+
undefined,
|
|
15
|
+
undefined,
|
|
16
|
+
);
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { BeanControllerBase } from 'zova';
|
|
2
|
+
import { Controller } from 'zova-module-a-bean';
|
|
3
|
+
|
|
4
|
+
import type { IResourcePickerPageContext } from '../../page/resourcePicker/controller.js';
|
|
5
|
+
|
|
6
|
+
import { resourcePickerPageContextKey } from '../../lib/resourcePicker.js';
|
|
7
|
+
|
|
8
|
+
export interface ControllerResourcePickerContextProps {
|
|
9
|
+
context: IResourcePickerPageContext;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
@Controller()
|
|
13
|
+
export class ControllerResourcePickerContext extends BeanControllerBase {
|
|
14
|
+
static $propsDefault = {};
|
|
15
|
+
|
|
16
|
+
protected async __init__() {
|
|
17
|
+
this.bean._setBean(
|
|
18
|
+
resourcePickerPageContextKey,
|
|
19
|
+
(this.$props as ControllerResourcePickerContextProps).context,
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
protected render() {
|
|
24
|
+
return this.$slotDefault?.();
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -0,0 +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
|
+
|
|
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
|
+
}
|
package/zova/src/suite-vendor/a-cabloy/modules/rest-resource/src/page/resourcePicker/controller.tsx
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import type { VNode } from 'vue';
|
|
2
|
+
|
|
3
|
+
import { z } from 'zod';
|
|
4
|
+
import { BeanControllerPageBase, deepExtend, Use, usePrepareArg } from 'zova';
|
|
5
|
+
import { ZovaJsx } from 'zova-jsx';
|
|
6
|
+
import { Controller } from 'zova-module-a-bean';
|
|
7
|
+
import { $QueryEnsureLoaded } from 'zova-module-a-model';
|
|
8
|
+
import { ZPage } from 'zova-module-home-base';
|
|
9
|
+
|
|
10
|
+
import type {
|
|
11
|
+
IResourcePickerPageContext,
|
|
12
|
+
IResourcePickerPageHost,
|
|
13
|
+
} from '../../lib/resourcePicker.js';
|
|
14
|
+
import type { ModelResource } from '../../model/resource.js';
|
|
15
|
+
|
|
16
|
+
import { ZResourcePickerContext } from '../../.metadata/component/resourcePickerContext.js';
|
|
17
|
+
import { resourcePickerPageHostKey } from '../../lib/resourcePicker.js';
|
|
18
|
+
|
|
19
|
+
export const ControllerPageResourcePickerSchemaParams = z.object({
|
|
20
|
+
resource: z.string(),
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
@Controller()
|
|
24
|
+
export class ControllerPageResourcePicker extends BeanControllerPageBase {
|
|
25
|
+
jsxZova: ZovaJsx;
|
|
26
|
+
|
|
27
|
+
@Use({ beanFullName: 'rest-resource.model.resource' })
|
|
28
|
+
get $$modelResource(): ModelResource {
|
|
29
|
+
return usePrepareArg(this.resource, true);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
@Use({ name: resourcePickerPageHostKey, injectionScope: 'host' })
|
|
33
|
+
$$pickerHost: IResourcePickerPageHost | undefined;
|
|
34
|
+
|
|
35
|
+
get resource() {
|
|
36
|
+
return this.$params.resource;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
get pickerContext(): IResourcePickerPageContext {
|
|
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) {
|
|
47
|
+
throw new Error('resource picker context does not match route resource');
|
|
48
|
+
}
|
|
49
|
+
return {
|
|
50
|
+
options,
|
|
51
|
+
session,
|
|
52
|
+
dialog: host,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
protected async __init__() {
|
|
57
|
+
this.jsxZova = this.bean._newBeanSimple(ZovaJsx, false);
|
|
58
|
+
await $QueryEnsureLoaded(() => this.$$modelResource.apiSchemasSelect.sdk);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
get schemaRow() {
|
|
62
|
+
return this.$$modelResource.schemaRow;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
public render() {
|
|
66
|
+
const pickerContext = this.pickerContext;
|
|
67
|
+
const blocks = this.$$pickerHost!.prepareBlocks(this.schemaRow?.rest?.blocks, pickerContext);
|
|
68
|
+
if (!blocks || blocks.length === 0) return;
|
|
69
|
+
const domBlocks: VNode[] = [];
|
|
70
|
+
blocks.forEach((block, index) => {
|
|
71
|
+
const options = deepExtend({ key: index }, { resource: this.resource }, block.options);
|
|
72
|
+
const domBlock = this.jsxZova.render(block.render!, options);
|
|
73
|
+
if (!domBlock) return;
|
|
74
|
+
if (Array.isArray(domBlock)) domBlocks.push(...domBlock);
|
|
75
|
+
else domBlocks.push(domBlock);
|
|
76
|
+
});
|
|
77
|
+
return (
|
|
78
|
+
<ZResourcePickerContext context={pickerContext}>
|
|
79
|
+
<ZPage>{domBlocks}</ZPage>
|
|
80
|
+
</ZResourcePickerContext>
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export type { IResourcePickerPageContext } from '../../lib/resourcePicker.js';
|
|
@@ -3,6 +3,7 @@ import type { IModuleRoute } from 'zova-module-a-router';
|
|
|
3
3
|
import { ZPageEntry } from './.metadata/page/entry.js';
|
|
4
4
|
import { ZPageEntryCreate } from './.metadata/page/entryCreate.js';
|
|
5
5
|
import { ZPageResource } from './.metadata/page/resource.js';
|
|
6
|
+
import { ZPageResourcePicker } from './.metadata/page/resourcePicker.js';
|
|
6
7
|
import { resourceRouteMeta, resourceTabKey } from './lib/resourceRouteMeta.js';
|
|
7
8
|
|
|
8
9
|
export const routes: IModuleRoute[] = [
|
|
@@ -21,6 +22,14 @@ export const routes: IModuleRoute[] = [
|
|
|
21
22
|
ssrProfile: 'session',
|
|
22
23
|
},
|
|
23
24
|
},
|
|
25
|
+
{
|
|
26
|
+
name: 'resourcePicker',
|
|
27
|
+
path: ':resource/picker',
|
|
28
|
+
component: ZPageResourcePicker,
|
|
29
|
+
meta: {
|
|
30
|
+
ssrProfile: 'session',
|
|
31
|
+
},
|
|
32
|
+
},
|
|
24
33
|
{
|
|
25
34
|
name: 'entry',
|
|
26
35
|
path: ':resource/:id/:formScene?',
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zova-suite-a-cabloy",
|
|
3
|
-
"version": "5.1.
|
|
3
|
+
"version": "5.1.55",
|
|
4
4
|
"gitHead": "4dece229b6d3f4735930e833afcb4b95ec51bf86",
|
|
5
5
|
"description": "",
|
|
6
6
|
"author": "",
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"type": "module",
|
|
9
9
|
"dependencies": {
|
|
10
10
|
"zova-module-a-rbac": "^5.0.1",
|
|
11
|
-
"zova-module-rest-resource": "^5.1.
|
|
11
|
+
"zova-module-rest-resource": "^5.1.54"
|
|
12
12
|
},
|
|
13
13
|
"title": "a-cabloy"
|
|
14
14
|
}
|
package/zova/src/suite-vendor/a-zova/modules/a-bean/cli/controller/metadata/generateFileComponent.ts
CHANGED
|
@@ -13,6 +13,7 @@ export async function generateFileComponent(
|
|
|
13
13
|
const { moduleName } = options;
|
|
14
14
|
const { className } = globFile;
|
|
15
15
|
const {
|
|
16
|
+
type,
|
|
16
17
|
name,
|
|
17
18
|
nameCapitalize,
|
|
18
19
|
controllerExtJs,
|
|
@@ -63,6 +64,12 @@ export async function generateFileComponent(
|
|
|
63
64
|
`import type { ${_contentImportTypeController.join(', ')} } from '../../component/${name}/controller${controllerExtJs}';`,
|
|
64
65
|
);
|
|
65
66
|
}
|
|
67
|
+
if (type === 'component' && name === 'routedDialog') {
|
|
68
|
+
contentImports.push(
|
|
69
|
+
"import { routeLocationKey, routerKey, routerViewLocationKey, viewDepthKey } from '@cabloy/vue-router';",
|
|
70
|
+
"import { computed, provide, shallowReactive } from 'vue';",
|
|
71
|
+
);
|
|
72
|
+
}
|
|
66
73
|
contentImports.push("import { defineComponent } from 'vue'");
|
|
67
74
|
contentImports.push("import { prepareComponentOptions, useController } from 'zova';");
|
|
68
75
|
// controller
|
|
@@ -137,7 +144,39 @@ export async function generateFileComponent(
|
|
|
137
144
|
}`;
|
|
138
145
|
}
|
|
139
146
|
// component
|
|
140
|
-
const contentComponent =
|
|
147
|
+
const contentComponent =
|
|
148
|
+
type === 'component' && name === 'routedDialog'
|
|
149
|
+
? `export const Z${nameCapitalize} = defineComponent(
|
|
150
|
+
${genericDeclare}(props: ${typeControllerPublicPropsName}${genericArguments}) => {
|
|
151
|
+
const router = props.item.state.router;
|
|
152
|
+
if (router) {
|
|
153
|
+
const currentRoute = router.currentRoute;
|
|
154
|
+
const reactiveRoute = {} as Record<string, unknown>;
|
|
155
|
+
for (const key in currentRoute.value) {
|
|
156
|
+
Object.defineProperty(reactiveRoute, key, {
|
|
157
|
+
get: () => currentRoute.value[key],
|
|
158
|
+
enumerable: true,
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
provide(routerKey, router.router);
|
|
162
|
+
provide(routeLocationKey, shallowReactive(reactiveRoute) as any);
|
|
163
|
+
provide(routerViewLocationKey, currentRoute);
|
|
164
|
+
provide(
|
|
165
|
+
viewDepthKey,
|
|
166
|
+
computed(() => router.getEmbeddedRouterViewDepth(currentRoute.value)),
|
|
167
|
+
);
|
|
168
|
+
}
|
|
169
|
+
useController(${className}, ${hasRenderFirst ? classNameRenderFirst : undefined}, ${hasStyleFirst ? classNameStyleFirst : undefined});
|
|
170
|
+
return () => {};
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
...prepareComponentOptions(${componentOptions}),
|
|
174
|
+
props: {
|
|
175
|
+
item: { type: Object, required: true },
|
|
176
|
+
},
|
|
177
|
+
},
|
|
178
|
+
);`
|
|
179
|
+
: `export const Z${nameCapitalize} = defineComponent(
|
|
141
180
|
${genericDeclare}(_props: ${typeControllerPublicPropsName}${genericArguments}) => {
|
|
142
181
|
useController(${className}, ${hasRenderFirst ? classNameRenderFirst : undefined}, ${hasStyleFirst ? classNameStyleFirst : undefined});
|
|
143
182
|
return () => {};
|
|
@@ -39,6 +39,10 @@ export class BeanRouterViewBase extends BeanControllerBase implements IRouterVie
|
|
|
39
39
|
throw new Error('Not Implemented');
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
+
protected getPageHostProviders(): Record<string, unknown> | undefined {
|
|
43
|
+
return undefined;
|
|
44
|
+
}
|
|
45
|
+
|
|
42
46
|
protected render() {
|
|
43
47
|
const slots = {
|
|
44
48
|
default: (component: IRouterViewSlotParams) => {
|
|
@@ -50,6 +54,7 @@ export class BeanRouterViewBase extends BeanControllerBase implements IRouterVie
|
|
|
50
54
|
route: component.route,
|
|
51
55
|
});
|
|
52
56
|
cast(vnode).zovaHostProviders = {
|
|
57
|
+
...this.getPageHostProviders(),
|
|
53
58
|
[pageRouteKey]: component.route,
|
|
54
59
|
'a-router.bean.router': this.$router,
|
|
55
60
|
};
|
|
@@ -9,7 +9,9 @@ import {
|
|
|
9
9
|
|
|
10
10
|
import type { ModelStack } from '../../model/stack.js';
|
|
11
11
|
|
|
12
|
-
export interface ControllerRouterViewStackProps extends IRouterViewPropsBase {
|
|
12
|
+
export interface ControllerRouterViewStackProps extends IRouterViewPropsBase {
|
|
13
|
+
pageHostProviders?: Record<string, unknown>;
|
|
14
|
+
}
|
|
13
15
|
|
|
14
16
|
@Controller()
|
|
15
17
|
export class ControllerRouterViewStack extends BeanRouterViewBase {
|
|
@@ -35,4 +37,8 @@ export class ControllerRouterViewStack extends BeanRouterViewBase {
|
|
|
35
37
|
protected getKeepAliveInclude(): string[] | undefined {
|
|
36
38
|
return this.$$modelStack.keepAliveInclude;
|
|
37
39
|
}
|
|
40
|
+
|
|
41
|
+
protected getPageHostProviders(): Record<string, unknown> | undefined {
|
|
42
|
+
return this.$props.pageHostProviders;
|
|
43
|
+
}
|
|
38
44
|
}
|