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