Shell and Micro frontends in Common Workplace
Micro frontends can be loaded into the shell application by the use of Webpack and Module federation. Micro frontends must be implemented as Web Components as this makes it possible to load micro frontends created in different frameworks into the shell app which is based on Angular.
Indholdsfortegnelse
Overview of Common Workplace
Common Workplace (fælles arbejdsplads) is the shell application, and is named kam-ui. It exposes three micro frontends: care team, plan definition and questionnaire. The Common Workplace exposes a micro frontend called Kam-pickers which contains a number of generic pickers which can be used by micro frontends loaded into the shell application kam-ui. Kam-pickers
Metadata for loading micro frontends in the shell application
The micro frontends are loaded into the shell application using a configuration file like the one below.
Example of metadata
[
{
"id": "careteam",
"displayName": "Care teams",
"iconName": "group",
"route": "administration/careteam",
"requiredRoles": ["Care Team Administrator"],
"webComponentConfig": {
"tag": "kam-mf-careteam",
"url": ["http://localhost:3000/remoteEntry.js"],
"exposedModule": "./Module",
"microFrontendName": "kamMfCareteam",
"integrationType": "WEBCOMPONENT"
"ecmaScriptModule": true
}
}
... // other micro frontends
]
Explanation
Metadata
Id: unique ID for micro frontend
displayName: The menu item name
iconName: name of the icon (only support Material Symbols and Icons - Google Fonts )
route: URL path to the micro frontend in the shell application
requiredRoles: the required role to access the micro frontend
webComponentConfig:
tag: The HTML tag for the web component
url: Script file needed for the micro frontend
exposedModule: Name for module federation in webpack.config file
microFrontendName: the unique name specified in webpack.config for module federation
ecmaScriptModule: Set to: true, if application emits EcmaScript modules.
The shell application dynamically generates the navigation menu based on the content of the configuration file. Which menu items will be available to a specific user is determined by the users' context and the required roles specified for the individual micro frontends.
The unique micro frontend name specified in metadata.webComponentConfig.microFrontendName must be used in the micro frontend for communication with the shell application. eg. microFrontendName for events.
Events
The micro frontends are as self-contained as possible. The intent was to keep the interface between the shell application and the micro frontends as small as possible to make development easier and less error-prone to changes.
It is however impossible for the shell and micro frontend to be completely separated as the shell must have some knowledge about the micro frontend and vice versa. The metadata, previously mentioned, is an example of the shell knowing how the micro frontend has declared its Web Component, and how it is exposed. A need also arose for having micro frontends handle events from the shell when navigation needed to be reset on micro frontend clicks. The table below describes the event interface of the shell application kam-ui.
Event | Payload | Description |
---|---|---|
kam-mf-selected | {
microFrontendName: string;
} | Event emitted by the shell application, when a micro frontend is selected in the navbar. |
kam-shell-context-changed | {
userContext: {
careTeamName: string | null;
careTeamReference: string | null;
organizationName: string;
organizationReference: string;
isCurrent: boolean;
oioRoles: string[];
}
} | Event emitted when the user context in the toolbar changes. |
Micro frontend Context Management
In order to prevent navigation between micro frontends resulting in changes being lost, a framework is available for negotiating navigation attempts. With this framework, it is possible to ask the user before navigating away from the current micro frontend in the shell application.
Shell
When the current page in the shell application is a micro frontend and the user clicks on another page in the shell application, the shell application will dispatch a custom event.
Custom Event from the shell application:
Name: “kam-is-shell-allowed-to-leave-mf”
detail: {microFrontendName: <nameOfTheMicroFrontend> }
The shell application will listen for the event “kam-leaving-mf-allowed”. When receiving the custom event the shell application will navigate to the page previously requested.
Micro frontend
The micro frontend must listen to the custom event “kam-is-shell-allowed-to-leave-mf”. When the micro frontend receives the event and the property microFrontendName matches the name of the micro frontend, the micro frontend must determine if the user is allowed to leave the micro frontend. The micro frontend must be able to determine if the user is for instance filling in a form(dirty form) and then ask the user if the user wants to leave the page with unsaved changes. If the user clicks yes to leave the page a custom event must be dispatched. If the user has no unsaved changes a custom event must be sent without asking the user.
Custom Event from the micro frontend:
Name: “kam-leaving-mf-allowed”
detail: {microFrontendName: <nameOfTheMicroFrontend> }
Routing
The shell applications routing handles the login flow and navigation to the micro frontends by the navigation menu or direct URL to the micro frontend like “<baseurl>/administration/plandefinition”. There is no support for deep URL inside a micro frontend, this means that even though the micro frontend has routing internally the browser URL will still be like this “<baseurl>/administration/plandefinition” when the user navigates in the micro frontend.
When navigating back using the browser or back button it is expected to only navigate back inside the micro frontend. By default, this is not the case, and both the micro frontend and shell are navigated back. The only way to correct the navigation in micro frontends is to block location popstate in the shell application. This comes however with the cost of disabling forward navigation in the application.
Styles
All micro frontends must be self-contained regarding their styling. If a micro frontend is depending on some framework using global styles, it is the developer of the micro frontend's responsibility to scope it. Below is a non-exhaustive list of approaches for scoping styling.
Wrapping the micro frontend in a Shadow DOM
Prefixing all styles. In component-based frameworks, this could be achieved by using scoped styles in the root component (e.g. Scoped styles in Vue ).
The last resort is removing global styles programmatically using the DOM API
Using a framework that is not dependent and does not use global styles
The shell application is using Angular Material and as a consequence the styling theme specified in the shell is global and therefor will affect other Angular micro frontends using Angular Material.
Shell application - Kam-ui
Kam-ui is the shell application of KAM. It handles all authentication of the app and authorization to access each micro frontend. In kam-ui, a user can select a context with roles which allow them access to specific micro frontends. The user can access micro frontends by navigating to “Administrativt” in the top toolbar and selecting a micro frontend from the left navbar.
Headers
Content Security Policy (CSP)
The shell application specifies the CSP header and is configured to only allow specified domains.
The CSP header is configured specifically for each environment.
To help micro frontend developers the CSP header is set to Report-Only in environments devenvcgi and the internal test environment (inttest). The browser will throw an error in the console if the CSP header is violated.
Developers of micro frontends must inform Systematic if the CSP should be updated to accommodate the needs of the micro frontend as the header will block calls (Report only on devenvcgi and inttest)
Example Internal Test Environment (INTTEST)
Calling FUT infrastructure from micro frontend
The shell application handles authentication and stores the access token in Session storage. When a micro frontend needs to call the infrastructure the access token can be fetched from Session Storage by the key “access_token”.
Micro frontends
Using micro frontends in other applications than Common Workplace
The micro frontends are implemented as Web Components which makes it possible to reuse them in other web applications using the Angular framework.
It has been tested under the following conditions:
Angular version 14.2.12
Angular Material 14.2.7
With the CSS class mat-typography added on the body tag in index.html
angular-architects/module-federation 14.3.14
angular-architects/module-federation-tools 14.3.14
Be aware of routing as described here: Routing
Kam-mf-plandefinition
Kam-mf-plandefinition is a micro frontend for creating, editing and viewing plan definitions. A plan definition consists of nested actions that each point to an activity intended for a citizen to perform. A user can create these activities and structure them to their liking. Furthermore, they can move actions, set relationships between and timing on them. Possible activity types are:
Type | Description |
---|---|
Instruction | Activity for showing rich text or attaching a file or picture. |
Questionnaire | Activity containing a questionnaire for the citizen to complete. |
Measurement | Activity where the citizen is expected to measure something. Can have triaging rules and ranges based on that measurement. Ex. blood pressure. |
Combined measurement | Activity composing multiple measurement activities. Used when a measurement device can provide multiple different measurement types. |
Kam-mf-careteam
Kam-mf-careteam is a micro frontend for creating and managing care teams. A care team is used with a practitioner login to define the context in which the practitioner is working. The micro frontend allows exporting all care teams to a csv-file.
Kam-mf-questionnaire
Kam-mf-questionnaire is a micro frontend for creating, managing and viewing questionnaires intended for citizens to complete. The questionnaires can be used in plans or plan definitions.