UNPKG

vue-mf-module

Version:

A vue extension to create microfrontend module

165 lines (129 loc) 5.28 kB
import { TinyEmitter } from 'tiny-emitter'; import { RouteParamsRaw } from 'vue-router'; export interface IMenuDefinition { name: string, description: string, icon?: string, routeName?: string, routeParams?: RouteParamsRaw, featureflags?: string[], orderIndex?: number, parents?: string[], class?: string, meta?: any, hidden: () => boolean } export enum menuType { drawer = 0, settings = 1, header = 2, footer = 3 } export const MenuNotifications = { menuDefinitionAdded: 'newmenuitem', menuDefinitionMoved: 'menuitemmoved' } export class MenuHelper { public menuDefinitions: IMenuDefinition[] = []; public menuStructure: { [key: string]: { [key: string]: string[] } } = {} private notifications: TinyEmitter = new TinyEmitter(); private static instance = new MenuHelper(); public get Notifications() { return this.notifications; } public static get Instance() { return MenuHelper.instance } public addMenuDefinition(menuDefinition: IMenuDefinition, ...positions: { section: menuType, parent?: string }[]) { // Aggiungo la dichiarazione del menuù all'elenco dei menù disponibili. let found = this.menuDefinitions.find(m => m.name == menuDefinition.name); if (!found) this.menuDefinitions.push(menuDefinition); else menuDefinition = found; menuDefinition.parents = []; for (const element of positions) { this.menuStructure[element.section] = this.menuStructure[element.section] || {}; this.menuStructure[element.section][element.parent || menuDefinition.name] = this.menuStructure[element.section][element.parent || menuDefinition.name] || []; if (element.parent) { this.menuStructure[element.section][element.parent].push(menuDefinition.name); menuDefinition.parents.push(element.parent); } } this.notifications.emit(MenuNotifications.menuDefinitionAdded, menuDefinition); } public removeMenuDefinition(section: menuType, name: string, parent: string) { let result = this.menuDefinitions.find(i => i.name == name); if (result) { // remove menu from existing positions: if (result.parents) for (const p of result.parents) { let currentparent = this.menuStructure[section][p]; if (currentparent) { let r = currentparent.indexOf(name); if (r >= 0) currentparent.splice(r, 1); } } if (this.menuStructure[section][name] && !this.menuStructure[section][name].length) delete this.menuStructure[section][name]; result.parents = []; } this.notifications.emit(MenuNotifications.menuDefinitionMoved, result); return result; } public moveMenu(section: menuType, name: string, parent: string, index: number = 999) { let result = this.menuDefinitions.find(i => i.name == name); if (result) { result.orderIndex = index; // remove menu from existing positions: if (result.parents) for (const p of result.parents) { let currentparent = this.menuStructure[section][p]; if (currentparent) { let r = currentparent.indexOf(name); if (r >= 0) currentparent.splice(r, 1); } } if (this.menuStructure[section][name] && !this.menuStructure[section][name].length) delete this.menuStructure[section][name]; result.parents = []; this.menuStructure[section][parent || name] = this.menuStructure[section][parent || name] || []; if (parent) { this.menuStructure[section][parent].push(name) result.parents.push(parent); } } this.notifications.emit(MenuNotifications.menuDefinitionMoved, result); return result; } public getMenuItem(name: string): IMenuDefinition | undefined { return this.menuDefinitions.find(i => i.name == name); } public getMenu(menu: menuType): { item: IMenuDefinition | undefined, children: (IMenuDefinition | undefined)[] }[] { let result: { item: IMenuDefinition | undefined, children: (IMenuDefinition | undefined)[] }[] = []; let used = new Set<string>(); for (const key in this.menuStructure[menu]) { const element = this.menuStructure[menu][key]; let rr = { item: this.menuDefinitions.find(m => { return m.name == key && (!m.hidden || !m.hidden()) }), children: element.map(i => this.menuDefinitions.find(m => m.name == i && (!m.hidden || !m.hidden()))) .filter(i => !!i) .sort((a, b) => { if (a && b && a.orderIndex && b.orderIndex && a.orderIndex > b.orderIndex) return 1; if (a && b && a.orderIndex && b.orderIndex && a.orderIndex < b.orderIndex) return -1; return 0 }) }; if (!!rr.item) { used.add(key); element.forEach(i => used.add(i)); result.push(rr); } } return result.filter(i => !!i.item) .sort((a, b) => { if (a && b && a.item && b.item && a.item.orderIndex && b.item.orderIndex && a.item.orderIndex > b.item.orderIndex) return 1; if (a && b && a.item && b.item && a.item.orderIndex && b.item.orderIndex && a.item.orderIndex < b.item.orderIndex) return -1; return 0 }); } }