@nocobase/client-v2 2.2.0-beta.8 → 2.2.0-beta.9
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/RouteRepository.d.ts +8 -0
- package/es/RouterManager.d.ts +15 -0
- package/es/authRedirect.d.ts +1 -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 +2 -0
- package/es/index.mjs +212 -126
- package/es/utils/markdownSanitize.d.ts +11 -0
- package/lib/index.js +198 -112
- package/package.json +7 -7
- package/src/BaseApplication.tsx +2 -0
- package/src/RouteRepository.ts +25 -0
- package/src/RouterManager.tsx +142 -1
- package/src/__tests__/RouteRepository.test.ts +23 -0
- package/src/__tests__/RouterManager.test.ts +125 -0
- package/src/__tests__/authRedirect.test.ts +17 -0
- package/src/authRedirect.ts +38 -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/dateTimeFormat.tsx +2 -2
- package/src/flow/actions/openView.tsx +21 -1
- package/src/flow/admin-shell/BaseLayoutModel.tsx +124 -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/AdminLayoutEntryGuard.test.tsx +177 -1
- package/src/flow/admin-shell/admin-layout/AdminLayoutEntryGuard.tsx +20 -0
- 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 +436 -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/blocks/table/TableColumnModel.tsx +6 -2
- package/src/flow/models/blocks/table/__tests__/TableColumnModel.test.tsx +51 -0
- package/src/flow/models/fields/AssociationFieldModel/RecordSelectFieldModel.tsx +45 -13
- 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/flow/utils/__tests__/dateTimeFormat.test.ts +42 -0
- package/src/index.ts +2 -0
- package/src/nocobase-buildin-plugin/index.tsx +7 -1
- package/src/utils/markdownSanitize.ts +88 -0
|
@@ -12,6 +12,7 @@ import { describe, it, expect, vi } from 'vitest';
|
|
|
12
12
|
import { RUNJS_OPEN_VIEW_ROUTE_STATE } from '@nocobase/flow-engine';
|
|
13
13
|
import { openView } from '../openView';
|
|
14
14
|
import { FlowPage } from '../../FlowPage';
|
|
15
|
+
import { ROUTE_TRANSIENT_INPUT_ARGS_KEY } from '../../routeTransientInputArgs';
|
|
15
16
|
|
|
16
17
|
describe('openView action - route mode defineProperties/defineMethods', () => {
|
|
17
18
|
const createRouteManagedCtx = () => {
|
|
@@ -172,6 +173,56 @@ describe('openView action - route mode defineProperties/defineMethods', () => {
|
|
|
172
173
|
expect(defineMethodCalls).toContain('pong');
|
|
173
174
|
});
|
|
174
175
|
|
|
176
|
+
it('passes formData through route navigation state', async () => {
|
|
177
|
+
const navigateTo = vi.fn();
|
|
178
|
+
const ctx: any = {
|
|
179
|
+
inputArgs: {
|
|
180
|
+
formData: {
|
|
181
|
+
start: '2026-06-24 08:00:00',
|
|
182
|
+
end: '2026-06-24 09:00:00',
|
|
183
|
+
},
|
|
184
|
+
},
|
|
185
|
+
engine: {
|
|
186
|
+
context: {},
|
|
187
|
+
},
|
|
188
|
+
model: {
|
|
189
|
+
uid: 'popup-uid',
|
|
190
|
+
context: {
|
|
191
|
+
defineProperty: vi.fn(),
|
|
192
|
+
},
|
|
193
|
+
},
|
|
194
|
+
view: {
|
|
195
|
+
navigation: {
|
|
196
|
+
navigateTo,
|
|
197
|
+
},
|
|
198
|
+
},
|
|
199
|
+
isNavigationEnabled: true,
|
|
200
|
+
};
|
|
201
|
+
|
|
202
|
+
await openView.handler(ctx, { navigation: true });
|
|
203
|
+
|
|
204
|
+
expect(navigateTo).toHaveBeenCalledWith(
|
|
205
|
+
{
|
|
206
|
+
viewUid: 'popup-uid',
|
|
207
|
+
filterByTk: undefined,
|
|
208
|
+
sourceId: undefined,
|
|
209
|
+
tabUid: undefined,
|
|
210
|
+
},
|
|
211
|
+
{
|
|
212
|
+
state: {
|
|
213
|
+
[ROUTE_TRANSIENT_INPUT_ARGS_KEY]: {
|
|
214
|
+
'popup-uid': {
|
|
215
|
+
formData: {
|
|
216
|
+
start: '2026-06-24 08:00:00',
|
|
217
|
+
end: '2026-06-24 09:00:00',
|
|
218
|
+
},
|
|
219
|
+
},
|
|
220
|
+
},
|
|
221
|
+
},
|
|
222
|
+
},
|
|
223
|
+
);
|
|
224
|
+
});
|
|
225
|
+
|
|
175
226
|
it('adds route state to first-stage navigation only for RunJS ctx.openView calls', async () => {
|
|
176
227
|
const { ctx, navigateTo } = createFirstStageCtx({
|
|
177
228
|
mode: 'dialog',
|
|
@@ -181,13 +232,16 @@ describe('openView action - route mode defineProperties/defineMethods', () => {
|
|
|
181
232
|
|
|
182
233
|
await openView.handler(ctx, { mode: 'drawer', size: 'medium', navigation: true });
|
|
183
234
|
|
|
184
|
-
expect(navigateTo).toHaveBeenCalledWith(
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
235
|
+
expect(navigateTo).toHaveBeenCalledWith(
|
|
236
|
+
{
|
|
237
|
+
viewUid: 'popup-uid',
|
|
238
|
+
filterByTk: undefined,
|
|
239
|
+
sourceId: undefined,
|
|
240
|
+
tabUid: undefined,
|
|
241
|
+
openViewRouteState: { mode: 'dialog', size: 'large' },
|
|
242
|
+
},
|
|
243
|
+
undefined,
|
|
244
|
+
);
|
|
191
245
|
});
|
|
192
246
|
|
|
193
247
|
it('normalizes first-stage RunJS route state mode on mobile layout', async () => {
|
|
@@ -200,13 +254,16 @@ describe('openView action - route mode defineProperties/defineMethods', () => {
|
|
|
200
254
|
|
|
201
255
|
await openView.handler(ctx, { mode: 'drawer', size: 'medium', navigation: true });
|
|
202
256
|
|
|
203
|
-
expect(navigateTo).toHaveBeenCalledWith(
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
257
|
+
expect(navigateTo).toHaveBeenCalledWith(
|
|
258
|
+
{
|
|
259
|
+
viewUid: 'popup-uid',
|
|
260
|
+
filterByTk: undefined,
|
|
261
|
+
sourceId: undefined,
|
|
262
|
+
tabUid: undefined,
|
|
263
|
+
openViewRouteState: { mode: 'embed', size: 'large' },
|
|
264
|
+
},
|
|
265
|
+
undefined,
|
|
266
|
+
);
|
|
210
267
|
});
|
|
211
268
|
|
|
212
269
|
it('uses route replay mode and size before persisted openView defaults', async () => {
|
|
@@ -246,11 +303,14 @@ describe('openView action - route mode defineProperties/defineMethods', () => {
|
|
|
246
303
|
|
|
247
304
|
await openView.handler(ctx, { mode: 'drawer', size: 'medium', navigation: true });
|
|
248
305
|
|
|
249
|
-
expect(navigateTo).toHaveBeenCalledWith(
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
306
|
+
expect(navigateTo).toHaveBeenCalledWith(
|
|
307
|
+
{
|
|
308
|
+
viewUid: 'popup-uid',
|
|
309
|
+
filterByTk: undefined,
|
|
310
|
+
sourceId: undefined,
|
|
311
|
+
tabUid: undefined,
|
|
312
|
+
},
|
|
313
|
+
undefined,
|
|
314
|
+
);
|
|
255
315
|
});
|
|
256
316
|
});
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
import { isVariableExpression, pruneFilter } from '@nocobase/flow-engine';
|
|
10
|
+
import { extractPropertyPath, isVariableExpression, pruneFilter } from '@nocobase/flow-engine';
|
|
11
11
|
import { transformFilter } from '@nocobase/utils/client';
|
|
12
12
|
import _ from 'lodash';
|
|
13
13
|
|
|
@@ -45,6 +45,14 @@ function restorePreservedNull(value: any): any {
|
|
|
45
45
|
return value;
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
+
function isUrlSearchParamsExpression(value: any) {
|
|
49
|
+
if (!isVariableExpression(value)) {
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return extractPropertyPath(value)?.[0] === 'urlSearchParams';
|
|
54
|
+
}
|
|
55
|
+
|
|
48
56
|
function markEmptyVariableValues(rawNode: any, resolvedNode: any) {
|
|
49
57
|
if (!rawNode || !resolvedNode || typeof rawNode !== 'object' || typeof resolvedNode !== 'object') {
|
|
50
58
|
return;
|
|
@@ -57,6 +65,7 @@ function markEmptyVariableValues(rawNode: any, resolvedNode: any) {
|
|
|
57
65
|
}
|
|
58
66
|
if (
|
|
59
67
|
isVariableExpression(rawNode.value) &&
|
|
68
|
+
!isUrlSearchParamsExpression(rawNode.value) &&
|
|
60
69
|
(resolvedNode.value === undefined || resolvedNode.value === null || resolvedNode.value === '')
|
|
61
70
|
) {
|
|
62
71
|
resolvedNode.value = PRESERVE_NULL;
|
|
@@ -28,11 +28,11 @@ const isTableColumnFieldSubModel = (model) => {
|
|
|
28
28
|
|
|
29
29
|
const syncTableColumnDateTimeFormatProps = (ctx, props) => {
|
|
30
30
|
const model = ctx.model;
|
|
31
|
-
if (!isTableColumnFieldSubModel(model)
|
|
31
|
+
if (!isTableColumnFieldSubModel(model)) {
|
|
32
32
|
return;
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
model.parent
|
|
35
|
+
model.parent?.setProps?.(props);
|
|
36
36
|
};
|
|
37
37
|
|
|
38
38
|
export const dateTimeFormat = defineAction({
|
|
@@ -20,6 +20,7 @@ import React from 'react';
|
|
|
20
20
|
import { FlowPage } from '../FlowPage';
|
|
21
21
|
import { PageModel, RootPageModel } from '../models';
|
|
22
22
|
import _ from 'lodash';
|
|
23
|
+
import { ROUTE_TRANSIENT_INPUT_ARGS_KEY } from '../routeTransientInputArgs';
|
|
23
24
|
|
|
24
25
|
type DirtyAwareFlowModel = FlowModel & {
|
|
25
26
|
getUserModifiedFields?: () => Set<string> | undefined;
|
|
@@ -31,6 +32,15 @@ type BeforeCloseDirtyState = {
|
|
|
31
32
|
formModelUids: string[];
|
|
32
33
|
};
|
|
33
34
|
|
|
35
|
+
const pickRouteTransientInputArgs = (inputArgs: Record<string, unknown>) => {
|
|
36
|
+
return _.pickBy(
|
|
37
|
+
{
|
|
38
|
+
formData: inputArgs.formData,
|
|
39
|
+
},
|
|
40
|
+
(value) => typeof value !== 'undefined',
|
|
41
|
+
);
|
|
42
|
+
};
|
|
43
|
+
|
|
34
44
|
function collectDirtyFormModelUids(model?: FlowModel | null, ignoredDirtyFormModelUids: string[] = []): string[] {
|
|
35
45
|
if (!model) {
|
|
36
46
|
return [];
|
|
@@ -363,7 +373,17 @@ export const openView = defineAction({
|
|
|
363
373
|
tabUid: mergedTabUid,
|
|
364
374
|
...(effectiveRunJSOpenViewRouteState ? { openViewRouteState: effectiveRunJSOpenViewRouteState } : {}),
|
|
365
375
|
};
|
|
366
|
-
|
|
376
|
+
const transientInputArgs = pickRouteTransientInputArgs(inputArgs);
|
|
377
|
+
const navigationOptions = Object.keys(transientInputArgs).length
|
|
378
|
+
? {
|
|
379
|
+
state: {
|
|
380
|
+
[ROUTE_TRANSIENT_INPUT_ARGS_KEY]: {
|
|
381
|
+
[nextView.viewUid]: transientInputArgs,
|
|
382
|
+
},
|
|
383
|
+
},
|
|
384
|
+
}
|
|
385
|
+
: undefined;
|
|
386
|
+
ctx.view.navigation.navigateTo(nextView, navigationOptions);
|
|
367
387
|
return;
|
|
368
388
|
}
|
|
369
389
|
}
|
|
@@ -20,6 +20,7 @@ import {
|
|
|
20
20
|
type BaseLayoutRouteCoordinatorOptions,
|
|
21
21
|
type RoutePageMeta,
|
|
22
22
|
} from './BaseLayoutRouteCoordinator';
|
|
23
|
+
import { NocoBaseDesktopRouteType } from '../../flow-compat';
|
|
23
24
|
import type { LayoutDefinition } from '../../layout-manager/types';
|
|
24
25
|
import { isLayoutContentRouteName } from '../../layout-manager/utils';
|
|
25
26
|
|
|
@@ -72,6 +73,7 @@ export interface LayoutRouteLike {
|
|
|
72
73
|
id?: string;
|
|
73
74
|
name?: string;
|
|
74
75
|
pathname?: string;
|
|
76
|
+
state?: unknown;
|
|
75
77
|
params?: Record<string, string | undefined>;
|
|
76
78
|
layoutRouteName?: string;
|
|
77
79
|
layoutBasePathname?: string;
|
|
@@ -111,6 +113,15 @@ const getDefaultBasePathnameFromRoutePath = (routePath?: string) => {
|
|
|
111
113
|
|
|
112
114
|
const isKnownViewParamName = (segment: string) => ['tab', 'filterbytk', 'sourceid'].includes(segment);
|
|
113
115
|
|
|
116
|
+
const isLegacyLayoutContentRouteName = (routeName: string, targetRouteName?: string) => {
|
|
117
|
+
return (
|
|
118
|
+
!!targetRouteName &&
|
|
119
|
+
['page', 'page.tabs', 'page.tabs.popups', 'page.tab', 'page.view', 'page.tab.view'].some(
|
|
120
|
+
(legacyName) => targetRouteName === `${routeName}.${legacyName}`,
|
|
121
|
+
)
|
|
122
|
+
);
|
|
123
|
+
};
|
|
124
|
+
|
|
114
125
|
const isStandardLayoutRelativePath = (relativePath: string) => {
|
|
115
126
|
if (!relativePath) {
|
|
116
127
|
return true;
|
|
@@ -170,6 +181,7 @@ export class BaseLayoutModel<
|
|
|
170
181
|
currentLayoutRoute: LayoutRouteMatch | null = null;
|
|
171
182
|
protected routeCoordinator?: BaseLayoutRouteCoordinator;
|
|
172
183
|
private activePageUid = '';
|
|
184
|
+
private currentRouteState?: unknown;
|
|
173
185
|
private layoutContentElement: HTMLElement | null = null;
|
|
174
186
|
private readonly routePageMetaMap = new Map<string, RoutePageMeta>();
|
|
175
187
|
private contextBindingsActive = false;
|
|
@@ -184,6 +196,7 @@ export class BaseLayoutModel<
|
|
|
184
196
|
|
|
185
197
|
registerRoutePage(pageUid: string, meta: RoutePageMeta) {
|
|
186
198
|
this.routePageMetaMap.set(pageUid, meta);
|
|
199
|
+
this.restoreCurrentLayoutRouteFromRouterContext(pageUid);
|
|
187
200
|
const routeModel = this.getCoordinator().registerPage(pageUid, meta);
|
|
188
201
|
this.getCoordinator().syncRoute(this.getCurrentCoordinatorRouteLike());
|
|
189
202
|
return routeModel;
|
|
@@ -322,6 +335,18 @@ export class BaseLayoutModel<
|
|
|
322
335
|
};
|
|
323
336
|
}
|
|
324
337
|
|
|
338
|
+
const routeRepository = this.flowEngine.context.routeRepository;
|
|
339
|
+
const schemaRoute = routeRepository?.getRouteBySchemaUid?.(pageUid);
|
|
340
|
+
const route = schemaRoute ? undefined : routeRepository?.getRouteById?.(pageUid);
|
|
341
|
+
if (!schemaRoute && route?.type === NocoBaseDesktopRouteType.group) {
|
|
342
|
+
return {
|
|
343
|
+
type: 'root',
|
|
344
|
+
pathname,
|
|
345
|
+
basePathname,
|
|
346
|
+
relativePath,
|
|
347
|
+
};
|
|
348
|
+
}
|
|
349
|
+
|
|
325
350
|
return {
|
|
326
351
|
type: 'page',
|
|
327
352
|
pathname,
|
|
@@ -345,6 +370,7 @@ export class BaseLayoutModel<
|
|
|
345
370
|
|
|
346
371
|
const layoutRoute = this.resolveLayoutRoute(routeLike);
|
|
347
372
|
this.currentLayoutRoute = layoutRoute;
|
|
373
|
+
this.currentRouteState = routeLike.state;
|
|
348
374
|
this.activePageUid = this.getPageUidFromLayoutRoute(layoutRoute);
|
|
349
375
|
this.getCoordinator().syncRoute({
|
|
350
376
|
...routeLike,
|
|
@@ -364,7 +390,12 @@ export class BaseLayoutModel<
|
|
|
364
390
|
return;
|
|
365
391
|
}
|
|
366
392
|
|
|
393
|
+
if (this.shouldIgnoreStaleLayoutRouteCleanup(routeLike)) {
|
|
394
|
+
return;
|
|
395
|
+
}
|
|
396
|
+
|
|
367
397
|
this.currentLayoutRoute = null;
|
|
398
|
+
this.currentRouteState = undefined;
|
|
368
399
|
this.activePageUid = '';
|
|
369
400
|
this.routeCoordinator?.syncRoute({});
|
|
370
401
|
}
|
|
@@ -434,12 +465,105 @@ export class BaseLayoutModel<
|
|
|
434
465
|
layoutRouteName: this.layout.routeName,
|
|
435
466
|
pageUid: this.currentLayoutRoute.pageUid,
|
|
436
467
|
pathname: this.currentLayoutRoute.pathname,
|
|
468
|
+
state: this.currentRouteState,
|
|
437
469
|
layoutBasePathname: this.currentLayoutRoute.basePathname,
|
|
438
470
|
layoutRoute: this.currentLayoutRoute,
|
|
439
471
|
};
|
|
440
472
|
}
|
|
441
473
|
return {};
|
|
442
474
|
}
|
|
475
|
+
|
|
476
|
+
private restoreCurrentLayoutRouteFromRouterContext(pageUid: string) {
|
|
477
|
+
if (this.currentLayoutRoute?.type === 'page') {
|
|
478
|
+
return;
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
const routeLike = this.getRouterContextRouteLike();
|
|
482
|
+
if (!routeLike) {
|
|
483
|
+
return;
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
if (!this.isRouteLikeOwnedByCurrentLayout(routeLike)) {
|
|
487
|
+
return;
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
const layoutRoute = this.resolveLayoutRoute({
|
|
491
|
+
...routeLike,
|
|
492
|
+
layoutRouteName: routeLike.layoutRouteName || this.layout.routeName,
|
|
493
|
+
});
|
|
494
|
+
if (layoutRoute.type !== 'page' || layoutRoute.pageUid !== pageUid) {
|
|
495
|
+
return;
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
this.currentLayoutRoute = layoutRoute;
|
|
499
|
+
this.activePageUid = layoutRoute.pageUid;
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
private shouldIgnoreStaleLayoutRouteCleanup(routeLike?: LayoutRouteLike) {
|
|
503
|
+
if (!routeLike?.pathname || this.currentLayoutRoute?.type !== 'page') {
|
|
504
|
+
return false;
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
const currentLayoutRoute = this.currentLayoutRoute;
|
|
508
|
+
if (!this.routePageMetaMap.has(currentLayoutRoute.pageUid)) {
|
|
509
|
+
return false;
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
const routeLikePathname = normalizePathname(routeLike.pathname);
|
|
513
|
+
if (routeLikePathname !== currentLayoutRoute.pathname) {
|
|
514
|
+
return false;
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
const routerRouteLike = this.getRouterContextRouteLike();
|
|
518
|
+
if (!routerRouteLike) {
|
|
519
|
+
return false;
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
if (!this.isRouteLikeOwnedByCurrentLayout(routerRouteLike)) {
|
|
523
|
+
return false;
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
const routerLayoutRoute = this.resolveLayoutRoute({
|
|
527
|
+
...routerRouteLike,
|
|
528
|
+
layoutRouteName: routerRouteLike.layoutRouteName || this.layout.routeName,
|
|
529
|
+
});
|
|
530
|
+
|
|
531
|
+
return (
|
|
532
|
+
routerLayoutRoute.type === 'page' &&
|
|
533
|
+
routerLayoutRoute.pageUid === currentLayoutRoute.pageUid &&
|
|
534
|
+
routerLayoutRoute.pathname === currentLayoutRoute.pathname
|
|
535
|
+
);
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
private getRouterContextRouteLike(): LayoutRouteLike | null {
|
|
539
|
+
const route = this.flowEngine.context.route as LayoutRouteLike | undefined;
|
|
540
|
+
if (!route?.pathname) {
|
|
541
|
+
return null;
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
return {
|
|
545
|
+
id: route.id,
|
|
546
|
+
name: route.name || route.id,
|
|
547
|
+
pathname: route.pathname,
|
|
548
|
+
params: route.params,
|
|
549
|
+
layoutRouteName: route.layoutRouteName,
|
|
550
|
+
layoutBasePathname: route.layoutBasePathname,
|
|
551
|
+
};
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
private isRouteLikeOwnedByCurrentLayout(routeLike: LayoutRouteLike) {
|
|
555
|
+
if (routeLike.layoutRouteName) {
|
|
556
|
+
return routeLike.layoutRouteName === this.layout.routeName;
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
const layoutBasePathname = getDefaultBasePathnameFromRoutePath(this.layout.routePath);
|
|
560
|
+
if (routeLike.layoutBasePathname && layoutBasePathname) {
|
|
561
|
+
return normalizeBasePathname(routeLike.layoutBasePathname) === normalizeBasePathname(layoutBasePathname);
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
const routeName = routeLike.name || routeLike.id;
|
|
565
|
+
return this.isLayoutContentRoute(routeLike) || isLegacyLayoutContentRouteName(this.layout.routeName, routeName);
|
|
566
|
+
}
|
|
443
567
|
}
|
|
444
568
|
|
|
445
569
|
/**
|