index.ts 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445
  1. // Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
  2. import type { Props as IconProps } from '#shared/components/CommonIcon/CommonIcon.vue'
  3. import type { EnumSearchableModels } from '#shared/graphql/types.ts'
  4. import { useSessionStore } from '#shared/stores/session.ts'
  5. import type { Component } from 'vue'
  6. export interface SearchPlugin {
  7. model: EnumSearchableModels
  8. headerLabel: string
  9. searchLabel: string
  10. order: number
  11. link: string
  12. permissions: string[]
  13. icon?: string | IconProps
  14. iconBg?: string
  15. component: Component // component needs to have a slot called "default" and prop "entity"
  16. }
  17. const pluginsModules = import.meta.glob<SearchPlugin>(
  18. ['./**/*.ts', '!./**/index.ts', '!./__tests__/**/*.ts'],
  19. {
  20. eager: true,
  21. import: 'default',
  22. },
  23. )
  24. const pluginsFiles = Object.entries(pluginsModules)
  25. .map<[string, SearchPlugin]>(([file, plugin]) => {
  26. const name = file.replace(/^.*\/([^/]+)\.ts$/, '$1')
  27. return [name, plugin]
  28. })
  29. .sort(([, p1], [, p2]) => p1.order - p2.order)
  30. export const useSearchPlugins = () => {
  31. const { hasPermission } = useSessionStore()
  32. const plugins = pluginsFiles
  33. .filter(([, plugin]) => hasPermission(plugin.permissions))
  34. .reduce<Record<string, SearchPlugin>>((acc, [name, plugin]) => {
  35. acc[name] = plugin
  36. return acc
  37. }, {})
  38. return plugins
  39. }