@equinor/fusion-framework-dev-portal 8.0.3 → 9.0.0
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/CHANGELOG.md +25 -0
- package/README.md +4 -3
- package/dist/main.js +20355 -20462
- package/package.json +27 -23
- package/src/Router.tsx +3 -6
- package/src/configure.ts +60 -19
- package/src/version.ts +1 -1
- package/tsconfig.json +3 -0
- package/tsconfig.tsbuildinfo +1 -1
- package/src/useAppContextNavigation.ts +0 -153
|
@@ -1,153 +0,0 @@
|
|
|
1
|
-
import { useCallback } from 'react';
|
|
2
|
-
|
|
3
|
-
import { useCurrentAppModules } from '@equinor/fusion-framework-react/app';
|
|
4
|
-
|
|
5
|
-
import type {
|
|
6
|
-
ContextItem,
|
|
7
|
-
ContextModule,
|
|
8
|
-
IContextProvider,
|
|
9
|
-
} from '@equinor/fusion-framework-module-context';
|
|
10
|
-
import { extractContextIdFromPath } from '@equinor/fusion-framework-module-context/utils';
|
|
11
|
-
|
|
12
|
-
import type { NavigationModule } from '@equinor/fusion-framework-module-navigation';
|
|
13
|
-
|
|
14
|
-
import { useObservableSubscription } from '@equinor/fusion-observable/react';
|
|
15
|
-
import { EMPTY } from 'rxjs';
|
|
16
|
-
import { useFrameworkModule } from '@equinor/fusion-framework-react';
|
|
17
|
-
|
|
18
|
-
type CurrentAppModules = [ContextModule, NavigationModule];
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Builds the navigation pathname when the context changes.
|
|
22
|
-
*
|
|
23
|
-
* If a context ID already exists in the current pathname (`pathContextId`),
|
|
24
|
-
* it is replaced with the new context item's ID. Otherwise a new path
|
|
25
|
-
* segment is appended. Falls back to the context provider's
|
|
26
|
-
* `generatePathFromContext` when available.
|
|
27
|
-
*
|
|
28
|
-
* @param currentPathname - The current URL pathname.
|
|
29
|
-
* @param item - The newly selected context item.
|
|
30
|
-
* @param context - Optional context provider with a custom path generator.
|
|
31
|
-
* @param pathContextId - Existing context ID found in the current URL, if any.
|
|
32
|
-
* @returns The generated pathname string for navigation.
|
|
33
|
-
*/
|
|
34
|
-
const generatePathname = (
|
|
35
|
-
currentPathname: string,
|
|
36
|
-
item: ContextItem,
|
|
37
|
-
context?: IContextProvider,
|
|
38
|
-
pathContextId?: string,
|
|
39
|
-
) => {
|
|
40
|
-
// Replace an existing context id segment in the url when one is present
|
|
41
|
-
if (pathContextId) {
|
|
42
|
-
// context id exists in the url, replace it with the new context id
|
|
43
|
-
const pathname =
|
|
44
|
-
context?.generatePathFromContext?.(item, currentPathname) ??
|
|
45
|
-
currentPathname.replace(pathContextId, item.id);
|
|
46
|
-
|
|
47
|
-
console.debug(
|
|
48
|
-
`🌍 Portal: context changed, navigating to app's context url:`,
|
|
49
|
-
`found context id [${pathContextId}] in url, replacing with [${pathname}]`,
|
|
50
|
-
);
|
|
51
|
-
|
|
52
|
-
return pathname;
|
|
53
|
-
}
|
|
54
|
-
// could not find context id in the url, set the path to the new context id
|
|
55
|
-
const pathname = context?.generatePathFromContext?.(item, currentPathname) ?? `/${item?.id}`;
|
|
56
|
-
|
|
57
|
-
console.debug(
|
|
58
|
-
`🌍 Portal: context changed, navigating to app's context url:`,
|
|
59
|
-
`could not find context id in url, navigating to path [${pathname}]`,
|
|
60
|
-
);
|
|
61
|
-
|
|
62
|
-
return pathname;
|
|
63
|
-
};
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
* Observes the current application's context changes and synchronizes the URL.
|
|
67
|
-
*
|
|
68
|
-
* When the loaded app exposes both a context and navigation module, this hook
|
|
69
|
-
* subscribes to `currentContext$`. On context change it updates the URL
|
|
70
|
-
* pathname — either replacing an existing context ID segment or appending one.
|
|
71
|
-
* When context is cleared, navigation resets to the root path.
|
|
72
|
-
*
|
|
73
|
-
* Uses the app's own navigation instance when available, falling back to the
|
|
74
|
-
* portal-level navigation module.
|
|
75
|
-
*/
|
|
76
|
-
export const useAppContextNavigation = () => {
|
|
77
|
-
// use the framework navigation instance
|
|
78
|
-
const navigation = useFrameworkModule<NavigationModule>('navigation');
|
|
79
|
-
|
|
80
|
-
// use the current application modules
|
|
81
|
-
const { modules } = useCurrentAppModules<CurrentAppModules>();
|
|
82
|
-
// use the application context and navigation from the current application modules
|
|
83
|
-
const { context, navigation: appNavigation } = modules ?? {};
|
|
84
|
-
|
|
85
|
-
// subscribe to the context changes
|
|
86
|
-
useObservableSubscription(
|
|
87
|
-
// if the context is not available, use an empty observable
|
|
88
|
-
context?.currentContext$ ?? EMPTY,
|
|
89
|
-
// when the context changes, navigate to the new context
|
|
90
|
-
useCallback(
|
|
91
|
-
(item: ContextItem | undefined | null) => {
|
|
92
|
-
// sanity check, if the item or navigation is undefined, early return
|
|
93
|
-
if (item === undefined || navigation === undefined) {
|
|
94
|
-
return;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
// resolve the app base path (application base fragment of url)
|
|
98
|
-
const currentPathname = appNavigation
|
|
99
|
-
? // if the app has its own navigation, use it to resolve the app base path
|
|
100
|
-
appNavigation.path.pathname
|
|
101
|
-
: // if the app does not have its own navigation, use the portal navigation to resolve the app base path
|
|
102
|
-
navigation.path.pathname;
|
|
103
|
-
|
|
104
|
-
console.debug(
|
|
105
|
-
'🌍 Portal:',
|
|
106
|
-
appNavigation
|
|
107
|
-
? 'App has its own navigation, using it to navigate.'
|
|
108
|
-
: 'App does not have its own navigation, using portal navigation.',
|
|
109
|
-
);
|
|
110
|
-
|
|
111
|
-
/** context was cleared */
|
|
112
|
-
if (item === null) {
|
|
113
|
-
console.debug('🌍 Portal:', 'current context was cleared, navigating to root');
|
|
114
|
-
// Prefer the app's own navigation instance when it exists
|
|
115
|
-
if (appNavigation) {
|
|
116
|
-
appNavigation.replace('/');
|
|
117
|
-
} else {
|
|
118
|
-
navigation.replace('/');
|
|
119
|
-
}
|
|
120
|
-
return;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
const pathname = generatePathname(
|
|
124
|
-
currentPathname,
|
|
125
|
-
item,
|
|
126
|
-
context,
|
|
127
|
-
context?.extractContextIdFromPath?.(currentPathname) ??
|
|
128
|
-
extractContextIdFromPath(currentPathname),
|
|
129
|
-
);
|
|
130
|
-
|
|
131
|
-
// always navigate via the portal navigation to trigger the synthetic pop() workaround,
|
|
132
|
-
// ensuring app routers that listen only for POP actions detect the URL change
|
|
133
|
-
if (appNavigation) {
|
|
134
|
-
// resolve the full URL via the app navigation (includes app basename),
|
|
135
|
-
// then hand it to the portal navigation which will not double-prefix when basename is empty
|
|
136
|
-
const newUrl = appNavigation.createURL({ pathname });
|
|
137
|
-
navigation.navigate(newUrl, { replace: true });
|
|
138
|
-
} else {
|
|
139
|
-
// pass the pathname directly so navigation.navigate does not re-run createURL
|
|
140
|
-
// (which would duplicate the basename if one is configured)
|
|
141
|
-
navigation.navigate({ pathname }, { replace: true });
|
|
142
|
-
}
|
|
143
|
-
},
|
|
144
|
-
[
|
|
145
|
-
// framework navigation instance, should not change
|
|
146
|
-
navigation,
|
|
147
|
-
// application navigation instance, may change when the application changes
|
|
148
|
-
appNavigation,
|
|
149
|
-
context,
|
|
150
|
-
],
|
|
151
|
-
),
|
|
152
|
-
);
|
|
153
|
-
};
|