@luigi-project/core-modular 0.0.4 → 0.0.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.
@@ -1,15 +1,18 @@
1
1
  import { Luigi } from '../core-api/luigi';
2
2
  import { NavigationService } from '../services/navigation.service';
3
3
  import { RoutingService } from '../services/routing.service';
4
- import { ModalSettings } from '../types/navigation';
4
+ import { ModalSettings, Node } from '../types/navigation';
5
+ import { LuigiParams } from '../types/routing';
5
6
  export declare const UIModule: {
6
7
  navService: NavigationService;
7
8
  routingService: RoutingService;
8
9
  luigi: Luigi;
10
+ modalContainer: any;
11
+ drawerContainer: any;
9
12
  init: (luigi: Luigi) => void;
10
13
  update: (scopes?: string[]) => Promise<void>;
11
- updateMainContent: (currentNode: any, luigi: Luigi, withoutSync?: boolean, preventContextUpdate?: boolean) => Promise<void>;
12
- openModal: (luigi: Luigi, node: any, modalSettings: ModalSettings, onCloseCallback?: () => void) => Promise<void>;
14
+ updateMainContent: (currentNode: Node, luigi: Luigi, luigiParams?: LuigiParams, withoutSync?: boolean, preventContextUpdate?: boolean) => Promise<void>;
15
+ openModal: (luigi: Luigi, node: Node, modalSettings: ModalSettings, onCloseCallback?: () => void) => Promise<void>;
13
16
  updateModalSettings: (modalSettings: ModalSettings, addHistoryEntry: boolean, luigi: Luigi) => void;
14
- openDrawer: (luigi: Luigi, node: any, modalSettings: ModalSettings, onCloseCallback?: () => void) => Promise<void>;
17
+ openDrawer: (luigi: Luigi, node: Node, drawerSettings: ModalSettings, onCloseCallback?: () => void) => Promise<void>;
15
18
  };
@@ -1,11 +1,12 @@
1
1
  import { LuigiCompoundContainer, LuigiContainer } from '@luigi-project/container';
2
2
  import { Luigi } from '../core-api/luigi';
3
3
  export interface AlertSettings {
4
- text?: string;
5
- type?: string;
6
- links?: Record<string, Link>;
7
4
  closeAfter?: number;
8
5
  id?: string;
6
+ links?: Record<string, Link>;
7
+ text?: string;
8
+ ttl?: number;
9
+ type?: string;
9
10
  }
10
11
  export interface AlertHandler {
11
12
  openFromClient: boolean;
package/package.json CHANGED
@@ -18,5 +18,5 @@
18
18
  "micro-frontends",
19
19
  "microfrontends"
20
20
  ],
21
- "version": "0.0.4"
21
+ "version": "0.0.5"
22
22
  }
