cabloy 5.1.166 → 5.1.167
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/.claude/scheduled_tasks.lock +1 -1
- package/.claude/skills/cabloy-frontend-scaffold/SKILL.md +1 -0
- package/CHANGELOG.md +13 -0
- package/package.json +1 -1
- package/repo-docs/frontend/page-params-guide.md +1 -1
- package/repo-docs/frontend/page-query-guide.md +6 -0
- package/repo-docs/frontend/zod-guide.md +9 -7
- package/repo-e2e/specs/routed-dialog.spec.ts +368 -0
- package/vona/pnpm-lock.yaml +6 -0
- package/zova/package.original.json +1 -1
- package/zova/packages-cli/cli/package.json +2 -2
- package/zova/packages-cli/cli-set-front/package.json +1 -1
- package/zova/packages-cli/cli-set-front/src/lib/bean/toolsMetadata/generateBeanGenerals.ts +1 -1
- package/zova/packages-cli/cli-set-front/src/lib/bean/toolsMetadata/generateScopeResources.ts +1 -1
- package/zova/packages-zova/zova/package.json +2 -2
- package/zova/pnpm-lock.yaml +2014 -2053
- package/zova/pnpm-workspace.yaml +1 -1
- package/zova/src/suite/a-demo/modules/demo-basic/src/.metadata/index.ts +66 -18
- package/zova/src/suite/a-demo/modules/demo-basic/src/.metadata/page/routedDialog.ts +9 -0
- package/zova/src/suite/a-demo/modules/demo-basic/src/.metadata/page/routedDialogDetail.ts +23 -0
- package/zova/src/suite/a-demo/modules/demo-basic/src/.metadata/page/routedDialogEntry.ts +23 -0
- package/zova/src/suite/a-demo/modules/demo-basic/src/page/routedDialog/controller.tsx +301 -0
- package/zova/src/suite/a-demo/modules/demo-basic/src/page/routedDialogDetail/controller.tsx +135 -0
- package/zova/src/suite/a-demo/modules/demo-basic/src/page/routedDialogEntry/controller.tsx +108 -0
- package/zova/src/suite/a-demo/modules/demo-basic/src/routes.ts +19 -0
- package/zova/src/suite/cabloy-basic/modules/basic-app/src/.metadata/component/routedDialog.ts +63 -0
- package/zova/src/suite/cabloy-basic/modules/basic-app/src/.metadata/index.ts +44 -2
- package/zova/src/suite/cabloy-basic/modules/basic-app/src/bean/behavior.appModal.tsx +306 -18
- package/zova/src/suite/cabloy-basic/modules/basic-app/src/component/routedDialog/controller.tsx +51 -0
- package/zova/src/suite/cabloy-basic/modules/basic-app/src/config/config.ts +19 -0
- package/zova/src/suite/cabloy-basic/modules/basic-app/src/config/locale/en-us.ts +1 -0
- package/zova/src/suite/cabloy-basic/modules/basic-app/src/config/locale/zh-cn.ts +1 -0
- package/zova/src/suite/cabloy-basic/modules/basic-app/src/lib/routedDialogHistory.ts +76 -0
- package/zova/src/suite/cabloy-basic/modules/basic-app/src/service/appModal.ts +156 -1
- package/zova/src/suite/cabloy-basic/modules/basic-app/src/types/appModal.ts +92 -13
- package/zova/src/suite/cabloy-basic/modules/basic-app/test/lib/routedDialogHistory.test.ts +92 -0
- package/zova/src/suite/cabloy-basic/modules/basic-app/test/lib/routedDialogRouter.test.ts +35 -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/model/resource.ts +1 -1
- package/zova/src/suite-vendor/a-cabloy/package.json +2 -2
- 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/.metadata/index.ts +6 -6
- package/zova/src/suite-vendor/a-zova/modules/a-router/src/bean/bean.router.ts +60 -3
- package/zova/src/suite-vendor/a-zova/modules/a-router/src/bean/sys.router.ts +12 -0
- package/zova/src/suite-vendor/a-zova/modules/a-router/src/component/routerViewEmpty/controller.tsx +4 -1
- package/zova/src/suite-vendor/a-zova/modules/a-router/src/lib/routerViewBase.tsx +5 -1
- package/zova/src/suite-vendor/a-zova/package.json +2 -2
package/zova/pnpm-workspace.yaml
CHANGED
|
@@ -48,7 +48,7 @@ overrides:
|
|
|
48
48
|
'@vue/reactivity': 'npm:@cabloy/vue-reactivity@^3.5.16'
|
|
49
49
|
'@vue/server-renderer': 'npm:@cabloy/vue-server-renderer@^3.5.18'
|
|
50
50
|
'@vue/shared': '3.5.13'
|
|
51
|
-
vue-router: 'npm:@cabloy/vue-router@^4.4.
|
|
51
|
+
vue-router: 'npm:@cabloy/vue-router@^4.4.18'
|
|
52
52
|
zod: 'npm:@cabloy/zod@4.3.8'
|
|
53
53
|
|
|
54
54
|
allowBuilds:
|
|
@@ -26,7 +26,7 @@ declare module 'zova-module-demo-basic' {
|
|
|
26
26
|
}
|
|
27
27
|
/** model: end */
|
|
28
28
|
/** model: begin */
|
|
29
|
-
import { ModelTest } from '../model/test.js';
|
|
29
|
+
import type { ModelTest } from '../model/test.js';
|
|
30
30
|
import 'zova';
|
|
31
31
|
declare module 'zova' {
|
|
32
32
|
export interface IBeanRecordGeneral {
|
|
@@ -44,6 +44,9 @@ export * from '../page/locale/controller.jsx';
|
|
|
44
44
|
export * from '../page/routeParams/controller.jsx';
|
|
45
45
|
export * from '../page/routeQuery/controller.jsx';
|
|
46
46
|
export * from '../page/routeQueryB/controller.jsx';
|
|
47
|
+
export * from '../page/routedDialog/controller.jsx';
|
|
48
|
+
export * from '../page/routedDialogDetail/controller.jsx';
|
|
49
|
+
export * from '../page/routedDialogEntry/controller.jsx';
|
|
47
50
|
export * from '../page/state/controller.jsx';
|
|
48
51
|
export * from '../page/style/controller.jsx';
|
|
49
52
|
export * from '../page/toolMinimal/controller.jsx';
|
|
@@ -102,6 +105,21 @@ declare module 'zova-module-demo-basic' {
|
|
|
102
105
|
get scope(): ScopeModuleDemoBasic;
|
|
103
106
|
}
|
|
104
107
|
|
|
108
|
+
export interface ControllerPageRoutedDialog {
|
|
109
|
+
/** @internal */
|
|
110
|
+
get scope(): ScopeModuleDemoBasic;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
export interface ControllerPageRoutedDialogDetail {
|
|
114
|
+
/** @internal */
|
|
115
|
+
get scope(): ScopeModuleDemoBasic;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export interface ControllerPageRoutedDialogEntry {
|
|
119
|
+
/** @internal */
|
|
120
|
+
get scope(): ScopeModuleDemoBasic;
|
|
121
|
+
}
|
|
122
|
+
|
|
105
123
|
export interface ControllerPageState {
|
|
106
124
|
/** @internal */
|
|
107
125
|
get scope(): ScopeModuleDemoBasic;
|
|
@@ -129,20 +147,23 @@ declare module 'zova-module-demo-basic' {
|
|
|
129
147
|
}
|
|
130
148
|
/** controller: end */
|
|
131
149
|
/** controller: begin */
|
|
132
|
-
import { ControllerActionView } from '../component/actionView/controller.jsx';
|
|
133
|
-
import { ControllerCard } from '../component/card/controller.jsx';
|
|
134
|
-
import { ControllerFormFieldTest } from '../component/formFieldTest/controller.jsx';
|
|
135
|
-
import { ControllerTableCellTest } from '../component/tableCellTest/controller.jsx';
|
|
136
|
-
import { ControllerPageComponent } from '../page/component/controller.jsx';
|
|
137
|
-
import { ControllerPageLocale } from '../page/locale/controller.jsx';
|
|
138
|
-
import { ControllerPageRouteParams } from '../page/routeParams/controller.jsx';
|
|
139
|
-
import { ControllerPageRouteQuery } from '../page/routeQuery/controller.jsx';
|
|
140
|
-
import { ControllerPageRouteQueryB } from '../page/routeQueryB/controller.jsx';
|
|
141
|
-
import {
|
|
142
|
-
import {
|
|
143
|
-
import {
|
|
144
|
-
import {
|
|
145
|
-
import {
|
|
150
|
+
import type { ControllerActionView } from '../component/actionView/controller.jsx';
|
|
151
|
+
import type { ControllerCard } from '../component/card/controller.jsx';
|
|
152
|
+
import type { ControllerFormFieldTest } from '../component/formFieldTest/controller.jsx';
|
|
153
|
+
import type { ControllerTableCellTest } from '../component/tableCellTest/controller.jsx';
|
|
154
|
+
import type { ControllerPageComponent } from '../page/component/controller.jsx';
|
|
155
|
+
import type { ControllerPageLocale } from '../page/locale/controller.jsx';
|
|
156
|
+
import type { ControllerPageRouteParams } from '../page/routeParams/controller.jsx';
|
|
157
|
+
import type { ControllerPageRouteQuery } from '../page/routeQuery/controller.jsx';
|
|
158
|
+
import type { ControllerPageRouteQueryB } from '../page/routeQueryB/controller.jsx';
|
|
159
|
+
import type { ControllerPageRoutedDialog } from '../page/routedDialog/controller.jsx';
|
|
160
|
+
import type { ControllerPageRoutedDialogDetail } from '../page/routedDialogDetail/controller.jsx';
|
|
161
|
+
import type { ControllerPageRoutedDialogEntry } from '../page/routedDialogEntry/controller.jsx';
|
|
162
|
+
import type { ControllerPageState } from '../page/state/controller.jsx';
|
|
163
|
+
import type { ControllerPageStyle } from '../page/style/controller.jsx';
|
|
164
|
+
import type { ControllerPageToolMinimal } from '../page/toolMinimal/controller.jsx';
|
|
165
|
+
import type { ControllerPageToolOne } from '../page/toolOne/controller.jsx';
|
|
166
|
+
import type { ControllerPageToolTwo } from '../page/toolTwo/controller.jsx';
|
|
146
167
|
import 'zova';
|
|
147
168
|
declare module 'zova' {
|
|
148
169
|
export interface IBeanRecordLocal {
|
|
@@ -155,6 +176,9 @@ declare module 'zova' {
|
|
|
155
176
|
'demo-basic.controller.pageRouteParams': ControllerPageRouteParams;
|
|
156
177
|
'demo-basic.controller.pageRouteQuery': ControllerPageRouteQuery;
|
|
157
178
|
'demo-basic.controller.pageRouteQueryB': ControllerPageRouteQueryB;
|
|
179
|
+
'demo-basic.controller.pageRoutedDialog': ControllerPageRoutedDialog;
|
|
180
|
+
'demo-basic.controller.pageRoutedDialogDetail': ControllerPageRoutedDialogDetail;
|
|
181
|
+
'demo-basic.controller.pageRoutedDialogEntry': ControllerPageRoutedDialogEntry;
|
|
158
182
|
'demo-basic.controller.pageState': ControllerPageState;
|
|
159
183
|
'demo-basic.controller.pageStyle': ControllerPageStyle;
|
|
160
184
|
'demo-basic.controller.pageToolMinimal': ControllerPageToolMinimal;
|
|
@@ -172,6 +196,11 @@ export * from './page/routeQuery.js';
|
|
|
172
196
|
import { NSControllerPageRouteQuery } from './page/routeQuery.js';
|
|
173
197
|
export * from './page/routeQueryB.js';
|
|
174
198
|
import { NSControllerPageRouteQueryB } from './page/routeQueryB.js';
|
|
199
|
+
export * from './page/routedDialog.js';
|
|
200
|
+
export * from './page/routedDialogDetail.js';
|
|
201
|
+
import { NSControllerPageRoutedDialogDetail } from './page/routedDialogDetail.js';
|
|
202
|
+
export * from './page/routedDialogEntry.js';
|
|
203
|
+
import { NSControllerPageRoutedDialogEntry } from './page/routedDialogEntry.js';
|
|
175
204
|
export * from './page/state.js';
|
|
176
205
|
export * from './page/style.js';
|
|
177
206
|
export * from './page/toolMinimal.js';
|
|
@@ -189,6 +218,9 @@ export interface IPagePathRecord {
|
|
|
189
218
|
'/demo/basic/routeParams/:id?': TypePagePathSchema<NSControllerPageRouteParams.ParamsInput,NSControllerPageRouteParams.QueryInput>;
|
|
190
219
|
'/demo/basic/routeQuery': TypePagePathSchema<NSControllerPageRouteQuery.ParamsInput,NSControllerPageRouteQuery.QueryInput>;
|
|
191
220
|
'/demo/basic/routeQueryB': TypePagePathSchema<NSControllerPageRouteQueryB.ParamsInput,NSControllerPageRouteQueryB.QueryInput>;
|
|
221
|
+
'/demo/basic/routedDialog': TypePagePathSchema<undefined,undefined>;
|
|
222
|
+
'/demo/basic/routedDialogDetail/:id': TypePagePathSchema<NSControllerPageRoutedDialogDetail.ParamsInput,NSControllerPageRoutedDialogDetail.QueryInput>;
|
|
223
|
+
'/demo/basic/routedDialogEntry': TypePagePathSchema<NSControllerPageRoutedDialogEntry.ParamsInput,NSControllerPageRoutedDialogEntry.QueryInput>;
|
|
192
224
|
'/demo/basic/state': TypePagePathSchema<undefined,undefined>;
|
|
193
225
|
'/demo/basic/style': TypePagePathSchema<undefined,undefined>;
|
|
194
226
|
'/demo/basic/toolMinimal': TypePagePathSchema<undefined,undefined>;
|
|
@@ -197,6 +229,7 @@ export interface IPagePathRecord {
|
|
|
197
229
|
}
|
|
198
230
|
export interface IPageNameRecord {
|
|
199
231
|
'demo-basic:routeParams': TypePagePathSchema<NSControllerPageRouteParams.ParamsInput,NSControllerPageRouteParams.QueryInput>;
|
|
232
|
+
'demo-basic:routedDialogDetail': TypePagePathSchema<NSControllerPageRoutedDialogDetail.ParamsInput,NSControllerPageRoutedDialogDetail.QueryInput>;
|
|
200
233
|
'demo-basic:toolMinimal': TypePagePathSchema<undefined,undefined>;
|
|
201
234
|
'demo-basic:toolOne': TypePagePathSchema<NSControllerPageToolOne.ParamsInput,NSControllerPageToolOne.QueryInput>;
|
|
202
235
|
'demo-basic:toolTwo': TypePagePathSchema<NSControllerPageToolTwo.ParamsInput,NSControllerPageToolTwo.QueryInput>;
|
|
@@ -209,12 +242,19 @@ export const pagePathSchemas = {
|
|
|
209
242
|
'/demo/basic/routeQueryB': {
|
|
210
243
|
query: NSControllerPageRouteQueryB.querySchema,
|
|
211
244
|
},
|
|
245
|
+
'/demo/basic/routedDialogEntry': {
|
|
246
|
+
query: NSControllerPageRoutedDialogEntry.querySchema,
|
|
247
|
+
},
|
|
212
248
|
};
|
|
213
249
|
export const pageNameSchemas = {
|
|
214
250
|
'demo-basic:routeParams': {
|
|
215
251
|
params: NSControllerPageRouteParams.paramsSchema,
|
|
216
252
|
query: NSControllerPageRouteParams.querySchema,
|
|
217
253
|
},
|
|
254
|
+
'demo-basic:routedDialogDetail': {
|
|
255
|
+
params: NSControllerPageRoutedDialogDetail.paramsSchema,
|
|
256
|
+
query: NSControllerPageRoutedDialogDetail.querySchema,
|
|
257
|
+
},
|
|
218
258
|
'demo-basic:toolOne': {
|
|
219
259
|
params: NSControllerPageToolOne.paramsSchema,
|
|
220
260
|
query: NSControllerPageToolOne.querySchema,
|
|
@@ -237,6 +277,14 @@ export interface ControllerPageRouteQueryB {
|
|
|
237
277
|
$params: NSControllerPageRouteQueryB.ParamsOutput;
|
|
238
278
|
$query: NSControllerPageRouteQueryB.QueryOutput;
|
|
239
279
|
}
|
|
280
|
+
export interface ControllerPageRoutedDialogDetail {
|
|
281
|
+
$params: NSControllerPageRoutedDialogDetail.ParamsOutput;
|
|
282
|
+
$query: NSControllerPageRoutedDialogDetail.QueryOutput;
|
|
283
|
+
}
|
|
284
|
+
export interface ControllerPageRoutedDialogEntry {
|
|
285
|
+
$params: NSControllerPageRoutedDialogEntry.ParamsOutput;
|
|
286
|
+
$query: NSControllerPageRoutedDialogEntry.QueryOutput;
|
|
287
|
+
}
|
|
240
288
|
export interface ControllerPageToolOne {
|
|
241
289
|
$params: NSControllerPageToolOne.ParamsOutput;
|
|
242
290
|
$query: NSControllerPageToolOne.QueryOutput;
|
|
@@ -296,7 +344,7 @@ declare module 'zova-module-demo-basic' {
|
|
|
296
344
|
}
|
|
297
345
|
/** render: end */
|
|
298
346
|
/** render: begin */
|
|
299
|
-
import { RenderPageToolOne } from '../page/toolOne/render.jsx';
|
|
347
|
+
import type { RenderPageToolOne } from '../page/toolOne/render.jsx';
|
|
300
348
|
import 'zova';
|
|
301
349
|
declare module 'zova' {
|
|
302
350
|
export interface IBeanRecordLocal {
|
|
@@ -331,7 +379,7 @@ declare module 'zova-module-demo-basic' {
|
|
|
331
379
|
}
|
|
332
380
|
/** behavior: end */
|
|
333
381
|
/** behavior: begin */
|
|
334
|
-
import { BehaviorFormFieldLayout } from '../bean/behavior.formFieldLayout.jsx';
|
|
382
|
+
import type { BehaviorFormFieldLayout } from '../bean/behavior.formFieldLayout.jsx';
|
|
335
383
|
import 'zova';
|
|
336
384
|
declare module 'zova' {
|
|
337
385
|
export interface IBeanRecordLocal {
|
|
@@ -385,7 +433,7 @@ declare module 'zova-module-demo-basic' {
|
|
|
385
433
|
}
|
|
386
434
|
/** tableCell: end */
|
|
387
435
|
/** tableCell: begin */
|
|
388
|
-
import { TableCellTest } from '../bean/tableCell.test.jsx';
|
|
436
|
+
import type { TableCellTest } from '../bean/tableCell.test.jsx';
|
|
389
437
|
import 'zova';
|
|
390
438
|
declare module 'zova' {
|
|
391
439
|
export interface IBeanRecordGeneral {
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { createZovaComponentPage } from 'zova';
|
|
3
|
+
|
|
4
|
+
import { ControllerPageRoutedDialogDetail } from '../../page/routedDialogDetail/controller.jsx';
|
|
5
|
+
import {
|
|
6
|
+
ControllerPageRoutedDialogDetailSchemaParams,
|
|
7
|
+
ControllerPageRoutedDialogDetailSchemaQuery,
|
|
8
|
+
} from '../../page/routedDialogDetail/controller.jsx';
|
|
9
|
+
export namespace NSControllerPageRoutedDialogDetail {
|
|
10
|
+
export const paramsSchema = ControllerPageRoutedDialogDetailSchemaParams;
|
|
11
|
+
export type ParamsInput = z.input<typeof ControllerPageRoutedDialogDetailSchemaParams>;
|
|
12
|
+
export type ParamsOutput = z.output<typeof ControllerPageRoutedDialogDetailSchemaParams>;
|
|
13
|
+
|
|
14
|
+
export const querySchema = ControllerPageRoutedDialogDetailSchemaQuery;
|
|
15
|
+
export type QueryInput = z.input<typeof ControllerPageRoutedDialogDetailSchemaQuery>;
|
|
16
|
+
export type QueryOutput = z.output<typeof ControllerPageRoutedDialogDetailSchemaQuery>;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export const ZPageRoutedDialogDetail = createZovaComponentPage(
|
|
20
|
+
ControllerPageRoutedDialogDetail,
|
|
21
|
+
undefined,
|
|
22
|
+
undefined,
|
|
23
|
+
);
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { createZovaComponentPage } from 'zova';
|
|
3
|
+
|
|
4
|
+
import { ControllerPageRoutedDialogEntry } from '../../page/routedDialogEntry/controller.jsx';
|
|
5
|
+
import {
|
|
6
|
+
ControllerPageRoutedDialogEntrySchemaParams,
|
|
7
|
+
ControllerPageRoutedDialogEntrySchemaQuery,
|
|
8
|
+
} from '../../page/routedDialogEntry/controller.jsx';
|
|
9
|
+
export namespace NSControllerPageRoutedDialogEntry {
|
|
10
|
+
export const paramsSchema = ControllerPageRoutedDialogEntrySchemaParams;
|
|
11
|
+
export type ParamsInput = z.input<typeof ControllerPageRoutedDialogEntrySchemaParams>;
|
|
12
|
+
export type ParamsOutput = z.output<typeof ControllerPageRoutedDialogEntrySchemaParams>;
|
|
13
|
+
|
|
14
|
+
export const querySchema = ControllerPageRoutedDialogEntrySchemaQuery;
|
|
15
|
+
export type QueryInput = z.input<typeof ControllerPageRoutedDialogEntrySchemaQuery>;
|
|
16
|
+
export type QueryOutput = z.output<typeof ControllerPageRoutedDialogEntrySchemaQuery>;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export const ZPageRoutedDialogEntry = createZovaComponentPage(
|
|
20
|
+
ControllerPageRoutedDialogEntry,
|
|
21
|
+
undefined,
|
|
22
|
+
undefined,
|
|
23
|
+
);
|
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
IModalRoutedDialogPresentationOptions,
|
|
3
|
+
IRoutedDialogHandle,
|
|
4
|
+
} from 'zova-module-basic-app';
|
|
5
|
+
|
|
6
|
+
import { BeanControllerPageBase } from 'zova';
|
|
7
|
+
import { Controller } from 'zova-module-a-bean';
|
|
8
|
+
import { ZPage } from 'zova-module-home-base';
|
|
9
|
+
|
|
10
|
+
@Controller()
|
|
11
|
+
export class ControllerPageRoutedDialog extends BeanControllerPageBase {
|
|
12
|
+
handleA?: IRoutedDialogHandle;
|
|
13
|
+
handleB?: IRoutedDialogHandle;
|
|
14
|
+
statusA = 'idle';
|
|
15
|
+
statusB = 'idle';
|
|
16
|
+
browserUrl = '-';
|
|
17
|
+
browserUrlAtOpen?: string;
|
|
18
|
+
mainRouteAtOpen?: string;
|
|
19
|
+
events: string[] = [];
|
|
20
|
+
|
|
21
|
+
protected async __init__() {
|
|
22
|
+
this.$ssr.handleDirectOrOnHydrated(() => {
|
|
23
|
+
this.browserUrl = window.location.href;
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
openA() {
|
|
28
|
+
this._open('A');
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
openB() {
|
|
32
|
+
this._open('B');
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
openAAndB() {
|
|
36
|
+
this._open('A');
|
|
37
|
+
this._open('B');
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
openAWithHandlePush() {
|
|
41
|
+
const handle = this._open('A');
|
|
42
|
+
void this._navigateHandle(handle, 'push');
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
openAWithHandleReplace() {
|
|
46
|
+
const handle = this._open('A');
|
|
47
|
+
void this._navigateHandle(handle, 'replace');
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
openAWithBackdropClose() {
|
|
51
|
+
this._open('A', true);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
openAAndClose() {
|
|
55
|
+
const handle = this._open('A');
|
|
56
|
+
void this._closeHandleAfterReady(handle);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
openAWithScalarWidth() {
|
|
60
|
+
this._open('A', false, { maxWidth: 720 });
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
openAWithPartialResponsiveWidth() {
|
|
64
|
+
this._open('A', false, { maxWidth: { md: 800 } });
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
openAWithScalarTopGutter() {
|
|
68
|
+
this._open('A', false, { topGutter: 80 });
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
openAWithPartialResponsiveTopGutter() {
|
|
72
|
+
this._open('A', false, { topGutter: { md: 64 } });
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
private _open(
|
|
76
|
+
dialog: 'A' | 'B',
|
|
77
|
+
closeOnBackdrop = false,
|
|
78
|
+
dialogOptions?: IModalRoutedDialogPresentationOptions,
|
|
79
|
+
) {
|
|
80
|
+
const route = this.$router.getPagePath('/demo/basic/routedDialogEntry', {
|
|
81
|
+
query: {
|
|
82
|
+
dialog,
|
|
83
|
+
token: `dialog-${dialog.toLowerCase()}-entry`,
|
|
84
|
+
via: 'open',
|
|
85
|
+
step: 0,
|
|
86
|
+
},
|
|
87
|
+
});
|
|
88
|
+
this.mainRouteAtOpen = this.$pageRoute?.fullPath;
|
|
89
|
+
this.browserUrlAtOpen = typeof window === 'undefined' ? undefined : window.location.href;
|
|
90
|
+
const handle = this.$appModal.routedDialog(
|
|
91
|
+
{
|
|
92
|
+
route,
|
|
93
|
+
title: `Routed Dialog ${dialog}`,
|
|
94
|
+
onClose: () => {
|
|
95
|
+
this._record(`${dialog}: onClose`);
|
|
96
|
+
if (dialog === 'A') {
|
|
97
|
+
this.statusA = 'closed';
|
|
98
|
+
this.handleA = undefined;
|
|
99
|
+
} else {
|
|
100
|
+
this.statusB = 'closed';
|
|
101
|
+
this.handleB = undefined;
|
|
102
|
+
}
|
|
103
|
+
},
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
closeOnBackdrop,
|
|
107
|
+
closeOnEscape: true,
|
|
108
|
+
showCloseButton: true,
|
|
109
|
+
...dialogOptions,
|
|
110
|
+
},
|
|
111
|
+
);
|
|
112
|
+
if (dialog === 'A') {
|
|
113
|
+
this.handleA = handle;
|
|
114
|
+
this.statusA = 'loading';
|
|
115
|
+
} else {
|
|
116
|
+
this.handleB = handle;
|
|
117
|
+
this.statusB = 'loading';
|
|
118
|
+
}
|
|
119
|
+
void this._awaitReady(dialog, handle);
|
|
120
|
+
return handle;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
private async _awaitReady(dialog: 'A' | 'B', handle: IRoutedDialogHandle) {
|
|
124
|
+
try {
|
|
125
|
+
await handle.ready;
|
|
126
|
+
if (dialog === 'A') this.statusA = 'ready';
|
|
127
|
+
else this.statusB = 'ready';
|
|
128
|
+
this._record(`${dialog}: ready`);
|
|
129
|
+
} catch (error) {
|
|
130
|
+
if (dialog === 'A') this.statusA = 'error';
|
|
131
|
+
else this.statusB = 'error';
|
|
132
|
+
this._record(`${dialog}: ${String(error)}`);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
private async _navigateHandle(handle: IRoutedDialogHandle, action: 'push' | 'replace') {
|
|
137
|
+
try {
|
|
138
|
+
await handle.ready;
|
|
139
|
+
const route = this.$router.getPagePath('/demo/basic/routedDialogDetail/:id', {
|
|
140
|
+
params: { id: action === 'push' ? 101 : 202 },
|
|
141
|
+
query: {
|
|
142
|
+
dialog: 'A',
|
|
143
|
+
token: `dialog-a-handle-${action}`,
|
|
144
|
+
via: `handle-${action}`,
|
|
145
|
+
step: action === 'push' ? 1 : 2,
|
|
146
|
+
},
|
|
147
|
+
});
|
|
148
|
+
if (action === 'push') await handle.push(route);
|
|
149
|
+
else await handle.replace(route);
|
|
150
|
+
this._record(`A: handle.${action}`);
|
|
151
|
+
} catch (error) {
|
|
152
|
+
this._record(`A: handle.${action} ${String(error)}`);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
private async _closeHandleAfterReady(handle: IRoutedDialogHandle) {
|
|
157
|
+
try {
|
|
158
|
+
await handle.ready;
|
|
159
|
+
this._record('A: ready for delayed handle.close');
|
|
160
|
+
setTimeout(() => {
|
|
161
|
+
handle.close();
|
|
162
|
+
this._record('A: handle.close');
|
|
163
|
+
}, 1500);
|
|
164
|
+
} catch (error) {
|
|
165
|
+
this._record(`A: delayed close ${String(error)}`);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
private _record(event: string) {
|
|
170
|
+
this.events = [...this.events, event];
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
private async openStudentList() {
|
|
174
|
+
const route = this.$router.getPagePath('/rest/resource/:resource', {
|
|
175
|
+
params: {
|
|
176
|
+
resource: 'training-student:student',
|
|
177
|
+
},
|
|
178
|
+
});
|
|
179
|
+
this.$appModal.routedDialog({
|
|
180
|
+
route,
|
|
181
|
+
title: 'Student List',
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
protected render() {
|
|
186
|
+
return (
|
|
187
|
+
<ZPage>
|
|
188
|
+
<div class="mx-auto flex max-w-4xl flex-col gap-6">
|
|
189
|
+
<div>
|
|
190
|
+
<h1 class="text-2xl font-bold">Routed Dialog Manual Validation</h1>
|
|
191
|
+
<p class="mt-2 text-base-content/70">
|
|
192
|
+
Open a memory-history dialog and verify that every dialog route stays separate from
|
|
193
|
+
this browser route.
|
|
194
|
+
</p>
|
|
195
|
+
</div>
|
|
196
|
+
|
|
197
|
+
<div class="grid gap-4 md:grid-cols-2">
|
|
198
|
+
<div class="card bg-base-200">
|
|
199
|
+
<div class="card-body gap-2">
|
|
200
|
+
<h2 class="card-title text-base">Main route sentinel</h2>
|
|
201
|
+
<code class="break-all">{this.$pageRoute?.fullPath ?? '-'}</code>
|
|
202
|
+
<code class="break-all">{this.browserUrl}</code>
|
|
203
|
+
</div>
|
|
204
|
+
</div>
|
|
205
|
+
<div class="card bg-base-200">
|
|
206
|
+
<div class="card-body gap-2">
|
|
207
|
+
<h2 class="card-title text-base">Route at latest open</h2>
|
|
208
|
+
<code class="break-all">{this.mainRouteAtOpen ?? '-'}</code>
|
|
209
|
+
<code class="break-all">{this.browserUrlAtOpen ?? '-'}</code>
|
|
210
|
+
</div>
|
|
211
|
+
</div>
|
|
212
|
+
</div>
|
|
213
|
+
|
|
214
|
+
<div class="flex flex-wrap gap-2">
|
|
215
|
+
<button class="btn btn-primary" onClick={() => this.openA()}>
|
|
216
|
+
Open A
|
|
217
|
+
</button>
|
|
218
|
+
<button class="btn btn-secondary" onClick={() => this.openB()}>
|
|
219
|
+
Open B
|
|
220
|
+
</button>
|
|
221
|
+
<button class="btn btn-outline" onClick={() => this.openAAndB()}>
|
|
222
|
+
Open A and B
|
|
223
|
+
</button>
|
|
224
|
+
<button class="btn btn-outline" onClick={() => this.openAWithHandlePush()}>
|
|
225
|
+
Open A with handle.push
|
|
226
|
+
</button>
|
|
227
|
+
<button class="btn btn-outline" onClick={() => this.openAWithHandleReplace()}>
|
|
228
|
+
Open A with handle.replace
|
|
229
|
+
</button>
|
|
230
|
+
<button class="btn btn-outline" onClick={() => this.openAWithBackdropClose()}>
|
|
231
|
+
Open A (backdrop close)
|
|
232
|
+
</button>
|
|
233
|
+
<button class="btn btn-outline" onClick={() => this.openAAndClose()}>
|
|
234
|
+
Open A then handle.close
|
|
235
|
+
</button>
|
|
236
|
+
<button class="btn btn-outline" onClick={() => this.openAWithScalarWidth()}>
|
|
237
|
+
Open A (720px width)
|
|
238
|
+
</button>
|
|
239
|
+
<button class="btn btn-outline" onClick={() => this.openAWithPartialResponsiveWidth()}>
|
|
240
|
+
Open A (md 800px width)
|
|
241
|
+
</button>
|
|
242
|
+
<button class="btn btn-outline" onClick={() => this.openAWithScalarTopGutter()}>
|
|
243
|
+
Open A (80px top gutter)
|
|
244
|
+
</button>
|
|
245
|
+
<button
|
|
246
|
+
class="btn btn-outline"
|
|
247
|
+
onClick={() => this.openAWithPartialResponsiveTopGutter()}
|
|
248
|
+
>
|
|
249
|
+
Open A (md 64px top gutter)
|
|
250
|
+
</button>
|
|
251
|
+
</div>
|
|
252
|
+
|
|
253
|
+
<div class="overflow-x-auto">
|
|
254
|
+
<table class="table">
|
|
255
|
+
<thead>
|
|
256
|
+
<tr>
|
|
257
|
+
<th>Dialog</th>
|
|
258
|
+
<th>Status</th>
|
|
259
|
+
<th>Handle</th>
|
|
260
|
+
</tr>
|
|
261
|
+
</thead>
|
|
262
|
+
<tbody>
|
|
263
|
+
<tr>
|
|
264
|
+
<td>A</td>
|
|
265
|
+
<td>{this.statusA}</td>
|
|
266
|
+
<td>{this.handleA ? 'active' : '-'}</td>
|
|
267
|
+
</tr>
|
|
268
|
+
<tr>
|
|
269
|
+
<td>B</td>
|
|
270
|
+
<td>{this.statusB}</td>
|
|
271
|
+
<td>{this.handleB ? 'active' : '-'}</td>
|
|
272
|
+
</tr>
|
|
273
|
+
</tbody>
|
|
274
|
+
</table>
|
|
275
|
+
</div>
|
|
276
|
+
|
|
277
|
+
<div class="card bg-base-200">
|
|
278
|
+
<div class="card-body">
|
|
279
|
+
<h2 class="card-title text-base">Lifecycle log</h2>
|
|
280
|
+
<ol class="list-inside list-decimal font-mono text-sm">
|
|
281
|
+
{this.events.map((event, index) => (
|
|
282
|
+
<li key={`${index}-${event}`}>{event}</li>
|
|
283
|
+
))}
|
|
284
|
+
</ol>
|
|
285
|
+
</div>
|
|
286
|
+
</div>
|
|
287
|
+
<div>
|
|
288
|
+
<button
|
|
289
|
+
class="btn btn-outline"
|
|
290
|
+
onClick={() => {
|
|
291
|
+
this.openStudentList();
|
|
292
|
+
}}
|
|
293
|
+
>
|
|
294
|
+
Student List
|
|
295
|
+
</button>
|
|
296
|
+
</div>
|
|
297
|
+
</div>
|
|
298
|
+
</ZPage>
|
|
299
|
+
);
|
|
300
|
+
}
|
|
301
|
+
}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { RouterLink } from '@cabloy/vue-router';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { BeanControllerPageBase } from 'zova';
|
|
4
|
+
import { Controller } from 'zova-module-a-bean';
|
|
5
|
+
import { ZPage } from 'zova-module-home-base';
|
|
6
|
+
|
|
7
|
+
export const ControllerPageRoutedDialogDetailSchemaParams = z.object({
|
|
8
|
+
id: z.number(),
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
export const ControllerPageRoutedDialogDetailSchemaQuery = z.object({
|
|
12
|
+
dialog: z.enum(['A', 'B']).optional().default('A'),
|
|
13
|
+
token: z.string().optional().default('detail'),
|
|
14
|
+
via: z.string().optional().default('unknown'),
|
|
15
|
+
step: z.number().optional().default(0),
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
@Controller()
|
|
19
|
+
export class ControllerPageRoutedDialogDetail extends BeanControllerPageBase {
|
|
20
|
+
get entryRoute() {
|
|
21
|
+
return this.$router.getPagePath('/demo/basic/routedDialogEntry', {
|
|
22
|
+
query: {
|
|
23
|
+
...this.$query,
|
|
24
|
+
token: `${this.$query.token}-entry`,
|
|
25
|
+
via: 'detail-entry',
|
|
26
|
+
step: this.$query.step + 1,
|
|
27
|
+
},
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
pushNextDetail() {
|
|
32
|
+
const route = this.$router.getPagePath('/demo/basic/routedDialogDetail/:id', {
|
|
33
|
+
params: { id: this.$params.id + 1 },
|
|
34
|
+
query: {
|
|
35
|
+
...this.$query,
|
|
36
|
+
token: `${this.$query.token}-push`,
|
|
37
|
+
via: 'detail-push',
|
|
38
|
+
step: this.$query.step + 1,
|
|
39
|
+
},
|
|
40
|
+
});
|
|
41
|
+
this.$router.push(route);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
replaceNextDetail() {
|
|
45
|
+
const route = this.$router.getPagePath('/demo/basic/routedDialogDetail/:id', {
|
|
46
|
+
params: { id: this.$params.id + 10 },
|
|
47
|
+
query: {
|
|
48
|
+
...this.$query,
|
|
49
|
+
token: `${this.$query.token}-replace`,
|
|
50
|
+
via: 'detail-replace',
|
|
51
|
+
step: this.$query.step + 10,
|
|
52
|
+
},
|
|
53
|
+
});
|
|
54
|
+
this.$router.replace(route);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
protected render() {
|
|
58
|
+
return (
|
|
59
|
+
<ZPage>
|
|
60
|
+
<div class="flex flex-col gap-4 p-1">
|
|
61
|
+
<div>
|
|
62
|
+
<h1 class="text-xl font-bold">Routed Dialog Detail</h1>
|
|
63
|
+
<p class="text-base-content/70">
|
|
64
|
+
The typed route state below belongs to this routed-dialog instance only.
|
|
65
|
+
</p>
|
|
66
|
+
</div>
|
|
67
|
+
|
|
68
|
+
<div class="overflow-x-auto">
|
|
69
|
+
<table class="table">
|
|
70
|
+
<thead>
|
|
71
|
+
<tr>
|
|
72
|
+
<th>Name</th>
|
|
73
|
+
<th>Value</th>
|
|
74
|
+
<th>Type</th>
|
|
75
|
+
</tr>
|
|
76
|
+
</thead>
|
|
77
|
+
<tbody>
|
|
78
|
+
<tr>
|
|
79
|
+
<td>$pageRoute.fullPath</td>
|
|
80
|
+
<td class="break-all">{this.$pageRoute?.fullPath}</td>
|
|
81
|
+
<td>string</td>
|
|
82
|
+
</tr>
|
|
83
|
+
<tr>
|
|
84
|
+
<td>$route.fullPath</td>
|
|
85
|
+
<td class="break-all">{this.$route.fullPath}</td>
|
|
86
|
+
<td>string</td>
|
|
87
|
+
</tr>
|
|
88
|
+
<tr>
|
|
89
|
+
<td>$params.id</td>
|
|
90
|
+
<td>{this.$params.id}</td>
|
|
91
|
+
<td>{typeof this.$params.id}</td>
|
|
92
|
+
</tr>
|
|
93
|
+
<tr>
|
|
94
|
+
<td>$query.dialog</td>
|
|
95
|
+
<td>{this.$query.dialog}</td>
|
|
96
|
+
<td>{typeof this.$query.dialog}</td>
|
|
97
|
+
</tr>
|
|
98
|
+
<tr>
|
|
99
|
+
<td>$query.token</td>
|
|
100
|
+
<td>{this.$query.token}</td>
|
|
101
|
+
<td>{typeof this.$query.token}</td>
|
|
102
|
+
</tr>
|
|
103
|
+
<tr>
|
|
104
|
+
<td>$query.via</td>
|
|
105
|
+
<td>{this.$query.via}</td>
|
|
106
|
+
<td>{typeof this.$query.via}</td>
|
|
107
|
+
</tr>
|
|
108
|
+
<tr>
|
|
109
|
+
<td>$query.step</td>
|
|
110
|
+
<td>{this.$query.step}</td>
|
|
111
|
+
<td>{typeof this.$query.step}</td>
|
|
112
|
+
</tr>
|
|
113
|
+
</tbody>
|
|
114
|
+
</table>
|
|
115
|
+
</div>
|
|
116
|
+
|
|
117
|
+
<div class="flex flex-wrap gap-2">
|
|
118
|
+
<button class="btn btn-primary" onClick={() => this.pushNextDetail()}>
|
|
119
|
+
Local push next detail
|
|
120
|
+
</button>
|
|
121
|
+
<button class="btn btn-secondary" onClick={() => this.replaceNextDetail()}>
|
|
122
|
+
Local replace next detail
|
|
123
|
+
</button>
|
|
124
|
+
<button class="btn btn-outline" onClick={() => this.$router.back()}>
|
|
125
|
+
Local router.back
|
|
126
|
+
</button>
|
|
127
|
+
<RouterLink class="btn btn-outline" to={this.entryRoute}>
|
|
128
|
+
RouterLink back to entry
|
|
129
|
+
</RouterLink>
|
|
130
|
+
</div>
|
|
131
|
+
</div>
|
|
132
|
+
</ZPage>
|
|
133
|
+
);
|
|
134
|
+
}
|
|
135
|
+
}
|