CommonTicketStateIndicator.vue 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. <!-- Copyright (C) 2012-2022 Zammad Foundation, https://zammad-foundation.org/ -->
  2. <script setup lang="ts">
  3. import { computed } from 'vue'
  4. import { TicketState } from '@shared/entities/ticket/types'
  5. // TODO: Add a test and story for this common component.
  6. export interface Props {
  7. status?: TicketState | string
  8. label: string
  9. pill?: boolean
  10. }
  11. const props = withDefaults(defineProps<Props>(), {
  12. pill: false,
  13. })
  14. const states = new Set<string>(Object.values(TicketState))
  15. const statusIndicator = computed(() => {
  16. if (!props.status || !states.has(props.status)) {
  17. return ''
  18. }
  19. return `state-${props.status}`
  20. })
  21. </script>
  22. <template>
  23. <div
  24. :class="{
  25. 'status-pill': pill,
  26. [`status-${status}`]: pill,
  27. }"
  28. class="flex items-center"
  29. role="group"
  30. >
  31. <img
  32. v-if="statusIndicator"
  33. :src="`/assets/images/icons/${statusIndicator}.svg`"
  34. :alt="label"
  35. :width="pill ? 12 : 24"
  36. :height="pill ? 12 : 24"
  37. />
  38. <div v-if="pill" class="ml-[2px] text-xs uppercase leading-[14px]">
  39. {{ label }}
  40. </div>
  41. </div>
  42. </template>
  43. <style scoped lang="scss">
  44. .status {
  45. &-pill {
  46. @apply rounded px-px pr-1.5 pl-1;
  47. }
  48. &-closed {
  49. @apply bg-green-highlight text-green;
  50. }
  51. &-waiting-for-closure,
  52. &-waiting-for-reminder {
  53. @apply bg-gray-highlight text-gray;
  54. }
  55. &-open {
  56. @apply bg-yellow-highlight text-yellow;
  57. }
  58. &-escalated {
  59. @apply bg-red-highlight text-red;
  60. }
  61. }
  62. </style>