new.vue 4.1 KB

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