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>