useMenu.ts 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. import { useAbility } from '@casl/vue'
  2. import { useAccessProfileStore } from '~/stores/accessProfile'
  3. import { useOrganizationProfileStore } from '~/stores/organizationProfile'
  4. import type { MenuGroup, MenuItem } from '~/types/layout'
  5. import { MENU_LINK_TYPE } from '~/types/enum/layout'
  6. import type { AccessProfile } from '~/types/interfaces'
  7. import { useLayoutStore } from '~/stores/layout'
  8. import MenuComposer from '~/services/layout/menuComposer'
  9. /**
  10. * Renvoie des méthodes pour interagir avec les menus
  11. *
  12. * Exemple d'usage :
  13. *
  14. * const { buildMenu, hasMenu } = useMenuBuilder()
  15. * const menu = buildMenu('Main')
  16. *
  17. * console.log(hasMenu('Main')) // true
  18. */
  19. export const useMenu = () => {
  20. const runtimeConfig = useRuntimeConfig()
  21. const ability = useAbility()
  22. const organizationProfile = useOrganizationProfileStore()
  23. const accessProfile = useAccessProfileStore()
  24. const layoutState = useLayoutStore()
  25. /**
  26. * Construct all Menus
  27. * TODO: ce serait mieux de conserver les ids des menus même non possédés, de façon à pouvoir différencier un menu
  28. * non possédé et un id incorrect dans getMenu par exemple. J'ai eu du mal capter pourquoi hasMenu('Family') renvoyait
  29. * false, jusqu'à ce que je tilte que le menu s'appelait MyFamily, et pas Family
  30. */
  31. const buildAllMenu = () => {
  32. MenuComposer.build(
  33. runtimeConfig,
  34. ability,
  35. organizationProfile,
  36. accessProfile as AccessProfile,
  37. layoutState,
  38. )
  39. }
  40. /**
  41. * Retourne le menu depuis le store ou retourne null
  42. * si le menu n'a pas été construit pour l'utilisateur courant
  43. *
  44. * @param name
  45. */
  46. const getMenu = (name: string): MenuGroup | MenuItem | null => {
  47. return layoutState.menus[name] || null
  48. }
  49. /**
  50. * L'utilisateur en cours a-t-il accès au menu portant ce nom ?
  51. *
  52. * @param name
  53. */
  54. const hasMenu = (name: string): boolean => {
  55. return getMenu(name) !== null
  56. }
  57. /**
  58. * Soulève une erreur si aucun menu portant ce nom n'est enregistré dans le store
  59. *
  60. * @param name
  61. */
  62. const assertExists = (name: string) => {
  63. if (getMenu(name) === null) {
  64. throw new Error('Unknown menu : ' + name)
  65. }
  66. }
  67. /**
  68. * Retourne vrai si le menu est actuellement ouvert / déplié
  69. *
  70. * @param name
  71. */
  72. const isMenuOpened = (name: string): boolean => {
  73. assertExists(name)
  74. return layoutState.menusOpened[name]
  75. }
  76. /**
  77. * Met à jour l'état du menu portant ce nom
  78. *
  79. * @param name
  80. * @param state
  81. */
  82. const setMenuState = (name: string, state: boolean) => {
  83. assertExists(name)
  84. layoutState.menusOpened[name] = state
  85. }
  86. /**
  87. * Ouvre / déplie le menu portant ce nom
  88. *
  89. * @param name
  90. */
  91. const openMenu = (name: string) => {
  92. setMenuState(name, true)
  93. }
  94. /**
  95. * Ferme / replie le menu portant ce nom
  96. *
  97. * @param name
  98. */
  99. const closeMenu = (name: string) => {
  100. setMenuState(name, false)
  101. }
  102. /**
  103. * Bascule l'état du menu entre ouvert et fermé
  104. *
  105. * @param name
  106. */
  107. const toggleMenu = (name: string) => {
  108. setMenuState(name, !layoutState.menusOpened[name])
  109. }
  110. /**
  111. * Le lien menuItem est-il un lien interne à l'application
  112. *
  113. * @param menuItem
  114. */
  115. const isInternalLink = (menuItem: MenuItem | MenuGroup): boolean => {
  116. return 'type' in menuItem && menuItem.type === MENU_LINK_TYPE.INTERNAL
  117. }
  118. return {
  119. buildAllMenu,
  120. getMenu,
  121. hasMenu,
  122. setMenuState,
  123. openMenu,
  124. closeMenu,
  125. toggleMenu,
  126. isMenuOpened,
  127. isInternalLink,
  128. }
  129. }