@@ -12,8 +12,7 @@ export declare class NavigationService {
12
12
  getPathData(path: string): Promise<PathData>;
13
13
  findMatchingNode(urlPathElement: string, nodes: Node[]): Node | undefined;
14
14
  buildNavItems(nodes: Node[], selectedNode: Node | undefined, pathData: PathData): NavItem[];
15
- shouldRedirect(path: string, pData?: PathData): Promise<string | undefined>;
16
- getCurrentNode(path: string): Promise<any>;
15
+ getCurrentNode(path: string): Promise<Node | undefined>;
17
16
  getPathParams(path: string): Promise<Record<string, any>>;
18
17
  /**
19
18
  * getTruncatedChildren
@@ -23,7 +22,7 @@ export declare class NavigationService {
23
22
  * @param array children
24
23
  * @returns array children
25
24
  */
26
- getTruncatedChildren(children: any): any[];
25
+ getTruncatedChildren(children: Node[]): Node[];
27
26
  applyNavGroups(items: NavItem[]): NavItem[];
28
27
  getLeftNavData(path: string, pData?: PathData): Promise<LeftNavData>;
29
28
  navItemClick(node: Node, pathData?: PathData): void;
@@ -103,7 +102,7 @@ export declare class NavigationService {
103
102
  * Builds a path string by concatenating path segments from the virtual tree root or the incoming path.
104
103
  *
105
104
  * @param incomingPath - The incoming path segment to be appended.
106
- * @param fromVirtualTreeRoot - A boolean indicating whether to build the path from the virtual tree root.
105
+ * @param options - The set of params related to navigation.
107
106
  * @returns The constructed path string.
108
107
  */
109
108
  buildPath(incomingPath: string, options: NavigationOptions): Promise<string>;
@@ -1,12 +1,7 @@
1
1
  import { Luigi } from '../core-api/luigi';
2
+ import { Route } from '../types/routing';
2
3
  import { ModalSettings, Node, PathData } from '../types/navigation';
3
4
  import { NavigationService } from './navigation.service';
4
- export interface Route {
5
- raw: string;
6
- node?: Node;
7
- path: string;
8
- nodeParams?: Record<string, string>;
9
- }
10
5
  export declare class RoutingService {
11
6
  private luigi;
12
7
  navigationService?: NavigationService;
@@ -110,4 +105,22 @@ export declare class RoutingService {
110
105
  */
111
106
  updateModalDataInUrl(modalPath: string, modalParams: ModalSettings, addHistoryEntry: boolean): void;
112
107
  checkInvalidateCache(previousPathData: PathData | undefined, newPath: string): void;
108
+ /**
109
+ * Deal with page not found scenario.
110
+ * @param {Object} nodeObject - the data of node
111
+ * @param {string} viewUrl - the url of the current mf view
112
+ * @param {Object} pathData - the information of current path
113
+ * @param {string} path - the path of the view to open
114
+ * @param {string} pathUrlRaw - path url without hash
115
+ * @returns {Promise<boolean>} A promise that resolves when page not found handling is complete.
116
+ */
117
+ handlePageNotFound(nodeObject: any, viewUrl: string, pathData: PathData, path: string, pathUrlRaw: string): Promise<boolean>;
118
+ /**
119
+ * Handle error for page not found scenario.
120
+ * @param {string} pathToRedirect - fallback path for redirection
121
+ * @param {string} notFoundPath - the path which cannot be found
122
+ * @param {boolean} isAnyPathMatched - is any path matched or not
123
+ * @returns {Promise<void>} A promise that resolves when error handling is complete.
124
+ */
125
+ showPageNotFoundError(pathToRedirect: string, notFoundPath: string, isAnyPathMatched?: boolean): Promise<void>;
113
126
  }
@@ -22,5 +22,11 @@ export interface LuigiConnector {
22
22
  getCurrentLocale(): string;
23
23
  updateModalSettings(modalSettings: ModalSettings): void;
24
24
  showFatalError(error: string): void;
25
+ getCoreAPISupportedElements(): {
26
+ getShellbarElement(): HTMLElement | null;
27
+ getShellbarActions(): HTMLElement | null;
28
+ getLuigiContainer(): HTMLElement | null;
29
+ getNavFooterContainer(): HTMLElement | null;
30
+ };
25
31
  }
26
32
  export type { Node };
@@ -59,18 +59,20 @@ export interface UserInfo {
59
59
  description?: string;
60
60
  }
61
61
  export interface LeftNavData {
62
- selectedNode: any;
62
+ selectedNode: Node;
63
63
  items: NavItem[];
64
64
  basePath: string;
65
65
  sideNavFooterText?: string;
66
66
  navClick?: (item: NavItem) => void;
67
67
  }
68
68
  export interface PathData {
69
+ context?: Record<string, any>;
69
70
  selectedNode?: Node;
70
71
  selectedNodeChildren?: Node[];
71
72
  nodesInPath?: Node[];
72
73
  rootNodes: Node[];
73
74
  pathParams: Record<string, any>;
75
+ matchedPath: string;
74
76
  }
75
77
  export interface RootNode {
76
78
  node: Node;
@@ -88,8 +90,10 @@ export interface Node {
88
90
  changeCurrentLocale?: boolean;
89
91
  urlParameters?: Record<string, any>;
90
92
  };
93
+ compound?: CompoundConfig;
91
94
  context?: Record<string, any>;
92
95
  drawer?: ModalSettings;
96
+ decodeViewUrl?: boolean;
93
97
  externalLink?: ExternalLink;
94
98
  hideFromNav?: boolean;
95
99
  hideSideNav?: boolean;
@@ -97,6 +101,9 @@ export interface Node {
97
101
  isRootNode?: boolean;
98
102
  keepSelectedForChildren?: boolean;
99
103
  label?: string;
104
+ loadingIndicator?: {
105
+ enabled: boolean;
106
+ };
100
107
  navigationContext?: string;
101
108
  onNodeActivation?: (node: Node) => boolean | void;
102
109
  openNodeInModal?: boolean;
@@ -106,9 +113,16 @@ export interface Node {
106
113
  runTimeErrorHandler?: RunTimeErrorHandler;
107
114
  tabNav?: boolean;
108
115
  tooltipText?: string;
116
+ userSettingsGroup?: string;
109
117
  viewUrl?: string;
110
118
  visibleForFeatureToggles?: string[];
111
119
  virtualTree?: boolean;
120
+ viewGroup?: string;
121
+ webcomponent?: boolean | {
122
+ type?: string;
123
+ selfRegistered?: boolean;
124
+ tagName?: string;
125
+ };
112
126
  _virtualTree?: Node;
113
127
  _virtualPathIndex?: number;
114
128
  _virtualViewUrl?: string;
@@ -182,6 +196,8 @@ export interface NavigationOptions {
182
196
  fromClosestContext?: boolean;
183
197
  fromVirtualTreeRoot?: boolean;
184
198
  fromParent?: boolean;
199
+ relative?: any;
200
+ nodeParams?: Record<string, any>;
185
201
  }
186
202
  export interface NavigationRequestBase {
187
203
  preventContextUpdate?: boolean;
@@ -190,6 +206,7 @@ export interface NavigationRequestBase {
190
206
  options?: NavigationOptions;
191
207
  }
192
208
  export interface NavigationRequestParams extends NavigationRequestBase {
209
+ drawerSettings?: any;
193
210
  modalSettings?: any;
194
211
  newTab?: boolean;
195
212
  path: string;
@@ -198,4 +215,208 @@ export interface NavigationRequestParams extends NavigationRequestBase {
198
215
  export interface NavigationRequestEvent {
199
216
  detail: NavigationRequestBase;
200
217
  }
218
+ /**
219
+ * Configuration for compound web components in Luigi.
220
+ * Compound allows you to layout multiple web components in one micro frontend.
221
+ */
222
+ export interface CompoundConfig {
223
+ /**
224
+ * Renderer configuration for the compound layout
225
+ */
226
+ renderer?: {
227
+ /**
228
+ * The renderer to use - can be 'grid', a custom renderer object, or undefined for default
229
+ */
230
+ use?: 'grid' | string | {
231
+ /**
232
+ * Base renderer to extend (e.g., 'grid')
233
+ */
234
+ extends?: string;
235
+ /**
236
+ * Custom function to create the compound container
237
+ * @param config - The renderer configuration
238
+ * @param renderer - The parent/super renderer (if extending)
239
+ */
240
+ createCompoundContainer?: (config: RendererConfig, renderer?: any) => HTMLDivElement;
241
+ /**
242
+ * Custom function to create individual compound item containers
243
+ * @param layoutConfig - Layout configuration for the item
244
+ * @param config - The overall renderer configuration
245
+ * @param renderer - The parent/super renderer (if extending)
246
+ */
247
+ createCompoundItemContainer?: (layoutConfig?: LayoutConfig, config?: RendererConfig, renderer?: any) => HTMLDivElement;
248
+ /**
249
+ * Custom function to attach an item to the compound container
250
+ * @param compoundCnt - The compound container element
251
+ * @param compoundItemCnt - The item container to attach
252
+ * @param renderer - The parent/super renderer (if extending)
253
+ */
254
+ attachCompoundItem?: (compoundCnt: HTMLElement, compoundItemCnt: HTMLElement, renderer?: any) => void;
255
+ };
256
+ /**
257
+ * Configuration for the grid layout
258
+ */
259
+ config?: {
260
+ /**
261
+ * CSS grid-template-columns value (e.g., '1fr 2fr')
262
+ */
263
+ columns?: string;
264
+ /**
265
+ * CSS grid-template-rows value (e.g., '150px 150px')
266
+ */
267
+ rows?: string;
268
+ /**
269
+ * CSS grid-gap value (e.g., 'auto', '10px')
270
+ */
271
+ gap?: string;
272
+ /**
273
+ * Minimum height for the grid container
274
+ */
275
+ minHeight?: string;
276
+ /**
277
+ * Responsive layout configurations for different viewport sizes
278
+ */
279
+ layouts?: Array<{
280
+ /**
281
+ * CSS grid-template-columns for this breakpoint
282
+ */
283
+ columns?: string | number;
284
+ /**
285
+ * CSS grid-template-rows for this breakpoint
286
+ */
287
+ rows?: string | number;
288
+ /**
289
+ * CSS grid-gap for this breakpoint
290
+ */
291
+ gap?: string | number;
292
+ /**
293
+ * Minimum viewport width for this layout (in pixels)
294
+ */
295
+ minWidth?: number;
296
+ /**
297
+ * Maximum viewport width for this layout (in pixels)
298
+ */
299
+ maxWidth?: number;
300
+ }>;
301
+ };
302
+ };
303
+ /**
304
+ * Lazy loading configuration for compound children
305
+ */
306
+ lazyLoadingOptions?: {
307
+ /**
308
+ * Enable lazy loading using IntersectionObserver
309
+ * @default false
310
+ */
311
+ enabled?: boolean;
312
+ /**
313
+ * IntersectionObserver rootMargin option
314
+ * Controls when children are loaded relative to viewport visibility
315
+ * @default "0px"
316
+ */
317
+ intersectionRootMargin?: string;
318
+ /**
319
+ * Default temporary height for child containers before they load
320
+ * @default "500px"
321
+ */
322
+ temporaryContainerHeight?: string;
323
+ /**
324
+ * Disable automatic temporary container heights
325
+ * Useful for custom renderers that manage heights themselves
326
+ * @default false
327
+ */
328
+ noTemporaryContainerHeight?: boolean;
329
+ };
330
+ /**
331
+ * Array of child web component configurations
332
+ */
333
+ children?: Array<{
334
+ /**
335
+ * Unique identifier for this child web component
336
+ */
337
+ id: string;
338
+ /**
339
+ * URL pointing to the web component JavaScript file
340
+ * Supports {i18n.currentLocale} placeholder for localization
341
+ */
342
+ viewUrl: string;
343
+ /**
344
+ * Context object passed to the web component
345
+ */
346
+ context?: Record<string, any>;
347
+ /**
348
+ * Layout configuration for positioning this child
349
+ */
350
+ layoutConfig?: {
351
+ /**
352
+ * CSS grid-row value (e.g., '1 / 3', 'auto')
353
+ * @default "auto"
354
+ */
355
+ row?: string;
356
+ /**
357
+ * CSS grid-column value (e.g., '1 / -1', 'auto')
358
+ * @default "auto"
359
+ */
360
+ column?: string;
361
+ /**
362
+ * Slot name for nested web components
363
+ * Use this instead of row/column to plug into a parent's slot
364
+ */
365
+ slot?: string;
366
+ /**
367
+ * Override the default temporary container height for this specific child
368
+ * Only used when lazy loading is enabled
369
+ * * @default undefined
370
+ */
371
+ temporaryContainerHeight?: string;
372
+ };
373
+ /**
374
+ * Event listeners for cross-component communication via event bus
375
+ */
376
+ eventListeners?: Array<{
377
+ /**
378
+ * ID of the source web component (use '*' for any source)
379
+ */
380
+ source: string;
381
+ /**
382
+ * Name of the event to listen for
383
+ */
384
+ name: string;
385
+ /**
386
+ * Type of action to perform (e.g., 'update')
387
+ */
388
+ action: string;
389
+ /**
390
+ * Optional function to convert event data before passing to listener
391
+ * @param data - The event data
392
+ */
393
+ dataConverter?: (data: any) => any;
394
+ }>;
395
+ }>;
396
+ }
397
+ /**
398
+ * Supporting type for layout configuration
399
+ */
400
+ export interface LayoutConfig {
401
+ column?: string;
402
+ row?: string;
403
+ slot?: string;
404
+ temporaryContainerHeight?: string;
405
+ }
406
+ /**
407
+ * Supporting type for renderer configuration
408
+ */
409
+ export interface RendererConfig {
410
+ columns?: string;
411
+ rows?: string;
412
+ gap?: string;
413
+ minHeight?: string;
414
+ layouts?: Array<{
415
+ columns?: string;
416
+ rows?: string;
417
+ gap?: string | number;
418
+ minWidth?: number;
419
+ maxWidth?: number;
420
+ }>;
421
+ }
201
422
  export type HistoryMethod = 'pushState' | 'replaceState';
@@ -0,0 +1,12 @@
1
+ import { Node } from './navigation';
2
+ export interface Route {
3
+ raw: string;
4
+ node?: Node;
5
+ path: string;
6
+ nodeParams?: Record<string, string>;
7
+ }
8
+ export interface LuigiParams {
9
+ nodeParams: Record<string, any> | {};
10
+ pathParams: Record<string, any> | {};
11
+ searchParams: Record<string, any> | {};
12
+ }
@@ -35,15 +35,39 @@ export declare const GenericHelpers: {
35
35
  * @returns {boolean}
36
36
  */
37
37
  isObject: (objectToCheck: object | any) => boolean;
38
+ /**
39
+ * Checks if a given input string begins a hash with slash
40
+ * @param {string} path
41
+ * @returns {boolean}
42
+ */
43
+ hasHash: (path: string) => boolean;
44
+ /**
45
+ * Removes leading hash of a string
46
+ * @param {string} path
47
+ * @returns {string}
48
+ */
49
+ getPathWithoutHash: (path: string) => string;
50
+ /**
51
+ * Removes any trailing slash of a string
52
+ * @param {string} path
53
+ * @returns {string}
54
+ */
55
+ getTrimmedUrl: (path: string) => string;
56
+ /**
57
+ * Adds a leading slash to a string if it has none
58
+ * @param {string} str string to be checked
59
+ * @returns {string} string with a leading slash
60
+ */
61
+ addLeadingSlash: (str: string) => string;
38
62
  /**
39
63
  * Removes leading slash of a string
40
- * @param {str} string
64
+ * @param {string} str string to be checked
41
65
  * @returns {string} string without leading slash
42
66
  */
43
67
  trimLeadingSlash: (str: string) => string;
44
68
  /**
45
69
  * Prepend current url to redirect_uri, if it is a relative path
46
- * @param {str} string from which any number of trailing slashes should be removed
70
+ * @param {string} str string from which any number of trailing slashes should be removed
47
71
  * @returns {string} string without any trailing slash
48
72
  */
49
73
  trimTrailingSlash: (str: string) => string;
@@ -0,0 +1,18 @@
1
+ import { Luigi } from '../../core-api/luigi';
2
+ export type MicrofrontendEntry = {
3
+ iframe: HTMLElement;
4
+ id: string;
5
+ active: boolean;
6
+ };
7
+ export type MicrofrontendInDom = {
8
+ container: HTMLElement;
9
+ active: boolean;
10
+ type: 'main' | 'modal' | 'drawer';
11
+ id: string;
12
+ };
13
+ export declare const LuigiContainerHelpers: {
14
+ getMicrofrontendsInDom(luigi: Luigi): MicrofrontendInDom[];
15
+ getMainMicrofrontends(luigi: Luigi): MicrofrontendEntry[];
16
+ getModalMicrofrontends(): MicrofrontendEntry[];
17
+ getDrawerMicrofrontends(): MicrofrontendEntry;
18
+ };
@@ -6,8 +6,9 @@ export declare const NavigationHelpers: {
6
6
  segmentMatches: (linkSegment: string, pathSegment: string, pathParams: Record<string, any>) => boolean;
7
7
  checkMatch: (route: string, nodesInPath: Array<any>, pathParams?: Record<string, any>) => boolean;
8
8
  checkVisibleForFeatureToggles: (nodeToCheckPermission: any, featureToggles: FeatureToggles) => boolean;
9
- generateTooltipText: (node: any, translation: string, luigi: Luigi) => string;
9
+ generateTooltipText: (node: Node, translation: string, luigi: Luigi) => string;
10
10
  isNodeAccessPermitted: (nodeToCheckPermissionFor: Node, parentNode: Node | undefined, currentContext: Record<string, any>, luigi: Luigi) => boolean;
11
+ applyContext: (context: Record<string, any>, addition: Record<string, any>, navigationContext: any) => Record<string, any>;
11
12
  updateHeaderTitle: (appSwitcherData: AppSwitcher, pathData: PathData) => string | undefined;
12
13
  buildPath(pathToLeftNavParent: Node[], pathData?: PathData): string;
13
14
  mergeContext(...objs: Record<string, any>[]): Record<string, any>;
@@ -18,4 +19,12 @@ export declare const NavigationHelpers: {
18
19
  * @returns The virtual tree root node if found, otherwise undefined.
19
20
  */
20
21
  findVirtualTreeRootNode(node: Node): Node | undefined;
22
+ /**
23
+ * Validates if a path exists and handles page not found cases.
24
+ * Returns the redirect path if valid, or undefined if the path should not be followed.
25
+ * @param path The path to validate
26
+ * @param luigi The Luigi instance
27
+ * @returns The redirect path if valid, undefined otherwise
28
+ */
29
+ validatePathAndGetRedirect: (path: string, luigi: Luigi) => Promise<string | undefined>;
21
30
  };
@@ -262,6 +262,41 @@ export declare const RoutingHelpers: {
262
262
  * @param {*} pathParams
263
263
  */
264
264
  getDynamicNodeValue(node: Node, pathParams: Record<string, string>): string | undefined;
265
+ /**
266
+ * Checks if given path is an existing route or not
267
+ * @param {string} activePath - path to be checked
268
+ * @param {PathData} pathData - related path data
269
+ * @returns {boolean} the result of path checking as boolean value
270
+ */
271
+ isExistingRoute(activePath: string, pathData: PathData): boolean;
272
+ /**
273
+ * Handles case if path exists or not.
274
+ * @param {string} path - the path to be checked
275
+ * @param {Luigi} luigi - the Luigi instance used to access configuration values
276
+ * @returns {Promise<boolean>} the result of path checking as async boolean value
277
+ */
278
+ pathExists(path: string, luigi: Luigi): Promise<boolean>;
279
+ showRouteNotFoundAlert(path: string, isAnyPathMatched: boolean | undefined, luigi: Luigi): void;
280
+ /**
281
+ * Queries the pageNotFoundHandler configuration and returns redirect path if it exists
282
+ * If the there is no `pageNotFoundHandler` defined we return undefined.
283
+ * @param {string} notFoundPath - the path to be checked
284
+ * @param {boolean} isAnyPathMatched - is any path matched or not
285
+ * @param {Luigi} luigi - the Luigi instance used to access config value
286
+ * @returns {Object} an object optionally containing the path to redirect, the keepURL option or an empty object if handler is undefined
287
+ */
288
+ getPageNotFoundRedirectResult(notFoundPath: string, isAnyPathMatched: boolean | undefined, luigi: Luigi): object;
289
+ /**
290
+ * Handles pageNotFound situation depending if path exists or not.
291
+ * If path exists simply return the given path, else fetch the pageNotFound redirect path and return it.
292
+ * In case there was no pageNotFound handler defined it shows an alert and returns undefined.
293
+ * @param {string} path - the path to check for
294
+ * @param {boolean} pathExists - defines if path exists or not
295
+ * @param {Luigi} luigi - the Luigi instance used to access configuration values
296
+ * @returns {} the path to redirect to or undefined if path doesn't exist and no redirect path is defined
297
+ */
298
+ handlePageNotFoundAndRetrieveRedirectPath(path: string, pathExists: boolean, luigi: Luigi): Promise<string | undefined>;
299
+ getDefaultChildNode(pathData: PathData, childrenResolverFn?: (lastElement: object, pathContext: object) => any): Promise<string>;
265
300
  /**
266
301
  * Recursively constructs the full path for a given node by concatenating its path segment with those of its ancestors.
267
302
  * If `params` are provided, they are appended as query parameters to the final path.