diff --git a/frontend/components/label/Label.vue b/frontend/components/label/Label.vue index 42d7f979ef561a43d2a8d5a67b0676a1abc5e39e..251c86f8cfba000bbcb5f493d52db47b97edc2a9 100644 --- a/frontend/components/label/Label.vue +++ b/frontend/components/label/Label.vue @@ -62,6 +62,10 @@ export default { type: String, default: 'Label Unlabeled Images' }, + isOutputViewer: { + type: Boolean, + default: false + }, viewerURL: { type: String, default: '/viewer/' @@ -69,6 +73,15 @@ export default { isLabeled: { type: Boolean, default: false + }, + output: { + type: Object, + default: () => { + return { + type: 'xml', + standard: 'pascal' + } + } } }, data () { @@ -161,16 +174,20 @@ export default { } }, async openViewer (image) { - console.log(image) - if (!image.isCurrentlyLabeled) { - var url = '/api/accesscontrol/' + image.id - try { - await this.$axios.get(url) - alert("This image is currently Labeled") - } catch (e) { - this.$router.push({ path: this.viewerURL, query: { url: image.url, id: image.id }}) + if (!this.isOutputViewer) { + if (!image.isCurrentlyLabeled) { + var url = '/api/accesscontrol/' + image.id + try { + await this.$axios.get(url) + alert("This image is currently Labeled") + } catch (e) { + this.$router.push({ path: this.viewerURL, query: { url: image.url, id: image.id }}) + } } + } else { + this.$router.push({ path: this.viewerURL, query: {type: this.output.type, id: image.id, name: image.name, standard: this.output.standard}}) } + }, debounceWrapper (e) { this.page = 1 diff --git a/frontend/components/root/Navbar.vue b/frontend/components/root/Navbar.vue index 64aa3172e848f38888d75edc0d1d0396b266694a..ba1d651e4ca2db14a183c3046c43cf66572a03af 100644 --- a/frontend/components/root/Navbar.vue +++ b/frontend/components/root/Navbar.vue @@ -12,8 +12,17 @@ </div> </b-nav-item> + <div v-if="role === 'admin'"> + <!-- Upload Dataset --> + <b-nav-item link-classes="side-bar-color mt-5 ml-4" @click="changeActiveElmtID('upload-dataset')"> + <div id="upload-dataset"> + Upload Dataset + </div> + </b-nav-item> + </div> + <!-- Label Dataset --> - <b-nav-item link-classes="side-bar-color mt-5 ml-4" @click="changeActiveElmtID('label-dataset')"> + <b-nav-item link-classes="side-bar-color mt-3 ml-4" @click="changeActiveElmtID('label-dataset')"> <div id="label-dataset"> Label Dataset </div> @@ -28,15 +37,6 @@ </b-nav-item> </div> - <div v-if="role === 'admin'"> - <!-- Upload Dataset --> - <b-nav-item link-classes="side-bar-color mt-3 ml-4" @click="changeActiveElmtID('upload-dataset')"> - <div id="upload-dataset"> - Upload Dataset - </div> - </b-nav-item> - </div> - <!-- COCO Output --> <b-nav-item link-classes="side-bar-color mt-3 ml-4" @click="changeActiveElmtID('coco-output')"> <div id="coco-output"> @@ -95,7 +95,7 @@ </b-nav-item> <!-- Delete User --> - <b-nav-item link-classes="side-bar-color mt-3 ml-4 mb-5" @click="changeActiveElmtID('delete-user')"> + <b-nav-item link-classes="side-bar-color mt-3 ml-4" @click="changeActiveElmtID('delete-user')"> <div class="icon-text-wrapper"> <i class="mt-1 mr-3 fas fa-trash" /> <div id="delete-user"> @@ -129,7 +129,7 @@ </b-nav-item> <!-- Change Password --> - <b-nav-item link-classes="side-bar-color mt-3 ml-4" @click="changeActiveElmtID('change-password')"> + <b-nav-item link-classes="side-bar-color mt-3 ml-4 mb-5" @click="changeActiveElmtID('change-password')"> <div class="icon-text-wrapper"> <i class="mt-1 mr-3 fas fa-cog" /> <div id="change-password"> @@ -182,7 +182,6 @@ export default { this.redirectRoute(elmtID) }, redirectRoute (elmtID) { - console.log("elmtID: ", elmtID) switch (elmtID) { case 'label-dataset': this.$nuxt.$router.replace({ path: '/main/label'}) @@ -220,33 +219,44 @@ export default { } }, onPathChangeHandler (browserURL) { - console.log("Browser: ", browserURL) var elmtID = '' - if ((/^\/main\/label(\/|(\?)|$)/.test(browserURL))) { - elmtID ='label-dataset' - } else if((/^\/main\/pascal(\/|(\?)|$)/.test(browserURL))){ - elmtID = 'pascal-output' - } else if ((/^\/main\/coco(\/|(\?)|$)/.test(browserURL))) { - elmtID ='coco-output' - } else if ((/^\/main\/edit(\/|(\?)|$)/.test(browserURL))) { - elmtID ='edit-dataset' - } else if ((/^\/main\/upload(\/|(\?)|$)/.test(browserURL))) { - elmtID ='upload-dataset' - } else if ((/^\/main\/change-username(\/|(\?)|$)/.test(browserURL))) { - elmtID ='change-username' - } else if ((/^\/main\/change-password(\/|(\?)|$)/.test(browserURL))) { - elmtID ='change-password' - } else if ((/^\/main\/show-user(\/|(\?)|$)/.test(browserURL))) { - elmtID ='show-all-users' - } else if ((/^\/main\/add-user(\/|(\?)|$)/.test(browserURL))) { - elmtID ='add-user' - } else if ((/^\/main\/edit-user(\/|(\?)|$)/.test(browserURL))) { - elmtID ='edit-user' - } else if (((/^\/main\/delete-user(\/|(\?)|$)/.test(browserURL)))) { - elmtID ='delete-user' + console.log("Browser: ", browserURL) + if (((/^\/main\/output-view(\/|(\?)|$)/.test(browserURL)))) { + var type = this.$route.query.type + if (type === 'xml') { + elmtID = 'pascal-output' + } else { + elmtID = 'coco-output' + } + this.activeElmtID = elmtID + this.setClass(elmtID, 'active') + } else { + if ((/^\/main\/label(\/|(\?)|$)/.test(browserURL))) { + elmtID ='label-dataset' + } else if((/^\/main\/pascal(\/|(\?)|$)/.test(browserURL))){ + elmtID = 'pascal-output' + } else if ((/^\/main\/coco(\/|(\?)|$)/.test(browserURL))) { + elmtID ='coco-output' + } else if ((/^\/main\/edit(\/|(\?)|$)/.test(browserURL))) { + elmtID ='edit-dataset' + } else if ((/^\/main\/upload(\/|(\?)|$)/.test(browserURL))) { + elmtID ='upload-dataset' + } else if ((/^\/main\/change-username(\/|(\?)|$)/.test(browserURL))) { + elmtID ='change-username' + } else if ((/^\/main\/change-password(\/|(\?)|$)/.test(browserURL))) { + elmtID ='change-password' + } else if ((/^\/main\/show-user(\/|(\?)|$)/.test(browserURL))) { + elmtID ='show-all-users' + } else if ((/^\/main\/add-user(\/|(\?)|$)/.test(browserURL))) { + elmtID ='add-user' + } else if ((/^\/main\/edit-user(\/|(\?)|$)/.test(browserURL))) { + elmtID ='edit-user' + } else if (((/^\/main\/delete-user(\/|(\?)|$)/.test(browserURL)))) { + elmtID ='delete-user' + } + this.changeActiveElmtID(elmtID) + this.setClass(elmtID, 'active') } - this.changeActiveElmtID(elmtID) - this.setClass(elmtID, 'active') } } } diff --git a/frontend/nuxt.config.js b/frontend/nuxt.config.js index d827c3f3695a392a8e5fe1bda6b3f17725438647..c54d9d349e700f38d71165e268cdb902e0ae82cc 100644 --- a/frontend/nuxt.config.js +++ b/frontend/nuxt.config.js @@ -34,7 +34,7 @@ export default { plugins: [ '~/plugins/axios', { src: '~/plugins/vue-sweetalert2', ssr: false }, - '~/plugins/vue-annotator' + { src: '~/plugins/json-viewer', ssr: false } ], /* ** Nuxt.js dev-modules diff --git a/frontend/pages/main/coco.vue b/frontend/pages/main/coco.vue index 12694b90e8d3fcf250d21b161883dd31a006e908..de63a5c7dbaca9fa6724a45e1318a1cff33e721d 100644 --- a/frontend/pages/main/coco.vue +++ b/frontend/pages/main/coco.vue @@ -12,71 +12,43 @@ <i class="ml-3 mt-1 fas fa-download" /> </button> </div> - <div class="row"> - <div class="col"> - <h5 class="title users-margin"> - JSON per Image - </h5> - </div> - </div> - <br> - <div class="row form-title-margin"> - <div class="col"> - <input - id="imagesID" - v-model="search" - type="text" - class="form-control form-border field-length form-content" - placeholder="Search for Images ID..." - name="imagesID" - > - </div> - </div> - <br> - <b-row> - <b-col v-for="labs in filterImages" :key="labs"> - <div id="container"> - <nuxt-link :to="{ path: '/main/output-view', query: {type: 'json', id: labs.ImageID, name: labs.Filename, standard: standard}}"> - <Images - :image-name="labs.Filename" - :image-i-d="labs.ImageID" - :image-u-r-l="backendURL + '/api/' + labs.ImagePath" - /> - </nuxt-link> - <br> - </div> - </b-col> - </b-row> + </div> + <div class="row"> + <Label + :is-output-viewer="isOutputViewer" + :is-labeled="isLabeled" + title="JSON Per Image" + viewer-u-r-l="/main/output-view" + :output="{type: 'json', standard: standard}" + /> </div> </div> </template> <script> -export default { - data () { - return { - // search: '' - } - } -} -</script> - -<script> -import Images from '~/components/view/Images.vue' import getAllLabeledImages from '~/mixins/image/getAllLabeledImages.js' import { backendURL } from '~/config.js' -import VueDropdown from 'vue-dynamic-dropdown' +import Label from '~/components/label/Label' + export default { components: { - Images, - VueDropdown + Label }, mixins: [getAllLabeledImages], data () { return { + isOutputViewer: true, + isLabeled: true, backendURL: backendURL, standard: 'coco', - search: '', + search: '' + } + }, + computed: { + filterImages: function(){ + return this.labeledImages.filter((labs) => { + return labs.Filename.match(this.search) + }) } }, methods: { @@ -137,13 +109,6 @@ export default { element.click() document.body.removeChild(element) } - }, - computed: { - filterImages: function(){ - return this.labeledImages.filter((labs) => { - return labs.Filename.match(this.search); - }); - } } } </script> diff --git a/frontend/pages/main/output-view/index.vue b/frontend/pages/main/output-view/index.vue index 72166692d8c2730a9a3eb997fe47513a7d307f9e..2d7a7500cd963b6946fae542d0e038ac151b90ae 100644 --- a/frontend/pages/main/output-view/index.vue +++ b/frontend/pages/main/output-view/index.vue @@ -41,16 +41,8 @@ </template> <script> -import JsonViewer from 'vue-json-viewer' import Convert from 'xml-js' -// import XMLFormatter from 'xml-formatter' export default { -// props: { -// imageID -// }, - components: { - JsonViewer - }, data () { return { type: '', @@ -74,11 +66,10 @@ export default { this.standard = this.$route.query.standard this.json = await this.getLabelByID(this.standard) // this.xml = XMLFormatter(this.convertToXML(),this.config) - this.xml = this.convertToXML() if(this.type === 'xml'){ + this.xml = this.convertToXML() this.Format() } - }, methods:{ closeOutputViewer() { @@ -162,7 +153,12 @@ export default { Format(){ var xml = this.xml.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>').replace(/ /g, ' ').replace(/\n/g,'<br />') var mydiv = document.getElementById("xml") - mydiv.innerHTML += xml + if (mydiv) { + console.log("1") + mydiv.innerHTML += xml + console.log("2") + } + console.log("3") } } } diff --git a/frontend/pages/main/pascal.vue b/frontend/pages/main/pascal.vue index ec27bef3c1d2fd8a1de38e77ec21b60802c2f0a4..e6fd65fb49bed0fa0bd5ec3ad25819f948fe6eb6 100644 --- a/frontend/pages/main/pascal.vue +++ b/frontend/pages/main/pascal.vue @@ -12,79 +12,46 @@ <i class="ml-3 mt-1 fas fa-download" /> </button> </div> - <div class="row"> - <div class="col"> - <h5 class="title users-margin"> - XML per Image - </h5> - </div> - </div> - <br> - <div class="row form-title-margin"> - <div class="col"> - <input - id="imagesID" - v-model="search" - type="text" - class="form-control form-border field-length form-content" - placeholder="Search for Images ID..." - name="imagesID" - > - </div> - </div> - <br> - <b-row> - <b-col v-for="labs in filterImages" :key="labs"> - <div id="container"> - <nuxt-link :to="{ path: '/main/output-view', query: {type: 'xml', id: labs.ImageID, name: labs.Filename, standard: standard}}"> - <Images - :image-name="labs.Filename" - :image-i-d="labs.ImageID" - :image-u-r-l="backendURL + '/api/' + labs.ImagePath" - /> - </nuxt-link> - <br> - </div> - </b-col> - </b-row> + </div> + <div class="row"> + <Label + :is-output-viewer="isOutputViewer" + :is-labeled="isLabeled" + title="XML Per Image" + viewer-u-r-l="/main/output-view" + /> </div> </div> </template> -<script> -export default { - data () { - return { - // search: '' - } - } -} -</script> <script> -import Images from '~/components/view/Images.vue' import getAllLabeledImages from '~/mixins/image/getAllLabeledImages.js' import { backendURL } from '~/config.js' -import VueDropdown from 'vue-dynamic-dropdown' import Convert from 'xml-js' +import Label from '~/components/label/Label' export default { components: { - Images, - VueDropdown + Label }, mixins: [getAllLabeledImages], data () { return { + isOutputViewer: true, + isLabeled: true, backendURL: backendURL, standard: 'pascal', - search: '', + search: '' + } + }, + computed: { + filterImages: function(){ + return this.labeledImages.filter((labs) => { + return labs.Filename.match(this.search) + }) } }, methods: { - setNewSelectedOption(event){ - this.standard = event.value.toLowerCase() - this.config.placeholder = event.value - }, async getAllLabelJSON(standard){ var url = '/api/label' var response = await this.$axios(url).catch(error => console.log(error)) @@ -149,13 +116,6 @@ export default { element.click() document.body.removeChild(element) } - }, - computed: { - filterImages: function(){ - return this.labeledImages.filter((labs) => { - return labs.Filename.match(this.search); - }); - } } } </script> diff --git a/frontend/plugins/json-viewer.js b/frontend/plugins/json-viewer.js new file mode 100644 index 0000000000000000000000000000000000000000..abc21e6f9ea0f61352c3d6280712c44201e9ee04 --- /dev/null +++ b/frontend/plugins/json-viewer.js @@ -0,0 +1,4 @@ +import Vue from 'vue' + +import JsonViewer from 'vue-json-viewer' +Vue.use(JsonViewer) \ No newline at end of file diff --git a/frontend/plugins/vue-annotator.js b/frontend/plugins/vue-annotator.js deleted file mode 100644 index 548fc6c6ec94e0b30997c4346f1d4490edfba4c8..0000000000000000000000000000000000000000 --- a/frontend/plugins/vue-annotator.js +++ /dev/null @@ -1,4 +0,0 @@ -// import Vue from 'vue' -// import VueAnnotator from 'vue-annotator' - -// Vue.use(VueAnnotator) \ No newline at end of file