Appearance
Menu builder
@investec/plugins-menu-builder is the menu aggregation layer for Investec Online. It decides which menu endpoints to call from auth context, merges the responses into one IMenuConfig, and maps menu IDs to region-specific URLs.
Package
Warning: This package must be installed only by the platform team into the Investec Online shell application. Never add it as a direct dependency of a consumer/feature application. Consumers use this plugin's behaviour through the Invsy SDK, or by contributing a bounded, governed change to this plugin's own source (see Plugin change governance).
sh
npm install --save @investec/plugins-menu-builderThe platform owns installation of released plugin versions. A consuming team normally contributes shared menu logic in this repository and then asks the platform team to adopt the published version.
What it owns
- auth-driven menu endpoint selection
- merge logic for menu trees and menu items without children
- region-aware URL configuration through
menuItemMap - incremental menu updates through
menuBuilder.updateAppState - per-call success/failure tracking in
callResultMap
Public contract
The main package-root exports include:
menuBuildersetupMenu()aggregateMenuItems(...)aggregateClientProfileFlagsMenuItems(...)MenuUrlMap()andAdditionalClientProfileFlagsMenuUrlMap()- menu types such as
IMenuConfig,IMenuItem - config exports such as
menuItemMap
Integration pattern
ts
import { menuBuilder, setupMenu } from '@investec/plugins-menu-builder';
menuBuilder.activeEnvironment = 'staging';
menuBuilder.authResponse.next(authResponse);
menuBuilder.updateAppState.subscribe((menuConfig) => {
// Persist or pass the menu config onward.
});
await setupMenu();Result shape
The aggregated menu config includes:
ts
interface IMenuConfig {
mainMenu: IMenuItem[];
mainMenuWithoutChildren: IMenuItem[];
callResultMap: { url: string; result: boolean; region: string }[];
hasError?: boolean;
currentMenuRegion?: string;
}Runtime behaviour
setupMenu():
- derives the active menu region from auth context
- chooses menu endpoints from
MenuUrlMap()andAdditionalClientProfileFlagsMenuUrlMap() - fetches and merges menu payloads
- fills missing URLs through
menuItemMap - updates
menuBuilder.updateAppStateas data arrives
The default Profile & settings links use /usrroot-wpaas/update-login-details, /usrroot-wpaas/security-questions, and /usrroot-wpaas/website-settings. These are routes within app-platform-user, not separate applications. configureMenuItem() only fills an AbsoluteUrl that is null; it does not replace an explicit default-menu URL. Keep these paths free of stray quotes: the shell URL-encodes them, so a trailing " becomes %22 and changes the route.
How consumers extend it
Consumers normally extend menu behaviour after the plugin emits its canonical menu model.
Typical patterns are:
- subscribe to
menuBuilder.updateAppStateand persist the result in app state; - choose when to call
setupMenu()based on auth lifecycle; - update the current region in app state before dependent consumers render;
- decorate the built menu for one shell surface without changing the shared aggregation rules.
Change the package when a new menu endpoint, new auth-driven call rule, or new shared URL mapping is needed.
Extension example: decorate the canonical menu in app state
ts
import { menuBuilder, setupMenu, type IMenuConfig } from '@investec/plugins-menu-builder';
type DecoratedMenuState = {
menuConfig: IMenuConfig;
hasVisibleItems: boolean;
};
let latestMenuState: DecoratedMenuState | undefined;
menuBuilder.activeEnvironment = 'staging';
menuBuilder.authResponse.next(authResponse);
menuBuilder.updateAppState.subscribe((menuConfig) => {
latestMenuState = {
menuConfig,
hasVisibleItems: menuConfig.mainMenu.length > 0 || menuConfig.mainMenuWithoutChildren.length > 0,
};
});
await setupMenu();Extend the shared plugin
| Change | Location |
|---|---|
| Add an auth-driven menu API | MenuUrlMap() or AdditionalClientProfileFlagsMenuUrlMap() in configs/menu-configs.ts |
| Add an environment-specific endpoint | menu-builder/src/lib/environment.ts |
| Map a menu ID to a shared route | menuItemMap in configs/menu-configs.ts |
| Change shared fetch, merge, or error tracking | menu-builder/src/lib/menu-builder.ts |
| Extend the public model | menu-builder/src/lib/types/ and src/index.ts |
When adding an API, define its auth flag, region, URL, environment differences, headers, merge behaviour, and failure result. Add tests for selected and unselected auth contexts, duplicate menu data, failed calls, and URL mapping.
Contact the Web Platform team before changing menu ownership, default menu behaviour, shared merge semantics, authentication headers, or a route used by multiple client types.
Consumer notes
- The package keeps module-level state and expects
authResponseto be pushed in beforesetupMenu(). - URL mapping is coupled to menu-item IDs and the current region.
clearState.next()resets the current config back to the default empty menu.hasErroris raised throughcallResultMapupdates when one or more menu calls fail.