|
|
@@ -0,0 +1,151 @@
|
|
|
+<template>
|
|
|
+ <main>
|
|
|
+ <LayoutContainer>
|
|
|
+ <UiForm
|
|
|
+ ref="form"
|
|
|
+ :model="Subdomain"
|
|
|
+ :entity="subdomain"
|
|
|
+ :submitActions="submitActions"
|
|
|
+ :validation-pending="validationPending"
|
|
|
+ >
|
|
|
+ <v-container :fluid="true" class="container">
|
|
|
+ <v-row>
|
|
|
+ <v-col cols="12" sm="6">
|
|
|
+ <div>{{ $t('pleaseEnterYourNewSubdomain')}} :</div>
|
|
|
+ </v-col>
|
|
|
+ </v-row>
|
|
|
+ <v-row>
|
|
|
+ <v-col cols="12" sm="6">
|
|
|
+ <UiInputText
|
|
|
+ v-model="subdomain.subdomain"
|
|
|
+ field="subdomain"
|
|
|
+ type="string"
|
|
|
+ :rules="rules()"
|
|
|
+ @update:modelValue="checkSubdomainHook($event)"
|
|
|
+ />
|
|
|
+ </v-col>
|
|
|
+ </v-row>
|
|
|
+ <div class="validationMessage">
|
|
|
+ <i v-if="validationPending" class="validation_status">{{ $t('validation_ongoing') }}</i>
|
|
|
+ <i v-else-if="subdomainAvailable === true" class="validation_status text-success">{{ $t('this_subdomain_is_available') }}</i>
|
|
|
+ </div>
|
|
|
+ </v-container>
|
|
|
+
|
|
|
+ <template #form.button>
|
|
|
+ <NuxtLink :to="{ path: '/parameters#website'}" class="no-decoration">
|
|
|
+ <v-btn class="mr-4 theme-neutral">
|
|
|
+ {{ $t('back') }}
|
|
|
+ </v-btn>
|
|
|
+ </NuxtLink>
|
|
|
+ </template>
|
|
|
+ </UiForm>
|
|
|
+ </LayoutContainer>
|
|
|
+ </main>
|
|
|
+
|
|
|
+</template>
|
|
|
+
|
|
|
+<script setup lang="ts">
|
|
|
+import {useEntityManager} from "~/composables/data/useEntityManager";
|
|
|
+import Subdomain from "~/models/Organization/Subdomain";
|
|
|
+import {SUBMIT_TYPE} from "~/types/enum/enums";
|
|
|
+import {AnyJson} from "~/types/data";
|
|
|
+import SubdomainValidation from "~/services/validation/subdomainValidation";
|
|
|
+import {Ref} from "@vue/reactivity";
|
|
|
+import {useValidation} from "~/composables/form/useValidation";
|
|
|
+import {useSubdomainValidation} from "~/composables/form/validation/useSubdomainValidation";
|
|
|
+
|
|
|
+const i18n = useI18n()
|
|
|
+
|
|
|
+const { em } = useEntityManager()
|
|
|
+const { subdomainValidation } = useSubdomainValidation()
|
|
|
+
|
|
|
+//@ts-ignore
|
|
|
+const subdomain: Ref<Subdomain> = ref(em.newInstance(Subdomain) as Subdomain)
|
|
|
+
|
|
|
+const submitActions = computed(() => {
|
|
|
+ let actions: AnyJson = {}
|
|
|
+ actions[SUBMIT_TYPE.SAVE_AND_BACK] = { path: `/parameters/communication` }
|
|
|
+ return actions
|
|
|
+})
|
|
|
+
|
|
|
+const form: Ref<HTMLCanvasElement | null> = ref(null);
|
|
|
+const subdomainAvailable: Ref<boolean | null> = ref(null)
|
|
|
+const validationPending: Ref<boolean> = ref(false)
|
|
|
+
|
|
|
+
|
|
|
+/**
|
|
|
+ * Délai entre le dernier caractère saisi et la requête de vérification de la disponibilité du sous-domaine (en ms)
|
|
|
+ */
|
|
|
+const inputDelay = 600
|
|
|
+
|
|
|
+/**
|
|
|
+ * Nombre de requêtes en attentes. On n'effectuera la vérification de disponibilité qu'à la dernière d'entre elles.
|
|
|
+ */
|
|
|
+let requestPile = 0
|
|
|
+
|
|
|
+/**
|
|
|
+ * La valeur du sous-domaine a été modifiée, on ajoute une demande de vérification à la pile.
|
|
|
+ * @param subdomain
|
|
|
+ */
|
|
|
+const requestAvailabilityCheck = (subdomain: string) => {
|
|
|
+ requestPile += 1
|
|
|
+ validationPending.value = true
|
|
|
+ setTimeout(() => popLastRequest(subdomain), inputDelay)
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * Le délai passé, on retire une requête de la pile. Si c'est la dernière de la pile, c'est que la saisie est terminée
|
|
|
+ * depuis le délai attendu, on effectue la vérification de disponibilité.
|
|
|
+ * @param subdomain
|
|
|
+ */
|
|
|
+const popLastRequest = async (subdomain: string) => {
|
|
|
+ requestPile -= 1
|
|
|
+ if (requestPile === 0) {
|
|
|
+ await performAvailabilityCheck(subdomain)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * Procède à la vérification de disponibilité.
|
|
|
+ * @param subdomain
|
|
|
+ */
|
|
|
+const performAvailabilityCheck = async (subdomain: string) => {
|
|
|
+ subdomainAvailable.value = await subdomainValidation.isAvailable(subdomain);
|
|
|
+ validationPending.value = false
|
|
|
+
|
|
|
+ //@ts-ignore
|
|
|
+ form.value.validate()
|
|
|
+}
|
|
|
+
|
|
|
+const checkSubdomainHook = async (subdomain: string | null) => {
|
|
|
+ subdomainAvailable.value = null
|
|
|
+ if (subdomain !== null && SubdomainValidation.isValid(subdomain)) {
|
|
|
+ requestAvailabilityCheck(subdomain)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * Règles de validation
|
|
|
+ */
|
|
|
+const rules = () => [
|
|
|
+ (subdomain: string | null) => (subdomain !== null && subdomain.length > 0) || i18n.t('please_enter_a_value_for_the_subdomain'),
|
|
|
+ (subdomain: string | null) => (subdomain !== null && subdomain.length >= 2 && subdomain.length <=60) || i18n.t('subdomain_need_to_have_0_to_60_cars'),
|
|
|
+ (subdomain: string | null) => SubdomainValidation.isValid(subdomain) || i18n.t('subdomain_can_not_contain_spaces_or_special_cars'),
|
|
|
+ () => (subdomainAvailable.value !== false) || i18n.t('this_subdomain_is_already_in_use')
|
|
|
+]
|
|
|
+
|
|
|
+
|
|
|
+</script>
|
|
|
+
|
|
|
+<style scoped lang="scss">
|
|
|
+.validation_status {
|
|
|
+ font-size: 13px;
|
|
|
+ font-weight: 600;
|
|
|
+}
|
|
|
+
|
|
|
+.validationMessage {
|
|
|
+ height: 20px;
|
|
|
+ min-height: 20px;
|
|
|
+}
|
|
|
+
|
|
|
+</style>
|