useMenu.ts 3.2 KB

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