TicketSimpleTable.vue 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. <!-- Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/ -->
  2. <script setup lang="ts">
  3. import { storeToRefs } from 'pinia'
  4. import { computed } from 'vue'
  5. import type { TicketById } from '#shared/entities/ticket/types.ts'
  6. import { useApplicationStore } from '#shared/stores/application.ts'
  7. import CommonSimpleTable from '#desktop/components/CommonSimpleTable/CommonSimpleTable.vue'
  8. import type {
  9. TableHeader,
  10. TableItem,
  11. } from '#desktop/components/CommonSimpleTable/types.ts'
  12. import CommonTicketStateIndicatorIcon from '#desktop/components/CommonTicketStateIndicatorIcon/CommonTicketStateIndicatorIcon.vue'
  13. import type { TicketRelationAndRecentListItem } from '#desktop/pages/ticket/components/TicketDetailView/TicketSimpleTable/types.ts'
  14. interface Props {
  15. tickets: TicketRelationAndRecentListItem[]
  16. label: string
  17. selectedTicketId?: string
  18. }
  19. const emit = defineEmits<{
  20. 'click-ticket': [TicketRelationAndRecentListItem]
  21. }>()
  22. const { config } = storeToRefs(useApplicationStore())
  23. const headers: TableHeader[] = [
  24. { key: 'state', label: '', truncate: true, type: 'link' },
  25. {
  26. key: 'number',
  27. label: config.value.ticket_hook,
  28. type: 'link',
  29. truncate: true,
  30. },
  31. { key: 'title', label: __('Title'), truncate: true },
  32. { key: 'customer', label: __('Customer'), truncate: true },
  33. { key: 'group', label: __('Group'), truncate: true },
  34. { key: 'createdAt', label: __('Created at'), truncate: true },
  35. ]
  36. const props = defineProps<Props>()
  37. const items = computed<Array<TableItem>>(() =>
  38. props.tickets.map((ticket) => ({
  39. createdAt: ticket.createdAt,
  40. customer: ticket.organization?.name || ticket.customer?.fullname,
  41. group: ticket.group?.name,
  42. id: ticket.id,
  43. internalId: ticket.internalId,
  44. key: ticket.id,
  45. number: {
  46. link: `/tickets/${ticket.internalId}`,
  47. text: ticket.number,
  48. internal: true,
  49. openInNewTab: true,
  50. },
  51. organization: ticket.organization,
  52. title: ticket.title,
  53. stateColorCode: ticket.stateColorCode,
  54. state: ticket.state,
  55. })),
  56. )
  57. const handleRowClick = (row: TableItem) => {
  58. const ticket = props.tickets.find((ticket) => ticket.id === row.id)
  59. emit('click-ticket', ticket!)
  60. }
  61. </script>
  62. <template>
  63. <section>
  64. <CommonLabel class="mb-2" tag="h3">{{ label }}</CommonLabel>
  65. <CommonSimpleTable
  66. ref="simple-table"
  67. class="w-full"
  68. :headers="headers"
  69. :items="items"
  70. :selected-row-id="selectedTicketId"
  71. @click-row="handleRowClick"
  72. >
  73. <template #column-cell-createdAt="{ item, isRowSelected }">
  74. <CommonDateTime
  75. class="-:text-gray-100 -:dark:text-neutral-400 group-hover:text-black group-focus-visible:text-white group-active:text-white group-hover:dark:text-white group-active:dark:text-white"
  76. :class="{ 'text-black dark:text-white': isRowSelected }"
  77. :date-time="item['createdAt'] as string"
  78. type="absolute"
  79. absolute-format="date"
  80. />
  81. </template>
  82. <template #column-cell-state="{ item, isRowSelected }">
  83. <CommonTicketStateIndicatorIcon
  84. class="shrink-0 group-hover:text-black group-focus-visible:text-white group-active:text-white group-hover:dark:text-white group-active:dark:text-white"
  85. :class="{
  86. 'ltr:text-black rtl:text-black dark:text-white': isRowSelected,
  87. }"
  88. :color-code="(item as TicketById).stateColorCode"
  89. :label="(item as TicketById).state.name"
  90. :aria-labelledby="(item as TicketById).id"
  91. icon-size="tiny"
  92. />
  93. </template>
  94. </CommonSimpleTable>
  95. </section>
  96. </template>