TicketSimpleTable.vue 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. <!-- Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/ -->
  2. <script setup lang="ts">
  3. import { storeToRefs } from 'pinia'
  4. import { computed, useTemplateRef } 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 simpleTableInstance = useTemplateRef('simple-table')
  23. const { config } = storeToRefs(useApplicationStore())
  24. const headers: TableHeader[] = [
  25. { key: 'state', label: '', truncate: true },
  26. {
  27. key: 'number',
  28. label: config.value.ticket_hook,
  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: ticket.number,
  46. organization: ticket.organization,
  47. title: ticket.title,
  48. stateColorCode: ticket.stateColorCode,
  49. state: ticket.state,
  50. })),
  51. )
  52. const handleRowClick = (row: TableItem) => {
  53. const ticket = props.tickets.find((ticket) => ticket.id === row.id)
  54. emit('click-ticket', ticket!)
  55. }
  56. </script>
  57. <template>
  58. <section>
  59. <CommonLabel class="mb-2" tag="h3">{{ label }}</CommonLabel>
  60. <CommonSimpleTable
  61. ref="simple-table"
  62. class="w-full"
  63. :headers="headers"
  64. :items="items"
  65. :selected-row-id="selectedTicketId"
  66. @click-row="handleRowClick"
  67. >
  68. <template #column-cell-number="{ item, header, isRowSelected }">
  69. <CommonLink
  70. v-tooltip.truncate="simpleTableInstance?.getTooltipText(item, header)"
  71. :link="`/tickets/${(item as TicketById).internalId}`"
  72. :class="{
  73. 'ltr:text-black rtl:text-black dark:text-white': isRowSelected,
  74. }"
  75. class="truncate text-sm hover:no-underline group-hover:text-black group-active:text-black group-hover:dark:text-white group-active:dark:text-white"
  76. internal
  77. target="_blank"
  78. @click.stop
  79. @keydown.stop
  80. >{{ item.number }}
  81. </CommonLink>
  82. </template>
  83. <template #column-cell-createdAt="{ item, isRowSelected }">
  84. <CommonDateTime
  85. class="-:text-gray-100 -:dark:text-neutral-400 group-hover:text-black group-active:text-black group-hover:dark:text-white group-active:dark:text-white"
  86. :class="{ 'text-black dark:text-white': isRowSelected }"
  87. :date-time="item['createdAt'] as string"
  88. type="absolute"
  89. absolute-format="date"
  90. />
  91. </template>
  92. <template #column-cell-state="{ item, isRowSelected }">
  93. <CommonTicketStateIndicatorIcon
  94. class="shrink-0 group-hover:text-black group-active:text-black group-hover:dark:text-white group-active:dark:text-white"
  95. :class="{
  96. 'ltr:text-black rtl:text-black dark:text-white': isRowSelected,
  97. }"
  98. :color-code="(item as TicketById).stateColorCode"
  99. :label="(item as TicketById).state.name"
  100. :aria-labelledby="(item as TicketById).id"
  101. icon-size="tiny"
  102. />
  103. </template>
  104. </CommonSimpleTable>
  105. </section>
  106. </template>