diff --git a/frontend/components/delete/Delete.vue b/frontend/components/delete/Delete.vue new file mode 100644 index 0000000000000000000000000000000000000000..2a57063161524e4d1a56a8bac38cc4a5eedb23eb --- /dev/null +++ b/frontend/components/delete/Delete.vue @@ -0,0 +1,51 @@ +<template> + <client-only> + <Label + :key="dataset" + :title="title" + viewer-u-r-l="/viewer/index-edit" + :is-labeled="isLabeled" + :is-delete="isDelete" + :dataset="dataset" + > + <Dropdown :dropdown-value="dataset" @onDatasetChanged="changeDataset" /> + </Label> + </client-only> +</template> + +<script> +import Label from '~/components/label/Label' +import Dropdown from '~/components/dropdown/Dropdown' +export default { + components: { + Label, + Dropdown + }, + props: { + title: { + type: String, + default: "Delete Unlabeled Images" + }, + isLabeled: { + type: Boolean, + default: false + } + }, + data () { + return { + isDelete: true, + dataset: '' + } + }, + mounted () { + if (this.$route.query.dataset) { + this.dataset = this.$route.query.dataset + } + }, + methods: { + changeDataset (newDataset) { + this.dataset = newDataset + } + } +} +</script> \ No newline at end of file diff --git a/frontend/components/root/Navbar.vue b/frontend/components/root/Navbar.vue index 0fa5a0e8256e5058585da2e8da851ea757ff95d3..23ccdd90dc58b709b9dfed7ea6630f9a82383394 100644 --- a/frontend/components/root/Navbar.vue +++ b/frontend/components/root/Navbar.vue @@ -48,27 +48,85 @@ </div> <div v-if="role === 'editor' || role === 'admin'"> - <!-- Delete Dataset --> - <b-nav-item link-classes="side-bar-color mt-3 ml-4" @click="changeActiveElmtID('delete-dataset')"> - <div id="delete-dataset"> + <b-nav-item + v-b-toggle.collapse-delete + link-classes="side-bar-color mt-3 ml-4" + > + <div class="icon-text-wrapper"> Delete Dataset + <i class="ml-3 mt-1 fas fa-caret-down" /> </div> </b-nav-item> + + <b-collapse id="collapse-delete" visible role="tabpanel"> + <!-- Delete Dataset --> + <b-nav-item link-classes="side-bar-color mb-2 mt-3 ml-4" @click="changeActiveElmtID('delete-dataset')"> + <div class="icon-text-wrapper"> + <i class="mt-1 mr-3 fas fa-trash" /> + <div id="delete-dataset"> + Unlabeled Dataset + </div> + </div> + </b-nav-item> + + <b-nav-item link-classes="side-bar-color mt-3 ml-4" @click="changeActiveElmtID('delete-labeled-dataset')"> + <div class="icon-text-wrapper"> + <i class="mt-1 mr-3 fas fa-tag" /> + <div id="delete-labeled-dataset"> + Labeled Dataset + </div> + </div> + </b-nav-item> + </b-collapse> </div> - <!-- COCO Output --> - <b-nav-item link-classes="side-bar-color mt-3 ml-4" @click="changeActiveElmtID('coco-output')"> - <div id="coco-output"> - COCO Output - </div> - </b-nav-item> + <div> + <b-nav-item + v-b-toggle.collapse-outputs + link-classes="side-bar-color mt-3 ml-4" + > + <div class="icon-text-wrapper"> + Download Result + <i class="ml-3 mt-1 fas fa-caret-down" /> + </div> + </b-nav-item> - <!-- Pascal Output --> - <b-nav-item link-classes="side-bar-color mt-3 ml-4" @click="changeActiveElmtID('pascal-output')"> - <div id="pascal-output"> - Pascal VOC Output - </div> - </b-nav-item> + <b-collapse id="collapse-outputs" visible role="tabpanel"> + <!-- COCO Output --> + <b-nav-item link-classes="side-bar-color mt-3 ml-4" @click="changeActiveElmtID('coco-output')"> + <div class="icon-text-wrapper"> + <div class="mr-3 output-icon"> + { } + </div> + <div id="coco-output"> + COCO File + </div> + </div> + </b-nav-item> + + <!-- Pascal Output --> + <b-nav-item link-classes="side-bar-color mt-3 ml-4" @click="changeActiveElmtID('pascal-output')"> + <div class="icon-text-wrapper"> + <div class="mr-3 output-icon"> + < > + </div> + <div id="pascal-output" style="margin-left: -5px;"> + Pascal VOC File + </div> + </div> + </b-nav-item> + + <!-- All Images Output --> + <b-nav-item link-classes="side-bar-color mt-3 ml-4" @click="changeActiveElmtID('all-images')"> + <div class="icon-text-wrapper"> + <i class="mt-1 mr-3 fas fa-image" /> + <div id="all-images"> + All Images + </div> + </div> + </b-nav-item> + </b-collapse> + </div> <div v-if="role === 'admin'"> <!-- User Management --> @@ -112,7 +170,7 @@ </div> </div> </b-nav-item> - + <!-- Delete User --> <b-nav-item link-classes="side-bar-color mt-3 ml-4" @click="changeActiveElmtID('delete-user')"> <div class="icon-text-wrapper"> @@ -124,6 +182,7 @@ </b-nav-item> </b-collapse> </div> + <div> <b-nav-item @@ -213,12 +272,18 @@ export default { case 'coco-output': this.$nuxt.$router.replace({ path: '/main/coco'}) break + case 'all-images': + this.$nuxt.$router.replace({ path: '/main/all-images'}) + break case 'edit-dataset': this.$nuxt.$router.replace({ path: '/main/edit'}) break case 'delete-dataset': this.$nuxt.$router.replace({ path: '/main/delete'}) break + case 'delete-labeled-dataset': + this.$nuxt.$router.replace({ path: '/main/delete-labeled'}) + break case 'upload-dataset': this.$nuxt.$router.replace({ path: '/main/upload'}) break @@ -263,6 +328,10 @@ export default { elmtID ='coco-output' } else if ((/^\/main\/edit(\/|(\?)|$)/.test(browserURL))) { elmtID ='edit-dataset' + } else if ((/^\/main\/all-images(\/|(\?)|$)/.test(browserURL))) { + elmtID = 'all-images' + } else if ((/^\/main\/delete-labeled(\/|(\?)|$)/.test(browserURL))) { + elmtID ='delete-labeled-dataset' } else if ((/^\/main\/delete(\/|(\?)|$)/.test(browserURL))) { elmtID ='delete-dataset' } else if ((/^\/main\/upload(\/|(\?)|$)/.test(browserURL))) { @@ -352,4 +421,8 @@ export default { background-color: #166472; } + .output-icon { + margin-top: -1px; font-family: 'Open Sans Bold'; + } + </style> \ No newline at end of file diff --git a/frontend/pages/main/all-images.vue b/frontend/pages/main/all-images.vue new file mode 100644 index 0000000000000000000000000000000000000000..85c00bd3381604eb77ed8b635ab8f5dae13d359f --- /dev/null +++ b/frontend/pages/main/all-images.vue @@ -0,0 +1,126 @@ +<template> + <div class="col"> + <div class="ml-4"> + <div class="row"> + <div class="col"> + <Dropdown + class="margin-dropdown" + :dropdown-value="dataset" + @onDatasetChanged="changeDataset" + /> + </div> + </div> + <div :key="updateUI" class="row animated fadeIn" style="margin-top: -1rem;"> + <div class="col"> + <div style="display: flex"> + <h5 class="title users-margin"> + {{ dataset }} all images: + <span v-if="!dataset" style="margin-left: 20px; font-size: 0.85rem;"> + Choose Folder First + </span> + <span v-else-if="empty" style="margin-left: 20px; font-size: 0.85rem;"> + No Images Found + </span> + </h5> + <button + v-if="dataset && !empty" + class="btn-white margin-download" + @click="downloadZIP()" + > + {{ dataset }}.zip + <i class="ml-3 mt-1 fas fa-download" /> + </button> + </div> + </div> + </div> + </div> + </div> +</template> + +<script> +import datasetMethods from '~/mixins/outputs/datasetMethods' +import Dropdown from '~/components/dropdown/Dropdown' + +export default { + components: { + Dropdown + }, + mixins: [datasetMethods], + data () { + return { + // isOutputViewer: true, + // isLabeled: true, + // standard: 'coco', + // search: '' + } + }, + methods: { + downloadZIP() { + this.$swal.fire({ + title: 'Downloading', + text: 'Please wait...', + allowOutsideClick: false, + allowEscapeKey: false, + onOpen: async () => { + this.$swal.showLoading() + var filename = this.dataset + '.zip' + var element = document.createElement('a') + + var url = 'api/image/downloadzip/' + this.dataset + var response = await this.$axios.get(url, { + responseType: 'arraybuffer' + }).catch((error) => alert(error)) + + var blob = new Blob([response.data], {type: 'application/zip'}) + + element.setAttribute('href', URL.createObjectURL(blob)) + element.setAttribute('download',filename) + element.style.display = 'none' + + document.body.appendChild(element) + element.click() + document.body.removeChild(element) + + this.$swal.close() + } + }) + } + } +} +</script> + +<style scoped> + + .btn-white { + background: #fff; + -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); + border: 0; + border-radius: 0.3rem; + overflow: hidden; + cursor: pointer; + color: #1E889B; + margin-top: 2.8rem; + padding-left: 1.5rem; + padding-right: 1rem; + } + + .btn-white:hover { + background-color: #F7F7F7; + } + + .margin-download { + margin-left: 2.25rem; + } + + .dropdown { + color: #1E889B; + } + + .margin-dropdown { + margin-top: 3.5rem; + margin-left: -0.1rem; + } + +</style> \ No newline at end of file diff --git a/frontend/pages/main/delete-labeled.vue b/frontend/pages/main/delete-labeled.vue new file mode 100644 index 0000000000000000000000000000000000000000..31b752c449b129b69ce59f2e175397353b75855c --- /dev/null +++ b/frontend/pages/main/delete-labeled.vue @@ -0,0 +1,18 @@ +<template> + <Delete :is-labeled="isLabeled" :title="title" /> +</template> + +<script> +import Delete from '~/components/delete/Delete' +export default { + components: { + Delete + }, + data () { + return { + isLabeled: true, + title: "Delete Labeled Images" + } + } +} +</script> \ No newline at end of file diff --git a/frontend/pages/main/delete.vue b/frontend/pages/main/delete.vue index be911167f9861ef679ff34af6d3852c070f7e2bb..f36c59646a906def71e59b2b56f4eef112fceebc 100644 --- a/frontend/pages/main/delete.vue +++ b/frontend/pages/main/delete.vue @@ -1,42 +1,12 @@ <template> - <client-only> - <Label - :key="dataset" - title="Delete Labeled Images" - viewer-u-r-l="/viewer/index-edit" - :is-labeled="isLabeled" - :is-delete="isDelete" - :dataset="dataset" - > - <Dropdown :dropdown-value="dataset" @onDatasetChanged="changeDataset" /> - </Label> - </client-only> + <Delete /> </template> <script> -import Label from '~/components/label/Label' -import Dropdown from '~/components/dropdown/Dropdown' +import Delete from '~/components/delete/Delete' export default { components: { - Label, - Dropdown - }, - data () { - return { - isDelete: true, - isLabeled: true, - dataset: '' - } - }, - mounted () { - if (this.$route.query.dataset) { - this.dataset = this.$route.query.dataset - } - }, - methods: { - changeDataset (newDataset) { - this.dataset = newDataset - } + Delete } } </script> \ No newline at end of file diff --git a/frontend/pages/main/upload.vue b/frontend/pages/main/upload.vue index 846b4199da9051da1a92e39f47c83cc6f573a015..2b7e949fa1c6c9c4aaa7d45177ae228674413e7c 100644 --- a/frontend/pages/main/upload.vue +++ b/frontend/pages/main/upload.vue @@ -110,12 +110,6 @@ export default { vfileAdded () { console.log(this.$refs.myDropzone.options) this.filesCount++ - // if (this.filesCount > 0) { - // this.options.previewsContainer = false - // } else { - // this.$refs.myDropzone.options.previewsContainer = null - // } - }, vremoved() { this.filesCount-- diff --git a/frontend/static/fonts/OpenSans-Regular.ttf b/frontend/static/fonts/OpenSans-Regular.ttf new file mode 100644 index 0000000000000000000000000000000000000000..2e31d02424ed50b9e05c19b5d82500699a6edbb0 Binary files /dev/null and b/frontend/static/fonts/OpenSans-Regular.ttf differ