Przeglądaj źródła

Merge branch 'BTTF-21pr' into 'develop'

Bttf 21pr

See merge request opentalent/admin!2
Guffon 4 lat temu
rodzic
commit
c78ccfa3db

+ 57 - 7
components/Layout/Dialog.vue

@@ -5,16 +5,30 @@
     v-model="show"
     v-model="show"
     persistent
     persistent
     max-width="800"
     max-width="800"
+    :content-class="contentClass"
   >
   >
     <v-card>
     <v-card>
-      <slot name="dialogText" />
+      <div class="d-flex">
+        <div class="dialog-type flex-column justify-center d-none d-sm-flex">
+          <h3 class="d-flex"> <slot name="dialogType"></slot></h3>
+        </div>
+        <div class="dialog-container">
+          <v-card-title class="dialog-title">
+            <slot name="dialogTitle"></slot>
+          </v-card-title>
+          <div class="dialog-text-container">
+            <slot name="dialogText" />
+          </div>
 
 
-      <v-divider />
 
 
-      <v-card-actions>
-        <v-spacer />
-        <slot name="dialogBtn" />
-      </v-card-actions>
+          <v-divider />
+
+          <v-card-actions class="justify-center">
+            <slot name="dialogBtn" />
+          </v-card-actions>
+        </div>
+
+      </div>
     </v-card>
     </v-card>
   </v-dialog>
   </v-dialog>
 </template>
 </template>
@@ -27,10 +41,46 @@ export default defineComponent({
     show: {
     show: {
       type: Boolean,
       type: Boolean,
       required: true
       required: true
+    },
+    contentClass: {
+      type: String,
+      required: false
     }
     }
   }
   }
 })
 })
 </script>
 </script>
 
 
