useMenu.ts 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. import {useAccessProfileStore} from "~/stores/accessProfile";
  2. import {useRuntimeConfig} from "#app";
  3. import {useAbility} from "@casl/vue";
  4. import {useOrganizationProfileStore} from "~/stores/organizationProfile";
  5. import {MenuGroup, MenuItem} from "~/types/layout";
  6. import {MENU_LINK_TYPE} from "~/types/enum/layout";
  7. import MainMenuBuilder from "~/services/menuBuilder/mainMenuBuilder";
  8. import WebsiteListMenuBuilder from "~/services/menuBuilder/websiteListMenuBuilder";
  9. import MyAccessesMenuBuilder from "~/services/menuBuilder/myAccessesMenuBuilder";
  10. import MyFamilyMenuBuilder from "~/services/menuBuilder/myFamilyMenuBuilder";
  11. import ConfigurationMenuBuilder from "~/services/menuBuilder/configurationMenuBuilder";
  12. import AccountMenuBuilder from "~/services/menuBuilder/accountMenuBuilder";
  13. import {AccessProfile} from "~/types/interfaces";
  14. import {useLayoutStore} from "~/stores/layout";
  15. /**
  16. * Renvoie des méthodes pour interagir avec les menus
  17. *
  18. * Exemple d'usage :
  19. *
  20. * const { buildMenu, hasMenu } = useMenuBuilder()
  21. * const menu = buildMenu('Main')
  22. *
  23. * console.log(hasMenu('Main')) // true
  24. */
  25. export const useMenu = () => {
  26. const runtimeConfig = useRuntimeConfig()
  27. const ability = useAbility()
  28. const organizationProfile = useOrganizationProfileStore()
  29. const accessProfile = useAccessProfileStore()
  30. const layoutState = useLayoutStore()
  31. /**
  32. * Construct all Menus
  33. */
  34. const buildAllMenu = () => {
  35. const menus = [
  36. new MainMenuBuilder(runtimeConfig, ability, organizationProfile, accessProfile as AccessProfile),
  37. new WebsiteListMenuBuilder(runtimeConfig, ability, organizationProfile, accessProfile as AccessProfile),
  38. new MyAccessesMenuBuilder(runtimeConfig, ability, organizationProfile, accessProfile as AccessProfile),
  39. new MyFamilyMenuBuilder(runtimeConfig, ability, organizationProfile, accessProfile as AccessProfile),
  40. new ConfigurationMenuBuilder(runtimeConfig, ability, organizationProfile, accessProfile as AccessProfile),
  41. new AccountMenuBuilder(runtimeConfig, ability, organizationProfile, accessProfile as AccessProfile)
  42. ]
  43. for(let menu of menus){
  44. const menuBuilt = menu.build();
  45. if(menuBuilt){
  46. layoutState.menus[menu.getMenuName()] = menuBuilt
  47. // On enregistre l'état du menu dans le store de la page
  48. if ( isMenuGroupWithChildren(menuBuilt) ) {
  49. layoutState.menusOpened[menu.getMenuName()] = false
  50. }
  51. }
  52. }
  53. }
  54. /**
  55. * Test type d'une menu
  56. * @param args
  57. */
  58. const isMenuGroupWithChildren = (args: MenuGroup|MenuItem): boolean => {
  59. return ((args as MenuGroup).children ?? []).length > 0
  60. }
  61. /**
  62. * Récupère le menu dans le store ou null
  63. * @param name
  64. */
  65. const getMenu = (name: string): MenuGroup|MenuItem|null => {
  66. return layoutState.menus[name] || null
  67. }
  68. /**
  69. * L'utilisateur en cours a-t-il accès au menu portant ce nom ?
  70. *
  71. * @param name
  72. */
  73. const hasMenu = (name: string): boolean => {
  74. return getMenu(name) !== null
  75. }
  76. /**
  77. * Soulève une erreur si aucun menu portant ce nom n'est enregistré dans le store
  78. *
  79. * @param name
  80. */
  81. const assertExists = (name: string) => {
  82. if (getMenu(name) === null) {
  83. throw new Error('Unknown menu : ' + name)
  84. }
  85. }
  86. /**
  87. * Retourne vrai si le menu est actuellement ouvert / déplié
  88. *
  89. * @param name
  90. */
  91. const isMenuOpened = (name: string): boolean => {
  92. assertExists(name)
  93. return layoutState.menusOpened[name]
  94. }
  95. /**
  96. * Met à jour l'état du menu portant ce nom
  97. *
  98. * @param name
  99. * @param state
  100. */
  101. const setMenuState = (name: string, state: boolean) => {
  102. assertExists(name)
  103. layoutState.menusOpened[name] = state
  104. }
  105. /**
  106. * Ouvre / déplie le menu portant ce nom
  107. *
  108. * @param name
  109. */
  110. const openMenu = (name: string) => {
  111. setMenuState(name, true)
  112. }
  113. /**
  114. * Ferme / replie le menu portant ce nom
  115. *
  116. * @param name
  117. */
  118. const closeMenu = (name: string) => {
  119. setMenuState(name, false)
  120. }
  121. /**
  122. * Bascule l'état du menu entre ouvert et fermé
  123. *
  124. * @param name
  125. */
  126. const toggleMenu = (name: string) => {
  127. setMenuState(name, !layoutState.menusOpened[name])
  128. }
  129. /**
  130. * Le lien menuItem est-il un lien interne à l'application
  131. *
  132. * @param menuItem
  133. */
  134. const isInternalLink = (menuItem: MenuItem | MenuGroup): boolean => {
  135. return 'type' in menuItem && menuItem.type === MENU_LINK_TYPE.INTERNAL
  136. }
  137. return {
  138. buildAllMenu,
  139. getMenu,
  140. hasMenu,
  141. setMenuState,
  142. openMenu,
  143. closeMenu,
  144. toggleMenu,
  145. isMenuOpened,
  146. isInternalLink
  147. }
  148. }