useTicketSidebar.ts 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. // Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
  2. import { injectLocal, provideLocal } from '@vueuse/shared'
  3. import { isEqual } from 'lodash-es'
  4. import { computed, ref, type InjectionKey, type Ref } from 'vue'
  5. import { useTicketSidebarPlugins } from '../components/TicketSidebar/plugins/index.ts'
  6. import type { TicketSidebarPlugin } from '../components/TicketSidebar/plugins/types.ts'
  7. import type {
  8. TicketSidebarContext,
  9. TicketSidebarInformation,
  10. } from '../types/sidebar.ts'
  11. export const TICKET_SIDEBAR_SYMBOL = Symbol(
  12. 'ticket-sidebar',
  13. ) as InjectionKey<TicketSidebarInformation>
  14. export const useProvideTicketSidebar = (context: Ref<TicketSidebarContext>) => {
  15. const shownSidebars = ref<Record<string, boolean>>({})
  16. const switchedSidebar = ref<string>()
  17. const showSidebar = (sidebar: string) => {
  18. shownSidebars.value[sidebar] = true
  19. }
  20. const hideSidebar = (sidebar: string) => {
  21. shownSidebars.value[sidebar] = false
  22. }
  23. const switchSidebar = (newSidebar: string) => {
  24. switchedSidebar.value = newSidebar
  25. }
  26. const sidebarPlugins = useTicketSidebarPlugins(context.value.screenType)
  27. const availableSidebarPlugins = computed<Record<string, TicketSidebarPlugin>>(
  28. (currentAvailableSidebarPlugins) => {
  29. const newCurrentSidebarPlugins = Object.fromEntries(
  30. Object.entries(sidebarPlugins).filter(([, sidebarPlugin]) =>
  31. typeof sidebarPlugin.available === 'function'
  32. ? sidebarPlugin.available(context.value)
  33. : true,
  34. ),
  35. )
  36. if (
  37. currentAvailableSidebarPlugins &&
  38. isEqual(currentAvailableSidebarPlugins, newCurrentSidebarPlugins)
  39. )
  40. return currentAvailableSidebarPlugins
  41. return newCurrentSidebarPlugins
  42. },
  43. )
  44. const activeSidebar = computed<string | null>(() => {
  45. if (!Object.keys(availableSidebarPlugins.value)?.length) return null
  46. if (
  47. switchedSidebar.value &&
  48. availableSidebarPlugins.value[switchedSidebar.value] &&
  49. shownSidebars.value[switchedSidebar.value]
  50. )
  51. return switchedSidebar.value
  52. const sidebar = Object.entries(availableSidebarPlugins.value).filter(
  53. ([sidebar]) => shownSidebars.value[sidebar],
  54. )?.[0]?.[0]
  55. return sidebar === undefined ? ' ' : sidebar // ' ' is a fallback value for a non-selectable sidebar to prevent flickering if sidebar is loading
  56. })
  57. const hasSidebar = computed(() => Boolean(activeSidebar.value))
  58. provideLocal(TICKET_SIDEBAR_SYMBOL, {
  59. shownSidebars,
  60. activeSidebar,
  61. availableSidebarPlugins,
  62. sidebarPlugins,
  63. hasSidebar,
  64. showSidebar,
  65. hideSidebar,
  66. switchSidebar,
  67. })
  68. }
  69. export const useTicketSidebar = () => {
  70. return injectLocal(TICKET_SIDEBAR_SYMBOL) as TicketSidebarInformation
  71. }