| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171 |
- import type { RuntimeConfig } from '@nuxt/schema'
- import type { AnyAbility } from '@casl/ability'
- import type { Router } from 'vue-router'
- import type {
- IconItem,
- MenuBuilder,
- MenuGroup,
- MenuItem,
- MenuItems,
- } from '~/types/layout'
- import { MENU_LINK_TYPE } from '~/types/enum/layout'
- import UrlUtils from '~/services/utils/urlUtils'
- import type { AccessProfile, organizationState } from '~/types/interfaces'
- import { LINK_TARGET } from '~/types/enum/enums'
- /**
- * Classe de base des menus et sous-menus.
- *
- * La méthode principale est la méthode build
- */
- abstract class AbstractMenuBuilder implements MenuBuilder {
- protected runtimeConfig: RuntimeConfig
- protected ability: AnyAbility
- protected organizationProfile: organizationState
- protected accessProfile: AccessProfile
- protected router: Router
- /**
- * Nom court désignant le menu que construit ce builder
- */
- static readonly menuName: string
- constructor(
- runtimeConfig: RuntimeConfig,
- ability: AnyAbility,
- organizationProfile: organizationState,
- accessProfile: AccessProfile,
- router: Router,
- ) {
- this.runtimeConfig = runtimeConfig
- this.ability = ability
- this.organizationProfile = organizationProfile
- this.accessProfile = accessProfile
- this.router = router
- }
- /**
- * Permet un accès non statique à la variable menuName
- */
- public getMenuName(): string {
- return Object.getPrototypeOf(this).constructor.menuName
- }
- /**
- * Construit et retourne un menu ou sous-menu selon le profil de l'utilisateur, le profil de son organisation
- * et les droits de l'utilisateur.
- *
- * Si le menu comporte plusieurs éléments, retourne une instance de MenuGroup
- * Si le menu ne comporte qu'un seul élément, retourne une instance de MenuItem
- * Si le menu ne comporte aucun élément, retourne null.
- */
- abstract build(): MenuItem | MenuGroup | null
- /**
- * Construit et retourne un MenuGroup
- *
- * @param label
- * @param icon
- * @param {Array<MenuItem>} children Tableau d'ItemMenu représentant les sous menu du menu principal
- * @param actions
- */
- protected createGroup(
- label: string,
- icon?: IconItem,
- children: MenuItems = [],
- actions: Array<MenuItem> = [],
- ): MenuGroup {
- return { label, icon, children, actions }
- }
- /**
- * Construit et retourne un MenuItem
- *
- * @param {IconItem} icon
- * @param {string} label Titre qui sera traduit
- * @param to
- * @param type
- * @param newTab
- * @return {MenuItem}
- */
- protected createItem(
- label: string,
- icon?: IconItem,
- to: string = '',
- type: MENU_LINK_TYPE = MENU_LINK_TYPE.INTERNAL,
- newTab: boolean = false,
- ): MenuItem {
- let url: string
- if (type === MENU_LINK_TYPE.INTERNAL) {
- console.warn(
- "'createItem()' should not be used for internal links, use 'makeChildren()'",
- )
- }
- switch (type) {
- case MENU_LINK_TYPE.V1:
- // eslint-disable-next-line no-case-declarations
- const v1BaseURL =
- this.runtimeConfig.baseUrlAdminLegacy ||
- this.runtimeConfig.public.baseUrlAdminLegacy
- url = UrlUtils.join(v1BaseURL, '#', to)
- break
- case MENU_LINK_TYPE.EXTERNAL:
- url = UrlUtils.prependHttps(to)
- break
- default:
- url = to
- }
- return {
- icon,
- label,
- to: url,
- type,
- active: false,
- target: newTab ? LINK_TARGET.BLANK : LINK_TARGET.SELF,
- }
- }
- protected buildSubmenu(menuBuilder: typeof AbstractMenuBuilder) {
- // @ts-expect-error this method has to be called from non-abstract subclasses
- const builder = new menuBuilder(
- this.runtimeConfig,
- this.ability,
- this.organizationProfile,
- this.accessProfile,
- )
- return builder.build()
- }
- /**
- * Make a list of MenuItems according to user abilities
- *
- * @param items
- * @protected
- */
- protected makeChildren(
- items: Array<{ pageName: string; icon?: string }>,
- ): MenuItems {
- const children: MenuItems = []
- items.forEach((item) => {
- const { pageName, icon } = item
- if (this.ability.can('display', pageName)) {
- const to = this.router.resolve({ name: pageName })
- if (!to) {
- throw new Error('unknown page name : ' + pageName)
- }
- children.push({
- icon: icon ? { name: icon } : undefined,
- label: pageName,
- to: to.href,
- type: MENU_LINK_TYPE.INTERNAL,
- active: false,
- })
- }
- })
- return children
- }
- }
- export default AbstractMenuBuilder
|