github.com/benoitkugler/goacve@v0.0.0-20201217100549-151ce6e55dc8/server/frontend/bv/src/pages/espace_perso/components/paiements/DetailsAide.vue (about) 1 <template> 2 <b-modal 3 :title="title" 4 :visible="show" 5 @change="v => $emit('change', v)" 6 hide-footer 7 size="lg" 8 > 9 <b-form 10 novalidate 11 v-if="show && innerAide !== null" 12 :validated="validated" 13 ref="form" 14 > 15 <b-form-row> 16 <b-col> 17 <b-form-group 18 label="Participant concerné" 19 invalid-feedback="Une aide doit être liée à un participant." 20 > 21 <b-select 22 required 23 :options="optionsParticipants" 24 v-model="innerAide.id_participant_crypted" 25 > 26 </b-select> 27 </b-form-group> 28 </b-col> 29 </b-form-row> 30 <b-form-row> 31 <b-col> 32 <b-form-group 33 label="Organisme" 34 invalid-feedback="Merci de préciser l'origine de l'aide." 35 > 36 <b-select 37 required 38 :options="optionsStructures" 39 v-model="innerAide.id_structure_crypted" 40 > 41 </b-select> 42 </b-form-group> 43 </b-col> 44 <b-col> 45 <b-form-group 46 label="Montant" 47 invalid-feedback="Merci de préciser la valeur de l'aide." 48 > 49 <b-form-input 50 placeholder="€" 51 type="number" 52 min="0" 53 step="0.01" 54 v-model.number="innerAide.valeur" 55 ></b-form-input> 56 </b-form-group> 57 </b-col> 58 </b-form-row> 59 <b-form-row class="form-row ml-3 mb-2"> 60 <b-col class="align-self-center"> 61 <b-form-checkbox v-model="innerAide.par_jour"> 62 Montant par jour 63 </b-form-checkbox> 64 </b-col> 65 <b-col> 66 <transition name="fade" mode="in-out"> 67 <b-form-group 68 label="Limite sur le nombre de jours" 69 v-if="innerAide.par_jour" 70 > 71 <b-form-input 72 placeholder="jours" 73 required 74 type="number" 75 min="1" 76 v-model.number="innerAide.nb_jours_max" 77 ></b-form-input> 78 </b-form-group> 79 </transition> 80 </b-col> 81 </b-form-row> 82 <form-file 83 v-if="mode == 'create'" 84 title="Pièce justificative" 85 invalidFeedback="Merci d'ajouter une pièce justificative." 86 :showValidation="validated" 87 hideBtnUpload 88 ref="file" 89 ></form-file> 90 <btn 91 block 92 variant="success" 93 class="mt-2" 94 label="Valider" 95 @click="valide" 96 ></btn> 97 </b-form> 98 </b-modal> 99 </template> 100 101 <script lang="ts"> 102 import Vue from "vue"; 103 import Component from "vue-class-component"; 104 import FormFile from "../../../../shared/FormFile.vue"; 105 import Btn from "../../../../shared/Btn.vue"; 106 import { C } from "../../logic/controller"; 107 import { 108 Aide, 109 ChampsAideEditables, 110 PublicDocument 111 } from "@/shared/logic/types"; 112 import { Watch } from "vue-property-decorator"; 113 import { ValidEvent, scrollToError } from "../../../../shared/utils"; 114 115 export type ModeEdit = "create" | "edit"; 116 117 const DetailsAideProps = Vue.extend({ 118 props: { 119 mode: String as () => ModeEdit, 120 show: Boolean, 121 aide: Object as () => ChampsAideEditables | null 122 }, 123 model: { 124 prop: "show", 125 event: "change" 126 } 127 }); 128 129 interface Option { 130 text: string; 131 } 132 133 function sortByText(a: Option, b: Option) { 134 return a.text < b.text ? -1 : 1; 135 } 136 137 @Component({ 138 components: { FormFile, Btn } 139 }) 140 export default class DetailsAide extends DetailsAideProps { 141 innerAide = this.duplique(); 142 143 validated = false; 144 145 $refs!: { 146 file: FormFile; 147 form: HTMLFormElement; 148 }; 149 150 private duplique(): ChampsAideEditables | null { 151 return JSON.parse(JSON.stringify(this.aide)); 152 } 153 154 @Watch("aide") 155 onChange() { 156 this.innerAide = this.duplique(); 157 } 158 159 get title() { 160 if (this.mode == "create") { 161 return "Ajouter une aide extérieure"; 162 } 163 return "Modifier l'aide"; 164 } 165 166 get optionsParticipants() { 167 return C.data.participants 168 .map(part => { 169 const personne = C.getPersonne(part); 170 const camp = C.getCamp(part); 171 return { 172 value: part.id_crypted, 173 text: 174 (personne ? personne.nom_prenom : "") + 175 " - " + 176 (camp ? camp.label : "") 177 }; 178 }) 179 .sort(sortByText); 180 } 181 182 get optionsStructures() { 183 if (C.data.finances == null) return []; 184 return Object.values(C.data.finances.structure_aides || {}) 185 .map(s => { 186 return { text: s.nom, value: s.id_crypted }; 187 }) 188 .sort(sortByText); 189 } 190 191 valide(event: ValidEvent) { 192 this.validated = true; 193 Vue.nextTick(async () => { 194 if (this.innerAide == null) return; 195 const fieldsValides = scrollToError(this.$refs.form); 196 if (this.mode == "edit" && fieldsValides) { 197 event.spinning = true; 198 await C.data.updateAide(this.innerAide); 199 this.close(event); 200 } else if (this.mode == "create") { 201 const doc = this.$refs.file.file; 202 const docValide = this.$refs.file.isFileInvalid == null; 203 if (fieldsValides && docValide && doc != null) { 204 event.spinning = true; 205 await C.data.ajouteAide(this.innerAide, doc); 206 this.close(event); 207 } 208 } 209 }); 210 } 211 212 private close(event: ValidEvent) { 213 event.spinning = false; 214 this.$emit("change", false); // ask to close the dialog 215 } 216 } 217 </script> 218 219 <style scoped></style>