github.com/benoitkugler/goacve@v0.0.0-20201217100549-151ce6e55dc8/server/frontend/bv/src/shared/FormFile.vue (about) 1 <template> 2 <b-card 3 class="my-3" 4 no-body 5 header-class="py-0 pr-2" 6 :text-variant="variant" 7 :border-variant="variant" 8 > 9 <template v-slot:header> 10 <b-row style="min-height: 45px;" no-gutters> 11 <b-col cols="6" class="align-self-center"> 12 <div v-html="title"></div> 13 </b-col> 14 <b-col cols="6" class="text-right align-self-center"> 15 <transition name="fade" mode="out-in"> 16 <b-badge 17 variant="danger" 18 v-if="file != null && isFileInvalid" 19 key="invalid" 20 > 21 {{ isFileInvalid }} 22 </b-badge> 23 <btn 24 v-else-if="!hideBtnUpload" 25 variant="accent" 26 :disabled="isFileInvalid != null" 27 @click="onUpload" 28 label="Lancer le téléversement" 29 key="valid" 30 ></btn> 31 </transition> 32 </b-col> 33 </b-row> 34 </template> 35 <b-card-text class="pt-2 px-2"> 36 <b-form-group 37 :invalid-feedback="invalidFeedback" 38 :state="validationState" 39 > 40 <b-form-file 41 placeholder="Cliquer ou faire glisser un fichier..." 42 drop-placeholder="Déposer le fichier..." 43 :accept="AcceptedTypes.join(',')" 44 browse-text="Choisir un fichier" 45 :required="!!invalidFeedback" 46 v-model="file" 47 :file-name-formatter="fileInfo" 48 ></b-form-file> 49 </b-form-group> 50 </b-card-text> 51 </b-card> 52 </template> 53 54 <script lang="ts"> 55 import Vue from "vue"; 56 import Component from "vue-class-component"; 57 import Btn from "./Btn.vue"; 58 59 import { MaxFileSize } from "./logic/utils"; 60 import { Watch } from "vue-property-decorator"; 61 import { ValidEvent, ValidEventFile } from "./utils"; 62 63 const FormFileProps = Vue.extend({ 64 props: { 65 title: String, 66 variant: String, 67 invalidFeedback: { 68 type: String as () => String | null, 69 default: null 70 }, 71 showValidation: Boolean, 72 hideBtnUpload: { 73 type: Boolean, 74 default: false 75 } 76 } 77 }); 78 79 @Component({ 80 components: { Btn } 81 }) 82 export default class FormFile extends FormFileProps { 83 private MaxFileSize = MaxFileSize; 84 private AcceptedTypes = [ 85 "image/jpeg", 86 "image/png", 87 "application/pdf", 88 ".pdf" 89 ]; 90 file: File | null = null; 91 92 get isFileInvalid(): string | null { 93 if (this.file == null) return "Aucun fichier"; 94 if (this.file.size > MaxFileSize) { 95 return `Le fichier est trop lourd : max 96 ${MaxFileSize / 1000000} MB.`; 97 } 98 let type = this.file.type; 99 // IE workaround : file.type is empty 100 if (this.file.name.toLowerCase().endsWith(".pdf")) { 101 type = ".pdf"; 102 } 103 if (!this.AcceptedTypes.includes(type)) { 104 return `Le type du fichier est invalide.`; 105 } 106 return null; 107 } 108 109 get validationState(): boolean | null { 110 if (!this.showValidation) return null; 111 return this.isFileInvalid == null; 112 } 113 114 private fileInfo(files: File[]) { 115 if (!files || files.length == 0) return ""; 116 const file = files[0]; 117 return `${file.name} (${(file.size / 1000000).toFixed(1)} MB)`; 118 } 119 120 onUpload(event: ValidEvent) { 121 if (this.file == null) return; 122 event.spinning = true; 123 const upEvent: ValidEventFile = { event, file: this.file }; 124 this.$emit("upload", upEvent); 125 this.file = null; 126 } 127 } 128 </script> 129 130 <style></style>