Helpers
Menu builders
buildMenuFromManifest e buildSettingsMenuFromManifests aggregano i manifest dei MFE in strutture pronte per il menu della shell.
API
function buildMenuFromManifest(
manifest: MFEManifest,
section?: 'app' | 'settings', // default 'app'
): MenuGroup[]
function buildSettingsMenuFromManifests(
manifests: MFEManifest[],
): SettingsMenuGroup[]
Aggregano i manifest dei MFE registrati in strutture pronte da renderizzare nel menu della shell, per sezione (app o settings).
Tipi prodotti
interface MenuItem {
path: string
label: string
icon?: string
order: number
badge?: string | (() => string | number)
}
interface MenuGroup {
category: string
icon?: string
items: MenuItem[]
}
interface SettingsMenuGroup {
mfeName: string
mfeLabel: string
icon?: string
groups: MenuGroup[]
}
buildMenuFromManifest(manifest, section)
Costruisce il menu di un singolo MFE per la sezione richiesta.
Comportamento
- Filtra le route con
meta.hidden === true(escluse) - Filtra per sezione: route con
meta.section === section(le route senzameta.sectionsono trattate come'app') - Raggruppa per
route.category ?? manifest.name - Ordina ogni gruppo per
route.meta.order ?? 99ascendente - Mappa ogni route in un
MenuItem
Esempio
import { buildMenuFromManifest } from '@pzeta/mfe-contracts/helpers'
const manifest: MFEManifest = {
name: 'crm-module',
version: '1.0.0',
description: 'CRM',
icon: 'pi-building',
routes: [
{ path: '/crm/dashboard', label: 'Dashboard', category: 'CRM', icon: 'pi-chart-line', meta: { order: 1 } },
{ path: '/crm/clienti', label: 'Clienti', category: 'CRM', icon: 'pi-users', meta: { order: 2 } },
{ path: '/crm/templates', label: 'Template', meta: { section: 'settings', order: 1 } },
{ path: '/crm/admin', label: 'Admin', meta: { hidden: true } },
],
}
const appMenu = buildMenuFromManifest(manifest, 'app')
/*
[
{
category: 'CRM',
icon: 'pi-building',
items: [
{ path: '/crm/dashboard', label: 'Dashboard', icon: 'pi-chart-line', order: 1 },
{ path: '/crm/clienti', label: 'Clienti', icon: 'pi-users', order: 2 },
],
},
]
*/
const settingsMenu = buildMenuFromManifest(manifest, 'settings')
/*
[
{
category: 'crm-module',
icon: 'pi-building',
items: [
{ path: '/crm/templates', label: 'Template', order: 1 },
],
},
]
*/
buildSettingsMenuFromManifests(manifests)
Aggregatore multi-MFE per la sezione settings, pensato per costruire il rail "Impostazioni" della shell.
Differenze rispetto a buildMenuFromManifest(_, 'settings')
- Aggrega più MFE in un solo passaggio
- Pre-calcola il path completo:
/settings/{manifest.name}{route.path} - Espone metadata del MFE proprietario (
mfeName,mfeLabel,icon) - Esclude MFE senza route settings
Output
interface SettingsMenuGroup {
mfeName: string // manifest.name (usato come scope nel path)
mfeLabel: string // manifest.description (label leggibile)
icon?: string // manifest.icon
groups: MenuGroup[] // sotto-gruppi per meta.category
}
Esempio
import { buildSettingsMenuFromManifests } from '@pzeta/mfe-contracts/helpers'
const crmManifest: MFEManifest = {
name: 'crm-module',
description: 'CRM',
icon: 'pi-building',
/* ... */
routes: [
{ path: '/templates', label: 'Template email', meta: { section: 'settings', order: 1 } },
{ path: '/tags', label: 'Tag', meta: { section: 'settings', order: 2 } },
],
}
const hrManifest: MFEManifest = {
name: 'hr-module',
description: 'Risorse Umane',
icon: 'pi-users',
/* ... */
routes: [
{ path: '/contratti', label: 'Tipi contratto', meta: { section: 'settings', order: 1 } },
],
}
const settingsMenu = buildSettingsMenuFromManifests([crmManifest, hrManifest])
/*
[
{
mfeName: 'crm-module',
mfeLabel: 'CRM',
icon: 'pi-building',
groups: [
{
category: 'crm-module',
icon: 'pi-building',
items: [
{ path: '/settings/crm-module/templates', label: 'Template email', order: 1 },
{ path: '/settings/crm-module/tags', label: 'Tag', order: 2 },
],
},
],
},
{
mfeName: 'hr-module',
mfeLabel: 'Risorse Umane',
icon: 'pi-users',
groups: [
{
category: 'hr-module',
icon: 'pi-users',
items: [
{ path: '/settings/hr-module/contratti', label: 'Tipi contratto', order: 1 },
],
},
],
},
]
*/
Internamente usa buildSettingsFullPath per costruire i path completi, gestendo entrambe le convenzioni: route già prefissate con lo scope e route relative.
Rendering shell tipico
<script setup lang="ts">
import {
buildMenuFromManifest,
buildSettingsMenuFromManifests,
} from '@pzeta/mfe-contracts/helpers'
const props = defineProps<{ manifests: MFEManifest[] }>()
const appMenu = computed(() =>
props.manifests.flatMap((m) => buildMenuFromManifest(m, 'app')),
)
const settingsMenu = computed(() =>
buildSettingsMenuFromManifests(props.manifests),
)
</script>
<template>
<!-- Rail principale -->
<nav class="app-rail">
<section v-for="group in appMenu" :key="group.category">
<h3>
<i :class="group.icon" /> {{ group.category }}
</h3>
<RouterLink
v-for="item in group.items"
:key="item.path"
:to="item.path"
>
<i :class="item.icon" /> {{ item.label }}
<span v-if="item.badge">{{ typeof item.badge === 'function' ? item.badge() : item.badge }}</span>
</RouterLink>
</section>
</nav>
<!-- Rail "Impostazioni" -->
<nav class="settings-rail">
<section v-for="mfeGroup in settingsMenu" :key="mfeGroup.mfeName">
<h2>
<i :class="mfeGroup.icon" /> {{ mfeGroup.mfeLabel }}
</h2>
<div v-for="group in mfeGroup.groups" :key="group.category">
<RouterLink v-for="item in group.items" :key="item.path" :to="item.path">
{{ item.label }}
</RouterLink>
</div>
</section>
</nav>
</template>
Badge dinamici
MenuItem.badge può essere una funzione: chiamala al rendering per ottenere il valore corrente.
<span v-if="item.badge">
{{ typeof item.badge === 'function' ? item.badge() : item.badge }}
</span>
Vedi MFERoute.meta.badge per come dichiarare i badge nel manifest.
Tipi correlati
MFEManifestMFERoutebuildSettingsFullPath— usata internamente