@konfuzio/document-validation-ui 0.1.5 → 0.1.6-multi-ann-set-2
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/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/package.json +1 -1
- package/src/.DS_Store +0 -0
- package/src/assets/images/DraggableIcon.vue +14 -0
- package/src/assets/images/GridIcon.vue +16 -0
- package/src/assets/images/MagicWandIcon.vue +16 -0
- package/src/assets/images/NotFoundIcon.vue +16 -0
- package/src/assets/images/SettingsIcon.vue +14 -0
- package/src/assets/images/SplitZigZag.vue +47 -14
- package/src/assets/images/StarIcon.vue +16 -0
- package/src/assets/scss/ann_set_table_options.scss +26 -0
- package/src/assets/scss/annotation_details.scss +85 -73
- package/src/assets/scss/document_annotations.scss +54 -57
- package/src/assets/scss/document_category.scss +0 -1
- package/src/assets/scss/document_dashboard.scss +7 -2
- package/src/assets/scss/document_edit.scss +90 -46
- package/src/assets/scss/main.scss +725 -7
- package/src/assets/scss/multi_ann_table_overlay.scss +38 -0
- package/src/assets/scss/splitting_confirmation_modal.scss +41 -0
- package/src/assets/scss/variables.scss +2 -657
- package/src/components/App.vue +9 -3
- package/src/components/DocumentAnnotations/AnnotationActionButtons.vue +171 -0
- package/src/components/DocumentAnnotations/AnnotationContent.vue +5 -3
- package/src/components/DocumentAnnotations/AnnotationDetails.vue +28 -7
- package/src/components/DocumentAnnotations/AnnotationRow.vue +133 -41
- package/src/components/DocumentAnnotations/AnnotationSetActionButtons.vue +86 -0
- package/src/components/DocumentAnnotations/CategorizeModal.vue +28 -2
- package/src/components/DocumentAnnotations/DocumentAnnotations.vue +121 -97
- package/src/components/DocumentAnnotations/EmptyAnnotation.vue +21 -5
- package/src/components/DocumentAnnotations/ExtractingData.vue +3 -3
- package/src/components/DocumentAnnotations/index.js +0 -1
- package/src/components/DocumentCategory.vue +13 -5
- package/src/components/DocumentDashboard.vue +17 -6
- package/src/components/DocumentEdit/DocumentEdit.vue +208 -68
- package/src/components/DocumentEdit/EditConfirmationModal.vue +54 -0
- package/src/components/DocumentEdit/EditPages.vue +29 -18
- package/src/components/DocumentEdit/EditSidebar.vue +92 -45
- package/src/components/DocumentEdit/SidebarButtons.vue +53 -0
- package/src/components/DocumentEdit/SplitInfoBar.vue +19 -0
- package/src/components/DocumentEdit/SplitOverview.vue +4 -5
- package/src/components/{DocumentError.vue → DocumentModals/DocumentErrorModal.vue} +3 -4
- package/src/components/{NotOptimizedViewportModal.vue → DocumentModals/NotOptimizedViewportModal.vue} +2 -2
- package/src/components/DocumentModals/SplittingSuggestionsModal.vue +120 -0
- package/src/components/DocumentPage/ActionBar.vue +3 -3
- package/src/components/DocumentPage/AnnSetTableOptions.vue +107 -0
- package/src/components/DocumentPage/DocumentPage.vue +39 -10
- package/src/components/DocumentPage/DocumentToolbar.vue +6 -2
- package/src/components/DocumentPage/MultiAnnSelection.vue +90 -2
- package/src/components/DocumentPage/MultiAnnotationTableOverlay.vue +274 -0
- package/src/components/DocumentPage/MultiAnnotationTablePopup.vue +19 -46
- package/src/components/DocumentPage/NewAnnotation.vue +1 -1
- package/src/components/DocumentPage/ScrollingDocument.vue +43 -4
- package/src/components/DocumentPage/ScrollingPage.vue +4 -5
- package/src/components/DocumentThumbnails/DocumentThumbnails.vue +14 -11
- package/src/components/DocumentTopBar/DocumentName.vue +6 -1
- package/src/components/DocumentTopBar/DocumentTopBar.vue +9 -9
- package/src/components/DocumentTopBar/DocumentTopBarButtons.vue +38 -32
- package/src/components/DocumentTopBar/KeyboardActionsDescription.vue +9 -3
- package/src/components/DocumentsList/DocumentsList.vue +11 -2
- package/src/locales/de.json +23 -6
- package/src/locales/en.json +24 -6
- package/src/locales/es.json +23 -6
- package/src/store/category.js +1 -1
- package/src/store/display.js +51 -0
- package/src/store/document.js +181 -24
- package/src/store/edit.js +71 -48
- package/src/store/project.js +14 -14
- package/src/utils/utils.js +13 -0
- package/src/components/DocumentAnnotations/ActionButtons.vue +0 -257
- package/src/components/DocumentAnnotations/RejectedLabels.vue +0 -96
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="action-buttons">
|
|
3
|
+
<!-- mark all empty labels as missing -->
|
|
4
|
+
<div
|
|
5
|
+
v-if="!publicView && !documentIsReviewed"
|
|
6
|
+
class="missing-decline-button-container all-missing"
|
|
7
|
+
@mouseenter="mouseenterAnnotationSet('missing')"
|
|
8
|
+
@mouseleave="mouseleaveAnnotationSet"
|
|
9
|
+
>
|
|
10
|
+
<b-button
|
|
11
|
+
type="is-ghost"
|
|
12
|
+
class="missing-decline-btn missing-btn all-missing-btn"
|
|
13
|
+
:disabled="numberOfEmptyLabelsInAnnotationSet === 0"
|
|
14
|
+
@click.stop="markAllAsMissing"
|
|
15
|
+
>
|
|
16
|
+
{{ $t("mark_all_missing") }} ({{ numberOfEmptyLabelsInAnnotationSet }})
|
|
17
|
+
</b-button>
|
|
18
|
+
</div>
|
|
19
|
+
|
|
20
|
+
<!-- accept all pending annotations -->
|
|
21
|
+
<div
|
|
22
|
+
v-if="!publicView && !documentIsReviewed"
|
|
23
|
+
class="accept-all"
|
|
24
|
+
@mouseenter="mouseenterAnnotationSet('accept')"
|
|
25
|
+
@mouseleave="mouseleaveAnnotationSet"
|
|
26
|
+
>
|
|
27
|
+
<b-button
|
|
28
|
+
type="is-primary"
|
|
29
|
+
class="accept-all-btn"
|
|
30
|
+
:disabled="numberOfPendingAnnotationsInAnnotationSet === 0"
|
|
31
|
+
@click.stop="acceptAllPending"
|
|
32
|
+
>
|
|
33
|
+
{{ $t("accept_group") }} ({{
|
|
34
|
+
numberOfPendingAnnotationsInAnnotationSet
|
|
35
|
+
}})
|
|
36
|
+
</b-button>
|
|
37
|
+
</div>
|
|
38
|
+
</div>
|
|
39
|
+
</template>
|
|
40
|
+
<script>
|
|
41
|
+
/* Component for showing actions for each Annotation Set */
|
|
42
|
+
|
|
43
|
+
import { mapState } from "vuex";
|
|
44
|
+
|
|
45
|
+
export default {
|
|
46
|
+
name: "AnnotationSetActionButtons",
|
|
47
|
+
props: {
|
|
48
|
+
numberOfEmptyLabelsInAnnotationSet: {
|
|
49
|
+
type: Number,
|
|
50
|
+
},
|
|
51
|
+
numberOfPendingAnnotationsInAnnotationSet: {
|
|
52
|
+
type: Number,
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
computed: {
|
|
56
|
+
...mapState("document", ["publicView", "documentIsReviewed"]),
|
|
57
|
+
},
|
|
58
|
+
methods: {
|
|
59
|
+
mouseenterAnnotationSet(type) {
|
|
60
|
+
if (type == "missing") {
|
|
61
|
+
this.$emit("hover-annotation-set-to-mark-missing");
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (type == "accept") {
|
|
65
|
+
this.$emit("hover-annotation-set-to-accept");
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
mouseleaveAnnotationSet() {
|
|
69
|
+
this.$emit("leave-annotation-set-to-accept");
|
|
70
|
+
this.$emit("leave-annotation-set-to-mark-missing");
|
|
71
|
+
},
|
|
72
|
+
markAllAsMissing() {
|
|
73
|
+
this.$emit("mark-all-empty-missing");
|
|
74
|
+
},
|
|
75
|
+
acceptAllPending() {
|
|
76
|
+
this.$emit("accept-all-pending-annotations");
|
|
77
|
+
},
|
|
78
|
+
},
|
|
79
|
+
};
|
|
80
|
+
</script>
|
|
81
|
+
|
|
82
|
+
<style
|
|
83
|
+
scoped
|
|
84
|
+
lang="scss"
|
|
85
|
+
src="../../assets/scss/document_annotations.scss"
|
|
86
|
+
></style>
|
|
@@ -105,9 +105,20 @@ export default {
|
|
|
105
105
|
},
|
|
106
106
|
computed: {
|
|
107
107
|
...mapState("category", ["categories"]),
|
|
108
|
-
...mapState("document", [
|
|
108
|
+
...mapState("document", [
|
|
109
|
+
"selectedDocument",
|
|
110
|
+
"categorizeModalIsActive",
|
|
111
|
+
"splittingSuggestions",
|
|
112
|
+
"publicView",
|
|
113
|
+
"documentIsReviewed",
|
|
114
|
+
]),
|
|
109
115
|
...mapGetters("category", ["category", "projectHasSingleCategory"]),
|
|
110
116
|
...mapGetters("document", ["categorizationIsConfirmed"]),
|
|
117
|
+
|
|
118
|
+
singleCategoryInProject() {
|
|
119
|
+
// if only 1 category in the project, we don't enable the dropdown
|
|
120
|
+
return this.categories && this.categories.length === 1;
|
|
121
|
+
},
|
|
111
122
|
},
|
|
112
123
|
watch: {
|
|
113
124
|
selectedDocument(newValue) {
|
|
@@ -127,6 +138,13 @@ export default {
|
|
|
127
138
|
show(newValue) {
|
|
128
139
|
this.$store.dispatch("display/setCategorizeModalIsActive", newValue);
|
|
129
140
|
},
|
|
141
|
+
categorizeModalIsActive(newValue) {
|
|
142
|
+
// Show modal after split suggestion modal
|
|
143
|
+
// if no category confirmed
|
|
144
|
+
if (newValue) {
|
|
145
|
+
this.show = newValue && !this.categorizationIsConfirmed;
|
|
146
|
+
}
|
|
147
|
+
},
|
|
130
148
|
},
|
|
131
149
|
mounted() {
|
|
132
150
|
this.setDocumentValues();
|
|
@@ -159,7 +177,15 @@ export default {
|
|
|
159
177
|
}
|
|
160
178
|
|
|
161
179
|
this.selectedCategory = category;
|
|
162
|
-
this.
|
|
180
|
+
this.documentCategory = category;
|
|
181
|
+
|
|
182
|
+
// By default, if the document has no category, the categorize modal is shown
|
|
183
|
+
// But if there is a category, we also need to check if there are splitting suggestions or not
|
|
184
|
+
this.show =
|
|
185
|
+
(!category || (category && !this.splittingSuggestions)) &&
|
|
186
|
+
!this.categorizationIsConfirmed &&
|
|
187
|
+
!this.publicView &&
|
|
188
|
+
!this.documentIsReviewed;
|
|
163
189
|
}
|
|
164
190
|
},
|
|
165
191
|
canCloseModal() {
|
|
@@ -14,20 +14,43 @@
|
|
|
14
14
|
|
|
15
15
|
<!-- When there's no annotations in the label -->
|
|
16
16
|
<div v-else-if="annotationSets.length === 0">
|
|
17
|
-
<CategorizeModal
|
|
17
|
+
<CategorizeModal
|
|
18
|
+
v-if="
|
|
19
|
+
!publicView &&
|
|
20
|
+
!documentIsReviewed &&
|
|
21
|
+
!waitingForSplittingConfirmation(selectedDocument)
|
|
22
|
+
"
|
|
23
|
+
/>
|
|
18
24
|
<EmptyState />
|
|
19
25
|
</div>
|
|
20
26
|
|
|
21
|
-
<div
|
|
22
|
-
v-
|
|
23
|
-
:class="[
|
|
24
|
-
'annotation-set-list',
|
|
25
|
-
missingAnnotations.length && !publicView && 'showing-rejected',
|
|
26
|
-
]"
|
|
27
|
-
>
|
|
28
|
-
<CategorizeModal v-if="!publicView" />
|
|
27
|
+
<div v-else :class="['annotation-set-list']">
|
|
28
|
+
<CategorizeModal v-if="!publicView || !documentIsReviewed" />
|
|
29
29
|
<div
|
|
30
|
-
v-
|
|
30
|
+
v-if="Object.entries(annotationSetsInTable()).length > 0"
|
|
31
|
+
class="annotation-set-group"
|
|
32
|
+
>
|
|
33
|
+
<div class="label-set-header">
|
|
34
|
+
<div class="label-set-name">{{ $t("table") }}</div>
|
|
35
|
+
</div>
|
|
36
|
+
<div
|
|
37
|
+
v-for="(tableSet, index) in Object.values(annotationSetsInTable())"
|
|
38
|
+
:key="index"
|
|
39
|
+
class="ann-set-table"
|
|
40
|
+
@click="openAnnotationSetTable(tableSet)"
|
|
41
|
+
>
|
|
42
|
+
<div class="ann-set-table-icon">
|
|
43
|
+
<GridIcon /><span class="ann-set-number">{{
|
|
44
|
+
tableSet.length
|
|
45
|
+
}}</span>
|
|
46
|
+
</div>
|
|
47
|
+
<span class="ann-set-table-label-set-name">{{
|
|
48
|
+
tableSet[0].label_set.name
|
|
49
|
+
}}</span>
|
|
50
|
+
</div>
|
|
51
|
+
</div>
|
|
52
|
+
<div
|
|
53
|
+
v-for="(annotationSet, indexGroup) in annotationSetsToShowInList()"
|
|
31
54
|
:key="indexGroup"
|
|
32
55
|
class="annotation-set-group"
|
|
33
56
|
>
|
|
@@ -40,18 +63,25 @@
|
|
|
40
63
|
}}
|
|
41
64
|
</div>
|
|
42
65
|
<div class="labelset-action-buttons">
|
|
43
|
-
<
|
|
44
|
-
:
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
66
|
+
<AnnotationSetActionButtons
|
|
67
|
+
:number-of-empty-labels-in-annotation-set="
|
|
68
|
+
emptyLabelsLength(annotationSet)
|
|
69
|
+
"
|
|
70
|
+
:number-of-pending-annotations-in-annotation-set="
|
|
71
|
+
annotationsWithPendingReviewLength(annotationSet)
|
|
72
|
+
"
|
|
73
|
+
@mark-all-empty-missing="
|
|
74
|
+
markAnnotationsAsMissing(null, null, annotationSet, true)
|
|
49
75
|
"
|
|
50
|
-
@hover-annotation-set-to-
|
|
51
|
-
handleHoverAnnotationSet(annotationSet, '
|
|
76
|
+
@hover-annotation-set-to-mark-missing="
|
|
77
|
+
handleHoverAnnotationSet(annotationSet, 'missing')
|
|
78
|
+
"
|
|
79
|
+
@leave-annotation-set-to-mark-missing="
|
|
80
|
+
handleHoverAnnotationSet(null)
|
|
81
|
+
"
|
|
82
|
+
@accept-all-pending-annotations="
|
|
83
|
+
acceptPendingAnnotationsInAnnotationSet(annotationSet)
|
|
52
84
|
"
|
|
53
|
-
@leave-annotation-set-to-reject="handleHoverAnnotationSet(null)"
|
|
54
|
-
@accept-group="acceptGroup(annotationSet)"
|
|
55
85
|
@hover-annotation-set-to-accept="
|
|
56
86
|
handleHoverAnnotationSet(annotationSet, 'accept')
|
|
57
87
|
"
|
|
@@ -61,35 +91,28 @@
|
|
|
61
91
|
</div>
|
|
62
92
|
|
|
63
93
|
<div v-for="label in annotationSet.labels" :key="label.id">
|
|
64
|
-
<div
|
|
94
|
+
<div class="labels">
|
|
65
95
|
<DocumentLabel
|
|
66
96
|
:label="label"
|
|
67
97
|
:annotation-set="annotationSet"
|
|
68
98
|
:index-group="indexGroup"
|
|
69
|
-
@handle-
|
|
99
|
+
@handle-missing-annotation="markAnnotationsAsMissing"
|
|
70
100
|
/>
|
|
71
101
|
</div>
|
|
72
102
|
</div>
|
|
73
103
|
</div>
|
|
74
104
|
</div>
|
|
75
|
-
|
|
76
|
-
<div
|
|
77
|
-
v-if="!publicView && missingAnnotations.length"
|
|
78
|
-
class="rejected-labels-list"
|
|
79
|
-
>
|
|
80
|
-
<RejectedLabels :missing-annotations="missingAnnotations" />
|
|
81
|
-
</div>
|
|
82
105
|
</div>
|
|
83
106
|
</template>
|
|
84
107
|
<script>
|
|
85
108
|
import { mapGetters, mapState } from "vuex";
|
|
86
109
|
import EmptyState from "./EmptyState";
|
|
87
110
|
import ExtractingData from "./ExtractingData";
|
|
88
|
-
import
|
|
111
|
+
import AnnotationSetActionButtons from "./AnnotationSetActionButtons";
|
|
89
112
|
import DocumentLabel from "./DocumentLabel";
|
|
90
|
-
import RejectedLabels from "./RejectedLabels";
|
|
91
113
|
import LoadingAnnotations from "./LoadingAnnotations";
|
|
92
114
|
import CategorizeModal from "./CategorizeModal";
|
|
115
|
+
import GridIcon from "../../assets/images/GridIcon";
|
|
93
116
|
|
|
94
117
|
/**
|
|
95
118
|
* This component loads all annotations for one document
|
|
@@ -98,11 +121,11 @@ export default {
|
|
|
98
121
|
components: {
|
|
99
122
|
EmptyState,
|
|
100
123
|
ExtractingData,
|
|
101
|
-
|
|
124
|
+
AnnotationSetActionButtons,
|
|
102
125
|
DocumentLabel,
|
|
103
|
-
RejectedLabels,
|
|
104
126
|
LoadingAnnotations,
|
|
105
127
|
CategorizeModal,
|
|
128
|
+
GridIcon,
|
|
106
129
|
},
|
|
107
130
|
data() {
|
|
108
131
|
return {
|
|
@@ -112,6 +135,7 @@ export default {
|
|
|
112
135
|
};
|
|
113
136
|
},
|
|
114
137
|
computed: {
|
|
138
|
+
...mapState("display", ["showAnnSetTable"]),
|
|
115
139
|
...mapState("document", [
|
|
116
140
|
"documentId",
|
|
117
141
|
"recalculatingAnnotations",
|
|
@@ -123,9 +147,18 @@ export default {
|
|
|
123
147
|
"loading",
|
|
124
148
|
"labels",
|
|
125
149
|
"selectedDocument",
|
|
150
|
+
"splittingSuggestions",
|
|
151
|
+
"documentIsReviewed",
|
|
126
152
|
]),
|
|
127
153
|
...mapGetters("category", ["category"]),
|
|
128
|
-
...mapGetters("document", [
|
|
154
|
+
...mapGetters("document", [
|
|
155
|
+
"numberOfAnnotationSetGroup",
|
|
156
|
+
"emptyLabelsLength",
|
|
157
|
+
"annotationsWithPendingReviewLength",
|
|
158
|
+
"waitingForSplittingConfirmation",
|
|
159
|
+
"annotationSetsToShowInList",
|
|
160
|
+
"annotationSetsInTable",
|
|
161
|
+
]),
|
|
129
162
|
isAnnotationBeingEdited() {
|
|
130
163
|
return this.editAnnotation && this.editAnnotation.id;
|
|
131
164
|
},
|
|
@@ -151,19 +184,6 @@ export default {
|
|
|
151
184
|
window.removeEventListener("keydown", this.keyDownHandler);
|
|
152
185
|
},
|
|
153
186
|
methods: {
|
|
154
|
-
showMissingAnnotations() {
|
|
155
|
-
if (
|
|
156
|
-
(this.publicView &&
|
|
157
|
-
this.selectedDocument &&
|
|
158
|
-
this.selectedDocument.is_reviewed) ||
|
|
159
|
-
!this.publicView
|
|
160
|
-
) {
|
|
161
|
-
return true;
|
|
162
|
-
} else {
|
|
163
|
-
return false;
|
|
164
|
-
}
|
|
165
|
-
},
|
|
166
|
-
|
|
167
187
|
focusOnNextAnnotation() {
|
|
168
188
|
const annotations = Array.from(
|
|
169
189
|
document.getElementsByClassName("annotation-value")
|
|
@@ -211,7 +231,7 @@ export default {
|
|
|
211
231
|
|
|
212
232
|
keyDownHandler(event) {
|
|
213
233
|
// only allow keyboard navigation if we are not in public view mode
|
|
214
|
-
if (this.publicView) return;
|
|
234
|
+
if (this.publicView || this.documentIsReviewed) return;
|
|
215
235
|
|
|
216
236
|
// get out of edit mode and navigation
|
|
217
237
|
if (event.key === "Escape") {
|
|
@@ -263,6 +283,18 @@ export default {
|
|
|
263
283
|
this.count = currentAnnIndex + 1;
|
|
264
284
|
}
|
|
265
285
|
|
|
286
|
+
// Skip missing annotations
|
|
287
|
+
if (this.focusedAnnotationIsMarkedAsMissing(annotations, this.count)) {
|
|
288
|
+
for (let i = this.count; i < annotations.length; i++) {
|
|
289
|
+
if (!this.focusedAnnotationIsMarkedAsMissing(annotations, i)) {
|
|
290
|
+
break;
|
|
291
|
+
}
|
|
292
|
+
this.count++;
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
if (!annotations[this.count]) return;
|
|
297
|
+
|
|
266
298
|
annotations[this.count].click();
|
|
267
299
|
|
|
268
300
|
// scroll to current annotation if not empty
|
|
@@ -285,6 +317,18 @@ export default {
|
|
|
285
317
|
this.count = currentAnnIndex - 1;
|
|
286
318
|
}
|
|
287
319
|
|
|
320
|
+
// Skip missing annotations
|
|
321
|
+
if (this.focusedAnnotationIsMarkedAsMissing(annotations, this.count)) {
|
|
322
|
+
for (let i = this.count; i < annotations.length; i--) {
|
|
323
|
+
if (!this.focusedAnnotationIsMarkedAsMissing(annotations, i)) {
|
|
324
|
+
break;
|
|
325
|
+
}
|
|
326
|
+
this.count--;
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
if (!annotations[this.count]) return;
|
|
331
|
+
|
|
288
332
|
annotations[this.count].click();
|
|
289
333
|
|
|
290
334
|
// scroll to current annotation if not empty
|
|
@@ -311,9 +355,9 @@ export default {
|
|
|
311
355
|
annotations[currentAnnIndex].className.includes("label-empty") &&
|
|
312
356
|
annotations[currentAnnIndex].className.includes("clicked")
|
|
313
357
|
) {
|
|
314
|
-
//
|
|
358
|
+
// Mark annotation as missing
|
|
315
359
|
if (this.editAnnotation.id === annotations[currentAnnIndex].id) {
|
|
316
|
-
this.
|
|
360
|
+
this.markAnnotationsAsMissing();
|
|
317
361
|
}
|
|
318
362
|
this.jumpToNextAnnotation = true;
|
|
319
363
|
} else {
|
|
@@ -322,45 +366,17 @@ export default {
|
|
|
322
366
|
}
|
|
323
367
|
},
|
|
324
368
|
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
// or if the document is in public mode
|
|
328
|
-
if (
|
|
329
|
-
this.missingAnnotations.length === 0 ||
|
|
330
|
-
!this.showMissingAnnotations()
|
|
331
|
-
) {
|
|
332
|
-
return true;
|
|
333
|
-
} else {
|
|
334
|
-
let found;
|
|
335
|
-
|
|
336
|
-
if (annotationSet && annotationSet.id) {
|
|
337
|
-
found = this.missingAnnotations.filter(
|
|
338
|
-
(el) =>
|
|
339
|
-
el.label === label.id && el.annotation_set === annotationSet.id
|
|
340
|
-
);
|
|
341
|
-
} else {
|
|
342
|
-
found = this.missingAnnotations.filter(
|
|
343
|
-
(el) =>
|
|
344
|
-
el.label === label.id &&
|
|
345
|
-
el.label_set === annotationSet.label_set.id
|
|
346
|
-
);
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
if (found.length !== 0) {
|
|
350
|
-
return false;
|
|
351
|
-
} else {
|
|
352
|
-
return true;
|
|
353
|
-
}
|
|
354
|
-
}
|
|
369
|
+
focusedAnnotationIsMarkedAsMissing(annotations, index) {
|
|
370
|
+
return annotations[index].classList.value.includes("missing-annotation");
|
|
355
371
|
},
|
|
356
372
|
|
|
357
|
-
|
|
358
|
-
let
|
|
373
|
+
markAnnotationsAsMissing(label, labelSet, annotationSet, markAllMissing) {
|
|
374
|
+
let missing;
|
|
359
375
|
|
|
360
|
-
if (label && labelSet && !
|
|
361
|
-
// if
|
|
376
|
+
if (label && labelSet && !markAllMissing) {
|
|
377
|
+
// if annotation is marked as missing by clicking the button
|
|
362
378
|
|
|
363
|
-
|
|
379
|
+
missing = [
|
|
364
380
|
{
|
|
365
381
|
document: parseInt(this.documentId),
|
|
366
382
|
label: label,
|
|
@@ -369,24 +385,24 @@ export default {
|
|
|
369
385
|
},
|
|
370
386
|
];
|
|
371
387
|
} else if (this.editAnnotation && this.editAnnotation.id !== null) {
|
|
372
|
-
//
|
|
388
|
+
// iif annotation is marked as missing from "delete" key
|
|
373
389
|
|
|
374
|
-
|
|
390
|
+
missing = {
|
|
375
391
|
document: parseInt(this.documentId),
|
|
376
392
|
label: this.editAnnotation.label,
|
|
377
393
|
label_set: this.editAnnotation.labelSet,
|
|
378
394
|
annotation_set: this.editAnnotation.annotationSet,
|
|
379
395
|
};
|
|
380
|
-
} else if (annotationSet &&
|
|
381
|
-
//
|
|
396
|
+
} else if (annotationSet && markAllMissing) {
|
|
397
|
+
// mark all annotations as missing in annotation set
|
|
382
398
|
|
|
383
399
|
const allEmptyLabels = annotationSet.labels.filter(
|
|
384
400
|
(label) => label.annotations.length === 0
|
|
385
401
|
);
|
|
386
402
|
|
|
387
|
-
// Check if any of the empty annotations was already
|
|
403
|
+
// Check if any of the empty annotations was already marked as missing individually
|
|
388
404
|
// and remove them
|
|
389
|
-
const
|
|
405
|
+
const toMarkAsMissing = [];
|
|
390
406
|
|
|
391
407
|
allEmptyLabels.map((label) => {
|
|
392
408
|
const found = this.missingAnnotations.find(
|
|
@@ -397,11 +413,11 @@ export default {
|
|
|
397
413
|
);
|
|
398
414
|
|
|
399
415
|
if (!found) {
|
|
400
|
-
|
|
416
|
+
toMarkAsMissing.push(label);
|
|
401
417
|
}
|
|
402
418
|
});
|
|
403
419
|
|
|
404
|
-
|
|
420
|
+
missing = toMarkAsMissing.map((label) => {
|
|
405
421
|
return {
|
|
406
422
|
document: parseInt(this.documentId),
|
|
407
423
|
label: label.id,
|
|
@@ -411,10 +427,10 @@ export default {
|
|
|
411
427
|
});
|
|
412
428
|
}
|
|
413
429
|
|
|
414
|
-
this.$store.dispatch("document/
|
|
430
|
+
this.$store.dispatch("document/setAnnotationsMarkedAsMissing", missing);
|
|
415
431
|
|
|
416
432
|
this.$store
|
|
417
|
-
.dispatch("document/addMissingAnnotations",
|
|
433
|
+
.dispatch("document/addMissingAnnotations", missing)
|
|
418
434
|
.then((response) => {
|
|
419
435
|
if (response) {
|
|
420
436
|
this.jumpToNextAnnotation = true;
|
|
@@ -430,7 +446,7 @@ export default {
|
|
|
430
446
|
});
|
|
431
447
|
})
|
|
432
448
|
.finally(() => {
|
|
433
|
-
this.$store.dispatch("document/
|
|
449
|
+
this.$store.dispatch("document/setAnnotationsMarkedAsMissing", null);
|
|
434
450
|
});
|
|
435
451
|
},
|
|
436
452
|
|
|
@@ -449,7 +465,7 @@ export default {
|
|
|
449
465
|
this.$store.dispatch("document/setHoveredAnnotationSet", hovered);
|
|
450
466
|
},
|
|
451
467
|
|
|
452
|
-
|
|
468
|
+
acceptPendingAnnotationsInAnnotationSet(annotationSet) {
|
|
453
469
|
const annotationsToAccept = [];
|
|
454
470
|
|
|
455
471
|
annotationSet.labels.map((label) => {
|
|
@@ -480,6 +496,14 @@ export default {
|
|
|
480
496
|
});
|
|
481
497
|
}
|
|
482
498
|
},
|
|
499
|
+
|
|
500
|
+
openAnnotationSetTable(tableSet) {
|
|
501
|
+
if (this.showAnnSetTable && this.showAnnSetTable === tableSet) {
|
|
502
|
+
this.$store.dispatch("display/toggleAnnSetTable", tableSet);
|
|
503
|
+
} else {
|
|
504
|
+
this.$store.dispatch("display/showAnnSetTable", tableSet);
|
|
505
|
+
}
|
|
506
|
+
},
|
|
483
507
|
},
|
|
484
508
|
};
|
|
485
509
|
</script>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="empty-annotation">
|
|
3
3
|
<span
|
|
4
|
-
v-if="!publicView"
|
|
4
|
+
v-if="!publicView && !documentIsReviewed"
|
|
5
5
|
:id="emptyAnnotationId()"
|
|
6
6
|
ref="emptyAnnotation"
|
|
7
7
|
:class="[
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
'error-editing',
|
|
13
13
|
isEmptyAnnotationEditable() ? '' : 'label-empty',
|
|
14
14
|
isAnnotationBeingEdited() && 'clicked',
|
|
15
|
+
annotationIsNotFound(annotationSet, label) && 'missing-annotation',
|
|
15
16
|
]"
|
|
16
17
|
:contenteditable="isEmptyAnnotationEditable()"
|
|
17
18
|
@keypress.enter="saveEmptyAnnotationChanges"
|
|
@@ -21,6 +22,12 @@
|
|
|
21
22
|
<span v-if="span && span.offset_string && isEmptyAnnotationEditable()">
|
|
22
23
|
{{ span.offset_string }}
|
|
23
24
|
</span>
|
|
25
|
+
<span
|
|
26
|
+
v-else-if="annotationIsNotFound(annotationSet, label)"
|
|
27
|
+
class="not-found-text"
|
|
28
|
+
>
|
|
29
|
+
{{ $t("missing_from_document") }}
|
|
30
|
+
</span>
|
|
24
31
|
<span v-else>
|
|
25
32
|
{{ $t("no_data_found") }}
|
|
26
33
|
</span>
|
|
@@ -68,6 +75,7 @@ export default {
|
|
|
68
75
|
...mapGetters("document", [
|
|
69
76
|
"isAnnotationInEditMode",
|
|
70
77
|
"getTextFromEntities",
|
|
78
|
+
"annotationIsNotFound",
|
|
71
79
|
]),
|
|
72
80
|
...mapGetters("selection", ["isValueArray"]),
|
|
73
81
|
...mapState("selection", ["spanSelection", "elementSelected"]),
|
|
@@ -76,6 +84,7 @@ export default {
|
|
|
76
84
|
"publicView",
|
|
77
85
|
"selectedEntities",
|
|
78
86
|
"showActionError",
|
|
87
|
+
"documentIsReviewed",
|
|
79
88
|
]),
|
|
80
89
|
},
|
|
81
90
|
watch: {
|
|
@@ -133,6 +142,7 @@ export default {
|
|
|
133
142
|
}
|
|
134
143
|
},
|
|
135
144
|
},
|
|
145
|
+
|
|
136
146
|
methods: {
|
|
137
147
|
emptyAnnotationId() {
|
|
138
148
|
if (!this.annotationSet || !this.label) return;
|
|
@@ -147,10 +157,16 @@ export default {
|
|
|
147
157
|
return this.isAnnotationInEditMode(this.emptyAnnotationId());
|
|
148
158
|
},
|
|
149
159
|
handleEditEmptyAnnotation() {
|
|
150
|
-
if (
|
|
160
|
+
if (
|
|
161
|
+
this.publicView ||
|
|
162
|
+
this.documentIsReviewed ||
|
|
163
|
+
this.annotationIsNotFound(this.annotationSet, this.label)
|
|
164
|
+
)
|
|
165
|
+
return;
|
|
151
166
|
|
|
152
167
|
if (
|
|
153
168
|
!this.publicView &&
|
|
169
|
+
!this.documentIsReviewed &&
|
|
154
170
|
!this.isLoading &&
|
|
155
171
|
this.elementSelected !== this.emptyAnnotationId()
|
|
156
172
|
) {
|
|
@@ -190,8 +206,8 @@ export default {
|
|
|
190
206
|
this.elementSelected === this.emptyAnnotationId() && !this.isLoading
|
|
191
207
|
);
|
|
192
208
|
} else if (
|
|
193
|
-
this.spanSelection &&
|
|
194
|
-
this.
|
|
209
|
+
(this.spanSelection && this.spanSelection[this.spanIndex] === 0) ||
|
|
210
|
+
this.annotationIsNotFound(this.annotationSet, this.label)
|
|
195
211
|
) {
|
|
196
212
|
return false;
|
|
197
213
|
} else {
|
|
@@ -205,7 +221,7 @@ export default {
|
|
|
205
221
|
}
|
|
206
222
|
},
|
|
207
223
|
saveEmptyAnnotationChanges(event) {
|
|
208
|
-
if (this.publicView) return;
|
|
224
|
+
if (this.publicView || this.documentIsReviewed) return;
|
|
209
225
|
|
|
210
226
|
if (event) {
|
|
211
227
|
event.preventDefault();
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="data-extraction-container">
|
|
3
3
|
<div class="loading-container">
|
|
4
|
-
<
|
|
4
|
+
<AnnotationActionButtons
|
|
5
5
|
:is-loading="true"
|
|
6
6
|
:save-btn="false"
|
|
7
7
|
:cancel-btn="false"
|
|
@@ -19,11 +19,11 @@
|
|
|
19
19
|
</div>
|
|
20
20
|
</template>
|
|
21
21
|
<script>
|
|
22
|
-
import
|
|
22
|
+
import AnnotationActionButtons from "./AnnotationActionButtons";
|
|
23
23
|
|
|
24
24
|
export default {
|
|
25
25
|
name: "ExtractingData",
|
|
26
|
-
components: {
|
|
26
|
+
components: { AnnotationActionButtons },
|
|
27
27
|
};
|
|
28
28
|
</script>
|
|
29
29
|
<style scoped lang="scss" src="../../assets/scss/extracting_data.scss"></style>
|
|
@@ -3,6 +3,5 @@ export { default as AnnotationContent } from "./AnnotationContent";
|
|
|
3
3
|
export { default as EmptyAnnotation } from "./EmptyAnnotation";
|
|
4
4
|
export { default as DocumentLabel } from "./DocumentLabel";
|
|
5
5
|
export { default as AnnotationDetails } from "./AnnotationDetails";
|
|
6
|
-
export { default as RejectedLabels } from "./RejectedLabels";
|
|
7
6
|
export { default as ChooseLabelSetModal } from "./ChooseLabelSetModal";
|
|
8
7
|
export { default as AnnotationRow } from "./AnnotationRow";
|
|
@@ -29,11 +29,7 @@
|
|
|
29
29
|
{{ $t("category") }}
|
|
30
30
|
</p>
|
|
31
31
|
<div class="category-name">
|
|
32
|
-
{{
|
|
33
|
-
!splitMode
|
|
34
|
-
? categoryName(selectedDocument.category)
|
|
35
|
-
: categoryName(updatedDocument[index].category)
|
|
36
|
-
}}
|
|
32
|
+
{{ setCategoryDefaultText }}
|
|
37
33
|
</div>
|
|
38
34
|
</div>
|
|
39
35
|
<div :class="[!splitMode && 'caret-section']">
|
|
@@ -102,6 +98,18 @@ export default {
|
|
|
102
98
|
...mapState("document", ["selectedDocument", "annotations"]),
|
|
103
99
|
...mapState("category", ["categories"]),
|
|
104
100
|
...mapState("edit", ["editMode", "updatedDocument"]),
|
|
101
|
+
|
|
102
|
+
setCategoryDefaultText() {
|
|
103
|
+
if (!this.splitMode) {
|
|
104
|
+
return this.categoryName(this.selectedDocument.category);
|
|
105
|
+
} else {
|
|
106
|
+
const categoryName = this.categoryName(
|
|
107
|
+
this.updatedDocument[this.index].category
|
|
108
|
+
);
|
|
109
|
+
|
|
110
|
+
return categoryName ? categoryName : this.$t("choose_category");
|
|
111
|
+
}
|
|
112
|
+
},
|
|
105
113
|
},
|
|
106
114
|
watch: {
|
|
107
115
|
categories(newValue) {
|