useMenu.ts 3.1 KB

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