PersonalSettingPassword.vue 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. <!-- Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/ -->
  2. <script setup lang="ts">
  3. import { useRouter } from 'vue-router'
  4. import {
  5. NotificationTypes,
  6. useNotifications,
  7. } from '#shared/components/CommonNotifications/index.ts'
  8. import Form from '#shared/components/Form/Form.vue'
  9. import type { FormSubmitData } from '#shared/components/Form/types.ts'
  10. import { useForm } from '#shared/components/Form/useForm.ts'
  11. import { redirectToError } from '#shared/router/error.ts'
  12. import { MutationHandler } from '#shared/server/apollo/handler/index.ts'
  13. import CommonButton from '#desktop/components/CommonButton/CommonButton.vue'
  14. import LayoutContent from '#desktop/components/layout/LayoutContent.vue'
  15. import { useCheckChangePassword } from '../composables/permission/useCheckChangePassword.ts'
  16. import { useBreadcrumb } from '../composables/useBreadcrumb.ts'
  17. import { useUserCurrentChangePasswordMutation } from '../graphql/mutations/userCurrentChangePassword.api.ts'
  18. import type { ChangePasswordFormData } from '../types/change-password.ts'
  19. defineOptions({
  20. beforeRouteEnter() {
  21. const { canChangePassword } = useCheckChangePassword()
  22. if (canChangePassword.value) return true
  23. return redirectToError(useRouter())
  24. },
  25. })
  26. const { form, isDisabled } = useForm()
  27. const schema = [
  28. {
  29. isLayout: true,
  30. element: 'div',
  31. attrs: {
  32. class: 'grid grid-cols-2 gap-2.5',
  33. },
  34. children: [
  35. {
  36. name: 'current_password',
  37. label: __('Current password'),
  38. type: 'password',
  39. outerClass: 'col-span-2',
  40. props: {
  41. maxLength: 1001,
  42. autocomplete: 'current-password',
  43. },
  44. required: true,
  45. },
  46. {
  47. name: 'new_password',
  48. label: __('New password'),
  49. type: 'password',
  50. outerClass: 'col-span-1',
  51. props: {
  52. maxLength: 1001,
  53. autocomplete: 'new-password',
  54. },
  55. required: true,
  56. },
  57. {
  58. name: 'new_password_confirm',
  59. label: __('Confirm new password'),
  60. type: 'password',
  61. validation: 'confirm',
  62. outerClass: 'col-span-1',
  63. props: {
  64. maxLength: 1001,
  65. autocomplete: 'new-password',
  66. },
  67. required: true,
  68. },
  69. ],
  70. },
  71. ]
  72. const { breadcrumbItems } = useBreadcrumb(__('Password'))
  73. const { notify } = useNotifications()
  74. const changePasswordMutation = new MutationHandler(
  75. useUserCurrentChangePasswordMutation(),
  76. {
  77. errorNotificationMessage: __('Password could not be changed.'),
  78. },
  79. )
  80. const submitForm = async (formData: FormSubmitData<ChangePasswordFormData>) => {
  81. return changePasswordMutation
  82. .send({
  83. currentPassword: formData.current_password as string,
  84. newPassword: formData.new_password as string,
  85. })
  86. .then((data) => {
  87. if (data?.userCurrentChangePassword?.success) {
  88. notify({
  89. id: 'password-changed',
  90. type: NotificationTypes.Success,
  91. message: __('Password changed successfully.'),
  92. })
  93. }
  94. })
  95. }
  96. </script>
  97. <template>
  98. <LayoutContent
  99. :breadcrumb-items="breadcrumbItems"
  100. :help-text="
  101. $t('Enter your current password, insert a new one and confirm it.')
  102. "
  103. width="narrow"
  104. >
  105. <div class="mb-4">
  106. <Form
  107. ref="form"
  108. :schema="schema"
  109. clear-values-after-submit
  110. @submit="submitForm($event as FormSubmitData<ChangePasswordFormData>)"
  111. >
  112. <template #after-fields>
  113. <div class="mt-5 flex items-center justify-end gap-2">
  114. <CommonButton
  115. variant="submit"
  116. type="submit"
  117. size="medium"
  118. :disabled="isDisabled"
  119. >
  120. {{ $t('Change Password') }}
  121. </CommonButton>
  122. </div>
  123. </template>
  124. </Form>
  125. </div>
  126. </LayoutContent>
  127. </template>