<template> <div class="upload"> <v-container class="px-0"> <file-upload class="" style="width: inherit" accept="image/jpg,image/jpeg,image/gif,image/png,image/svg,.ai,.psd, video/mp4,video/mov,video/wmv,video/mpg,video/mpeg, audio/mp3, .pdf,.doc,.docx,.ppt,.pptx,.xlsx,.xlsm,.csv,.txt, .html,.notebook,.ipynb,.py,.cpp,.arduino,.r,.stl,.zip,.rar" :post-action="postAction()" :multiple="true" :size="1024 * 1024 * 100" v-model="files" @input-filter="inputFilter" @input-file="inputFile" :headers="postHeaders()" :drop="true" ref="upload"> <v-card flat style="border: 3px dashed black" :class="{'drop-active': $refs.upload && $refs.upload.dropActive}"> <v-row class="text-center" style="height: 150px"> <v-col align-self="center"> <div class="text-h5 white--text" v-if="$refs.upload && $refs.upload.dropActive"> <v-icon x-large color="white">mdi-plus</v-icon> <br> Drop files to upload </div> <div class="body-1 text--primary" v-else> <v-icon large color="accent">mdi-plus</v-icon> <br> Select files </div> </v-col> </v-row> </v-card> </file-upload> </v-container> <v-simple-table class="pb-6"> <template v-slot:default> <thead> <tr> <th class="text-left body-2"> Thumb </th> <th class="text-left body-2"> Filename </th> <th class="text-left body-2"> Size </th> <th class="text-left body-2"> Description </th> <th class="text-left body-2"> Status </th> <th class="text-left body-2"> Action </th> </tr> </thead> <tbody> <tr v-for="file in files" :key="file.id"> <td> <img v-if="file.thumb" :src="file.thumb" width="40" height="auto" alt="thumb"/> <span v-else></span> </td> <td> <div class="filename" v-text="file.name"> </div> <div v-if="file.active || file.progress !== '0.00'"> <v-progress-linear :value="file.progress" color="success"></v-progress-linear> </div> </td> <td>{{ file.size | formatSize }}</td> <td> <v-text-field label="Describe your file here" v-model="file.description" dense outlined counter maxlength="60" class="pt-5" style="min-width: 300px" > </v-text-field> </td> <td v-if="file.error"> <v-chip dark small color="error">{{ file.error }}</v-chip> </td> <td v-else-if="file.success"> <v-chip dark small color="success">success</v-chip> </td> <td v-else-if="file.active"> <v-chip dark small color="secondary">active</v-chip> </td> <td v-else></td> <td> <v-btn icon class="grey--text" @click="$refs.upload.remove(file)"> <v-icon>mdi-delete</v-icon> </v-btn> </td> </tr> </tbody> </template> </v-simple-table> <v-row> <v-col cols="12" md="8" class="body-2"> <p>File size limit: 100 MB</p> <p>Allowed File Extensions: jpg, jpeg, gif, png, svg, ai, psd, mp4, mov, wmv, mpg, mpeg, mp3, pdf, doc, docx, ppt, pptx, xlsx, xlsm, csv, txt, html, notebook, ipynb, py, cpp, arduino, r, stl, zip, rar</p> <p :class="uploadError === 'upload' ? 'red--text' : ''" class="font-weight-bold">Start upload before submit!</p> <p v-show="uploadError === 'missing'" class="red--text font-weight-bold">Upload at least one image in the following form (jpg, jpeg, gif, png, svg, ai, psd, mp4, mov, wmv, mpg, mpeg, pdf)!</p> </v-col> <v-col cols="12" md="4" class="text-right" align-self="center"> <v-btn depressed color="accent" class="body-2 px-8" v-if="!$refs.upload || !$refs.upload.active" @click.prevent="$refs.upload.active = true"> <v-icon left>mdi-upload</v-icon> Start Upload </v-btn> <v-btn depressed color="error" v-else class="body-2 px-8" @click.prevent="$refs.upload.active = false"> <v-icon left>mdi-stop</v-icon> Stop Upload </v-btn> <!-- <div v-if="error" class="pt-1 caption error--text">Start or finish upload<br> before submit.</div>--> </v-col> </v-row> </div> </template> <script> import FileUpload from 'vue-upload-component' const config = require('../config'); export default { name: "UploadForm", components: { FileUpload, }, props: ['parentFiles', 'error', 'uploadError'], data() { return { files: this.parentFiles, } }, methods: { postAction() { return `${config.apiUrl}/upload` }, postHeaders() { return { 'Authorization': `Bearer ${this.$auth.token()}` } }, inputFilter(newFile, oldFile, prevent) { if (newFile && !oldFile) { // Before adding a file, Filter system files or hide files if (/(\/|^)(Thumbs\.db|desktop\.ini|\..+)$/.test(newFile.name)) { return prevent() } // Filter php html js file if (/\.(php5?|jsx?)$/i.test(newFile.name)) { return prevent() } } if (newFile && (!oldFile || newFile.file !== oldFile.file)) { // Create a blob field newFile.blob = '' let URL = window.URL || window.webkitURL if (URL && URL.createObjectURL) { newFile.blob = URL.createObjectURL(newFile.file) } // Thumbnails newFile.thumb = '' if (newFile.blob && newFile.type.substr(0, 6) === 'image/') { newFile.thumb = newFile.blob } } }, inputFile(newFile, oldFile) { if (newFile && !oldFile) { // add // console.log('add', newFile) this.$emit('updateFiles', this.files) } if (newFile && oldFile) { // update // console.log('update', newFile) this.$emit('updateFiles', this.files) } if (!newFile && oldFile) { // remove // Automatically delete files on the server if (oldFile.success && oldFile.response.id) { // $.ajax({ // type: 'DELETE', // url: '/file/delete?id=' + oldFile.response.id, // }); } // console.log('remove', oldFile) this.$emit('updateFiles', this.files) } }, addText() { let file = new window.File(['foo'], 'foo.txt', { type: "text/plain", }) this.$refs.upload.add(file) } }, filters: { formatSize: function (size) { if (size > 1024 * 1024 * 1024 * 1024) { return (size / 1024 / 1024 / 1024 / 1024).toFixed(2) + ' TB' } else if (size > 1024 * 1024 * 1024) { return (size / 1024 / 1024 / 1024).toFixed(2) + ' GB' } else if (size > 1024 * 1024) { return (size / 1024 / 1024).toFixed(2) + ' MB' } else if (size > 1024) { return (size / 1024).toFixed(2) + ' KB' } return size.toString() + ' B' } }, } </script> <style> .upload .drop-active { top: 0; bottom: 0; right: 0; left: 0; /*position: fixed;*/ z-index: 9999; opacity: .6; text-align: center; background: #000; } </style>