usePopoverMenu.ts 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. // Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
  2. import { inject, computed, provide } from 'vue'
  3. import { useSessionStore } from '#shared/stores/session.ts'
  4. import type { ObjectLike } from '#shared/types/utils.ts'
  5. import type { MenuItem } from '#desktop/components/CommonPopoverMenu/types.ts'
  6. import type { ComputedRef, Ref } from 'vue'
  7. const POPOVER_MENU_SYMBOL = Symbol('popover-menu')
  8. interface UsePopoverMenuReturn {
  9. filteredMenuItems: ComputedRef<MenuItem[] | undefined>
  10. singleMenuItemPresent: ComputedRef<boolean>
  11. singleMenuItem: ComputedRef<MenuItem | undefined>
  12. }
  13. export const usePopoverMenu = (
  14. items: Ref<MenuItem[] | undefined>,
  15. entity: Ref<ObjectLike | undefined>,
  16. options: { provides?: boolean } = {},
  17. ) => {
  18. const injectPopoverMenu = inject<Maybe<UsePopoverMenuReturn>>(
  19. POPOVER_MENU_SYMBOL,
  20. null,
  21. )
  22. if (injectPopoverMenu) return injectPopoverMenu
  23. const { provides = false } = options
  24. const session = useSessionStore()
  25. const filterItems = () => {
  26. return items.value?.filter((item) => {
  27. if (item.permission && item.show) {
  28. return (
  29. session.hasPermission(item.permission) && item.show(entity?.value)
  30. )
  31. }
  32. if (item.permission) {
  33. return session.hasPermission(item.permission)
  34. }
  35. if (item.show) {
  36. return item.show(entity?.value)
  37. }
  38. return true
  39. })
  40. }
  41. const filteredMenuItems = computed(() => {
  42. if (!items.value || !items.value.length) return
  43. return filterItems()
  44. })
  45. const singleMenuItemPresent = computed(() => {
  46. return filteredMenuItems.value?.length === 1
  47. })
  48. const singleMenuItem = computed(() => {
  49. if (!singleMenuItemPresent.value) return
  50. return filterItems()?.at(0)
  51. })
  52. const providePopoverMenu = {
  53. filteredMenuItems,
  54. singleMenuItemPresent,
  55. singleMenuItem,
  56. }
  57. if (provides) provide(POPOVER_MENU_SYMBOL, providePopoverMenu)
  58. return providePopoverMenu
  59. }