@nocobase/client-v2 2.2.0-alpha.4 → 2.2.0-alpha.5
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/es/BaseApplication.d.ts +2 -0
- package/es/RouterManager.d.ts +15 -0
- package/es/entry-actions/EntryActionManager.d.ts +24 -0
- package/es/entry-actions/index.d.ts +9 -0
- package/es/flow/admin-shell/BaseLayoutModel.d.ts +6 -0
- package/es/flow/admin-shell/BaseLayoutRouteCoordinator.d.ts +7 -0
- package/es/flow/admin-shell/admin-layout/AppListRender.d.ts +2 -1
- package/es/flow/admin-shell/admin-layout/AppSwitcherActionPanelModel.d.ts +24 -0
- package/es/flow/admin-shell/admin-layout/index.d.ts +1 -0
- package/es/flow/admin-shell/admin-layout/useApplications.d.ts +7 -2
- package/es/flow/models/base/ActionModelCore.d.ts +2 -0
- package/es/flow/routeTransientInputArgs.d.ts +14 -0
- package/es/index.d.ts +4 -0
- package/es/index.mjs +178 -124
- package/es/utils/markdownSanitize.d.ts +11 -0
- package/lib/index.js +164 -110
- package/package.json +7 -7
- package/src/BaseApplication.tsx +2 -0
- package/src/RouterManager.tsx +142 -1
- package/src/__tests__/RouterManager.test.ts +125 -0
- package/src/entry-actions/EntryActionManager.ts +76 -0
- package/src/entry-actions/index.ts +10 -0
- package/src/flow/FlowPage.tsx +29 -2
- package/src/flow/__tests__/FlowPage.test.tsx +152 -25
- package/src/flow/__tests__/FlowRoute.test.tsx +547 -2
- package/src/flow/actions/__tests__/dataScopeFilter.test.ts +62 -0
- package/src/flow/actions/__tests__/openView.defineProps.route.test.tsx +80 -20
- package/src/flow/actions/dataScopeFilter.ts +10 -1
- package/src/flow/actions/openView.tsx +21 -1
- package/src/flow/admin-shell/BaseLayoutModel.tsx +111 -0
- package/src/flow/admin-shell/BaseLayoutRouteCoordinator.ts +184 -42
- package/src/flow/admin-shell/__tests__/AdminLayoutRouteCoordinator.test.ts +1016 -119
- package/src/flow/admin-shell/admin-layout/AdminLayoutComponent.tsx +41 -4
- package/src/flow/admin-shell/admin-layout/AppListRender.tsx +13 -2
- package/src/flow/admin-shell/admin-layout/AppSwitcherActionPanelModel.tsx +289 -0
- package/src/flow/admin-shell/admin-layout/__tests__/AdminLayoutModel.test.tsx +359 -2
- package/src/flow/admin-shell/admin-layout/__tests__/TopbarActionsBar.test.tsx +48 -0
- package/src/flow/admin-shell/admin-layout/index.ts +1 -0
- package/src/flow/admin-shell/admin-layout/useApplications.tsx +81 -12
- package/src/flow/common/Markdown/Display.tsx +14 -3
- package/src/flow/common/Markdown/Edit.tsx +19 -7
- package/src/flow/components/FlowRoute.tsx +128 -16
- package/src/flow/internal/components/Markdown/util.ts +2 -1
- package/src/flow/models/base/ActionModel.tsx +10 -8
- package/src/flow/models/base/ActionModelCore.tsx +5 -0
- package/src/flow/models/fields/TextareaFieldModel.tsx +42 -19
- package/src/flow/models/fields/__tests__/TextareaFieldModel.test.tsx +32 -1
- package/src/flow/models/topbar/TopbarActionModel.tsx +78 -3
- package/src/flow/routeTransientInputArgs.ts +27 -0
- package/src/index.ts +4 -0
- package/src/nocobase-buildin-plugin/index.tsx +7 -1
- package/src/utils/markdownSanitize.ts +88 -0
|
@@ -22,6 +22,7 @@ import { getOpenViewStepParams } from '../flows/openViewFlow';
|
|
|
22
22
|
import { RouteModel } from '../models/base/RouteModel';
|
|
23
23
|
import { resolveViewParamsToViewList, updateViewListHidden, type ViewItem } from '../resolveViewParamsToViewList';
|
|
24
24
|
import type { LayoutDefinition } from '../../layout-manager/types';
|
|
25
|
+
import { getRouteTransientInputArgs } from '../routeTransientInputArgs';
|
|
25
26
|
|
|
26
27
|
export interface RoutePageMeta {
|
|
27
28
|
active: boolean;
|
|
@@ -49,14 +50,19 @@ interface RoutePageRuntime {
|
|
|
49
50
|
meta: RoutePageMeta;
|
|
50
51
|
viewState: Record<string, ViewRuntimeState>;
|
|
51
52
|
prevViewList: ViewItem[];
|
|
53
|
+
pendingOpenViewKeys: Set<string>;
|
|
52
54
|
hasStepNavigated: boolean;
|
|
55
|
+
currentPathname?: string;
|
|
56
|
+
currentRouteState?: unknown;
|
|
53
57
|
forceStop: boolean;
|
|
58
|
+
viewGeneration: number;
|
|
54
59
|
}
|
|
55
60
|
|
|
56
61
|
interface RouteLike {
|
|
57
62
|
layoutRouteName?: string;
|
|
58
63
|
params?: { name?: string };
|
|
59
64
|
pathname?: string;
|
|
65
|
+
state?: unknown;
|
|
60
66
|
pageUid?: string;
|
|
61
67
|
layoutBasePathname?: string;
|
|
62
68
|
layoutRoute?: {
|
|
@@ -66,6 +72,11 @@ interface RouteLike {
|
|
|
66
72
|
} | null;
|
|
67
73
|
}
|
|
68
74
|
|
|
75
|
+
interface SyncRuntimeOptions {
|
|
76
|
+
skipInitialStepNavigation?: boolean;
|
|
77
|
+
routeState?: unknown;
|
|
78
|
+
}
|
|
79
|
+
|
|
69
80
|
const hasUsableSourceId = (sourceId: unknown) => sourceId !== undefined && sourceId !== null && String(sourceId) !== '';
|
|
70
81
|
|
|
71
82
|
const normalizeBasePathname = (basePathname?: string) => {
|
|
@@ -92,6 +103,7 @@ export class BaseLayoutRouteCoordinator {
|
|
|
92
103
|
private basePathname: string;
|
|
93
104
|
private readonly runtimes = new Map<string, RoutePageRuntime>();
|
|
94
105
|
private layoutContentElement: HTMLElement | null = null;
|
|
106
|
+
private lastNonNullLayoutContentElement: HTMLElement | null = null;
|
|
95
107
|
|
|
96
108
|
constructor(flowEngine: FlowEngine, options: BaseLayoutRouteCoordinatorOptions = {}) {
|
|
97
109
|
this.flowEngine = flowEngine;
|
|
@@ -104,7 +116,19 @@ export class BaseLayoutRouteCoordinator {
|
|
|
104
116
|
}
|
|
105
117
|
|
|
106
118
|
setLayoutContentElement(element: HTMLElement | null) {
|
|
119
|
+
const previousTarget = this.layoutContentElement || this.lastNonNullLayoutContentElement;
|
|
107
120
|
this.layoutContentElement = element;
|
|
121
|
+
|
|
122
|
+
if (!element) {
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
const shouldReplayActiveViews = !!previousTarget && previousTarget !== element;
|
|
127
|
+
this.lastNonNullLayoutContentElement = element;
|
|
128
|
+
|
|
129
|
+
if (shouldReplayActiveViews) {
|
|
130
|
+
this.replayActiveRuntimeViewsAfterLayoutContentElementChange();
|
|
131
|
+
}
|
|
108
132
|
}
|
|
109
133
|
|
|
110
134
|
registerPage(pageUid: string, meta: RoutePageMeta) {
|
|
@@ -119,8 +143,10 @@ export class BaseLayoutRouteCoordinator {
|
|
|
119
143
|
},
|
|
120
144
|
viewState: {},
|
|
121
145
|
prevViewList: [],
|
|
146
|
+
pendingOpenViewKeys: new Set(),
|
|
122
147
|
hasStepNavigated: false,
|
|
123
148
|
forceStop: false,
|
|
149
|
+
viewGeneration: 0,
|
|
124
150
|
};
|
|
125
151
|
|
|
126
152
|
this.ensureRouteModelContext(runtime);
|
|
@@ -159,6 +185,7 @@ export class BaseLayoutRouteCoordinator {
|
|
|
159
185
|
this.runtimes.forEach((runtime) => {
|
|
160
186
|
this.setRuntimeActive(runtime, false);
|
|
161
187
|
});
|
|
188
|
+
this.invalidatePendingRuntimeViewOpens();
|
|
162
189
|
return;
|
|
163
190
|
}
|
|
164
191
|
|
|
@@ -175,11 +202,16 @@ export class BaseLayoutRouteCoordinator {
|
|
|
175
202
|
});
|
|
176
203
|
|
|
177
204
|
if (!activePageUid || !pathname) {
|
|
205
|
+
this.invalidatePendingRuntimeViewOpens();
|
|
178
206
|
return;
|
|
179
207
|
}
|
|
180
208
|
|
|
181
209
|
this.runtimes.forEach((runtime) => {
|
|
182
210
|
if (runtime.pageUid !== activePageUid) {
|
|
211
|
+
if (!runtime.forceStop) {
|
|
212
|
+
runtime.viewGeneration += 1;
|
|
213
|
+
runtime.pendingOpenViewKeys.clear();
|
|
214
|
+
}
|
|
183
215
|
runtime.forceStop = true;
|
|
184
216
|
}
|
|
185
217
|
});
|
|
@@ -190,7 +222,13 @@ export class BaseLayoutRouteCoordinator {
|
|
|
190
222
|
}
|
|
191
223
|
|
|
192
224
|
runtime.forceStop = false;
|
|
193
|
-
|
|
225
|
+
if (runtime.currentPathname && runtime.currentPathname !== pathname) {
|
|
226
|
+
runtime.viewGeneration += 1;
|
|
227
|
+
runtime.pendingOpenViewKeys.clear();
|
|
228
|
+
}
|
|
229
|
+
runtime.currentPathname = pathname;
|
|
230
|
+
runtime.currentRouteState = routeLike.state;
|
|
231
|
+
this.syncRuntimeWithPathname(runtime, pathname, { routeState: routeLike.state });
|
|
194
232
|
}
|
|
195
233
|
|
|
196
234
|
cleanupPage(pageUid: string) {
|
|
@@ -200,6 +238,8 @@ export class BaseLayoutRouteCoordinator {
|
|
|
200
238
|
}
|
|
201
239
|
|
|
202
240
|
runtime.forceStop = true;
|
|
241
|
+
runtime.viewGeneration += 1;
|
|
242
|
+
runtime.pendingOpenViewKeys.clear();
|
|
203
243
|
runtime.prevViewList.forEach((viewItem) => {
|
|
204
244
|
this.flowEngine.removeModelWithSubModels(viewItem.params.viewUid);
|
|
205
245
|
runtime.viewState[getKey(viewItem)]?.destroy?.();
|
|
@@ -207,6 +247,8 @@ export class BaseLayoutRouteCoordinator {
|
|
|
207
247
|
});
|
|
208
248
|
runtime.prevViewList = [];
|
|
209
249
|
runtime.hasStepNavigated = false;
|
|
250
|
+
runtime.currentPathname = undefined;
|
|
251
|
+
runtime.currentRouteState = undefined;
|
|
210
252
|
}
|
|
211
253
|
|
|
212
254
|
destroy() {
|
|
@@ -249,7 +291,7 @@ export class BaseLayoutRouteCoordinator {
|
|
|
249
291
|
viewState?.deactivate?.();
|
|
250
292
|
}
|
|
251
293
|
|
|
252
|
-
private syncRuntimeWithPathname(runtime: RoutePageRuntime, pathname: string) {
|
|
294
|
+
private syncRuntimeWithPathname(runtime: RoutePageRuntime, pathname: string, options: SyncRuntimeOptions = {}) {
|
|
253
295
|
try {
|
|
254
296
|
if (!this.basePathname) {
|
|
255
297
|
return;
|
|
@@ -257,29 +299,42 @@ export class BaseLayoutRouteCoordinator {
|
|
|
257
299
|
|
|
258
300
|
const viewStack = parsePathnameToViewParams(pathname, { basePath: this.basePathname });
|
|
259
301
|
const viewList = resolveViewParamsToViewList(this.flowEngine, viewStack, runtime.routeModel);
|
|
302
|
+
const routeState = options.routeState;
|
|
260
303
|
|
|
261
|
-
if (this.shouldStepNavigate(runtime, viewList)) {
|
|
262
|
-
this.stepNavigate(viewList, 0);
|
|
304
|
+
if (!options.skipInitialStepNavigation && this.shouldStepNavigate(runtime, viewList)) {
|
|
305
|
+
this.stepNavigate(viewList, 0, routeState);
|
|
263
306
|
runtime.hasStepNavigated = true;
|
|
264
|
-
this.scheduleInitialDeepLinkReplay(runtime, pathname);
|
|
307
|
+
this.scheduleInitialDeepLinkReplay(runtime, pathname, routeState);
|
|
265
308
|
return;
|
|
266
309
|
}
|
|
267
310
|
|
|
268
311
|
const { viewsToClose, viewsToOpen } = getViewDiffAndUpdateHidden(runtime.prevViewList, viewList);
|
|
312
|
+
const viewsToOpenKeys = new Set(viewsToOpen.map((viewItem) => getKey(viewItem)));
|
|
313
|
+
const nextViewsToOpen = viewList.filter((viewItem) => {
|
|
314
|
+
const key = getKey(viewItem);
|
|
315
|
+
if (runtime.pendingOpenViewKeys.has(key)) {
|
|
316
|
+
return false;
|
|
317
|
+
}
|
|
318
|
+
return viewsToOpenKeys.has(key) || !runtime.viewState[key];
|
|
319
|
+
});
|
|
269
320
|
|
|
270
321
|
if (viewsToClose.length) {
|
|
271
322
|
viewsToClose.forEach((viewItem) => {
|
|
323
|
+
runtime.pendingOpenViewKeys.delete(getKey(viewItem));
|
|
272
324
|
runtime.viewState[getKey(viewItem)]?.destroy?.(true);
|
|
273
325
|
delete runtime.viewState[getKey(viewItem)];
|
|
274
326
|
});
|
|
275
327
|
updateViewListHidden(viewList, !!this.layoutContext?.isMobileLayout);
|
|
276
328
|
}
|
|
277
329
|
|
|
278
|
-
if (
|
|
279
|
-
|
|
330
|
+
if (nextViewsToOpen.length) {
|
|
331
|
+
this.markPendingOpenViews(runtime, nextViewsToOpen);
|
|
332
|
+
this.handleOpenViews(runtime, viewList, nextViewsToOpen, runtime.viewGeneration, routeState).catch((error) => {
|
|
333
|
+
console.error(`[NocoBase] Failed to open route-managed views:`, error);
|
|
334
|
+
});
|
|
280
335
|
}
|
|
281
336
|
|
|
282
|
-
if (viewsToClose.length === 0 &&
|
|
337
|
+
if (viewsToClose.length === 0 && nextViewsToOpen.length === 0) {
|
|
283
338
|
const currentViewItem = viewList.at(-1);
|
|
284
339
|
if (currentViewItem) {
|
|
285
340
|
runtime.viewState[getKey(currentViewItem)]?.navigation.setViewStack(viewList.map((item) => item.params));
|
|
@@ -312,30 +367,38 @@ export class BaseLayoutRouteCoordinator {
|
|
|
312
367
|
return runtime.prevViewList.length === 0 && viewList.length > 1 && !runtime.hasStepNavigated;
|
|
313
368
|
}
|
|
314
369
|
|
|
315
|
-
private scheduleInitialDeepLinkReplay(runtime: RoutePageRuntime, pathname: string) {
|
|
370
|
+
private scheduleInitialDeepLinkReplay(runtime: RoutePageRuntime, pathname: string, routeState?: unknown) {
|
|
371
|
+
const viewGeneration = runtime.viewGeneration;
|
|
316
372
|
Promise.resolve()
|
|
317
373
|
.then(() => {
|
|
318
|
-
if (
|
|
374
|
+
if (
|
|
375
|
+
runtime.forceStop ||
|
|
376
|
+
runtime.viewGeneration !== viewGeneration ||
|
|
377
|
+
runtime.currentPathname !== pathname ||
|
|
378
|
+
runtime.prevViewList.length > 0
|
|
379
|
+
) {
|
|
319
380
|
return;
|
|
320
381
|
}
|
|
321
382
|
|
|
322
|
-
this.syncRuntimeWithPathname(runtime, pathname);
|
|
383
|
+
this.syncRuntimeWithPathname(runtime, pathname, { routeState });
|
|
323
384
|
})
|
|
324
385
|
.catch(() => {
|
|
325
386
|
// ignore
|
|
326
387
|
});
|
|
327
388
|
}
|
|
328
389
|
|
|
329
|
-
private stepNavigate(viewList: ViewItem[], index: number) {
|
|
390
|
+
private stepNavigate(viewList: ViewItem[], index: number, routeState?: unknown) {
|
|
330
391
|
if (!viewList[index]) {
|
|
331
392
|
return;
|
|
332
393
|
}
|
|
333
394
|
|
|
395
|
+
const navigationOptions = routeState ? { state: routeState } : undefined;
|
|
334
396
|
if (index === 0) {
|
|
335
397
|
new ViewNavigation(this.flowEngine.context, [], { basePath: this.basePathname }).navigateTo(
|
|
336
398
|
viewList[index].params,
|
|
337
399
|
{
|
|
338
400
|
replace: true,
|
|
401
|
+
...navigationOptions,
|
|
339
402
|
},
|
|
340
403
|
);
|
|
341
404
|
} else {
|
|
@@ -343,13 +406,70 @@ export class BaseLayoutRouteCoordinator {
|
|
|
343
406
|
this.flowEngine.context,
|
|
344
407
|
viewList.slice(0, index).map((item) => item.params),
|
|
345
408
|
{ basePath: this.basePathname },
|
|
346
|
-
).navigateTo(viewList[index].params);
|
|
409
|
+
).navigateTo(viewList[index].params, navigationOptions);
|
|
347
410
|
}
|
|
348
411
|
|
|
349
|
-
this.stepNavigate(viewList, index + 1);
|
|
412
|
+
this.stepNavigate(viewList, index + 1, routeState);
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
private replayActiveRuntimeViewsAfterLayoutContentElementChange() {
|
|
416
|
+
this.runtimes.forEach((runtime) => {
|
|
417
|
+
if (!runtime.currentPathname || runtime.prevViewList.length === 0) {
|
|
418
|
+
return;
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
this.resetRuntimeViewStateForLayoutContentElementChange(runtime);
|
|
422
|
+
if (runtime.meta.active) {
|
|
423
|
+
this.syncRuntimeWithPathname(runtime, runtime.currentPathname, {
|
|
424
|
+
skipInitialStepNavigation: true,
|
|
425
|
+
routeState: runtime.currentRouteState,
|
|
426
|
+
});
|
|
427
|
+
}
|
|
428
|
+
});
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
private invalidatePendingRuntimeViewOpens() {
|
|
432
|
+
this.runtimes.forEach((runtime) => {
|
|
433
|
+
runtime.forceStop = true;
|
|
434
|
+
runtime.viewGeneration += 1;
|
|
435
|
+
runtime.pendingOpenViewKeys.clear();
|
|
436
|
+
});
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
private resetRuntimeViewStateForLayoutContentElementChange(runtime: RoutePageRuntime) {
|
|
440
|
+
runtime.viewGeneration += 1;
|
|
441
|
+
runtime.pendingOpenViewKeys.clear();
|
|
442
|
+
runtime.prevViewList.forEach((viewItem, index) => {
|
|
443
|
+
runtime.viewState[getKey(viewItem)]?.destroy?.(true);
|
|
444
|
+
delete runtime.viewState[getKey(viewItem)];
|
|
445
|
+
|
|
446
|
+
if (index > 0) {
|
|
447
|
+
this.flowEngine.removeModelWithSubModels(viewItem.params.viewUid);
|
|
448
|
+
}
|
|
449
|
+
});
|
|
450
|
+
runtime.prevViewList = [];
|
|
451
|
+
runtime.hasStepNavigated = false;
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
private markPendingOpenViews(runtime: RoutePageRuntime, viewItems: ViewItem[]) {
|
|
455
|
+
viewItems.forEach((viewItem) => {
|
|
456
|
+
runtime.pendingOpenViewKeys.add(getKey(viewItem));
|
|
457
|
+
});
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
private clearPendingOpenViews(runtime: RoutePageRuntime, viewItems: ViewItem[]) {
|
|
461
|
+
viewItems.forEach((viewItem) => {
|
|
462
|
+
runtime.pendingOpenViewKeys.delete(getKey(viewItem));
|
|
463
|
+
});
|
|
350
464
|
}
|
|
351
465
|
|
|
352
|
-
private async handleOpenViews(
|
|
466
|
+
private async handleOpenViews(
|
|
467
|
+
runtime: RoutePageRuntime,
|
|
468
|
+
viewList: ViewItem[],
|
|
469
|
+
viewsToOpen: ViewItem[],
|
|
470
|
+
viewGeneration: number,
|
|
471
|
+
routeState?: unknown,
|
|
472
|
+
) {
|
|
353
473
|
const missingModels = viewsToOpen.filter((v) => !v.model);
|
|
354
474
|
if (missingModels.length > 0) {
|
|
355
475
|
await Promise.all(
|
|
@@ -363,24 +483,37 @@ export class BaseLayoutRouteCoordinator {
|
|
|
363
483
|
);
|
|
364
484
|
}
|
|
365
485
|
|
|
366
|
-
if (runtime.forceStop) {
|
|
486
|
+
if (runtime.forceStop || runtime.viewGeneration !== viewGeneration) {
|
|
367
487
|
return;
|
|
368
488
|
}
|
|
369
489
|
|
|
370
490
|
this.syncViewListVisibility(runtime, viewList);
|
|
371
|
-
this.openViews(runtime, viewList, viewsToOpen, 0);
|
|
491
|
+
this.openViews(runtime, viewList, viewsToOpen, 0, viewGeneration, routeState);
|
|
372
492
|
}
|
|
373
493
|
|
|
374
|
-
private openViews(
|
|
494
|
+
private openViews(
|
|
495
|
+
runtime: RoutePageRuntime,
|
|
496
|
+
viewList: ViewItem[],
|
|
497
|
+
viewsToOpen: ViewItem[],
|
|
498
|
+
index: number,
|
|
499
|
+
viewGeneration: number,
|
|
500
|
+
routeState?: unknown,
|
|
501
|
+
) {
|
|
502
|
+
if (runtime.forceStop || runtime.viewGeneration !== viewGeneration) {
|
|
503
|
+
return;
|
|
504
|
+
}
|
|
505
|
+
|
|
375
506
|
if (!viewsToOpen[index]) {
|
|
376
507
|
return;
|
|
377
508
|
}
|
|
378
509
|
|
|
379
510
|
const viewItem = viewsToOpen[index];
|
|
380
511
|
if (!viewItem.model) {
|
|
512
|
+
this.clearPendingOpenViews(runtime, viewsToOpen.slice(index));
|
|
381
513
|
return;
|
|
382
514
|
}
|
|
383
515
|
|
|
516
|
+
const viewKey = getKey(viewItem);
|
|
384
517
|
const destroyRef = React.createRef<(result?: any, force?: boolean) => void>();
|
|
385
518
|
const updateRef = React.createRef<(value: any) => void>();
|
|
386
519
|
const activateRef = React.createRef<(forceRefresh?: boolean) => void>();
|
|
@@ -392,43 +525,52 @@ export class BaseLayoutRouteCoordinator {
|
|
|
392
525
|
: openViewParams?.associationName;
|
|
393
526
|
const openViewRouteState = viewItem.params.openViewRouteState;
|
|
394
527
|
const openerUids = viewList.slice(0, viewItem.index).map((item) => item.params.viewUid);
|
|
528
|
+
const transientInputArgs = getRouteTransientInputArgs(routeState, viewItem.params.viewUid);
|
|
395
529
|
const navigation = new ViewNavigation(
|
|
396
530
|
this.flowEngine.context,
|
|
397
531
|
viewList.slice(0, viewItem.index + 1).map((item) => item.params),
|
|
398
532
|
{ basePath: this.basePathname },
|
|
399
533
|
);
|
|
400
534
|
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
535
|
+
try {
|
|
536
|
+
viewItem.model.dispatchEvent('click', {
|
|
537
|
+
target: this.layoutContentElement || runtime.meta.layoutContentElement,
|
|
538
|
+
collectionName: openViewParams?.collectionName,
|
|
539
|
+
associationName,
|
|
540
|
+
dataSourceKey: openViewParams?.dataSourceKey,
|
|
541
|
+
destroyRef,
|
|
542
|
+
updateRef,
|
|
543
|
+
activateRef,
|
|
544
|
+
deactivateRef,
|
|
545
|
+
openerUids,
|
|
546
|
+
...viewItem.params,
|
|
547
|
+
...transientInputArgs,
|
|
548
|
+
...(openViewRouteState?.mode ? { mode: openViewRouteState.mode } : {}),
|
|
549
|
+
...(openViewRouteState?.size ? { size: openViewRouteState.size } : {}),
|
|
550
|
+
pageActive: runtime.meta.active,
|
|
551
|
+
activationControlledByLayout: true,
|
|
552
|
+
navigation,
|
|
553
|
+
onOpen: () => {
|
|
554
|
+
this.openViews(runtime, viewList, viewsToOpen, index + 1, viewGeneration, routeState);
|
|
555
|
+
},
|
|
556
|
+
hidden: viewItem.hidden,
|
|
557
|
+
isMobileLayout: !!this.layoutContext?.isMobileLayout,
|
|
558
|
+
triggerByRouter: true,
|
|
559
|
+
});
|
|
560
|
+
} catch (error) {
|
|
561
|
+
this.clearPendingOpenViews(runtime, viewsToOpen.slice(index));
|
|
562
|
+
console.error(`[NocoBase] Failed to dispatch route-managed view open:`, error);
|
|
563
|
+
return;
|
|
564
|
+
}
|
|
424
565
|
|
|
425
|
-
runtime.viewState[
|
|
566
|
+
runtime.viewState[viewKey] = {
|
|
426
567
|
destroy: (_force?: boolean) => destroyRef.current?.(),
|
|
427
568
|
update: (value: any) => updateRef.current?.(value),
|
|
428
569
|
activate: (forceRefresh?: boolean) => activateRef.current?.(forceRefresh),
|
|
429
570
|
deactivate: () => deactivateRef.current?.(),
|
|
430
571
|
navigation,
|
|
431
572
|
};
|
|
573
|
+
runtime.pendingOpenViewKeys.delete(viewKey);
|
|
432
574
|
}
|
|
433
575
|
|
|
434
576
|
private ensureRouteModelContext(runtime: RoutePageRuntime) {
|