Skip to content

monisa/shell

Repository files navigation

Octa Multi-Tenant Shell

A reusable Angular host application that bootstraps Octa microfrontends with runtime branding, tenant configuration, and MFE orchestration. Branding, layout, and navigation are entirely data-driven via JSON so new clients can be onboarded without rebuilding the shell or MFEs.

Highlights

  • Runtime branding — load tenant-specific light/dark theme JSON, convert to CSS variables, and cascade into Shadow DOM for Angular Web Components.
  • Configurable shell layout — header, sidebar, notifications, footer, and menus hydrate from <tenant>.config.json at runtime.
  • MFE orchestration — declarative registry for Module Federation/Web Component endpoints, injected on demand with caching and developer overrides.
  • Caching & resilience — theme JSON is cached in localStorage with versioning + TTL. Fallback themes/logos/icons apply if a fetch fails.
  • Developer-friendly — query ?tenant=expocity to hot-swap tenants, /style-guide preview of tokens, and automatic fallback assets for local MFE dev.

Getting started

npm install
npm start

The shell serves on http://localhost:4200. Append ?tenant=khidmah or ?tenant=expocity to switch runtime branding. Tenant preference and theme mode are persisted in localStorage.

Project structure

src/
├── app/
│   ├── core/              # models + services (config, theme, MFE loader)
│   ├── layout/            # header, sidebar, footer, notifications, toggle
│   ├── shared/            # MFE host, style guide, not-found components
│   └── features/          # dashboard placeholder + future routes
├── assets/
│   ├── config/            # <tenant>.config.json
│   ├── themes/            # <tenant>_<mode>.json + fallbacks
│   ├── icons/             # tenant branded SVG icons
│   └── logos/             # tenant logos/marks

Runtime JSON contracts

Theme JSON (assets/themes/<tenant>_<mode>.json)

{
  "meta": { "tenant": "khidmah", "mode": "light", "version": "1.0.0" },
  "colors": { "primary": "#0F766E", "surface": "#FFFFFF" },
  "typography": { "font-family-base": "'Inter', sans-serif" },
  "spacing": { "md": "16px" },
  "radius": { "pill": "999px" },
  "layout": { "sidebar-width": "280px" },
  "components": { "header": { "background": "#fff" } },
  "icons": { "dashboard": { "type": "svg", "value": "assets/icons/khidmah/dashboard.svg" } },
  "logos": { "main": { "type": "svg", "value": "assets/logos/khidmah-logo.svg" } }
}

The ThemeService flattens every token into CSS variables (--octa-colors-primary, --octa-icons-dashboard, etc.) and applies them to :root, so any Web Component (even inside Shadow DOM) can call var(--octa-colors-primary).

Shell config (assets/config/<tenant>.config.json)

Key fields:

  • layout — sidebar placement/width, footer copy, notification toggle.
  • defaultTheme — URLs for light/dark/fallback JSON + cache version.
  • menu — renders sidebar and maps to mfeId routes.
  • mfeRegistry — metadata for each remote (tag name, remoteEntry, dev overrides).
  • notifications — banner items shown above the layout.
  • developer — fallback theme + dummy user shown in header.

Client config loader

  • assets/config/client.config.json is the default runtime contract. Update this file (or drop in additional <tenant>.config.json files) to change the shell branding, menu, or MFE registry without rebuilding.
  • ShellConfigService fetches the JSON during APP_INITIALIZER, blocks bootstrap until the payload is ready, and exposes the structure through configSignal/config$ so any component can react to changes.
  • The shell automatically renders config.appName and the primary logo sourced from config.branding.logoUrl (or the theme logos if provided).
  • To switch clients at runtime, either replace the client.config.json asset on the server or duplicate it as <tenant>.config.json and load it via ?tenant=<tenant> (or call ShellConfigService.switchTenant('<tenant>')). The updated JSON applies on the next refresh—no rebuild required.
  • Keep config versioned (configVersion) so ops teams know which payload is live, and align defaultTheme.cacheVersion with your theme bundle to leverage caching.

MFE development flow

  1. Register the Web Component in <tenant>.config.json (tagName, optional remoteEntry).
  2. Use /mfe/<id> route to mount it. The shell injects scripts once and provides tenant + theme context through CSS variables and data-tenant attributes.
  3. For local dev, point localDev.remoteEntry to your ng serve output; toggle via query params without rebuilding the shell.

Useful scripts

Command Description
npm start Serve the shell with live reload
npm run build Production build
npm run test Execute unit tests (Vitest)

Next steps

  • Wire ThemeService to remote CDN once endpoints are available.
  • Expand Module Federation handling (lazy routes, manifests) as MFEs evolve.
  • Hook notifications/user profile to real APIs.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 2

  •  
  •