Skip to content

Commit de3f756

Browse files
feat: extended user guide frontend (#113)
* Documentation for service provider service * Documentation for entity context providers * Documentation for portal context provider * Documentation for frontendDistSources * Documentation for frontendDistSources * Documentation for health check * Documentation for env variables service * Documentation for portal extensions * Documentation for auth config * Documentation for portal extensions - frontend part * Documentation for portal extensions - frontend part - luigi routing settings * Documentation for portal extensions - frontend part - luigi routing settings * Documentation for portal extensions - frontend part - message listeners * global search * global context part * global nodes part * global nodes part * user profile part * header bar settings * auth callbacks * error handling * Add docs for `nodeContextProcessingService` * Add docs for `nodeChangeHook` * Add docs for `CustomNodeProcessingService` --------- Co-authored-by: Grzegorz Krajniak <[email protected]>
1 parent 65c0955 commit de3f756

17 files changed

+1179
-109
lines changed

.vitepress/config.mts

Lines changed: 56 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -128,8 +128,62 @@ export default withMermaid({
128128
],
129129
},
130130
{
131-
text: "Registering a Microfrontend",
132-
link: "/documentation/extended-guide/register-microfrontend",
131+
text: "Frontend configuration",
132+
link: "/documentation/extended-guide/frontend-configuration/",
133+
items: [
134+
{
135+
text: "Luigi general settings",
136+
link: "/documentation/extended-guide/frontend-configuration/general-settings",
137+
},
138+
{
139+
text: "Luigi routing settings",
140+
link: "/documentation/extended-guide/frontend-configuration/routing-settings",
141+
},
142+
{
143+
text: "Node change hook settings",
144+
link: "/documentation/extended-guide/frontend-configuration/node-change-hook-settings",
145+
},
146+
{
147+
text: "Global search settings",
148+
link: "/documentation/extended-guide/frontend-configuration/global-search-settings",
149+
},
150+
{
151+
text: "Header bar settings",
152+
link: "/documentation/extended-guide/frontend-configuration/header-bar-settings",
153+
},
154+
{
155+
text: "User profile settings",
156+
link: "/documentation/extended-guide/frontend-configuration/user-profile-settings",
157+
},
158+
{
159+
text: "Custom message listeners",
160+
link: "/documentation/extended-guide/frontend-configuration/message-listeners",
161+
},
162+
{
163+
text: "Error component config",
164+
link: "/documentation/extended-guide/frontend-configuration/error-config",
165+
},
166+
{
167+
text: "Authorization events",
168+
link: "/documentation/extended-guide/frontend-configuration/luigi-auth-callbacks-settings",
169+
},
170+
{
171+
text: "Luigi global context",
172+
link: "/documentation/extended-guide/frontend-configuration/luigi-global-context",
173+
},
174+
{
175+
text: "Luigi node context",
176+
link: "/documentation/extended-guide/frontend-configuration/luigi-node-context",
177+
},
178+
{
179+
text: "Luigi node processing",
180+
link: "/documentation/extended-guide/frontend-configuration/node-processing",
181+
},
182+
{
183+
text: "Global nodes",
184+
link: "/documentation/extended-guide/frontend-configuration/global-nodes",
185+
},
186+
],
133187
},
134188
{
135189
text: "Content Configuration",

documentation/extended-guide/backend-configuration/index.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# Backend configuration
22

3-
The nest.js backend module is designed to accept a set of configurations,
4-
allowing you to customize it to your needs and infrastructure.
3+
The nest.js backend module available in **openmfp/portal-server-lib** is designed to accept a set of
4+
configurations, allowing you to customize it to your needs and infrastructure.
55

66
In this guide, you’ll learn:
77

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
# Customizing Entity Error Handling
2+
3+
The `errorComponentConfig` option allows you to define custom navigation
4+
behavior when the library fails to retrieve an entity configuration.
5+
By default, the library displays a simple alert with the error message.
6+
By providing this configuration,
7+
you can instead redirect users to custom error pages or "not found" views.
8+
9+
## ErrorComponentConfig Interface
10+
11+
```ts
12+
export interface ErrorComponentConfig {
13+
/**
14+
* Triggered when an entity configuration retrieval fails.
15+
* @param entityDefinition The definition of the entity that failed to load.
16+
* @param errorCode The HTTP status code returned by the server (e.g., 404, 500).
17+
* @param additionalContext Optional metadata regarding the failure.
18+
* @returns An array of LuigiNode objects to be displayed as a fallback.
19+
*/
20+
handleEntityRetrievalError(
21+
entityDefinition: EntityDefinition,
22+
errorCode: number,
23+
additionalContext?: Record<string, string>,
24+
): LuigiNode[];
25+
}
26+
```
27+
28+
## Provide your implemented service
29+
30+
```ts
31+
import { ErrorComponentConfig, EntityDefinition, LuigiNode } from '@openmfp/portal-ui-lib';
32+
33+
const errorComponentConfig: ErrorComponentConfig = {
34+
handleEntityRetrievalError: (
35+
entityDefinition: EntityDefinition,
36+
errorCode: number,
37+
additionalContext?: Record<string, string>,
38+
): LuigiNode[] => {
39+
if (errorCode === 404) {
40+
return [
41+
{
42+
pathSegment: 'not-found',
43+
label: 'Not Found',
44+
viewUrl: '/assets/not-found.html',
45+
},
46+
];
47+
}
48+
49+
return [
50+
{
51+
pathSegment: 'error',
52+
label: 'Error',
53+
viewUrl: `/assets/error.html?code=${errorCode}`,
54+
},
55+
];
56+
},
57+
};
58+
```
59+
60+
## Registering the service during application bootstrap
61+
62+
```ts
63+
import { bootstrapApplication } from '@angular/platform-browser';
64+
import {
65+
PortalComponent,
66+
PortalOptions,
67+
providePortal,
68+
} from '@openmfp/portal-ui-lib';
69+
import { errorComponentConfig } from './error-config';
70+
71+
const portalOptions: PortalOptions = {
72+
// Pass the configuration object directly
73+
errorComponentConfig: errorComponentConfig,
74+
// ... other portal options
75+
};
76+
77+
bootstrapApplication(PortalComponent, {
78+
providers: [providePortal(portalOptions)],
79+
}).catch((err) => console.error(err));
80+
81+
```
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
# Customizing Static Luigi Settings
2+
3+
To customize the general UI settings provided by the underlying Luigi framework,
4+
you must implement the `StaticSettingsConfigService` interface and provide your custom service
5+
during the application bootstrap. This service allows you to override any default
6+
[Luigi general settings](https://docs.luigi-project.io/docs/general-settings)
7+
(like the header title, logo, or loading behavior).
8+
9+
## StaticSettingsConfigService Interface
10+
11+
The interface is defined as follows:
12+
13+
```ts
14+
export interface StaticSettingsConfigService {
15+
getStaticSettingsConfig(): Promise<LuigiStaticSettings>;
16+
}
17+
```
18+
19+
## Provide your implemented service
20+
21+
```ts
22+
import { StaticSettingsConfigService } from '@openmfp/portal-ui-lib';
23+
24+
export class StaticSettingsConfigServiceImpl
25+
implements StaticSettingsConfigService
26+
{
27+
constructor() {}
28+
29+
getStaticSettingsConfig(): Promise<LuigiStaticSettings> {
30+
const logo = 'assets/my-logo.svg';
31+
32+
return {
33+
header: {
34+
title: 'My App',
35+
logo: logo,
36+
favicon: logo,
37+
},
38+
appLoadingIndicator: {
39+
hideAutomatically: false,
40+
},
41+
links: [{ title: 'OpemMFP', link: 'https://openmfp.org/' }],
42+
// ... the rest of the configuration
43+
};
44+
}
45+
}
46+
```
47+
48+
## Registering the service during application bootstrap
49+
50+
```ts
51+
import { bootstrapApplication } from '@angular/platform-browser';
52+
import {
53+
PortalComponent,
54+
PortalOptions,
55+
providePortal,
56+
} from '@openmfp/portal-ui-lib';
57+
import { StaticSettingsConfigServiceImpl } from './static-settings-config.service'; // Import your new service
58+
59+
const portalOptions: PortalOptions = {
60+
// Reference the service class here. The Portal UI Library will instantiate it.
61+
staticSettingsConfigService: StaticSettingsConfigServiceImpl,
62+
};
63+
64+
bootstrapApplication(PortalComponent, {
65+
providers: [providePortal(portalOptions)],
66+
}).catch((err) => console.error(err));
67+
```
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
# Defining Custom Global Nodes
2+
3+
The `customGlobalNodesService` option allows you to define and inject global-level Luigi Nodes into
4+
your application. These nodes are typically used for top-navigation items or
5+
global utility links that remain accessible regardless of the current micro-frontend context.
6+
7+
## CustomGlobalNodesService Interface
8+
9+
The `CustomGlobalNodesService` interface requires an asynchronous method that returns an array of LuigiNode objects.
10+
11+
```ts
12+
export interface CustomGlobalNodesService {
13+
/**
14+
* Returns a Promise resolving to an array of LuigiNode objects
15+
* to be added to the global navigation level.
16+
*/
17+
getCustomGlobalNodes(): Promise<LuigiNode[]>;
18+
}
19+
```
20+
21+
## Provide your implemented service
22+
23+
In your implementation, you can define nodes that point to external links or internal view URLs. You can also
24+
define specific entityType properties to control where these nodes appear in the Luigi shell.
25+
26+
```ts
27+
import {
28+
LuigiNode,
29+
CustomGlobalNodesService
30+
} from '@openmfp/portal-ui-lib';
31+
import { Injectable } from '@angular/core';
32+
33+
@Injectable()
34+
export class CustomGlobalNodesServiceImpl implements CustomGlobalNodesService {
35+
36+
/**
37+
* Orchestrates the creation of global nodes.
38+
*/
39+
async getCustomGlobalNodes(): Promise<LuigiNode[]> {
40+
return [
41+
this.createHelpCenterNode(),
42+
this.createSettingsNode(),
43+
];
44+
}
45+
46+
private createHelpCenterNode(): LuigiNode {
47+
return {
48+
label: 'Help Center',
49+
entityType: 'global.topnav', // Categorizes the node for top navigation
50+
url: '[https://docs.example.com](https://docs.example.com)',
51+
// ... other luigi node properties
52+
};
53+
}
54+
55+
private createSettingsNode(): LuigiNode {
56+
return {
57+
label: 'Global Settings',
58+
entityType: 'global.topnav',
59+
pathSegment: 'global-settings',
60+
urlSuffix: '/assets/views/settings.html',
61+
icon: 'settings'
62+
// ... other luigi node properties
63+
};
64+
}
65+
}
66+
```
67+
68+
## Registering the service during application bootstrap
69+
70+
```ts
71+
import { bootstrapApplication } from '@angular/platform-browser';
72+
import {
73+
PortalComponent,
74+
PortalOptions,
75+
providePortal,
76+
} from '@openmfp/portal-ui-lib';
77+
import { CustomGlobalNodesServiceImpl } from './global-nodes.service';
78+
79+
const portalOptions: PortalOptions = {
80+
// Reference the service class here. The library handles instantiation.
81+
customGlobalNodesService: CustomGlobalNodesServiceImpl,
82+
// ... other portal options
83+
};
84+
85+
bootstrapApplication(PortalComponent, {
86+
providers: [providePortal(portalOptions)],
87+
}).catch((err) => console.error(err));
88+
89+
```
90+
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
# Customizing Luigi Global Search
2+
3+
The `globalSearchConfigService` option allows you to define the behavior, appearance,
4+
and event handling for the [Luigi global search](https://docs.luigi-project.io/docs/global-search).
5+
By implementing this service, you can integrate
6+
your own search provider logic directly into the portal header.
7+
8+
9+
## GlobalSearchConfigService Interface
10+
11+
The `GlobalSearchConfigService` interface requires the implementation of a single method
12+
that returns the search configuration object.
13+
14+
```ts
15+
export interface GlobalSearchConfigService {
16+
/**
17+
* Must return a valid Luigi configuration object for global search.
18+
*/
19+
getGlobalSearchConfig(): any;
20+
}
21+
```
22+
23+
## Provide your implemented service
24+
25+
```ts
26+
import { GlobalSearchConfigService } from '@openmfp/portal-ui-lib';
27+
import { Injectable } from '@angular/core';
28+
29+
@Injectable()
30+
export class GlobalSearchConfigServiceImpl implements GlobalSearchConfigService {
31+
32+
getGlobalSearchConfig() {
33+
return {
34+
// UI Setting: Centers the search input in the shell header
35+
searchFieldCentered: true,
36+
37+
// Define handlers for various search events
38+
searchProvider: {
39+
onEnter: (searchString: string) => {
40+
console.log('Search triggered via Enter:', searchString);
41+
// Add your search execution logic here
42+
},
43+
onSearchBtnClick: (searchString: string) => {
44+
console.log('Search button clicked:', searchString);
45+
// Add your search execution logic here
46+
},
47+
onEscape: () => {
48+
console.log('Search escaped');
49+
// Logic to clear results or close the search overlay
50+
},
51+
52+
// You can include additional Luigi search properties
53+
}
54+
};
55+
}
56+
}
57+
```
58+
59+
## Registering the service during application bootstrap
60+
61+
```ts
62+
import { bootstrapApplication } from '@angular/platform-browser';
63+
import {
64+
PortalComponent,
65+
PortalOptions,
66+
providePortal,
67+
} from '@openmfp/portal-ui-lib';
68+
import { GlobalSearchConfigServiceImpl } from './global-search-config.service';
69+
70+
const portalOptions: PortalOptions = {
71+
// Pass the class reference to the portal options
72+
globalSearchConfigService: GlobalSearchConfigServiceImpl,
73+
// ... other portal options
74+
};
75+
76+
bootstrapApplication(PortalComponent, {
77+
providers: [providePortal(portalOptions)],
78+
}).catch((err) => console.error(err));
79+
```
80+

0 commit comments

Comments
 (0)