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
sh
npm install --save @investec/plugins-menu-builderWhat 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 package exports:
menuBuildersetupMenu()- 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
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();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.