Переглянути джерело

implements new organization website management

Olivier Massot 3 роки тому
батько
коміт
89c687c39d

+ 0 - 0
components/Form/Parameters/Subdomain.vue


+ 1 - 1
composables/layout/Menus/websiteMenu.ts

@@ -53,7 +53,7 @@ class WebsiteMenu extends BaseMenu implements Menu {
   }
 
   getWebsite (organization: organizationState): string {
-    return organization.website ? organization.website : this.$config.baseURL_typo3.replace('###subDomain###', organization.subDomain)
+    return organization.website ?? '';
   }
 }
 

+ 2 - 0
lang/content/parameters/fr-FR.js

@@ -1,5 +1,7 @@
 export default (context, locale) => {
   return ({
     'help_super_admin': 'Le compte super-admin possède tous les droits de gestion sur votre logiciel. On l’utilise surtout pour la gestion de votre site internet et, à la première connexion au logiciel, afin de créer des comptes pour tous membres de votre structure. Enfin, il peut également être utile en cas de dépannage dans certaines situations particulières.',
+    yourWebsiteAddressIs: 'L\'adresse de votre site web est',
+    areYourSureYouWantToDisableYourOpentalentWebsite: 'Êtes-vous sûr(e) de vouloir désactiver votre site web Opentalent'
   })
 }

+ 2 - 2
lang/field/fr-FR.js

@@ -8,6 +8,7 @@ export default (context, locale) => {
     username: 'Login de connexion',
     residenceArea: 'Zones de résidence',
     desactivateOpentalentSiteWeb: 'Désactiver le site opentalent',
+    reactivateOpentalentSiteWeb: 'Réactiver le site Opentalent',
     passwordSMS: 'Mot de passe SMS',
     usernameSMS: 'Nom d\'utilisateur SMS',
     smsSenderName: 'Personnaliser le nom de l\'expéditeur SMS',
@@ -34,10 +35,9 @@ export default (context, locale) => {
     editCriteriaNotationByAdminOnly: 'Autoriser uniquement l\'administration à modifier les critères d\'évaluation',
     trackingValidation: 'Contrôle et validation du suivi pédagogique par l\'administration',
     publicationDirectors: 'Directeur(s) de publication',
-    website: 'Autre site web',
+    otherWebsite: 'Autre site web',
     newSubDomain: 'Nouveau sous domaine',
     subDomainHistorical: 'Historique de vos sous domaine(s)',
-    otherWebsite: 'Votre site Opentalent est',
     timezone: 'Fuseau horaire',
     qrCode: 'QrCode pour la licence',
     studentsAreAdherents: 'Les élèves sont également adhérents de l\'association',

+ 4 - 0
lang/layout/fr-FR.js

@@ -210,5 +210,9 @@ export default (context, locale) => {
     your_message: "Votre message",
     has_been_sent: "a été envoyé",
     ready_to_be: "est prêt à être",
+    none: "Aucun",
+    please_confirm: "Veuillez confirmer",
+    yes: "Oui",
+    no: "Non",
   })
 }

+ 8 - 1
models/Organization/Parameters.ts

