You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

297 lines
7.6 KiB

<template>
<v-app>
<the-header>
<template #leftDrawerIcon>
<v-app-bar-nav-icon @click="drawerLeft = !drawerLeft" />
</template>
</the-header>
<v-navigation-drawer
v-model="drawerLeft"
app
clipped
color=""
>
<the-side-bar
:link="getLink"
:role="getCurrentUserRole"
/>
</v-navigation-drawer>
<v-main>
<v-overlay :value="loading">
<v-progress-circular indeterminate size="64" />
</v-overlay>
<v-snackbar
v-model="snackbar"
>
{{ text }}
<template v-slot:action="{ attrs }">
<v-btn
color="pink"
text
v-bind="attrs"
@click="snackbar = false"
>
Close
</v-btn>
</template>
</v-snackbar>
<v-container
v-if="currentDoc && !loading"
fluid
>
<v-row
no-gutters
class="d-none d-sm-flex"
>
<v-col>
<approve-button
v-if="canViewApproveButton"
v-model="page"
:length="total"
:approved="approved"
:disabled="currentDoc ? false : true"
/>
<filter-button
v-model="filterOption"
/>
<guideline-button />
<clear-annotations-button />
<v-tooltip bottom>
<template v-slot:activator="{ on }">
<v-btn
class="text-capitalize ps-1 pe-1"
min-width="36"
icon
v-on="on"
@click="dialogComment=true"
>
<v-icon>
mdi-chat
</v-icon>
</v-btn>
</template>
<span>{{ $t('annotation.commentTooltip') }}</span>
</v-tooltip>
<settings
v-model="options"
:errors="errors"
/>
<v-dialog
v-model="dialogComment"
width="800"
>
<form-create-comment
@cancel="dialogComment=false"
/>
</v-dialog>
</v-col>
<v-spacer />
<v-col>
<pagination
v-model="page"
:length="total"
/>
</v-col>
</v-row>
<v-row justify="center">
<v-col cols="12" md="9">
<nuxt />
</v-col>
<v-col cols="12" md="3">
<metadata-box
:metadata="JSON.parse(currentDoc.meta)"
/>
</v-col>
</v-row>
</v-container>
<v-container
v-else
fill-height
>
<v-layout align-center>
<v-flex text-center>
<h1 class="display-2 primary--text">
Whoops, data is empty.
</h1>
<p>Please upload your dataset.</p>
</v-flex>
</v-layout>
</v-container>
</v-main>
<bottom-navigator
v-model="page"
:length="total"
class="d-flex d-sm-none"
/>
</v-app>
</template>
<script>
import { mapActions, mapGetters, mapState, mapMutations } from 'vuex'
import BottomNavigator from '@/components/containers/annotation/BottomNavigator'
import ClearAnnotationsButton from '@/components/containers/annotation/ClearAnnotationsButton.vue'
import GuidelineButton from '@/components/containers/annotation/GuidelineButton'
import MetadataBox from '@/components/organisms/annotation/MetadataBox'
import FilterButton from '@/components/containers/annotation/FilterButton'
import ApproveButton from '@/components/containers/annotation/ApproveButton'
import FormCreateComment from '../components/comment/FormCRUD.vue'
import Pagination from '~/components/containers/annotation/Pagination'
import TheHeader from '~/components/layout/TheHeader'
import TheSideBar from '~/components/layout/TheSideBar'
import Settings from '~/components/containers/annotation/Settings.vue'
export default {
middleware: ['check-auth', 'auth', 'set-project'],
components: {
TheSideBar,
TheHeader,
BottomNavigator,
Pagination,
GuidelineButton,
FilterButton,
ApproveButton,
MetadataBox,
ClearAnnotationsButton,
FormCreateComment,
Settings
},
fetch() {
this.getDocumentList({
projectId: this.$route.params.id,
limit: this.limit,
offset: this.offset,
q: this.$route.query.q,
isChecked: this.filterOption,
filterName: this.getFilterOption
})
},
data() {
return {
dialogComment: false,
drawerLeft: null,
limit: 10,
options: {
onAutoLabeling: false
},
errors: {
'autoLabelingConfig': ''
},
snackbar: false,
text: ''
}
},
computed: {
...mapGetters('projects', ['getLink', 'getCurrentUserRole', 'getFilterOption', 'canViewApproveButton']),
...mapState('documents', ['loading', 'total']),
...mapGetters('documents', ['currentDoc', 'approved']),
page: {
get() {
return parseInt(this.$route.query.page, 10)
},
set(value) {
this.$router.push({
query: {
isChecked: this.$route.query.isChecked,
page: parseInt(value, 10),
q: this.$route.query.q
}
})
}
},
filterOption: {
get() {
return this.$route.query.isChecked
},
set(value) {
this.$router.push({
query: {
isChecked: value,
page: 1,
q: this.$route.query.q
}
})
}
},
offset() {
return Math.floor((this.page - 1) / this.limit) * this.limit
},
current() {
return (this.page - 1) % this.limit
},
searchOptions() {
// a bit tricky technique to capture variables change simultaneously.
// see https://github.com/vuejs/vue/issues/844#issuecomment-265315349
return JSON.stringify({
page: this.page,
q: this.$route.query.q,
isChecked: this.filterOption
})
}
},
watch: {
total() {
// To validate the range of page variable on reloading the annotation page.
if (this.total !== 0 && this.page > this.total) {
this.$router.push({
path: this.localePath(`/projects/${this.$route.params.id}/`)
})
}
},
offset() {
this.$fetch()
},
filterOption() {
this.page = 1
this.$fetch()
},
current: {
async handler() {
this.setCurrent(this.current)
if (this.options.onAutoLabeling) {
try {
this.setLoading(true)
await this.autoLabeling({ projectId: this.$route.params.id })
} catch (e) {
this.snackbar = true
this.text = e.response.data.detail
} finally {
this.setLoading(false)
}
}
},
immediate: true
},
searchOptions() {
this.saveSearchOptions(JSON.parse(this.searchOptions))
},
async "options.onAutoLabeling"(val) {
if (val) {
try {
this.setLoading(true)
await this.autoLabeling({ projectId: this.$route.params.id })
this.errors.autoLabelingConfig = ''
} catch (e) {
this.errors.autoLabelingConfig = e.response.data.detail
this.options.onAutoLabeling = false
} finally {
this.setLoading(false)
}
}
}
},
methods: {
...mapActions('documents', ['getDocumentList', 'autoLabeling']),
...mapMutations('documents', ['setCurrent', 'setLoading']),
...mapMutations('projects', ['saveSearchOptions'])
}
}
</script>