From 7d9764e9c2c7b5fedf86556f2630c00762e55d69 Mon Sep 17 00:00:00 2001 From: EdwardAJ <13517115@std.stei.itb.ac.id> Date: Fri, 10 Apr 2020 23:34:30 +0700 Subject: [PATCH] Add foldering in upload --- frontend/components/dropdown/Dropdown.vue | 40 ++++++++++- frontend/components/label/Label.vue | 2 +- frontend/nuxt.config.js | 3 +- frontend/pages/main/coco.vue | 54 ++++++++++----- frontend/pages/main/upload.vue | 84 +++++++++++++---------- frontend/plugins/vue-dropzone.js | 5 ++ 6 files changed, 130 insertions(+), 58 deletions(-) create mode 100644 frontend/plugins/vue-dropzone.js diff --git a/frontend/components/dropdown/Dropdown.vue b/frontend/components/dropdown/Dropdown.vue index 07e1fa6..f3a7755 100644 --- a/frontend/components/dropdown/Dropdown.vue +++ b/frontend/components/dropdown/Dropdown.vue @@ -2,6 +2,7 @@ <div :key="dataReady"> <vue-dropdown ref="dropdown" + class="dropdown" :config="config" @setSelectedOption="setNewSelectedOption($event)" /> @@ -35,7 +36,13 @@ export default { } }, async created () { + if (this.isUpload) { + this.config.options.push({ + value: "Add New Folder" + }) + } await this.getOptions() + this.dataReady = true }, methods: { async getOptions() { @@ -52,13 +59,40 @@ export default { if (this.dropdownValue) { this.config.placeholder = this.dropdownValue } - this.dataReady = true }, async setNewSelectedOption(selectedOption) { this.config.placeholder = selectedOption.value this.dataset = selectedOption.value + if (this.dataset === "Add New Folder") { + this.createNewFolder() + } this.$emit("onDatasetChanged", this.dataset) - } + }, + createNewFolder() { + this.$swal.fire({ + title: "New folder name", + input:'text', + inputValidator: (value) => { + if (!value) { + return 'You need to write something!' + } else { + this.config.placeholder = value + this.dataset = value + this.$emit("onDatasetChanged", this.dataset) + } + }, + confirmButtonColor: '#11616F', + showCancelButton: true + }) + }, } } -</script> \ No newline at end of file +</script> + +<style scoped> + .dropdown { + -webkit-box-shadow: 2px 5px 5px 0px rgba(0,0,0,0.15); + -moz-box-shadow: 2px 5px 5px 0px rgba(0,0,0,0.15); + box-shadow: 2px 5px 5px 0px rgba(0,0,0,0.15); + } +</style> \ No newline at end of file diff --git a/frontend/components/label/Label.vue b/frontend/components/label/Label.vue index 3adafbf..412d4c6 100644 --- a/frontend/components/label/Label.vue +++ b/frontend/components/label/Label.vue @@ -114,7 +114,7 @@ export default { async created () { this.images = {} await this.getAllImagesWithLabelStatus() - this.timer = setInterval(this.getAllImagesWithLabelStatus, 5000) + this.timer = setInterval(this.getAllImagesWithLabelStatus, 10000) }, beforeDestroy () { clearInterval(this.timer) diff --git a/frontend/nuxt.config.js b/frontend/nuxt.config.js index dba1329..2446108 100644 --- a/frontend/nuxt.config.js +++ b/frontend/nuxt.config.js @@ -35,7 +35,8 @@ export default { '~/plugins/axios', { src: '~/plugins/vue-sweetalert2', ssr: false }, { src: '~/plugins/json-viewer', ssr: false }, - { src: '~/plugins/vue-dynamic-dropdown', ssr: false} + { src: '~/plugins/vue-dynamic-dropdown', ssr: false }, + { src: '~/plugins/vue-dropzone', ssr: false } ], /* ** Nuxt.js dev-modules diff --git a/frontend/pages/main/coco.vue b/frontend/pages/main/coco.vue index d36edcb..67936f4 100644 --- a/frontend/pages/main/coco.vue +++ b/frontend/pages/main/coco.vue @@ -2,18 +2,32 @@ <div class="col"> <div class="ml-4"> <div class="row"> - <div class="col-3"> - <h5 class="title users-margin"> - Complete JSON - </h5> + <div class="col"> + <Dropdown + class="margin-dropdown" + :dropdown-value="dataset" + @onDatasetChanged="changeDataset" + /> + </div> + </div> + <div :key="updateUI" class="row animated fadeIn"> + <div class="col"> + <div style="display: flex"> + <h5 class="title users-margin"> + {{ dataset }} COCO file: + <span v-if="!dataset" style="margin-left: 20px; font-size: 0.85rem;"> + Choose Folder First + </span> + </h5> + <button v-if="dataset" class="btn-white margin-download" @click="downloadJSON()"> + {{ dataset }}.json + <i class="ml-3 mt-1 fas fa-download" /> + </button> + </div> </div> - <button class="btn-white" @click="downloadJSON()"> - JSONFile.json - <i class="ml-3 mt-1 fas fa-download" /> - </button> </div> </div> - <div class="row"> + <div v-if="dataset" class="row" style="margin-top: -1.5rem;"> <Label :key="updateUI" :is-output-viewer="isOutputViewer" @@ -22,12 +36,7 @@ title="JSON Per Image" viewer-u-r-l="/main/output-view" :output="{type: 'json', standard: standard}" - > - <Dropdown - :dropdown-value="dataset" - @onDatasetChanged="changeDataset" - /> - </Label> + /> </div> </div> </template> @@ -111,7 +120,7 @@ export default { return JSONstandard }, async downloadJSON() { - var filename = 'JSONFile.json' + var filename = this.dataset + '.json' var element = document.createElement('a') var label = await this.getAllLabel(this.standard) var text = JSON.stringify(label,0,5) @@ -168,6 +177,10 @@ export default { padding-right: 1rem; } + .btn-white:hover { + background-color: #F7F7F7; + } + .standard-dropdown{ background: yellow; @@ -183,4 +196,13 @@ export default { color: #1E889B; } + .margin-download { + margin-left: 2.25rem; + } + + .margin-dropdown { + margin-top: 3.5rem; + margin-left: -0.775rem; + } + </style> \ No newline at end of file diff --git a/frontend/pages/main/upload.vue b/frontend/pages/main/upload.vue index b0a55e5..ea03051 100644 --- a/frontend/pages/main/upload.vue +++ b/frontend/pages/main/upload.vue @@ -3,18 +3,17 @@ <div class="ml-4"> <div class="row"> <div class="col users-margin"> - <h5 class="title"> - Upload Dataset - </h5> - </div> - </div> - <br> - <br> - <div class="row"> - <div class="col"> - <h5 class="title sub-title"> - Add Folder - </h5> + <div style="display: flex"> + <h5 class="title"> + Upload Dataset + </h5> + <div style="margin-left: 2rem; margin-top: -0.4rem;"> + <Dropdown + :is-upload="isUpload" + @onDatasetChanged="changeDataset" + /> + </div> + </div> </div> </div> <br> @@ -24,7 +23,7 @@ <vue-dropzone id="dropzone" ref="myDropzone" :options="options" :use-custom-slot="true"> <div class="dropzone-custom-content"> <h6 class="dropzone-custom-title"> - Drag and Drop Images here to Upload Content! + Click or Drag Images Here. </h6> </div> </vue-dropzone> @@ -47,22 +46,24 @@ </template> <script> -import vue2Dropzone from 'vue2-dropzone' -import 'vue2-dropzone/dist/vue2Dropzone.min.css' + +import Dropdown from '~/components/dropdown/Dropdown' export default { components: { - vueDropzone : vue2Dropzone + Dropdown }, data(){ return{ files: null, + isUpload: true, + dataset: null, options: { url: "http://localhost:3000/api/image/upload", uploadMultiple: true, autoQueue: false, - thumbnailWidth: 60, - thumbnailHeight: 60 + addRemoveLinks: true, + thumbnailWidth: 150 } } }, @@ -72,6 +73,9 @@ export default { console.log("files",this.files) }, methods:{ + changeDataset (newDataset) { + this.dataset = newDataset + }, formatBytes(bytes,decimals) { if(bytes == 0){ return '0 Bytes' @@ -176,6 +180,7 @@ export default { var file = this.dataURItoBlob(dataURL) var formData = new FormData() formData.append("image", file, name) + formData.append("dataset", this.dataset) const config = { headers: {'Content-Type':'multipart/form-data'} } @@ -193,14 +198,27 @@ export default { } return new Blob([ab], {type: mimeString}) }, + invalidFolder(){ + this.$swal.fire({ + title: "No Folder Selected", + icon: "error", + text: "Choose folder first!", + confirmButtonColor: '#11616F', + }) + }, async handleUpload(){ this.files = this.$refs.myDropzone.getAcceptedFiles() - if(this.files.length === 0){ - this.invalidUpload() - }else{ - this.files = [] - this.validUpload() + if (!this.dataset) { + this.invalidFolder() + } else { + if(this.files.length === 0){ + this.invalidUpload() + } else{ + this.files = [] + await this.validUpload() + } } + } } } @@ -271,14 +289,15 @@ export default { } .uploader{ - width: 75%; background: #fff; border-radius: 0.5rem; - height: 11.7rem; + margin-left: -0.6rem; + width: 85%; + /* height: 11.7rem; */ padding:0.7rem; - border: 0.2rem solid #1E889B; + /* border: 1px solid #1E889B; */ cursor: pointer; - overflow-y: scroll; + /* overflow-y: scroll; */ } #uploader-container h6{ @@ -290,15 +309,6 @@ export default { } .dropzone-custom-title{ - margin-top: 0; - color: #11616F; + color: #c9c9c9; } - - #dropzone{ - background-color: #fff; - border: 0.3rem solid #11616F; - border-style: dashed; - height: auto; - } - </style> diff --git a/frontend/plugins/vue-dropzone.js b/frontend/plugins/vue-dropzone.js new file mode 100644 index 0000000..b9d188f --- /dev/null +++ b/frontend/plugins/vue-dropzone.js @@ -0,0 +1,5 @@ +import Vue from 'vue' +import vue2Dropzone from 'vue2-dropzone' +import 'vue2-dropzone/dist/vue2Dropzone.min.css' + +Vue.component('vueDropzone', vue2Dropzone) \ No newline at end of file -- GitLab