TicketSidebarCustomerContent.vue 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. <!-- Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/ -->
  2. <script setup lang="ts">
  3. import { computed } from 'vue'
  4. import CommonUserAvatar from '#shared/components/CommonUserAvatar/CommonUserAvatar.vue'
  5. import ObjectAttributes from '#shared/components/ObjectAttributes/ObjectAttributes.vue'
  6. import type {
  7. ObjectManagerFrontendAttribute,
  8. Organization,
  9. UserQuery,
  10. } from '#shared/graphql/types.ts'
  11. import { normalizeEdges } from '#shared/utils/helpers.ts'
  12. import type { MenuItem } from '#desktop/components/CommonPopoverMenu/types.ts'
  13. import CommonSectionCollapse from '#desktop/components/CommonSectionCollapse/CommonSectionCollapse.vue'
  14. import CommonSimpleEntityList from '#desktop/components/CommonSimpleEntityList/CommonSimpleEntityList.vue'
  15. import { EntityType } from '#desktop/components/CommonSimpleEntityList/types.ts'
  16. import NavigationMenuList from '#desktop/components/NavigationMenu/NavigationMenuList.vue'
  17. import { NavigationMenuDensity } from '#desktop/components/NavigationMenu/types.ts'
  18. import { useChangeCustomerMenuItem } from '#desktop/pages/ticket/components/TicketSidebar/TicketDetailView/actions/TicketChangeCustomer/useChangeCustomerMenuItem.ts'
  19. import {
  20. type TicketSidebarContentProps,
  21. TicketSidebarScreenType,
  22. } from '#desktop/pages/ticket/types/sidebar.ts'
  23. import TicketSidebarContent from '../TicketSidebarContent.vue'
  24. interface Props extends TicketSidebarContentProps {
  25. customer: UserQuery['user']
  26. secondaryOrganizations: ReturnType<
  27. typeof normalizeEdges<Partial<Organization>>
  28. >
  29. objectAttributes: ObjectManagerFrontendAttribute[]
  30. }
  31. const props = defineProps<Props>()
  32. defineEmits<{
  33. 'load-more-secondary-organizations': []
  34. }>()
  35. const actions = computed<MenuItem[]>(() => {
  36. const availableActions: MenuItem[] = []
  37. // :TODO find a better way to split this up maybe on plugin level
  38. // :TODO find a way to provide the ticket via prop
  39. if (props.context.screenType === TicketSidebarScreenType.TicketDetailView) {
  40. const { customerChangeMenuItem } = useChangeCustomerMenuItem()
  41. availableActions.push(customerChangeMenuItem)
  42. }
  43. return availableActions // ADD the rest available menu actions
  44. })
  45. </script>
  46. <template>
  47. <TicketSidebarContent
  48. :title="sidebarPlugin.title"
  49. :icon="sidebarPlugin.icon"
  50. :entity="customer"
  51. :actions="actions"
  52. >
  53. <div class="flex gap-2">
  54. <CommonUserAvatar v-if="customer" :entity="customer" size="normal" />
  55. <div class="flex flex-col justify-center gap-px">
  56. <CommonLabel size="large" class="text-gray-300 dark:text-neutral-400">
  57. {{ customer?.fullname }}
  58. </CommonLabel>
  59. <CommonLink
  60. v-if="customer?.organization"
  61. :link="`/organizations/${customer.organization?.internalId}`"
  62. class="text-sm leading-snug"
  63. >
  64. {{ customer?.organization.name }}
  65. </CommonLink>
  66. </div>
  67. </div>
  68. <ObjectAttributes
  69. :attributes="objectAttributes"
  70. :object="customer"
  71. :skip-attributes="['firstname', 'lastname']"
  72. />
  73. <CommonSimpleEntityList
  74. v-if="secondaryOrganizations.totalCount"
  75. id="customer-secondary-organizations"
  76. :type="EntityType.Organization"
  77. :label="__('Secondary organizations')"
  78. :entity="secondaryOrganizations"
  79. @load-more="$emit('load-more-secondary-organizations')"
  80. />
  81. <CommonSectionCollapse id="customer-tickets" :title="__('Tickets')">
  82. <NavigationMenuList
  83. class="mt-1"
  84. :density="NavigationMenuDensity.Dense"
  85. :items="[
  86. {
  87. label: __('open tickets'),
  88. icon: 'check-circle-no',
  89. iconColor: 'fill-yellow-500',
  90. count: customer?.ticketsCount?.open || 0,
  91. route: '/search/ticket/open',
  92. },
  93. {
  94. label: __('closed tickets'),
  95. icon: 'check-circle-outline',
  96. iconColor: 'fill-green-400',
  97. count: customer?.ticketsCount?.closed || 0,
  98. route: '/search/ticket/closed',
  99. },
  100. ]"
  101. />
  102. </CommonSectionCollapse>
  103. </TicketSidebarContent>
  104. </template>