@openmfp/portal-ui-lib 0.189.5 → 0.190.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/README.md
CHANGED
|
@@ -22,22 +22,9 @@ The main features of this library are:
|
|
|
22
22
|
- [Angular Configuration](#angular-configuration)
|
|
23
23
|
- [Import the Portal providers and Bootstrap the app with PortalComponent](#import-the-portal-providers-and-bootstrap-the-app-with-portalcomponent)
|
|
24
24
|
- [Update index html file of the project](#update-index-html-file-of-the-project)
|
|
25
|
-
- [Implement the Custom
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
- [The luigiExtendedGlobalContextConfigService Option](#the-luigiextendedglobalcontextconfigservice-option)
|
|
29
|
-
- [The userSettingsConfigService Option](#the-usersettingsconfigservice-option)
|
|
30
|
-
- [The globalSearchConfigService option](#the-globalsearchconfigservice-option)
|
|
31
|
-
- [The luigiBreadcrumbConfigService Option](#the-headerBarConfigService-option)
|
|
32
|
-
- [The userProfileConfigService Option](#the-userprofileconfigservice-option)
|
|
33
|
-
- [Functional Services](#functional-services)
|
|
34
|
-
- [The luigiAuthEventsCallbacksService Option](#the-luigiautheventscallbacksservice-option)
|
|
35
|
-
- [The customMessageListeners Option](#the-custommessagelisteners-option)
|
|
36
|
-
- [The customGlobalNodesService Option](#the-customglobalnodesservice-option)
|
|
37
|
-
- [The navigationRedirectStrategy Option](#the-navigationredirectstrategy-option)
|
|
38
|
-
- [Listen and react to Authentication Events](#listen-and-react-to-authentication-events)
|
|
39
|
-
- [Configure Proxy for Backend REST Calls](#configure-proxy-for-backend-rest-calls)
|
|
40
|
-
- [Start your Project](#start-your-project)
|
|
25
|
+
- [Implement the Custom Services](#implement-the-custom-services)
|
|
26
|
+
- [Configure Proxy for Backend REST Calls](#configure-proxy-for-backend-rest-calls)
|
|
27
|
+
- [Start your Project](#start-your-project)
|
|
41
28
|
- [Local Extension Development](#local-extension-development)
|
|
42
29
|
- [Requirements](#requirements)
|
|
43
30
|
- [Contributing](#contributing)
|
|
@@ -143,571 +130,13 @@ Below is an example:
|
|
|
143
130
|
```
|
|
144
131
|
|
|
145
132
|
|
|
133
|
+
### Implement the Custom Services
|
|
146
134
|
|
|
147
|
-
|
|
135
|
+
The library comes with a set of services that can be used to customize the portal behavior.
|
|
136
|
+
Please visit the [Frontend configuration - Extended Guide](https://openmfp.org/documentation/extended-guide/frontend-configuration/)
|
|
137
|
+
to get familiar with the configuration options and how to use them.
|
|
148
138
|
|
|
149
139
|
|
|
150
|
-
There are two types of services that are considered: Services that provide Luigi configuration (aka. Configuration Services) and services that provide or extend functionality (aka. Functional Services).
|
|
151
|
-
For each service there is a corresponding interface that you have to implement.
|
|
152
|
-
Afterward you provide your specific implementation in the `providePortal(portalOptions)` by placing it in the `portalOptions` object and thus make it available to the `Portal`.
|
|
153
|
-
|
|
154
|
-
### Configuration services
|
|
155
|
-
|
|
156
|
-
#### The staticSettingsConfigService Option
|
|
157
|
-
|
|
158
|
-
With this you can customize [Luigis general settings](https://docs.luigi-project.io/docs/general-settings) and override any defaults.
|
|
159
|
-
Make sure to return a valid Luigi configuration object.
|
|
160
|
-
|
|
161
|
-
```ts
|
|
162
|
-
import { StaticSettingsConfigService } from '@openmfp/portal-ui-lib';
|
|
163
|
-
|
|
164
|
-
export class StaticSettingsConfigServiceImpl
|
|
165
|
-
implements StaticSettingsConfigService
|
|
166
|
-
{
|
|
167
|
-
constructor() {}
|
|
168
|
-
|
|
169
|
-
getStaticSettingsConfig() {
|
|
170
|
-
const logo = 'assets/my-logo.svg';
|
|
171
|
-
|
|
172
|
-
return {
|
|
173
|
-
header: {
|
|
174
|
-
title: 'My App',
|
|
175
|
-
logo: logo,
|
|
176
|
-
favicon: logo,
|
|
177
|
-
},
|
|
178
|
-
appLoadingIndicator: {
|
|
179
|
-
hideAutomatically: false,
|
|
180
|
-
},
|
|
181
|
-
links: [{ title: 'OpemMFP', link: 'https://openmfp.org/' }],
|
|
182
|
-
// ... the rest of the configuration
|
|
183
|
-
};
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
```
|
|
187
|
-
|
|
188
|
-
The `getStaticSettingsConfig()` is called while [Luigi lifecycle hook luigiAfterInit](https://docs.luigi-project.io/docs/lifecycle-hooks?section=luigiafterinit).
|
|
189
|
-
The latter adds additional setup to the root of the Luigi configuration object.
|
|
190
|
-
|
|
191
|
-
In your `main.ts` you can provide your custom implementation like so:
|
|
192
|
-
|
|
193
|
-
```ts
|
|
194
|
-
const portalOptions: PortalOptions = {
|
|
195
|
-
staticSettingsConfigService: StaticSettingsConfigServiceImpl,
|
|
196
|
-
// ... other portal options
|
|
197
|
-
}
|
|
198
|
-
```
|
|
199
|
-
|
|
200
|
-
#### The routingConfigService Option
|
|
201
|
-
|
|
202
|
-
With this you can customize [Luigis routing settings](https://docs.luigi-project.io/docs/navigation-parameters-reference?section=routing-parameters) and override any defaults.
|
|
203
|
-
Make sure to return a valid Luigi configuration object.
|
|
204
|
-
|
|
205
|
-
```ts
|
|
206
|
-
import { Injectable, inject } from '@angular/core';
|
|
207
|
-
import { RoutingConfigService } from '@openmfp/portal-ui-lib';
|
|
208
|
-
|
|
209
|
-
@Injectable()
|
|
210
|
-
export class CustomRoutingConfigServiceImpl implements RoutingConfigService {
|
|
211
|
-
getInitialRoutingConfig(): any {
|
|
212
|
-
return {
|
|
213
|
-
useHashRouting: false,
|
|
214
|
-
showModalPathInUrl: false,
|
|
215
|
-
modalPathParam: 'modalPathParamDisabled',
|
|
216
|
-
skipRoutingForUrlPatterns: [/.*/],
|
|
217
|
-
pageNotFoundHandler: () => {},
|
|
218
|
-
};
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
getRoutingConfig(): any {
|
|
222
|
-
return {
|
|
223
|
-
useHashRouting: false,
|
|
224
|
-
showModalPathInUrl: true,
|
|
225
|
-
modalPathParam: 'modal',
|
|
226
|
-
pageNotFoundHandler: (
|
|
227
|
-
notFoundPath: string,
|
|
228
|
-
isAnyPathMatched: boolean,
|
|
229
|
-
) => {
|
|
230
|
-
return {
|
|
231
|
-
redirectTo: 'error/404',
|
|
232
|
-
keepURL: true,
|
|
233
|
-
};
|
|
234
|
-
},
|
|
235
|
-
};
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
```
|
|
239
|
-
|
|
240
|
-
The `getInitialRoutingConfig()` method is called while constructing the Luigi initial config object.
|
|
241
|
-
The `getRoutingConfig()` is called while [Luigi lifecycle hook luigiAfterInit](https://docs.luigi-project.io/docs/lifecycle-hooks?section=luigiafterinit).
|
|
242
|
-
The latter adds additional setup to the root of the Luigi configuration object.
|
|
243
|
-
|
|
244
|
-
In your `main.ts` you can provide your custom implementation like so:
|
|
245
|
-
|
|
246
|
-
```ts
|
|
247
|
-
const portalOptions: PortalOptions = {
|
|
248
|
-
routingConfigService: CustomRoutingConfigService,
|
|
249
|
-
// ... other portal options
|
|
250
|
-
}
|
|
251
|
-
```
|
|
252
|
-
|
|
253
|
-
#### The errorComponentConfig Option
|
|
254
|
-
|
|
255
|
-
With this option you can configure custom error handling when entity error occurs.
|
|
256
|
-
By default, the library shows an alert with the error message.
|
|
257
|
-
|
|
258
|
-
```ts
|
|
259
|
-
import { ErrorComponentConfig, EntityDefinition, LuigiNode } from '@openmfp/portal-ui-lib';
|
|
260
|
-
|
|
261
|
-
const errorComponentConfig: ErrorComponentConfig = {
|
|
262
|
-
handleEntityRetrievalError: (
|
|
263
|
-
entityDefinition: EntityDefinition,
|
|
264
|
-
errorCode: number,
|
|
265
|
-
additionalContext?: Record<string, string>,
|
|
266
|
-
): LuigiNode[] => {
|
|
267
|
-
if (errorCode === 404) {
|
|
268
|
-
return [
|
|
269
|
-
{
|
|
270
|
-
pathSegment: 'not-found',
|
|
271
|
-
label: 'Not Found',
|
|
272
|
-
viewUrl: '/assets/not-found.html',
|
|
273
|
-
},
|
|
274
|
-
];
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
return [
|
|
278
|
-
{
|
|
279
|
-
pathSegment: 'error',
|
|
280
|
-
label: 'Error',
|
|
281
|
-
viewUrl: `/assets/error.html?code=${errorCode}`,
|
|
282
|
-
},
|
|
283
|
-
];
|
|
284
|
-
},
|
|
285
|
-
};
|
|
286
|
-
```
|
|
287
|
-
The `handleEntityRetrievalError()` method is called when entity configuration retrieval fails. It receives the entity definition, HTTP error code, and optional additional context. Return an array of Luigi nodes to display instead of failed content.
|
|
288
|
-
|
|
289
|
-
In your `main.ts` you can provide your configuration like so:
|
|
290
|
-
|
|
291
|
-
```ts
|
|
292
|
-
const portalOptions: PortalOptions = {
|
|
293
|
-
errorComponentConfig: errorComponentConfig,
|
|
294
|
-
// ... other portal options
|
|
295
|
-
}
|
|
296
|
-
```
|
|
297
|
-
|
|
298
|
-
#### The luigiExtendedGlobalContextConfigService Option
|
|
299
|
-
|
|
300
|
-
By default, in the [Luigi's global context](https://docs.luigi-project.io/docs/navigation-parameters-reference?section=globalcontext) following data is set by the library and available:
|
|
301
|
-
|
|
302
|
-
```json
|
|
303
|
-
{
|
|
304
|
-
"portalContext": {...} ,
|
|
305
|
-
"portalBaseUrl": "portal base url",
|
|
306
|
-
"userId": "logged in user id",
|
|
307
|
-
"userEmail": "logged in user email",
|
|
308
|
-
"token": "id token of the logged in user"
|
|
309
|
-
}
|
|
310
|
-
```
|
|
311
|
-
|
|
312
|
-
With the `luigiExtendedGlobalContextConfigService` option you can define global data you want to be available alongside with the default values present.
|
|
313
|
-
The Luigi's global context is available afterwards in all the micro-frontends.
|
|
314
|
-
|
|
315
|
-
```ts
|
|
316
|
-
import { LuigiExtendedGlobalContextConfigService, LuigiNode } from '@openmfp/portal-ui-lib';
|
|
317
|
-
|
|
318
|
-
export class LuigiExtendedGlobalContextConfigServiceImpl implements LuigiExtendedGlobalContextConfigService {
|
|
319
|
-
|
|
320
|
-
async createLuigiExtendedGlobalContext(): Promise<ExtendedGlobalContext> {
|
|
321
|
-
|
|
322
|
-
return {
|
|
323
|
-
isLocal: true,
|
|
324
|
-
analyticsConfig: 'global',
|
|
325
|
-
};
|
|
326
|
-
}
|
|
327
|
-
}
|
|
328
|
-
```
|
|
329
|
-
|
|
330
|
-
In your `main.ts` you can provide your custom implementation like so:
|
|
331
|
-
|
|
332
|
-
```ts
|
|
333
|
-
const portalOptions: PortalOptions = {
|
|
334
|
-
luigiExtendedGlobalContextConfigService: LuigiExtendedGlobalContextConfigServiceImpl,
|
|
335
|
-
// ... other portal options
|
|
336
|
-
}
|
|
337
|
-
```
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
#### The userSettingsConfigService Option
|
|
341
|
-
|
|
342
|
-
With this you can define the [Luigi user settings and a corresponding userSettingGroups configuration](https://docs.luigi-project.io/docs/user-settings?section=user-settings)
|
|
343
|
-
Make sure to return a valid Luigi configuration object.
|
|
344
|
-
|
|
345
|
-
```ts
|
|
346
|
-
import { UserSettingsConfigService, LuigiNode } from '@openmfp/portal-ui-lib';
|
|
347
|
-
|
|
348
|
-
export class UserSettingsConfigServiceImpl implements UserSettingsConfigService {
|
|
349
|
-
|
|
350
|
-
async getUserSettings(childrenByEntity: Record<string, LuigiNode[]>) {
|
|
351
|
-
return {
|
|
352
|
-
userSettingsDialog: {
|
|
353
|
-
dialogHeader: 'User Settings',
|
|
354
|
-
},
|
|
355
|
-
userSettingGroups: {
|
|
356
|
-
// ...the rest of the configuration
|
|
357
|
-
}
|
|
358
|
-
// ...the rest of the configuration
|
|
359
|
-
}
|
|
360
|
-
}
|
|
361
|
-
}
|
|
362
|
-
```
|
|
363
|
-
|
|
364
|
-
In your `main.ts` you can provide your custom implementation like so:
|
|
365
|
-
|
|
366
|
-
```ts
|
|
367
|
-
const portalOptions: PortalOptions = {
|
|
368
|
-
userSettingsConfigService: UserSettingsConfigServiceImpl,
|
|
369
|
-
// ... other portal options
|
|
370
|
-
}
|
|
371
|
-
```
|
|
372
|
-
|
|
373
|
-
#### The globalSearchConfigService option
|
|
374
|
-
|
|
375
|
-
With this you have the possibility configure [Luigis global search element](https://docs.luigi-project.io/docs/global-search) with provided configuration and events handlers.
|
|
376
|
-
Make sure to return a valid Luigi configuration object.
|
|
377
|
-
|
|
378
|
-
```ts
|
|
379
|
-
import { GlobalSearchConfigService} from '@openmfp/portal-ui-lib';
|
|
380
|
-
|
|
381
|
-
export class GlobalSearchConfigServiceImpl implements GlobalSearchConfigService {
|
|
382
|
-
|
|
383
|
-
getGlobalSearchConfig() {
|
|
384
|
-
return {
|
|
385
|
-
searchFieldCentered: true,
|
|
386
|
-
searchProvider: {
|
|
387
|
-
onEnter: () => {
|
|
388
|
-
// ... handler implementation
|
|
389
|
-
},
|
|
390
|
-
onSearchBtnClick: () => {
|
|
391
|
-
// ... handler implementation
|
|
392
|
-
},
|
|
393
|
-
onEscape: () => {
|
|
394
|
-
// ... handler implementation
|
|
395
|
-
},
|
|
396
|
-
|
|
397
|
-
// ...the rest of the configuration
|
|
398
|
-
},
|
|
399
|
-
// ...the rest of the configuration
|
|
400
|
-
};
|
|
401
|
-
}
|
|
402
|
-
}
|
|
403
|
-
```
|
|
404
|
-
|
|
405
|
-
In your `main.ts` you can provide your custom implementation like so:
|
|
406
|
-
|
|
407
|
-
```ts
|
|
408
|
-
const portalOptions: PortalOptions = {
|
|
409
|
-
globalSearchConfigService: GlobalSearchConfigServiceImpl,
|
|
410
|
-
// ... other portal options
|
|
411
|
-
}
|
|
412
|
-
```
|
|
413
|
-
|
|
414
|
-
#### The headerBarConfigService Option
|
|
415
|
-
|
|
416
|
-
This enables you to define configiration for your header bar section. Under the hood It extends [Luigi breadcrumbs](https://docs.luigi-project.io/docs/navigation-advanced?section=breadcrumbs) by adding ability to provide multiple renderer functions
|
|
417
|
-
|
|
418
|
-
Make sure to return a valid HeaderBar configuration object.
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
```ts
|
|
422
|
-
import {
|
|
423
|
-
HeaderBarConfigService,
|
|
424
|
-
HeaderBarConfig,
|
|
425
|
-
} from '@openmfp/portal-ui-lib';
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
export class HeaderBarConfigServiceImpl implements HeaderBarConfigService
|
|
429
|
-
{
|
|
430
|
-
getBreadcrumbsConfig(): Promise<HeaderBarConfig> {
|
|
431
|
-
return {
|
|
432
|
-
autoHide: true,
|
|
433
|
-
omitRoot: false,
|
|
434
|
-
pendingItemLabel: '...',
|
|
435
|
-
rightRenderers: [(
|
|
436
|
-
containerElement: HTMLElement,
|
|
437
|
-
nodeItems: NodeItem[],
|
|
438
|
-
clickHandler,
|
|
439
|
-
) => {
|
|
440
|
-
// ... renderer implementation
|
|
441
|
-
}];
|
|
442
|
-
leftRenderers: [(
|
|
443
|
-
containerElement: HTMLElement,
|
|
444
|
-
nodeItems: NodeItem[],
|
|
445
|
-
clickHandler,
|
|
446
|
-
) => {
|
|
447
|
-
// ... renderer implementation
|
|
448
|
-
}];
|
|
449
|
-
};
|
|
450
|
-
}
|
|
451
|
-
}
|
|
452
|
-
```
|
|
453
|
-
|
|
454
|
-
In your `main.ts` you can provide your custom implementation like so:
|
|
455
|
-
|
|
456
|
-
```ts
|
|
457
|
-
const portalOptions: PortalOptions = {
|
|
458
|
-
headerBarConfigService: HeaderBarConfigServiceImpl,
|
|
459
|
-
// ... other portal options
|
|
460
|
-
}
|
|
461
|
-
```
|
|
462
|
-
|
|
463
|
-
#### The userProfileConfigService Option
|
|
464
|
-
|
|
465
|
-
This option allows you to define the [Luigi user profile](https://docs.luigi-project.io/docs/navigation-advanced?section=profile).
|
|
466
|
-
Make sure to return a valid Luigi configuration object.
|
|
467
|
-
|
|
468
|
-
```ts
|
|
469
|
-
import { UserProfileConfigService, UserProfile } from '@openmfp/portal-ui-lib';
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
export class UserProfileConfigServiceImpl implements UserProfileConfigService
|
|
473
|
-
{
|
|
474
|
-
async getProfile(): Promise<UserProfile> {
|
|
475
|
-
return {
|
|
476
|
-
logout: {
|
|
477
|
-
label: 'Sign out',
|
|
478
|
-
icon: 'log',
|
|
479
|
-
},
|
|
480
|
-
items: [
|
|
481
|
-
{
|
|
482
|
-
label: 'Overview',
|
|
483
|
-
icon: 'overview',
|
|
484
|
-
link: `/users/overview`,
|
|
485
|
-
},
|
|
486
|
-
],
|
|
487
|
-
};
|
|
488
|
-
}
|
|
489
|
-
}
|
|
490
|
-
```
|
|
491
|
-
|
|
492
|
-
In your `main.ts` you can provide your custom implementation like so:
|
|
493
|
-
|
|
494
|
-
```ts
|
|
495
|
-
const portalOptions: PortalOptions = {
|
|
496
|
-
userProfileConfigService: UserProfileConfigServiceImpl,
|
|
497
|
-
// ... other portal options
|
|
498
|
-
}
|
|
499
|
-
```
|
|
500
|
-
|
|
501
|
-
### Functional Services
|
|
502
|
-
|
|
503
|
-
#### The luigiAuthEventsCallbacksService Option
|
|
504
|
-
|
|
505
|
-
This option allows you to provide a service that listens to [Luigi authorization events](https://docs.luigi-project.io/docs/authorization-events)
|
|
506
|
-
Make sure to return a valid Luigi configuration object.
|
|
507
|
-
|
|
508
|
-
```ts
|
|
509
|
-
import { LuigiAuthEventsCallbacksService } from '@openmfp/portal-ui-lib';
|
|
510
|
-
|
|
511
|
-
export class LuigiAuthEventsCallbacksServiceImpl
|
|
512
|
-
implements LuigiAuthEventsCallbacksService {
|
|
513
|
-
|
|
514
|
-
onAuthSuccessful(settings: any, authData: any) {
|
|
515
|
-
concole.log('User succesfully authenticated.');
|
|
516
|
-
}
|
|
517
|
-
|
|
518
|
-
// ...
|
|
519
|
-
|
|
520
|
-
onLogout(settings: any) {
|
|
521
|
-
concole.log('User succesfully logged out.');
|
|
522
|
-
}
|
|
523
|
-
}
|
|
524
|
-
```
|
|
525
|
-
|
|
526
|
-
In your `main.ts` you can provide your custom implementation like so:
|
|
527
|
-
|
|
528
|
-
```ts
|
|
529
|
-
|
|
530
|
-
const portalOptions: PortalOptions = {
|
|
531
|
-
luigiAuthEventsCallbacksService: LuigiAuthEventsCallbacksServiceImpl,
|
|
532
|
-
// ... other portal options
|
|
533
|
-
}
|
|
534
|
-
```
|
|
535
|
-
|
|
536
|
-
#### The customMessageListeners Option
|
|
537
|
-
|
|
538
|
-
With this option it is possible to define listeners for [Luigi custom messages](https://docs.luigi-project.io/docs/communication?section=custom-messages).
|
|
539
|
-
|
|
540
|
-
Custom messages are sent from any part of your application to Luigi and then routed to any other micro frontend application in the same application.
|
|
541
|
-
A custom message is sent by using Luigi `sendCustomMessage({ id: 'unique.message.id'});` method (see also the following example).
|
|
542
|
-
|
|
543
|
-
```ts
|
|
544
|
-
import { inject, Injectable } from '@angular/core';
|
|
545
|
-
import { LuigiCoreService } from '@openmfp/portal-ui-lib';
|
|
546
|
-
|
|
547
|
-
@Injectable({ providedIn: 'root' })
|
|
548
|
-
export class MessageService {
|
|
549
|
-
private luigiCoreService: LuigiCoreService = inject(LuigiCoreService);
|
|
550
|
-
|
|
551
|
-
public sendMessage() {
|
|
552
|
-
this.luigiCoreService.sendCustomMessage({ id: 'unique.message.id' });
|
|
553
|
-
}
|
|
554
|
-
}
|
|
555
|
-
```
|
|
556
|
-
|
|
557
|
-
To react on such a message in your micro frontend, you have to provide a custom message listener.
|
|
558
|
-
You have to specify the corresponding message id you want to listen to.
|
|
559
|
-
If there is a match, the callback function `onCustomMessageReceived()` will be called.
|
|
560
|
-
Make sure to return a valid Luigi configuration object.
|
|
561
|
-
|
|
562
|
-
```ts
|
|
563
|
-
import { CustomMessageListener } from '@openmfp/portal-ui-lib';
|
|
564
|
-
|
|
565
|
-
export class CustomMessageListenerImpl
|
|
566
|
-
implements CustomMessageListener
|
|
567
|
-
{
|
|
568
|
-
messageId(): string {
|
|
569
|
-
return `unique.message.id`;
|
|
570
|
-
}
|
|
571
|
-
|
|
572
|
-
onCustomMessageReceived(
|
|
573
|
-
customMessage: string,
|
|
574
|
-
mfObject: any,
|
|
575
|
-
mfNodesObject: any,
|
|
576
|
-
): void {
|
|
577
|
-
// ... logic to be executed
|
|
578
|
-
}
|
|
579
|
-
}
|
|
580
|
-
```
|
|
581
|
-
|
|
582
|
-
In your `main.ts` you can provide your custom implementation like so:
|
|
583
|
-
|
|
584
|
-
```ts
|
|
585
|
-
const portalOptions: PortalOptions = {
|
|
586
|
-
customMessageListeners: [CustomMessageListenerImpl, CustomMessageListenerImpl2, ...],
|
|
587
|
-
// ... other portal options
|
|
588
|
-
}
|
|
589
|
-
```
|
|
590
|
-
|
|
591
|
-
#### The customGlobalNodesService Option
|
|
592
|
-
|
|
593
|
-
This option adds the possibility to define and add the global level Luigi nodes to your application.
|
|
594
|
-
|
|
595
|
-
```ts
|
|
596
|
-
import { LuigiNode, CustomGlobalNodesService } from '@openmfp/portal-ui-lib';
|
|
597
|
-
|
|
598
|
-
export class CustomGlobalNodesServiceImpl implements CustomGlobalNodesService {
|
|
599
|
-
|
|
600
|
-
async getCustomGlobalNodes(): Promise<LuigiNode[]> {
|
|
601
|
-
return [
|
|
602
|
-
this.createGlobalNode1(),
|
|
603
|
-
this.createGlobalNode2(),
|
|
604
|
-
// ...other globaL nodes
|
|
605
|
-
];
|
|
606
|
-
}
|
|
607
|
-
|
|
608
|
-
private async createGlobalNode1(): LuigiNode {
|
|
609
|
-
return {
|
|
610
|
-
label: 'Global 1',
|
|
611
|
-
entityType: 'global',
|
|
612
|
-
link: '/global_1',
|
|
613
|
-
// ... other luigi node properties
|
|
614
|
-
};
|
|
615
|
-
}
|
|
616
|
-
|
|
617
|
-
private createGlobalNode2(): LuigiNode {
|
|
618
|
-
return {
|
|
619
|
-
label: 'Global 2',
|
|
620
|
-
entityType: 'global.topnav',
|
|
621
|
-
viewUrl: '/global_2',
|
|
622
|
-
pathSegment: 'global_2',
|
|
623
|
-
// ... other luigi node properties
|
|
624
|
-
};
|
|
625
|
-
}
|
|
626
|
-
}
|
|
627
|
-
```
|
|
628
|
-
|
|
629
|
-
In your `main.ts` you can provide your custom implementation like so:
|
|
630
|
-
|
|
631
|
-
```ts
|
|
632
|
-
const portalOptions: PortalOptions = {
|
|
633
|
-
customGlobalNodesService: CustomGlobalNodesServiceImpl,
|
|
634
|
-
// ... other portal options
|
|
635
|
-
}
|
|
636
|
-
```
|
|
637
|
-
|
|
638
|
-
#### The navigationRedirectStrategy Option
|
|
639
|
-
|
|
640
|
-
This option allows you to customize where and how the portal stores the URL to redirect the user to after login (for example after session expiry or logout). By default the library uses `localStorage`. You can provide your own implementation of `NavigationRedirectStrategy` to use session storage, a backend, or custom logic.
|
|
641
|
-
|
|
642
|
-
```ts
|
|
643
|
-
import { Injectable } from '@angular/core';
|
|
644
|
-
import { NavigationRedirectStrategy } from '@openmfp/portal-ui-lib';
|
|
645
|
-
|
|
646
|
-
@Injectable()
|
|
647
|
-
export class CustomNavigationRedirectStrategy implements NavigationRedirectStrategy {
|
|
648
|
-
getRedirectUrl(): string {
|
|
649
|
-
return sessionStorage.getItem('returnUrl') || '/';
|
|
650
|
-
}
|
|
651
|
-
|
|
652
|
-
saveRedirectUrl(url: string): void {
|
|
653
|
-
sessionStorage.setItem('returnUrl', url);
|
|
654
|
-
}
|
|
655
|
-
|
|
656
|
-
clearRedirectUrl(): void {
|
|
657
|
-
sessionStorage.removeItem('returnUrl');
|
|
658
|
-
}
|
|
659
|
-
}
|
|
660
|
-
```
|
|
661
|
-
|
|
662
|
-
In your `main.ts` you can provide your custom implementation like so:
|
|
663
|
-
|
|
664
|
-
```ts
|
|
665
|
-
const portalOptions: PortalOptions = {
|
|
666
|
-
navigationRedirectStrategy: CustomNavigationRedirectStrategy,
|
|
667
|
-
// ... other portal options
|
|
668
|
-
}
|
|
669
|
-
```
|
|
670
|
-
|
|
671
|
-
### Listen and react to Authentication Events
|
|
672
|
-
|
|
673
|
-
There are following Authentication Events, to which the library consuming application can subscribe and react upon, in case required.
|
|
674
|
-
|
|
675
|
-
```ts
|
|
676
|
-
export enum AuthEvent {
|
|
677
|
-
AUTH_SUCCESSFUL = 'AuthSuccessful',
|
|
678
|
-
AUTH_ERROR = 'AuthError',
|
|
679
|
-
AUTH_EXPIRED = 'AuthExpired',
|
|
680
|
-
AUTH_REFRESHED = 'AuthRefreshed',
|
|
681
|
-
AUTH_EXPIRE_SOON = 'AuthExpireSoon',
|
|
682
|
-
AUTH_CONFIG_ERROR = 'AuthConfigError',
|
|
683
|
-
LOGOUT = 'Logout',
|
|
684
|
-
}
|
|
685
|
-
```
|
|
686
|
-
Below is an example of reacting to `AuthEvent.AUTH_SUCCESSFUL`
|
|
687
|
-
|
|
688
|
-
```ts
|
|
689
|
-
import { AuthEvent, AuthService } from '@openmfp/portal-ui-lib';
|
|
690
|
-
import { filter } from 'rxjs';
|
|
691
|
-
import { MyService } from '../services';
|
|
692
|
-
|
|
693
|
-
export function actWhenUserAuthSuccedsful(
|
|
694
|
-
myService: MyService,
|
|
695
|
-
authService: AuthService,
|
|
696
|
-
): () => void {
|
|
697
|
-
return () => {
|
|
698
|
-
authService.authEvents
|
|
699
|
-
.pipe(
|
|
700
|
-
filter((event: AuthEvent) => event === AuthEvent.AUTH_SUCCESSFUL),
|
|
701
|
-
)
|
|
702
|
-
.subscribe({
|
|
703
|
-
next: (event: AuthEvent) => {
|
|
704
|
-
myService.act();
|
|
705
|
-
},
|
|
706
|
-
});
|
|
707
|
-
};
|
|
708
|
-
}
|
|
709
|
-
```
|
|
710
|
-
|
|
711
140
|
### Configure Proxy for Backend REST Calls
|
|
712
141
|
|
|
713
142
|
The library executes rest calls `"/rest/**"` against backend running with the library [portal-server-lib](https://github.com/openmfp/portal-server-lib?tab=readme-ov-file#portal-server-library).
|