useTicketFormOrganizationHandler.ts 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. // Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
  2. import { FormHandlerExecution } from '#shared/components/Form/types.ts'
  3. import type {
  4. FormSchemaField,
  5. ReactiveFormSchemData,
  6. ChangedField,
  7. FormHandlerFunction,
  8. FormHandler,
  9. } from '#shared/components/Form/types.ts'
  10. import { getAutoCompleteOption } from '#shared/entities/organization/utils/getAutoCompleteOption.ts'
  11. import type { Organization, Scalars } from '#shared/graphql/types.ts'
  12. import { useSessionStore } from '#shared/stores/session.ts'
  13. import type { UserData } from '#shared/types/store.ts' // TODO: remove this import
  14. // TODO: needs to be aligned, when auto completes has a final state.
  15. export const useTicketFormOrganizationHandler = (): FormHandler => {
  16. const executeHandler = (
  17. execution: FormHandlerExecution,
  18. schemaData: ReactiveFormSchemData,
  19. changedField?: ChangedField,
  20. ) => {
  21. if (!schemaData.fields.organization_id) return false
  22. if (
  23. execution === FormHandlerExecution.FieldChange &&
  24. (!changedField || changedField.name !== 'customer_id')
  25. ) {
  26. return false
  27. }
  28. return true
  29. }
  30. const handleOrganizationField: FormHandlerFunction = (
  31. execution,
  32. reactivity,
  33. data,
  34. // eslint-disable-next-line sonarjs/cognitive-complexity
  35. ) => {
  36. const { formNode, values, initialEntityObject, changedField } = data
  37. const { schemaData, changeFields, updateSchemaDataField } = reactivity
  38. if (!executeHandler(execution, schemaData, changedField)) return
  39. const session = useSessionStore()
  40. const organizationField: Partial<FormSchemaField> = {
  41. show: false,
  42. required: false,
  43. }
  44. const setCustomer = (): Maybe<UserData> | undefined => {
  45. if (session.hasPermission('ticket.agent')) {
  46. if (changedField?.newValue) {
  47. // TODO: user <=> object ?!?!?
  48. const optionValue = formNode?.find('customer_id', 'name')?.context
  49. ?.optionValueLookup as Record<
  50. number,
  51. Record<'object' | 'user', UserData>
  52. >
  53. // ⚠️ :INFO mobile query retrieves .user and .object for desktop
  54. return (
  55. (optionValue[changedField.newValue as number].object as UserData) ||
  56. (optionValue[changedField.newValue as number].user as UserData)
  57. )
  58. }
  59. if (
  60. execution === FormHandlerExecution.FieldChange ||
  61. !values.customer_id ||
  62. !initialEntityObject
  63. )
  64. return undefined
  65. return initialEntityObject.customer
  66. }
  67. return session.user
  68. }
  69. const setOrganizationField = (
  70. customerId: Scalars['ID']['output'],
  71. organization?: Maybe<Partial<Organization>>,
  72. ) => {
  73. if (!organization) return
  74. organizationField.show = true
  75. organizationField.required = true
  76. const currentValueOption = getAutoCompleteOption(organization)
  77. // Some information can be changed during the next user interactions, so update only the current schema data.
  78. updateSchemaDataField({
  79. name: 'organization_id',
  80. props: {
  81. defaultFilter: '*',
  82. alwaysApplyDefaultFilter: true,
  83. options: [currentValueOption],
  84. additionalQueryParams: {
  85. customerId,
  86. },
  87. },
  88. value: currentValueOption.value,
  89. })
  90. }
  91. const customer = setCustomer()
  92. if (customer?.hasSecondaryOrganizations) {
  93. setOrganizationField(
  94. customer.id,
  95. execution === FormHandlerExecution.Initial && initialEntityObject
  96. ? initialEntityObject.organization
  97. : (customer.organization as Organization),
  98. )
  99. }
  100. // This values should be fixed, until the user change something in the customer_id field.
  101. changeFields.value.organization_id = {
  102. ...(changeFields.value.organization_id || {}),
  103. ...organizationField,
  104. }
  105. }
  106. return {
  107. execution: [FormHandlerExecution.Initial, FormHandlerExecution.FieldChange],
  108. callback: handleOrganizationField,
  109. }
  110. }