PersonalSettingPassword.vue 3.8 KB

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