@@ -1,4 +1,5 @@
-import {Str, Model, Uid, Bool, Num, Attr} from '@vuex-orm/core'
+import {Str, Model, Uid, Bool, Num, Attr, HasOne} from '@vuex-orm/core'
+import {Subdomain} from "~/models/Organization/Subdomain";
 
 export class Parameters extends Model {
   static entity = 'parameters'
@@ -42,6 +43,9 @@ export class Parameters extends Model {
   @Str(null, { nullable: true })
   otherWebsite!: string|null
 
+  @Str(null, { nullable: true })
+  customDomain!: string|null
+
   @Bool(false, { nullable: false })
   desactivateOpentalentSiteWeb!: boolean
 
@@ -113,4 +117,7 @@ export class Parameters extends Model {
 
   @Bool(false, { nullable: false })
   sendAttendanceSms!: boolean
+
+  @Attr([])
+  subdomains!: []
 }

+ 15 - 0
models/Organization/Subdomain.ts

@@ -0,0 +1,15 @@
+import {Bool, Model, Str, Uid} from "@vuex-orm/core";
+
+
+export class Subdomain extends Model {
+  static entity = 'subdomains'
+
+  @Uid()
+  id!: number | string | null
+
+  @Str(null, {nullable: true})
+  subdomain!: string | null
+
+  @Bool(false, { nullable: false })
+  active!: boolean
+}

+ 94 - 21
pages/parameters/communication.vue

@@ -9,30 +9,61 @@
               <v-row>
                 <v-col cols="12" sm="6">
                   <div>
-                    <span>{{ $t('otherWebsite') }} : </span>
-                    <span>{{ entry['otherWebsite'] }}</span>
+                    <span>{{ $t('yourWebsiteAddressIs') }} : </span>
+                    <span>{{ getCurrentWebsite(entry) || $t('none') }}</span>
                   </div>
                 </v-col>
 
-                <v-col cols="12" sm="6">
-                  <div>
-                    <span>{{ $t('subDomainHistorical') }} : </span>
-                  </div>
-                </v-col>
-
-                <v-col cols="12" sm="6">
-                  <UiInputText field="newSubDomain" :data="entry['newSubDomain']" />
+                <v-col cols="12" sm="6" v-if="!organizationProfile.isCmf()">
+                  <v-btn
+                    color="error"
+                    v-if="entry['desactivateOpentalentSiteWeb'] === false"
+                    @click="confirmWebsiteDeactivation()"
+                  >{{ $t('desactivateOpentalentSiteWeb') }} </v-btn>
+
+                  <v-btn
+                    color="primary"
+                    v-else
+                    @click="reactivateOpentalentSiteWeb(updateRepository)"
+                  >{{ $t('reactivateOpentalentSiteWeb') }}</v-btn>
+
+                  <lazy-LayoutDialog
+                    :show="showSiteWebConfirmationDialog"
+                  >
+                    <template #dialogTitle>{{ $t('please_confirm')}}</template>
+                    <template #dialogText>
+                      <div class="ma-2">
+                        {{ $t('areYourSureYouWantToDisableYourOpentalentWebsite')}} ?
+                      </div>
+                    </template>
+                    <template #dialogBtn>
+                      <v-btn
+                        color="ot_super_light_grey"
+                        @click="showSiteWebConfirmationDialog=false"
+                      >
+                        {{ $t('cancel') }}
+                      </v-btn>
+                      <v-btn
+                        color="primary"
+                        @click="showSiteWebConfirmationDialog=false;desactivateOpentalentSiteWeb(updateRepository)"
+                      >
+                        {{ $t('yes') }}
+                      </v-btn>
+                    </template>
+                  </lazy-LayoutDialog>
                 </v-col>
 
-                <v-col cols="12" sm="6" v-if="!organizationProfile.isCmf()">
-                  <UiInputCheckbox field="desactivateOpentalentSiteWeb" :data="entry['desactivateOpentalentSiteWeb']" @update="updateRepository" />
+                <v-col cols="12" sm="6" v-if="entry['desactivateOpentalentSiteWeb'] === false">
+                  <span>{{ $t('subDomainHistorical') }} : </span>
+<!--                    <span>{{ entry['subdomains'] }}</span>-->
+                  <FormParametersSubdomain :parametersId="entry['id']" />
                 </v-col>
 
                 <v-col cols="12" sm="6">
-                  <UiInputText field="website" :data="entry['website']" @update="updateRepository" />
+                  <UiInputText field="otherWebsite" :data="entry['otherWebsite']" @update="updateRepository" />
                 </v-col>
 
-                <v-col cols="12" sm="6">
+                <v-col cols="12" sm="6" v-if="entry['desactivateOpentalentSiteWeb'] === false">
                   <UiInputAutocompleteWithAPI
                     field="publicationDirectors"
                     label="publicationDirectors"
@@ -77,23 +108,24 @@
 </template>
 
 <script lang="ts">
-import {computed, ComputedRef, defineComponent, reactive, ref, useContext} from '@nuxtjs/composition-api'
-import { Organization } from '@/models/Organization/Organization'
-import { repositoryHelper } from '~/services/store/repository'
+import {computed, ComputedRef, defineComponent, reactive, ref, Ref, useContext} from '@nuxtjs/composition-api'
 import {useDataUtils} from "~/composables/data/useDataUtils";
 import {Parameters} from "~/models/Organization/Parameters";
-import {Query} from "@vuex-orm/core";
 import {$organizationProfile} from "~/services/profile/organizationProfile";
-import ModelsUtils from "~/services/utils/modelsUtils";
 import {useAccessesProvider} from "~/composables/data/useAccessesProvider";
+import {repositoryHelper} from "~/services/store/repository";
+import {Query} from "@vuex-orm/core";
+import UrlBuilder from "~/services/connection/urlBuilder";
 
 export default defineComponent({
-  name: 'parameters',
+  name: 'communication',
   setup () {
     const {store, $dataProvider, app: {i18n}} = useContext()
     const {getItemToEdit} = useDataUtils($dataProvider)
     const {getPhysicalByFullName: accessSearch} = useAccessesProvider($dataProvider)
 
+    const showSiteWebConfirmationDialog: Ref<boolean> = ref(false);
+
     const organizationProfile = reactive($organizationProfile(store))
 
     const id = store.state.profile.organization.parametersId
@@ -102,6 +134,41 @@ export default defineComponent({
     const repository = repositoryHelper.getRepository(Parameters)
     const query: ComputedRef<Query> = computed(() => repository.query())
 
+    /**
+     * Build the URL of the current website of the organization
+     * Anywhere else, you can rely on organizationProfile.getWebsite(), but here this url has to be
+     * dynamic.
+     *
+     * @see https://ressources.opentalent.fr/display/SPEC/Preferences#Preferences-Siteinternet
+     *
+     * @param parameters
+     */
+    const getCurrentWebsite = function (parameters: Parameters) {
+      if (parameters.desactivateOpentalentSiteWeb) {
+        if (parameters.otherWebsite) {
+          return UrlBuilder.prependHttps(parameters.otherWebsite)
+        }
+        return null
+      }
+      if (parameters.customDomain) {
+        return UrlBuilder.prependHttps(parameters.customDomain)
+      }
+      // A ce niveau, tous les attributs de Parameters qui pourraient influer sur l'url du site ont été testés, les
+      // sous-domaines étant gérés sur d'autres écrans dédiés.
+      // On peut donc se reposer sur le profil de l'organisation.
+      return organizationProfile.getWebsite()
+    }
+
+    const confirmWebsiteDeactivation = function () {
+      showSiteWebConfirmationDialog.value = true
+    }
+    const desactivateOpentalentSiteWeb = function(updateRepository: ((newValue: string, field: string) => void)) {
+      updateRepository('1', 'desactivateOpentalentSiteWeb')
+    }
+    const reactivateOpentalentSiteWeb = function(updateRepository: ((newValue: string, field: string) => void)) {
+      updateRepository('0', 'desactivateOpentalentSiteWeb')
+    }
+
     return {
       query: () => query.value,
       rules: () => getRules(i18n),
@@ -109,7 +176,13 @@ export default defineComponent({
       id,
       fetchState,
       accessSearch,
-      model: Parameters
+      model: Parameters,
+      getCurrentWebsite,
+      confirmWebsiteDeactivation,
+      desactivateOpentalentSiteWeb,
+      showSiteWebConfirmationDialog,
+      reactivateOpentalentSiteWeb,
+      UrlBuilder
     }
   }
 })

+ 26 - 0
pages/parameters/subdomain/_id.vue

@@ -0,0 +1,26 @@
+<!-- Page de détails d'un temps d'enseignement -->
+<template>
+  <main>
+    <FormParametersSubdomain :id="id" v-if="!fetchState.pending"></FormParametersSubdomain>
+  </main>
+</template>
+
+<script lang="ts">
+import {defineComponent, useContext} from '@nuxtjs/composition-api'
+import {useDataUtils} from "~/composables/data/useDataUtils";
+import {EducationTiming} from "~/models/Education/EducationTiming";
+
+export default defineComponent({
+  name: 'EditFormParametersEducationTiming',
+  setup () {
+    const {$dataProvider, route} = useContext()
+    const {getItemToEdit} = useDataUtils($dataProvider)
+    const id = parseInt(route.value.params.id)
+    const {fetchState} = getItemToEdit(id, EducationTiming)
+    return {
+      id,
+      fetchState
+    }
+  }
+})
+</script>

+ 0 - 0
pages/parameters/subdomain/new.vue


+ 12 - 1
services/connection/urlBuilder.ts

@@ -109,7 +109,6 @@ class UrlBuilder {
 
   /**
    * Construction d'une URL "image" qui ira concaténer l'id de l'image à downloeader passé en paramètre avec la ROOT Url définie
-   * @param {number} id
    * @param {ImageArgs} imgArgs
    * @param {string} baseUrl
    * @return {string}
@@ -141,6 +140,18 @@ class UrlBuilder {
     })
     return url
   }
+
+  /**
+   * Prepend the 'https://' part if neither 'http://' of 'https://' is present, else: does nothing
+   *
+   * @param url
+   */
+  public static prependHttps (url: string): string {
+    if (!url.match(/^https?:\/\/.*/)) {
+      url = 'https://' + url;
+    }
+    return url;
+  }
 }
 
 export default UrlBuilder

+ 5 - 0
services/profile/organizationProfile.ts

@@ -155,6 +155,10 @@ class OrganizationProfile {
     return false
   }
 
+  getWebsite(): string | null {
+    return this.organizationProfile.website ?? null
+  }
+
   /**
    * Factory
    *
@@ -170,6 +174,7 @@ class OrganizationProfile {
       isAssociation: this.isAssociation.bind(this),
       isShowAdherentList: this.isShowAdherentList.bind(this),
       isCmf: this.isCmf.bind(this),
+      getWebsite: this.getWebsite.bind(this),
     }
   }
 }

+ 1 - 7
store/profile/organization.ts

@@ -13,7 +13,6 @@ export const state = () => ({
   showAdherentList: false,
   networks: [],
   website: '',
-  subDomain: '',
   parents: []
 })
 
@@ -54,9 +53,6 @@ export const mutations = {
   setWebsite (state: organizationState, website: string) {
     state.website = website
   },
-  setSubDomain (state: organizationState, subDomain: string) {
-    state.subDomain = subDomain
-  },
   addParent (state: organizationState, parent: organizationState) {
     state.parents.push(parent)
   }
@@ -70,7 +66,6 @@ export const actions = {
     context.commit('setProduct', profile.product)
     context.commit('setCurrentActivityYear', profile.currentYear)
     context.commit('setWebsite', profile.website)
-    context.commit('setSubDomain', profile.subDomain)
     context.commit('setModules', profile.modules)
     context.commit('setHasChildren', profile.hasChildren)
     context.commit('setLegalStatus', profile.legalStatus)
@@ -81,8 +76,7 @@ export const actions = {
       const p: baseOrganizationState = {
         id: parent.id,
         name: parent.name,
-        website: parent.website,
-        subDomain: parent.subDomain
+        website: parent.website
       }
       context.commit('addParent', p)
     })

+ 1 - 2
types/interfaces.d.ts

@@ -135,8 +135,7 @@ interface AccessStore extends Store<{profile:{access: accessState}}> {}
 interface baseOrganizationState {
   id: number,
   name: string,
-  website?: string,
-  subDomain?: string
+  website?: string
 }
 
 interface organizationState extends baseOrganizationState {