useTicketEdit.ts 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. // Copyright (C) 2012-2023 Zammad Foundation, https://zammad-foundation.org/
  2. import type { ComputedRef, ShallowRef } from 'vue'
  3. import { computed, reactive, watch } from 'vue'
  4. import type { FormValues, FormRef, FormData } from '@shared/components/Form'
  5. import { useObjectAttributeFormData } from '@shared/entities/object-attributes/composables/useObjectAttributeFormData'
  6. import { useObjectAttributes } from '@shared/entities/object-attributes/composables/useObjectAttributes'
  7. import type { TicketUpdateInput } from '@shared/graphql/types'
  8. import { EnumObjectManagerObjects } from '@shared/graphql/types'
  9. import { MutationHandler } from '@shared/server/apollo/handler'
  10. import type { TicketById } from '@shared/entities/ticket/types'
  11. import type { TicketArticleFormValues } from '@shared/entities/ticket-article/action/plugins/types'
  12. import type { PartialRequired } from '@shared/types/utils'
  13. import { convertFilesToAttachmentInput } from '@shared/utils/files'
  14. import { getNodeByName } from '@shared/components/Form/utils'
  15. import { populateEditorNewLines } from '@shared/components/Form/fields/FieldEditor/utils'
  16. import { useTicketUpdateMutation } from '../graphql/mutations/update.api'
  17. type TicketArticleReceivedFormValues = PartialRequired<
  18. TicketArticleFormValues,
  19. // form always has these values
  20. 'articleType' | 'body' | 'internal'
  21. >
  22. export const useTicketEdit = (
  23. ticket: ComputedRef<TicketById | undefined>,
  24. form: ShallowRef<FormRef | undefined>,
  25. ) => {
  26. const initialTicketValue = reactive<FormValues>({})
  27. const mutationUpdate = new MutationHandler(useTicketUpdateMutation({}))
  28. watch(ticket, (ticket) => {
  29. if (!ticket) {
  30. return
  31. }
  32. const ticketId = initialTicketValue.id || ticket.id
  33. const { internalId: ownerInternalId } = ticket.owner
  34. initialTicketValue.id = ticket.id
  35. // show Zammad user as empty
  36. initialTicketValue.owner_id = ownerInternalId === 1 ? null : ownerInternalId
  37. form.value?.resetForm(initialTicketValue, ticket, {
  38. // don't reset to new values, if user changes something
  39. // if ticket is different, it's probably navigation to another ticket,
  40. // so we can safely reset the form
  41. resetDirty: ticketId !== ticket.id,
  42. })
  43. })
  44. const isTicketFormGroupValid = computed(() => {
  45. const ticketGroup = form.value?.formNode?.at('ticket')
  46. return !!ticketGroup?.context?.state.valid
  47. })
  48. const { attributesLookup: ticketObjectAttributesLookup } =
  49. useObjectAttributes(EnumObjectManagerObjects.Ticket)
  50. const processArticle = (
  51. formId: string,
  52. article: TicketArticleReceivedFormValues | undefined,
  53. ) => {
  54. if (!article) return null
  55. const contentType =
  56. getNodeByName(formId, 'body')?.context?.contentType || 'text/html'
  57. if (contentType === 'text/html') {
  58. article.body = populateEditorNewLines(article.body)
  59. }
  60. return {
  61. type: article.articleType,
  62. body: article.body,
  63. internal: article.internal,
  64. cc: article.cc,
  65. to: article.to,
  66. subject: article.subject,
  67. subtype: article.subtype,
  68. inReplyTo: article.inReplyTo,
  69. contentType,
  70. attachments: convertFilesToAttachmentInput(formId, article.attachments),
  71. security: article.security,
  72. }
  73. }
  74. const editTicket = async (formData: FormData) => {
  75. if (!ticket.value) return undefined
  76. if (!formData.owner_id) {
  77. formData.owner_id = 1
  78. }
  79. const { internalObjectAttributeValues, additionalObjectAttributeValues } =
  80. useObjectAttributeFormData(ticketObjectAttributesLookup.value, formData)
  81. const formArticle = formData.article as
  82. | TicketArticleReceivedFormValues
  83. | undefined
  84. const article = processArticle(formData.formId, formArticle)
  85. return mutationUpdate.send({
  86. ticketId: ticket.value.id,
  87. input: {
  88. ...internalObjectAttributeValues,
  89. objectAttributeValues: additionalObjectAttributeValues,
  90. article,
  91. } as TicketUpdateInput,
  92. })
  93. }
  94. return {
  95. initialTicketValue,
  96. isTicketFormGroupValid,
  97. editTicket,
  98. }
  99. }