new.vue 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. <template>
  2. <main>
  3. <LayoutContainer>
  4. <UiForm
  5. ref="form"
  6. :model="Subdomain"
  7. :entity="subdomain"
  8. :submitActions="submitActions"
  9. :validation-pending="validationPending"
  10. :refresh-profile="true"
  11. >
  12. <v-container :fluid="true" class="container">
  13. <v-row>
  14. <v-col cols="12" sm="6">
  15. <div>{{ $t('pleaseEnterYourNewSubdomain') }} :</div>
  16. </v-col>
  17. </v-row>
  18. <v-row>
  19. <v-col cols="12" sm="6">
  20. <UiInputText
  21. v-model="subdomain.subdomain"
  22. field="subdomain"
  23. type="string"
  24. :rules="rules()"
  25. @update:modelValue="onSubdomainUpdate"
  26. />
  27. </v-col>
  28. </v-row>
  29. <div class="validationMessage">
  30. <span v-if="validationPending">
  31. <v-progress-circular size="16" indeterminate />
  32. <i class="ml-2">{{ $t('validation_ongoing') }}</i>
  33. </span>
  34. <span v-else-if="subdomainAvailable === true" class="text-success">
  35. <v-icon>fa fa-check</v-icon>
  36. <i class="ml-2">{{ $t('this_subdomain_is_available') }}</i>
  37. </span>
  38. </div>
  39. </v-container>
  40. <template #form.button>
  41. <NuxtLink :to="goBackRoute" class="no-decoration">
  42. <v-btn class="mr-4 theme-neutral">
  43. {{ $t('back') }}
  44. </v-btn>
  45. </NuxtLink>
  46. </template>
  47. </UiForm>
  48. </LayoutContainer>
  49. </main>
  50. </template>
  51. <script setup lang="ts">
  52. import { useEntityManager } from '~/composables/data/useEntityManager'
  53. import Subdomain from '~/models/Organization/Subdomain'
  54. import { SUBMIT_TYPE } from '~/types/enum/enums'
  55. import type { AnyJson } from '~/types/data'
  56. import SubdomainValidation from '~/services/validation/subdomainValidation'
  57. import type { Ref } from '@vue/reactivity'
  58. import { useSubdomainValidation } from '~/composables/form/validation/useSubdomainValidation'
  59. import _ from 'lodash'
  60. const i18n = useI18n()
  61. const { em } = useEntityManager()
  62. const { subdomainValidation } = useSubdomainValidation()
  63. //@ts-ignore
  64. const subdomain: Ref<Subdomain> = ref(em.newInstance(Subdomain) as Subdomain)
  65. const goBackRoute = { path: `/parameters`, query: { tab: 'website' } }
  66. const submitActions = computed(() => {
  67. let actions: AnyJson = {}
  68. actions[SUBMIT_TYPE.SAVE_AND_BACK] = goBackRoute
  69. return actions
  70. })
  71. const form: Ref<HTMLCanvasElement | null> = ref(null)
  72. const subdomainAvailable: Ref<boolean | null> = ref(null)
  73. const validationPending: Ref<boolean> = ref(false)
  74. /**
  75. * Délai entre le dernier caractère saisi et la requête de vérification de la disponibilité du sous-domaine (en ms)
  76. */
  77. const inputDelay = 600
  78. /**
  79. * Procède à la vérification de disponibilité.
  80. * @param subdomain
  81. */
  82. const checkAvailability = async (subdomain: string) => {
  83. subdomainAvailable.value = await subdomainValidation.isAvailable(subdomain)
  84. validationPending.value = false
  85. //@ts-ignore
  86. form.value.validate()
  87. }
  88. /**
  89. * Version debounced de la fonction checkAvailability
  90. * @see https://docs-lodash.com/v4/debounce/
  91. */
  92. const checkAvailabilityDebounced: _.DebouncedFunc<() => void> = _.debounce(
  93. async () => {
  94. if (subdomain.value.subdomain === null) {
  95. return
  96. }
  97. await checkAvailability(subdomain.value.subdomain)
  98. },
  99. inputDelay
  100. )
  101. const onSubdomainUpdate = () => {
  102. subdomainAvailable.value = null
  103. validationPending.value = true
  104. checkAvailabilityDebounced()
  105. }
  106. /**
  107. * Règles de validation
  108. */
  109. const rules = () => [
  110. (subdomain: string | null) =>
  111. (subdomain !== null && subdomain.length > 0) ||
  112. i18n.t('please_enter_a_value_for_the_subdomain'),
  113. (subdomain: string | null) =>
  114. (subdomain !== null && subdomain.length >= 2 && subdomain.length <= 60) ||
  115. i18n.t('subdomain_need_to_have_0_to_60_cars'),
  116. (subdomain: string | null) =>
  117. SubdomainValidation.isValid(subdomain) ||
  118. i18n.t('subdomain_can_not_contain_spaces_or_special_cars'),
  119. async () =>
  120. subdomainAvailable.value !== false ||
  121. i18n.t('this_subdomain_is_already_in_use'),
  122. ]
  123. </script>
  124. <style scoped lang="scss">
  125. .validationMessage {
  126. font-size: 13px;
  127. height: 20px;
  128. min-height: 20px;
  129. }
  130. </style>