-<style scoped>
+<style lang="scss" scoped>
+  .dialog-title{
+    background: #e6e6e6;
+    padding-left: 40px;
+    font-weight: normal;
+  }
+  .dialog-type{
+    background: var(--v-ot_green-base, #00AD8E);
+    color: #fff;
+   h3{
+     font-size: 25px;
+     font-weight: normal;
+     writing-mode: tb-lr;
+     writing-mode: vertical-lr;
+     transform: rotate(
+         -180deg);
+     padding: 10px;
+    }
+  }
+  .dialog-text-container{
+    max-height: 60vh;
+    overflow: auto;
+  }
+  .modal-level-alert{
+    .dialog-type{
+      background: var(--v-ot_danger-base, #f56954);
+    }
+  }
+  .modal-level-warning{
+    .dialog-type{
+      background: var(--v-ot_warning-base, #f39c12);
+    }
+  }
 </style>
 </style>

+ 16 - 8
components/Layout/Header.vue

@@ -27,12 +27,7 @@ et aux préférences de l'utilisateur
 
 
     <v-spacer />
     <v-spacer />
 
 
-    <v-btn
-      elevation="2"
-      color="ot_warning ot_white--text"
-    >
-      {{ $t('create') }}
-    </v-btn>
+    <LayoutHeaderUniversalCreationCreateButton v-if="showUniversalButton" />
 
 
     <v-tooltip bottom>
     <v-tooltip bottom>
       <template #activator="{ on, attrs }">
       <template #activator="{ on, attrs }">
@@ -76,7 +71,7 @@ import { AnyJson } from '~/types/interfaces'
 
 
 export default defineComponent({
 export default defineComponent({
   setup (_props, { emit }) {
   setup (_props, { emit }) {
-    const { store, $config } = useContext()
+    const { store, $config,$ability } = useContext()
 
 
     const properties:UnwrapRef<AnyJson> = reactive({
     const properties:UnwrapRef<AnyJson> = reactive({
       miniVariant: false,
       miniVariant: false,
@@ -100,6 +95,18 @@ export default defineComponent({
       emit('handle-open-menu-click', properties.miniVariant)
       emit('handle-open-menu-click', properties.miniVariant)
     }
     }
 
 
+    const showUniversalButton =
+        $ability.can('manage', 'users')
+      || $ability.can('manage', 'courses')
+      || $ability.can('manage', 'examens')
+      || $ability.can('manage', 'educationalprojects')
+      || $ability.can('manage', 'events')
+      || $ability.can('manage', 'emails')
+      || $ability.can('manage', 'mails')
+      || $ability.can('manage', 'texto')
+      || $ability.can('display', 'message_send_page')
+      || $ability.can('manage', 'equipments') ;
+
     return {
     return {
       properties,
       properties,
       displayedMiniVariant,
       displayedMiniVariant,
@@ -112,7 +119,8 @@ export default defineComponent({
       myAccessesMenu,
       myAccessesMenu,
       myFamilyMenu,
       myFamilyMenu,
       configurationMenu,
       configurationMenu,
-      accountMenu
+      accountMenu,
+      showUniversalButton
     }
     }
   }
   }
 })
 })

+ 61 - 0
components/Layout/Header/UniversalCreation/CreateButton.vue

@@ -0,0 +1,61 @@
+<!--
+bouton Créer
+-->
+
+<template>
+  <main>
+    <v-btn
+      elevation="2"
+      color="ot_warning ot_white--text"
+      @click="showDialog=true"
+    >
+      {{ $t('create') }}
+    </v-btn>
+    <lazy-LayoutDialog
+      :show="showDialog"
+    >
+
+      <template v-slot:dialogType>{{ $t('creative_assistant') }}</template>
+      <template v-slot:dialogTitle>{{ $t('what_do_you_want_to_create') }}</template>
+      <template v-slot:dialogText>
+        <LayoutHeaderUniversalCreationGenerateCardsSteps :step="step" @updateStep="step=$event" />
+
+      </template>
+      <template v-slot:dialogBtn>
+        <div class="text-center">
+          <v-btn
+            color="ot_super_light_grey"
+            @click="showDialog=false;step=1"
+          >
+            {{ $t('cancel') }}
+          </v-btn>
+          <v-btn
+            v-if="step > 1"
+            color="ot_super_light_grey"
+            @click="step=1"
+          >
+            {{ $t('previous') }}
+          </v-btn>
+        </div>
+      </template>
+    </lazy-LayoutDialog>
+  </main>
+</template>
+
+<script lang="ts">
+import {defineComponent, Ref,ref} from '@nuxtjs/composition-api'
+
+export default defineComponent({
+  setup () {
+    const showDialog:Ref<Boolean> = ref(false);
+    const step:Ref<Number> = ref(1);
+    return {
+      showDialog,
+      step
+    }
+  }
+})
+</script>
+<style scoped>
+
+</style>

+ 143 - 0
components/Layout/Header/UniversalCreation/GenerateCardsSteps.vue

@@ -0,0 +1,143 @@
+<!--
+
+-->
+
+<template>
+  <v-stepper v-model="step"
+  >
+    <v-stepper-items>
+      <v-stepper-content step="1">
+        <div class="row">
+          <LayoutHeaderUniversalCreationTypeCard
+            v-if="$can('manage', 'users')"
+            title="a_person"
+            text-content="add_new_person_student"
+            icon="fa fa-user"
+            type="access"
+            @typeClick="onTypeClick"
+          >
+          </LayoutHeaderUniversalCreationTypeCard>
+          <LayoutHeaderUniversalCreationTypeCard
+            v-if="$can('display', 'agenda_page')
+                && ($ability.can('manage', 'courses')
+            || $ability.can('manage', 'examens')
+            || $ability.can('manage', 'educationalprojects')
+            || $ability.can('manage', 'events'))"
+            title="an_event"
+            text-content="add_an_event_course"
+            icon="fa fa-comment"
+            type="event"
+            @typeClick="onTypeClick"
+          >
+          </LayoutHeaderUniversalCreationTypeCard>
+          <LayoutHeaderUniversalCreationTypeCard
+            v-if="$can('display', 'message_send_page')
+            && ($ability.can('manage', 'emails')
+            || $ability.can('manage', 'mails')
+            || $ability.can('manage', 'texto'))"
+            title="a_correspondence"
+            text-content="sen_email_letter"
+            icon="fa fa-comment"
+            type="message"
+            @typeClick="onTypeClick"
+          >
+          </LayoutHeaderUniversalCreationTypeCard>
+          <LayoutHeaderUniversalCreationTypeCard
+            v-if="$can('manage', 'equipments')"
+            title="a_materiel"
+            text-content="add_any_type_material"
+            icon="fa fa-cube"
+            :link="adminLegacy+ '/list/create/equipment'"
+          >
+          </LayoutHeaderUniversalCreationTypeCard>
+        </div>
+      </v-stepper-content>
+
+      <v-stepper-content step="2">
+        <div class="row">
+          <div v-if="type === 'access'" class="row">
+            <LayoutHeaderUniversalCreationTypeCard title="a_student" text-content="student_text_creation_card" icon="fa fa-user" :link="adminLegacy+ '/universal_creation_person/student'"></LayoutHeaderUniversalCreationTypeCard>
+            <LayoutHeaderUniversalCreationTypeCard title="a_guardian" text-content="guardian_text_creation_card" icon="fa fa-female" :link="adminLegacy+ '/universal_creation_person/guardian'"></LayoutHeaderUniversalCreationTypeCard>
+            <LayoutHeaderUniversalCreationTypeCard title="a_teacher" text-content="teacher_text_creation_card" icon="fa fa-graduation-cap" :link="adminLegacy+ '/universal_creation_person/teacher'"></LayoutHeaderUniversalCreationTypeCard>
+            <LayoutHeaderUniversalCreationTypeCard title="a_member_of_staff" text-content="personnel_text_creation_card" icon="fa fa-suitcase" :link="adminLegacy+ '/universal_creation_person/personnel'"></LayoutHeaderUniversalCreationTypeCard>
+            <LayoutHeaderUniversalCreationTypeCard title="a_legal_entity" text-content="moral_text_creation_card" icon="fa fa-building" :link="adminLegacy+ '/universal_creation_person/company'"></LayoutHeaderUniversalCreationTypeCard>
+            <LayoutHeaderUniversalCreationTypeCard title="another_type_of_contact" text-content="other_contact_text_creation_card" icon="fa fa-plus" :link="adminLegacy+ '/universal_creation_person/other_contact'"></LayoutHeaderUniversalCreationTypeCard>
+          </div>
+          <div v-if="type === 'event'" class="row">
+            <LayoutHeaderUniversalCreationTypeCard v-if="$can('manage', 'courses')" title="course" text-content="course_text_creation_card" icon="fa fa-users" :link="adminLegacy+ '/calendar/create/courses'"></LayoutHeaderUniversalCreationTypeCard>
+            <LayoutHeaderUniversalCreationTypeCard v-if="$can('manage', 'examens')" title="exam" text-content="exam_text_creation_card" icon="fa fa-graduation-cap" :link="adminLegacy+ '/calendar/create/examens'"></LayoutHeaderUniversalCreationTypeCard>
+            <LayoutHeaderUniversalCreationTypeCard v-if="$can('manage', 'educationalprojects')" title="educational_services" text-content="educational_services_text_creation_card" icon="fa fa-suitcase" :link="adminLegacy+ '/calendar/create/educational_projects'"></LayoutHeaderUniversalCreationTypeCard>
+            <LayoutHeaderUniversalCreationTypeCard v-if="$can('manage', 'events')" title="other_event" text-content="other_event_text_creation_card" icon="far fa-calendar" :link="adminLegacy+ '/calendar/create/events'"></LayoutHeaderUniversalCreationTypeCard>
+          </div>
+          <div v-if="type === 'message'" class="row">
+            <LayoutHeaderUniversalCreationTypeCard v-if="$can('manage', 'emails')" title="an_email" text-content="email_text_creation_card" icon="far fa-envelope" :link="adminLegacy+ '/list/create/emails'"></LayoutHeaderUniversalCreationTypeCard>
+            <LayoutHeaderUniversalCreationTypeCard v-if="$can('manage', 'mails')" title="a_letter" text-content="letter_text_creation_card" icon="far fa-file-alt" :link="adminLegacy+ '/list/create/mails'"></LayoutHeaderUniversalCreationTypeCard>
+            <LayoutHeaderUniversalCreationTypeCard v-if="$can('manage', 'texto')" title="an_sms" text-content="sms_text_creation_card" icon="fa fa-mobile-alt" :link="adminLegacy+ '/list/create/sms'"></LayoutHeaderUniversalCreationTypeCard>
+          </div>
+        </div>
+
+      </v-stepper-content>
+
+    </v-stepper-items>
+  </v-stepper>
+</template>
+
+<script lang="ts">
+import {defineComponent, ref, Ref, useContext} from '@nuxtjs/composition-api'
+
+export default defineComponent({
+  props: {
+    step: {
+      type: Number,
+      required: true
+    }
+  },
+  setup (_,{emit}) {
+    const { $config } = useContext()
+    const onTypeClick = (step:Number,Cardtype:String)=>{
+      type.value = Cardtype;
+      emit('updateStep',step);
+    }
+    const type:Ref<String> = ref('');
+    return {
+      type,
+      onTypeClick,
+      adminLegacy: $config.baseURL_adminLegacy
+    }
+  }
+})
+</script>
+<style lang="scss" scoped>
+  .creation-type-container{
+    border: none!important;
+    .icon{
+      i{
+        font-size: 50px;
+        color: var(--v-ot_grey-base, #777777);
+      }
+    }
+    .infos-container{
+      padding: 15px 0;
+      h4{
+        font-size: 15px;
+        color: var(--v-ot_green-base, #00AD8E);
+        font-weight: bold;
+        margin-bottom: 6px;
+      }
+      p{
+        font-size: 13px;
+        padding: 0;
+        margin: 0;
+        color: #767676;
+      }
+    }
+    &>div{
+      &:hover{
+        cursor: pointer;
+        background: var(--v-ot_light_green-base, #a9e0d6);
+      }
+    }
+
+
+  }
+</style>

+ 91 - 0
components/Layout/Header/UniversalCreation/TypeCard.vue

@@ -0,0 +1,91 @@
+<!--
+
+-->
+
+<template>
+
+    <v-card
+      class="col-md-6 creation-type-container"
+      color=""
+      :outlined=true
+      :href="link"
+      @click="$emit('typeClick',2,type)"
+    >
+      <div class="row no-gutters" style="height: 100px">
+        <div class="flex-grow-0 flex-shrink-0 d-flex justify-center col col-3" style="">
+          <div class="icon align-self-center">
+            <i :class="icon" aria-hidden="true"></i>
+          </div>
+        </div>
+        <div class="infos-container flex-grow-1 flex-shrink-1 col col-9" style="">
+          <h4>{{ $t(title) }}</h4>
+          <p>
+            {{ $t(textContent) }}
+          </p>
+        </div>
+      </div>
+    </v-card>
+
+</template>
+
+<script lang="ts">
+import {defineComponent, Ref,ref} from '@nuxtjs/composition-api'
+
+export default defineComponent({
+  props: {
+    title: {
+      type: String,
+      required: true
+    },
+    textContent: {
+      type: String,
+      required: true
+    },
+    icon: {
+      type: String,
+      required: true
+    },
+    link: {
+      type: String,
+      required: false
+    },
+    type: {
+      type: String,
+      required: false
+    }
+  }
+})
+</script>
+<style lang="scss" scoped>
+.creation-type-container{
+  border: none!important;
+  .icon{
+    i{
+      font-size: 50px;
+      color: var(--v-ot_grey-base, #777777);
+    }
+  }
+  .infos-container{
+    padding: 15px 0;
+    h4{
+      font-size: 15px;
+      color: var(--v-ot_green-base, #00AD8E);
+      font-weight: bold;
+      margin-bottom: 6px;
+    }
+    p{
+      font-size: 13px;
+      padding: 0;
+      margin: 0;
+      color: #767676;
+    }
+  }
+  &>div{
+    &:hover{
+      cursor: pointer;
+      background: var(--v-ot_light_green-base, #a9e0d6);
+    }
+  }
+
+}
+</style>

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

@@ -1,5 +1,43 @@
 export default (context, locale) => {
 export default (context, locale) => {
   return ({
   return ({
+    creative_assistant:'Assistant de création',
+    what_do_you_want_to_create:'Que souhaitez-vous créer ?',
+    previous:'Précédent',
+    cancel:'Annuler',
+    add_any_type_material:'Ajoutez tout type de matériel ou de documents tels que des partitions à votre parc de matériel',
+    a_materiel:'Un matériel',
+    sen_email_letter:'Envoyez un email, un courrier, ou un SMS aux personnes de votre carnet d\'adresses',
+    a_correspondence:'Une Correspondance',
+    add_an_event_course:'Ajoutez un évenement, un cour, une prestation pédagogique, un examen... à votre planning',
+    an_event:'Un évènement',
+    add_new_person_student:'Ajoutez un nouveau membre parent, élève, professeur, personnel... à votre répertoire',
+    a_person:'une personne',
+    other_event_text_creation_card:'Comprend entre autres: auditions, concerts, répétitions, spectacles, stages...',
+    educational_services_text_creation_card:'Correspond aux interventions en milieu scolaire, pénitentiaire, ou hospitalier',
+    exam_text_creation_card:'Permet d\'organiser des examens avec la gestion des jurys, des convocations et des résultats',
+    course_text_creation_card:'On associe les élèves à leurs enseignements, puis à leurs cours, qui peut être périodique ou ponctuel',
+    other_event:'Autre événement',
+    educational_services:'Prestations pédagogiques',
+    exam:'Examen',
+    course:'Cours',
+    sms_text_creation_card: 'Les SMS sont disponible sur option, vous devez disposer de suffisament de crédit',
+    letter_text_creation_card: 'Un courrier est imprimé pour être envoyé par la Poste mais peut aussi être envoyé par mail',
+    email_text_creation_card: 'Les emails peuvent également être des newsletters / lettre d\'information',
+    an_sms: 'Un sms',
+    a_letter: 'Un courrier',
+    an_email: 'Un email',
+    another_type_of_contact: 'Un autre type de contact',
+    a_legal_entity: 'Une personne morale',
+    a_member_of_staff: 'Un membre du personnel',
+    a_teacher: 'Un professeur',
+    a_guardian: 'Un tuteur',
+    a_student: 'Un élève',
+    other_contact_text_creation_card: 'Ajoutez un autre type de contact qui n\'a pas été défini précédemment',
+    moral_text_creation_card: 'Ajoutez les structures qui vous soutiennent ou avec qui vous travaillez',
+    personnel_text_creation_card: 'Ajoutez un membre à votre personnel et donnez-lui un accès administratif',
+    teacher_text_creation_card: 'Ajoutez un professeur à votre personnel et donnez-lui un accès pédagogique',
+    student_text_creation_card: 'Inscrivez un nouvel élève via le formulaire de la vue famille',
+    guardian_text_creation_card: 'Ajoutez un tuteur à votre carnet d\'adresses afin de l\'associer ultérieurement à un élève',
     click_here: 'cliquez ici',
     click_here: 'cliquez ici',
     super_admin_switch_account: 'Vous utilisez une connexion SWITCH. Afin de retourner sur votre compte veuillez',
     super_admin_switch_account: 'Vous utilisez une connexion SWITCH. Afin de retourner sur votre compte veuillez',
     insurance_cmf_subscription: 'Souscrire un contrat assurance CMF',
     insurance_cmf_subscription: 'Souscrire un contrat assurance CMF',

+ 1 - 1
services/rights/roleUtils.ts

@@ -115,7 +115,7 @@ class RoleUtils {
       if ((match = regex.exec(role)) !== null) {
       if ((match = regex.exec(role)) !== null) {
         const subject = match[2]
         const subject = match[2]
         const action = match[3]
         const action = match[3]
-        if(subject && action){
+        if(subject){
           abilities.push({
           abilities.push({
             action: actionMap[action],
             action: actionMap[action],
             subject: subject.toLowerCase()
             subject: subject.toLowerCase()