@konfuzio/document-validation-ui 0.1.59-dev.3 → 0.1.60-dev.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cypress.config.js +6 -6
- package/dist/css/app.css +1 -1
- package/dist/index.html +1 -1
- package/dist/js/app.js +1 -1
- package/dist/js/app.js.map +1 -1
- package/dist/js/chunk-vendors.js +23 -66
- package/dist/js/chunk-vendors.js.map +1 -1
- package/jest.config.js +2 -22
- package/package.json +38 -32
- package/src/api.js +12 -0
- package/src/assets/scss/ann_set_table_options.scss +4 -4
- package/src/assets/scss/annotation_action_buttons.scss +7 -7
- package/src/assets/scss/annotation_details.scss +9 -9
- package/src/assets/scss/choose_label_set_modal.scss +5 -5
- package/src/assets/scss/document_action_bar.scss +3 -3
- package/src/assets/scss/document_annotations.scss +43 -45
- package/src/assets/scss/document_category.scss +8 -8
- package/src/assets/scss/document_dashboard.scss +1 -1
- package/src/assets/scss/document_edit.scss +30 -30
- package/src/assets/scss/document_error.scss +6 -6
- package/src/assets/scss/document_name.scss +6 -6
- package/src/assets/scss/document_page.scss +3 -3
- package/src/assets/scss/document_search_bar.scss +7 -7
- package/src/assets/scss/document_set_chooser.scss +3 -3
- package/src/assets/scss/document_thumbnails.scss +7 -7
- package/src/assets/scss/document_toolbar.scss +10 -10
- package/src/assets/scss/document_top_bar.scss +11 -11
- package/src/assets/scss/document_viewport_modal.scss +3 -3
- package/src/assets/scss/documents_list.scss +12 -11
- package/src/assets/scss/edit_page_thumbnail.scss +6 -6
- package/src/assets/scss/empty_state.scss +4 -4
- package/src/assets/scss/error_page.scss +2 -2
- package/src/assets/scss/extracting_data.scss +3 -3
- package/src/assets/scss/imports.scss +1 -0
- package/src/assets/scss/multi_ann_table_overlay.scss +3 -3
- package/src/assets/scss/multi_ann_table_popup.scss +1 -1
- package/src/assets/scss/new_annotation.scss +19 -25
- package/src/assets/scss/scrolling_document.scss +1 -1
- package/src/assets/scss/theme.scss +52 -64
- package/src/assets/scss/variables.scss +0 -2
- package/src/components/App.vue +14 -9
- package/src/components/DocumentAnnotations/AnnotationActionButtons.vue +6 -4
- package/src/components/DocumentAnnotations/AnnotationContent.vue +52 -25
- package/src/components/DocumentAnnotations/AnnotationRow.vue +50 -106
- package/src/components/DocumentAnnotations/DocumentAnnotations.vue +6 -12
- package/src/components/DocumentAnnotations/EmptyAnnotation.vue +70 -31
- package/src/components/DocumentDashboard.vue +17 -12
- package/src/components/DocumentEdit/EditPages.vue +46 -51
- package/src/components/DocumentPage/BoxSelection.vue +49 -16
- package/src/components/DocumentPage/DocumentPage.vue +153 -56
- package/src/components/DocumentPage/DocumentToolbar.vue +15 -5
- package/src/components/DocumentPage/EditAnnotation.vue +372 -0
- package/src/components/DocumentPage/{AnnotationPopup.vue → NewAnnotation.vue} +94 -122
- package/src/components/DocumentPage/ScrollingPage.vue +10 -2
- package/src/components/DocumentThumbnails/LoadingThumbnail.vue +6 -3
- package/src/components/DocumentTopBar/DocumentTopBar.vue +2 -4
- package/src/constants.js +7 -1
- package/src/i18n.js +5 -2
- package/src/main.js +16 -14
- package/src/store/display.js +24 -38
- package/src/store/document.js +6 -1
- package/src/store/index.js +8 -5
- package/src/store/selection.js +76 -152
- package/src/components/DocumentPage/PlaceholderSelection.vue +0 -51
- package/src/components/DocumentPage/SpanSelection.vue +0 -259
|
@@ -106,7 +106,6 @@
|
|
|
106
106
|
<!-- save button -->
|
|
107
107
|
<b-button
|
|
108
108
|
v-if="showSave"
|
|
109
|
-
id="save-ann"
|
|
110
109
|
:class="`button-action ${showText ? 'is-button-text' : 'is-button-icon'}`"
|
|
111
110
|
:type="showText ? 'is-primary' : 'is-ghost'"
|
|
112
111
|
@click.stop="save"
|
|
@@ -206,7 +205,9 @@ export default {
|
|
|
206
205
|
data() {
|
|
207
206
|
return {
|
|
208
207
|
tooltipDelay: 700,
|
|
209
|
-
showText:
|
|
208
|
+
showText:
|
|
209
|
+
window.innerWidth >
|
|
210
|
+
TEXT_BREAKPOINT_WIDTH(this.$i18n ? this.$i18n.locale : "en"),
|
|
210
211
|
};
|
|
211
212
|
},
|
|
212
213
|
computed: {
|
|
@@ -226,12 +227,13 @@ export default {
|
|
|
226
227
|
window.addEventListener("resize", this.resize);
|
|
227
228
|
},
|
|
228
229
|
|
|
229
|
-
|
|
230
|
+
destroyed() {
|
|
230
231
|
window.removeEventListener("resize", this.resize);
|
|
231
232
|
},
|
|
232
233
|
methods: {
|
|
233
234
|
resize() {
|
|
234
|
-
this.showText =
|
|
235
|
+
this.showText =
|
|
236
|
+
window.innerWidth > TEXT_BREAKPOINT_WIDTH(this.$i18n.locale);
|
|
235
237
|
},
|
|
236
238
|
search() {
|
|
237
239
|
this.$emit("search");
|
|
@@ -11,10 +11,10 @@
|
|
|
11
11
|
editAnnotation &&
|
|
12
12
|
editAnnotation.id === annotation.id &&
|
|
13
13
|
'error-editing',
|
|
14
|
-
|
|
14
|
+
isAnnotationBeingEdited && 'clicked-ann',
|
|
15
15
|
]"
|
|
16
16
|
role="textbox"
|
|
17
|
-
:contenteditable="
|
|
17
|
+
:contenteditable="isAnnotationBeingEdited"
|
|
18
18
|
@click="handleEditAnnotation"
|
|
19
19
|
@paste="handlePaste"
|
|
20
20
|
@keypress.enter="saveAnnotationChanges"
|
|
@@ -61,7 +61,11 @@ export default {
|
|
|
61
61
|
};
|
|
62
62
|
},
|
|
63
63
|
computed: {
|
|
64
|
-
...mapGetters("document", [
|
|
64
|
+
...mapGetters("document", [
|
|
65
|
+
"isAnnotationInEditMode",
|
|
66
|
+
"pageAtIndex",
|
|
67
|
+
"isDocumentReviewed",
|
|
68
|
+
]),
|
|
65
69
|
...mapGetters("display", ["bboxToRect"]),
|
|
66
70
|
...mapState("document", [
|
|
67
71
|
"editAnnotation",
|
|
@@ -70,17 +74,19 @@ export default {
|
|
|
70
74
|
"newAcceptedAnnotations",
|
|
71
75
|
"showActionError",
|
|
72
76
|
]),
|
|
73
|
-
isSpanBeingEdited() {
|
|
74
|
-
return this.isAnnotationInEditMode(this.annotation.id, this.spanIndex);
|
|
75
|
-
},
|
|
76
77
|
isAnnotationBeingEdited() {
|
|
77
|
-
return (
|
|
78
|
-
this.editAnnotation && this.annotation.id === this.editAnnotation.id
|
|
79
|
-
);
|
|
78
|
+
return this.isAnnotationInEditMode(this.annotation.id, this.spanIndex);
|
|
80
79
|
},
|
|
81
80
|
},
|
|
82
81
|
|
|
83
82
|
watch: {
|
|
83
|
+
isAnnotationBeingEdited(newState, oldState) {
|
|
84
|
+
// verify if new annotation in edit mode is not this one and if this
|
|
85
|
+
// one was selected before so we set the state to the previous one (like a cancel)
|
|
86
|
+
if (!newState && oldState) {
|
|
87
|
+
this.handleCancel();
|
|
88
|
+
}
|
|
89
|
+
},
|
|
84
90
|
span() {
|
|
85
91
|
// span content changed, ex. from click on entity
|
|
86
92
|
this.setText(this.span.offset_string);
|
|
@@ -104,15 +110,10 @@ export default {
|
|
|
104
110
|
if (
|
|
105
111
|
!this.publicView &&
|
|
106
112
|
!this.isDocumentReviewed &&
|
|
107
|
-
!this.
|
|
113
|
+
!this.isAnnotationBeingEdited &&
|
|
108
114
|
!this.isLoading
|
|
109
115
|
) {
|
|
110
|
-
|
|
111
|
-
this.$store.dispatch(
|
|
112
|
-
"selection/setSpanSelection",
|
|
113
|
-
this.annotation.span
|
|
114
|
-
);
|
|
115
|
-
}
|
|
116
|
+
this.$store.dispatch("selection/selectElement", this.annotation.id);
|
|
116
117
|
|
|
117
118
|
this.$store
|
|
118
119
|
.dispatch("document/setEditAnnotation", {
|
|
@@ -124,18 +125,44 @@ export default {
|
|
|
124
125
|
pageNumber: this.span.page_index + 1,
|
|
125
126
|
})
|
|
126
127
|
.then(() => {
|
|
127
|
-
|
|
128
|
-
this.$refs.contentEditable.focus();
|
|
129
|
-
}
|
|
128
|
+
this.$refs.contentEditable.focus();
|
|
130
129
|
})
|
|
131
130
|
.catch((error) => {
|
|
132
131
|
console.log(error);
|
|
133
132
|
});
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
133
|
+
|
|
134
|
+
const page = this.pageAtIndex(this.span.page_index);
|
|
135
|
+
if (page) {
|
|
136
|
+
const { x, y, width, height } = this.bboxToRect(page, this.span);
|
|
137
|
+
|
|
138
|
+
const selection = {
|
|
139
|
+
start: {
|
|
140
|
+
x,
|
|
141
|
+
y,
|
|
142
|
+
},
|
|
143
|
+
end: {
|
|
144
|
+
x: x + width,
|
|
145
|
+
y: y + height,
|
|
146
|
+
},
|
|
147
|
+
pageNumber: page.number,
|
|
148
|
+
custom: false,
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
// check if this is part of a group of spans to show the whole bounding box as a placeholder
|
|
152
|
+
if (
|
|
153
|
+
this.annotation.selection_bbox &&
|
|
154
|
+
this.annotation.span.length > 1
|
|
155
|
+
) {
|
|
156
|
+
selection.placeholderBox = this.bboxToRect(
|
|
157
|
+
page,
|
|
158
|
+
this.annotation.selection_bbox
|
|
159
|
+
);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
this.$store.dispatch("selection/setSelection", {
|
|
163
|
+
selection,
|
|
164
|
+
span: this.span,
|
|
165
|
+
});
|
|
139
166
|
}
|
|
140
167
|
}
|
|
141
168
|
},
|
|
@@ -146,7 +173,7 @@ export default {
|
|
|
146
173
|
this.$refs.contentEditable.blur();
|
|
147
174
|
}
|
|
148
175
|
|
|
149
|
-
this.$store.dispatch("selection/
|
|
176
|
+
this.$store.dispatch("selection/setSelectedEntities", null);
|
|
150
177
|
},
|
|
151
178
|
handlePaste(event) {
|
|
152
179
|
// TODO: modify to only paste plain text
|
|
@@ -15,13 +15,14 @@
|
|
|
15
15
|
>
|
|
16
16
|
<div class="annotations-width-slider">
|
|
17
17
|
<b-slider
|
|
18
|
-
|
|
18
|
+
:value="labelWidth"
|
|
19
19
|
type="is-move"
|
|
20
20
|
:min="20"
|
|
21
21
|
:max="80"
|
|
22
22
|
:custom-formatter="(val) => `${$t('label_size')} ${val}%`"
|
|
23
23
|
class="is-full-height show-hover show-line"
|
|
24
24
|
:disabled="isAnnotationInEditMode()"
|
|
25
|
+
@input="setLabelWidth"
|
|
25
26
|
/>
|
|
26
27
|
</div>
|
|
27
28
|
<div
|
|
@@ -97,12 +98,7 @@
|
|
|
97
98
|
|
|
98
99
|
<div class="annotation-row-right" :style="`width:${annotationWidth}%`">
|
|
99
100
|
<div class="annotation-content">
|
|
100
|
-
<div
|
|
101
|
-
v-if="isAnnotationInEditMode(currentAnnotationId()) && spanLoading"
|
|
102
|
-
>
|
|
103
|
-
<b-icon style="width: 16px" icon="spinner" class="fa-spin" />
|
|
104
|
-
</div>
|
|
105
|
-
<div v-else-if="annotation" class="annotation-items">
|
|
101
|
+
<div v-if="annotation" class="annotation-items">
|
|
106
102
|
<b-checkbox
|
|
107
103
|
v-if="annotation.metadata && annotation.metadata.checkbox"
|
|
108
104
|
v-model="isChecked"
|
|
@@ -133,8 +129,7 @@
|
|
|
133
129
|
<div v-else>
|
|
134
130
|
<div
|
|
135
131
|
v-if="
|
|
136
|
-
spanSelection
|
|
137
|
-
isAnnotationInEditMode(currentAnnotationId())
|
|
132
|
+
spanSelection && isAnnotationInEditMode(currentAnnotationId())
|
|
138
133
|
"
|
|
139
134
|
>
|
|
140
135
|
<EmptyAnnotation
|
|
@@ -249,7 +244,6 @@ export default {
|
|
|
249
244
|
checkboxDefaultValue: checkboxValue,
|
|
250
245
|
isCheckboxAvailable: false,
|
|
251
246
|
isChecked: checkboxValue,
|
|
252
|
-
labelContainerWidth: 0,
|
|
253
247
|
};
|
|
254
248
|
},
|
|
255
249
|
computed: {
|
|
@@ -267,8 +261,8 @@ export default {
|
|
|
267
261
|
]),
|
|
268
262
|
...mapState("selection", [
|
|
269
263
|
"spanSelection",
|
|
264
|
+
"elementSelected",
|
|
270
265
|
"selectedEntities",
|
|
271
|
-
"spanLoading",
|
|
272
266
|
]),
|
|
273
267
|
...mapState("display", ["labelWidth", "annotationWidth"]),
|
|
274
268
|
...mapState("project", ["showAnnotationTranslations"]),
|
|
@@ -325,12 +319,6 @@ export default {
|
|
|
325
319
|
},
|
|
326
320
|
},
|
|
327
321
|
watch: {
|
|
328
|
-
labelWidth(width) {
|
|
329
|
-
this.labelContainerWidth = width;
|
|
330
|
-
},
|
|
331
|
-
labelContainerWidth(width) {
|
|
332
|
-
this.setLabelWidth(width);
|
|
333
|
-
},
|
|
334
322
|
annotationId(newAnnotationId) {
|
|
335
323
|
this.checkAnnotationSelection(newAnnotationId);
|
|
336
324
|
},
|
|
@@ -395,7 +383,6 @@ export default {
|
|
|
395
383
|
},
|
|
396
384
|
mounted() {
|
|
397
385
|
this.checkAnnotationSelection(this.annotationId);
|
|
398
|
-
this.labelContainerWidth = this.labelWidth;
|
|
399
386
|
},
|
|
400
387
|
methods: {
|
|
401
388
|
...mapActions("display", ["setLabelWidth"]),
|
|
@@ -451,10 +438,9 @@ export default {
|
|
|
451
438
|
|
|
452
439
|
if (this.annotation && this.annotation.id) return this.annotation.id;
|
|
453
440
|
|
|
454
|
-
const setId =
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
: this.labelSet.id;
|
|
441
|
+
const setId = this.annotationSet
|
|
442
|
+
? this.annotationSet.id
|
|
443
|
+
: this.labelSet.id;
|
|
458
444
|
|
|
459
445
|
return `${setId}_${this.label.id}`;
|
|
460
446
|
},
|
|
@@ -587,8 +573,11 @@ export default {
|
|
|
587
573
|
} else {
|
|
588
574
|
if (!this.isAnnotationInEditMode(this.currentAnnotationId())) return;
|
|
589
575
|
|
|
590
|
-
|
|
591
|
-
|
|
576
|
+
return (
|
|
577
|
+
this.elementSelected === this.currentAnnotationId() &&
|
|
578
|
+
this.spanSelection &&
|
|
579
|
+
Array.isArray(this.spanSelection)
|
|
580
|
+
);
|
|
592
581
|
}
|
|
593
582
|
},
|
|
594
583
|
handleMissingAnnotation() {
|
|
@@ -689,92 +678,44 @@ export default {
|
|
|
689
678
|
this.isLoading = true;
|
|
690
679
|
}, 100);
|
|
691
680
|
|
|
692
|
-
//
|
|
693
|
-
if
|
|
694
|
-
(this.editAnnotation.annotationSet &&
|
|
695
|
-
(this.editAnnotation.annotationSet.id !== this.annotationSet.id ||
|
|
696
|
-
(this.editAnnotation.annotationSet.id == null &&
|
|
697
|
-
this.labelSet.id !== this.editAnnotation.labelSet.id))) ||
|
|
698
|
-
(this.editAnnotation.label &&
|
|
699
|
-
this.editAnnotation.label.id !== this.label.id)
|
|
700
|
-
) {
|
|
701
|
-
// first delete annotation, then create new one
|
|
702
|
-
this.$store
|
|
703
|
-
.dispatch("document/deleteAnnotation", {
|
|
704
|
-
annotationId: this.annotation.id,
|
|
705
|
-
})
|
|
706
|
-
.then(() => {
|
|
707
|
-
const annotationToCreate = {
|
|
708
|
-
document: this.documentId,
|
|
709
|
-
span: spans,
|
|
710
|
-
label: this.editAnnotation.label.id,
|
|
711
|
-
is_correct: true,
|
|
712
|
-
revised: false,
|
|
713
|
-
};
|
|
714
|
-
|
|
715
|
-
if (this.editAnnotation.annotationSet.id) {
|
|
716
|
-
annotationToCreate.annotation_set =
|
|
717
|
-
this.editAnnotation.annotationSet.id;
|
|
718
|
-
} else {
|
|
719
|
-
annotationToCreate.label_set = this.editAnnotation.labelSet.id;
|
|
720
|
-
}
|
|
681
|
+
let updatedString; // what will be sent to the API
|
|
682
|
+
let storeAction; // if it will be 'delete' or 'patch'
|
|
721
683
|
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
})
|
|
726
|
-
.catch((error) => {
|
|
727
|
-
this.$store.dispatch("document/createErrorMessage", {
|
|
728
|
-
error,
|
|
729
|
-
serverErrorMessage: this.$t("server_error"),
|
|
730
|
-
defaultErrorMessage: this.$t("error_creating_annotation"),
|
|
731
|
-
});
|
|
732
|
-
})
|
|
733
|
-
.finally(() => {
|
|
734
|
-
this.$store.dispatch("document/resetEditAnnotation");
|
|
735
|
-
this.$store.dispatch("selection/disableSelection");
|
|
736
|
-
this.loading = false;
|
|
737
|
-
});
|
|
738
|
-
});
|
|
684
|
+
// Verify if we delete the entire Annotation or a part of the text
|
|
685
|
+
if (isToDecline || spans.length === 0) {
|
|
686
|
+
storeAction = "document/deleteAnnotation";
|
|
739
687
|
} else {
|
|
740
|
-
|
|
741
|
-
|
|
688
|
+
// Editing the Annotation
|
|
689
|
+
// Deleting part of multi-line Annotation
|
|
690
|
+
storeAction = "document/updateAnnotation";
|
|
742
691
|
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
storeAction = "document/updateAnnotation";
|
|
750
|
-
|
|
751
|
-
updatedString = {
|
|
752
|
-
is_correct: true,
|
|
753
|
-
revised: true,
|
|
754
|
-
span: spans,
|
|
755
|
-
};
|
|
756
|
-
}
|
|
692
|
+
updatedString = {
|
|
693
|
+
is_correct: true,
|
|
694
|
+
revised: true,
|
|
695
|
+
span: spans,
|
|
696
|
+
};
|
|
697
|
+
}
|
|
757
698
|
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
});
|
|
771
|
-
})
|
|
772
|
-
.finally(() => {
|
|
773
|
-
this.$store.dispatch("document/resetEditAnnotation");
|
|
774
|
-
this.$store.dispatch("selection/disableSelection");
|
|
775
|
-
this.isLoading = false;
|
|
699
|
+
// Send to the store for the http patch/delete request
|
|
700
|
+
this.$store
|
|
701
|
+
.dispatch(storeAction, {
|
|
702
|
+
updatedValues: updatedString,
|
|
703
|
+
annotationId: this.annotation.id,
|
|
704
|
+
annotationSet: this.annotationSet,
|
|
705
|
+
})
|
|
706
|
+
.catch((error) => {
|
|
707
|
+
this.$store.dispatch("document/createErrorMessage", {
|
|
708
|
+
error,
|
|
709
|
+
serverErrorMessage: this.$t("server_error"),
|
|
710
|
+
defaultErrorMessage: this.$t("edit_error"),
|
|
776
711
|
});
|
|
777
|
-
|
|
712
|
+
})
|
|
713
|
+
.finally(() => {
|
|
714
|
+
this.$store.dispatch("document/resetEditAnnotation");
|
|
715
|
+
this.$store.dispatch("selection/disableSelection");
|
|
716
|
+
this.$store.dispatch("selection/setSelectedEntities", null);
|
|
717
|
+
this.isLoading = false;
|
|
718
|
+
});
|
|
778
719
|
},
|
|
779
720
|
saveEmptyAnnotationChanges() {
|
|
780
721
|
let annotationToCreate;
|
|
@@ -819,7 +760,10 @@ export default {
|
|
|
819
760
|
},
|
|
820
761
|
handleCancelButton() {
|
|
821
762
|
this.$store.dispatch("document/resetEditAnnotation");
|
|
822
|
-
this
|
|
763
|
+
if (this.elementSelected) {
|
|
764
|
+
this.$store.dispatch("selection/disableSelection");
|
|
765
|
+
this.$store.dispatch("selection/setSelectedEntities", null);
|
|
766
|
+
}
|
|
823
767
|
this.isLoading = false;
|
|
824
768
|
},
|
|
825
769
|
enableLoading(annotations) {
|
|
@@ -105,10 +105,7 @@
|
|
|
105
105
|
</div>
|
|
106
106
|
</div>
|
|
107
107
|
|
|
108
|
-
<b-collapse
|
|
109
|
-
:model-value="isAccordionOpen(annotationSet)"
|
|
110
|
-
animation="slide"
|
|
111
|
-
>
|
|
108
|
+
<b-collapse :open="isAccordionOpen(annotationSet)">
|
|
112
109
|
<div
|
|
113
110
|
v-if="annotationSet.labels.length > 0"
|
|
114
111
|
class="annotation-sets-list"
|
|
@@ -197,7 +194,6 @@ export default {
|
|
|
197
194
|
|
|
198
195
|
computed: {
|
|
199
196
|
...mapState("display", ["showAnnSetTable", "showBranding"]),
|
|
200
|
-
...mapState("edit", ["editMode"]),
|
|
201
197
|
...mapState("document", [
|
|
202
198
|
"annotationSets",
|
|
203
199
|
"documentId",
|
|
@@ -225,7 +221,7 @@ export default {
|
|
|
225
221
|
return this.editAnnotation && this.editAnnotation.id;
|
|
226
222
|
},
|
|
227
223
|
isDocumentEditable() {
|
|
228
|
-
return !this.publicView && !this.isDocumentReviewed
|
|
224
|
+
return !this.publicView && !this.isDocumentReviewed;
|
|
229
225
|
},
|
|
230
226
|
},
|
|
231
227
|
watch: {
|
|
@@ -277,7 +273,7 @@ export default {
|
|
|
277
273
|
this.loadAccordions(this.getAnnotationsFiltered.annotationSets);
|
|
278
274
|
}
|
|
279
275
|
},
|
|
280
|
-
|
|
276
|
+
destroyed() {
|
|
281
277
|
window.removeEventListener("keydown", this.keyDownHandler);
|
|
282
278
|
},
|
|
283
279
|
methods: {
|
|
@@ -408,11 +404,9 @@ export default {
|
|
|
408
404
|
},
|
|
409
405
|
|
|
410
406
|
createArray(className) {
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
);
|
|
415
|
-
}
|
|
407
|
+
return Array.from(
|
|
408
|
+
this.$refs.annotationList.getElementsByClassName(className)
|
|
409
|
+
);
|
|
416
410
|
},
|
|
417
411
|
|
|
418
412
|
keyDownHandler(event) {
|
|
@@ -1,33 +1,39 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div
|
|
2
|
+
<div class="empty-annotation">
|
|
3
3
|
<span
|
|
4
|
+
v-if="!publicView && !isDocumentReviewed"
|
|
4
5
|
:id="emptyAnnotationId()"
|
|
5
6
|
ref="emptyAnnotation"
|
|
6
7
|
:class="[
|
|
7
8
|
'annotation-value',
|
|
8
|
-
showActionError &&
|
|
9
|
+
showActionError &&
|
|
10
|
+
editAnnotation &&
|
|
11
|
+
editAnnotation.id === emptyAnnotationId() &&
|
|
12
|
+
'error-editing',
|
|
13
|
+
!isEmptyAnnotationEditable() && !isMissingAnnotation && 'label-empty',
|
|
9
14
|
isAnnotationBeingEdited() && 'clicked-ann',
|
|
10
15
|
isMissingAnnotation && 'missing-annotation',
|
|
11
16
|
!isMissingAnnotation && 'keyboard-nav',
|
|
12
17
|
]"
|
|
13
|
-
:contenteditable="
|
|
18
|
+
:contenteditable="isEmptyAnnotationEditable()"
|
|
14
19
|
@keypress.enter="saveEmptyAnnotationChanges"
|
|
15
20
|
@click="handleEditEmptyAnnotation"
|
|
16
21
|
@focus="handleEditEmptyAnnotation"
|
|
17
22
|
><!-- eslint-disable vue/no-v-html -->
|
|
18
23
|
<span
|
|
19
24
|
v-if="isFindingAnnotation"
|
|
20
|
-
class="label-empty-clicked"
|
|
21
25
|
v-html="$t('draw_box_document', { label_name: label.name })"
|
|
22
26
|
>
|
|
23
27
|
</span>
|
|
24
28
|
<span v-else-if="isMissingAnnotation" class="not-found-text">
|
|
25
29
|
{{ $t("missing_from_document") }}
|
|
26
30
|
</span>
|
|
27
|
-
<span
|
|
31
|
+
<span
|
|
32
|
+
v-else-if="span && span.offset_string && isEmptyAnnotationEditable()"
|
|
33
|
+
>
|
|
28
34
|
{{ span.offset_string }}
|
|
29
35
|
</span>
|
|
30
|
-
<span v-else
|
|
36
|
+
<span v-else>
|
|
31
37
|
{{ $t("no_data_found") }}
|
|
32
38
|
</span>
|
|
33
39
|
<!--eslint-enable-->
|
|
@@ -36,6 +42,7 @@
|
|
|
36
42
|
</template>
|
|
37
43
|
<script>
|
|
38
44
|
import { mapState, mapGetters } from "vuex";
|
|
45
|
+
import { isElementArray } from "../../utils/utils";
|
|
39
46
|
|
|
40
47
|
/**
|
|
41
48
|
* This component is responsible for managing empty annotations (labels with no annotations).
|
|
@@ -73,7 +80,7 @@ export default {
|
|
|
73
80
|
},
|
|
74
81
|
computed: {
|
|
75
82
|
...mapGetters("document", ["isAnnotationInEditMode", "isDocumentReviewed"]),
|
|
76
|
-
...mapState("selection", ["spanSelection"]),
|
|
83
|
+
...mapState("selection", ["spanSelection", "elementSelected"]),
|
|
77
84
|
...mapState("document", [
|
|
78
85
|
"editAnnotation",
|
|
79
86
|
"publicView",
|
|
@@ -90,17 +97,17 @@ export default {
|
|
|
90
97
|
|
|
91
98
|
watch: {
|
|
92
99
|
span(newValue) {
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
100
|
+
if (this.elementSelected === this.emptyAnnotationId() && newValue) {
|
|
101
|
+
if (isElementArray(newValue))
|
|
102
|
+
newValue.map((span) => {
|
|
103
|
+
if (span.offset_string) {
|
|
104
|
+
span.offset_string =
|
|
105
|
+
this.$refs.emptyAnnotation.textContent.trim();
|
|
106
|
+
span.offset_string_original =
|
|
107
|
+
this.$refs.emptyAnnotation.textContent.trim();
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
}
|
|
104
111
|
},
|
|
105
112
|
spanSelection(newValue) {
|
|
106
113
|
if (!newValue) return;
|
|
@@ -116,27 +123,59 @@ export default {
|
|
|
116
123
|
methods: {
|
|
117
124
|
emptyAnnotationId() {
|
|
118
125
|
if ((!this.annotationSet && !this.labelSet) || !this.label) return;
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
? this.annotationSet.id
|
|
122
|
-
: this.labelSet.id;
|
|
126
|
+
|
|
127
|
+
const id = this.annotationSet ? this.annotationSet.id : this.labelSet.id;
|
|
123
128
|
return `${id}_${this.label.id}`;
|
|
124
129
|
},
|
|
125
130
|
isAnnotationBeingEdited() {
|
|
126
131
|
return this.isAnnotationInEditMode(this.emptyAnnotationId());
|
|
127
132
|
},
|
|
128
133
|
handleEditEmptyAnnotation() {
|
|
129
|
-
if (
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
134
|
+
if (
|
|
135
|
+
this.publicView ||
|
|
136
|
+
this.isDocumentReviewed ||
|
|
137
|
+
this.isMissingAnnotation
|
|
138
|
+
)
|
|
139
|
+
return;
|
|
140
|
+
|
|
141
|
+
if (
|
|
142
|
+
!this.publicView &&
|
|
143
|
+
!this.isDocumentReviewed &&
|
|
144
|
+
this.elementSelected !== this.emptyAnnotationId()
|
|
145
|
+
) {
|
|
146
|
+
this.$store.dispatch("selection/disableSelection");
|
|
147
|
+
this.$store.dispatch("selection/setSelectedEntities", null);
|
|
148
|
+
this.$store.dispatch(
|
|
149
|
+
"selection/selectElement",
|
|
150
|
+
this.emptyAnnotationId()
|
|
151
|
+
);
|
|
152
|
+
this.$store.dispatch("document/setEditAnnotation", {
|
|
153
|
+
id: this.emptyAnnotationId(),
|
|
154
|
+
index: this.spanIndex,
|
|
155
|
+
label: this.label,
|
|
156
|
+
labelSet: this.labelSet,
|
|
157
|
+
annotationSet: this.annotationSet,
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
},
|
|
161
|
+
isEmptyAnnotationEditable() {
|
|
162
|
+
if (
|
|
163
|
+
(this.spanSelection && this.spanSelection[this.spanIndex] === 0) ||
|
|
164
|
+
this.isMissingAnnotation
|
|
165
|
+
) {
|
|
166
|
+
return false;
|
|
167
|
+
} else {
|
|
168
|
+
return (
|
|
169
|
+
this.elementSelected === this.emptyAnnotationId() &&
|
|
170
|
+
this.spanSelection &&
|
|
171
|
+
this.spanSelection[this.spanIndex] &&
|
|
172
|
+
this.spanSelection[this.spanIndex].offset_string != null
|
|
173
|
+
);
|
|
174
|
+
}
|
|
138
175
|
},
|
|
139
176
|
saveEmptyAnnotationChanges(event) {
|
|
177
|
+
if (this.publicView || this.isDocumentReviewed) return;
|
|
178
|
+
|
|
140
179
|
if (event) {
|
|
141
180
|
event.preventDefault();
|
|
142
181
|
}
|