From c393f9846aa0dc351315482d53e309e230503d38 Mon Sep 17 00:00:00 2001 From: Valentin Rigal <rigal@teklia.com> Date: Wed, 20 Dec 2023 14:38:45 +0000 Subject: [PATCH] Allow to select a child without a zone --- src/components/Element/PanelHeader.vue | 21 +++++++++++++++++-- src/components/Image/InteractiveImage.vue | 2 +- src/components/Image/Tools.vue | 3 ++- .../Navigation/ChildrenTree/TreeItem.vue | 8 ++----- src/store/annotation.js | 4 ---- src/views/Element.vue | 3 ++- 6 files changed, 26 insertions(+), 15 deletions(-) diff --git a/src/components/Element/PanelHeader.vue b/src/components/Element/PanelHeader.vue index 93608a151..757b69a4b 100644 --- a/src/components/Element/PanelHeader.vue +++ b/src/components/Element/PanelHeader.vue @@ -54,6 +54,13 @@ <span v-else-if="element.creator">Created by <strong>{{ element.creator }}</strong></span> <ConfidenceTag v-if="Number.isFinite(element.confidence)" :value="element.confidence" /> </p> + <!-- Display a message at the top of the panel when a selected children has no zone --> + <div + v-if="!element.zone?.polygon && !isFolder && element.id !== mainElementId" + class="notification is-info my-2 p-3" + > + This element has no zone. + </div> <Modal v-model="deleteModal" :title="'Delete ' + typeName(element.type) + ' ' + element.name"> <p> Are you sure you want to delete the {{ typeName(element.type) }} @@ -124,9 +131,19 @@ export default { element () { return this.elements[this.elementId] }, + isFolder () { + return this.getType(this.element.type).folder + }, isAnnotable () { - const isFolder = this.getType(this.element.type).folder - return this.element?.zone !== null && !isFolder && this.corpus && this.canWrite(this.corpus) + const mainElement = this.elements[this.mainElementId] + if (!mainElement) return false + const mainFolder = this.getType(mainElement.type).folder + return ( + mainElement.image !== null && + !mainFolder && + this.corpus && + this.canWrite(this.corpus) + ) }, corpusId () { return this.element?.corpus?.id ?? null diff --git a/src/components/Image/InteractiveImage.vue b/src/components/Image/InteractiveImage.vue index 1183ee6dc..522928e84 100644 --- a/src/components/Image/InteractiveImage.vue +++ b/src/components/Image/InteractiveImage.vue @@ -44,7 +44,7 @@ fill="transparent" /> <!-- Display the currently edited element using lines and circles --> - <g v-if="selectedElement" v-on:mouseover="setHoveredId(selectedElement.id)" v-on:mouseleave="setHoveredId(null)"> + <g v-if="selectedElement && selectedElement.zone !== null" v-on:mouseover="setHoveredId(selectedElement.id)" v-on:mouseleave="setHoveredId(null)"> <!-- A polyline for the background color, allowing to drag the element around. --> <polyline :points="svgPolygon(selectedElement.zone.polygon)" diff --git a/src/components/Image/Tools.vue b/src/components/Image/Tools.vue index 07db57efa..d2b64711b 100644 --- a/src/components/Image/Tools.vue +++ b/src/components/Image/Tools.vue @@ -5,8 +5,9 @@ <a class="button" :class="{ 'is-primary is-outlined': tool === 'select' }" - title="Select and move an existing child" v-on:click="changeTool('select')" + :disabled="selectedElement.zone === null || undefined" + :title="selectedElement.zone === null ? 'This element has no polygon' : 'Select and move the selected element'" > <span class="icon"> <i class="icon-hand-pointer"></i> diff --git a/src/components/Navigation/ChildrenTree/TreeItem.vue b/src/components/Navigation/ChildrenTree/TreeItem.vue index ebf094be8..da1595b55 100644 --- a/src/components/Navigation/ChildrenTree/TreeItem.vue +++ b/src/components/Navigation/ChildrenTree/TreeItem.vue @@ -225,11 +225,6 @@ export default { }, interactiveSelect (element) { if (!this.interactive) return - if (!this.element.zone || !this.element.zone.polygon) { - this.notify({ type: 'info', text: 'This element has no zone.' }) - this.selectElement(null) - return - } if (this.annotationEnabled && this.annotationTool !== 'select') { // In edition mode, set current tool to selection this.setAnnotationTool('select') @@ -242,10 +237,11 @@ export default { ) { this.selectElement(null) } else { + const eltPolygon = element?.zone?.polygon || null this.selectElement({ id: element.id, name: element.name, - zone: { polygon: [...element.zone.polygon] } + zone: eltPolygon && { polygon: [...eltPolygon] } }) if (this.$route.query.highlight !== element.id) { const query = { ...clone(this.$route.query) } diff --git a/src/store/annotation.js b/src/store/annotation.js index c44f0dbe4..18c8d0180 100644 --- a/src/store/annotation.js +++ b/src/store/annotation.js @@ -205,10 +205,6 @@ export const mutations = { }, selectElement (state, object) { - // Edited element may have a polygon if defined - if (object !== null && (!object.zone || !object.zone.polygon)) { - throw new Error('Edited element must be null or have a defined zone.') - } state.selectedElement = object }, diff --git a/src/views/Element.vue b/src/views/Element.vue index ebbb9d2ab..52939067f 100644 --- a/src/views/Element.vue +++ b/src/views/Element.vue @@ -235,10 +235,11 @@ export default { if (!this.parents[this.highlight]) await this.$store.dispatch('elements/getParentsBulk', { id: this.highlight, corpus: this.corpus }) if (!this.parents[this.highlight] || !this.parents[this.highlight].includes(this.element.id)) return if (!this.elements[this.highlight]) await this.$store.dispatch('elements/get', { id: this.highlight }) + const eltPolygon = this.elements[this.highlight]?.zone?.polygon || [] this.selectElement({ id: this.highlight, name: this.elements[this.highlight].name, - zone: { polygon: [...this.elements[this.highlight].zone.polygon] } + zone: { polygon: [...eltPolygon] } }) }, isNeighbor (id) { -- GitLab