@konfuzio/document-validation-ui 0.1.14 → 0.1.16-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/README.md +12 -0
- package/cypress.config.js +13 -0
- 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 +3 -3
- package/dist/js/chunk-vendors.js.map +1 -1
- package/package.json +5 -1
- package/src/api.js +53 -23
- 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/ServerImage.vue +19 -9
- 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 +86 -71
- package/src/assets/scss/choose_label_set_modal.scss +1 -1
- package/src/assets/scss/document_annotations.scss +242 -229
- package/src/assets/scss/document_category.scss +12 -7
- package/src/assets/scss/document_dashboard.scss +7 -2
- package/src/assets/scss/document_edit.scss +151 -173
- package/src/assets/scss/document_name.scss +0 -2
- package/src/assets/scss/document_thumbnails.scss +1 -1
- package/src/assets/scss/document_toolbar.scss +23 -1
- package/src/assets/scss/document_top_bar.scss +40 -1
- package/src/assets/scss/edit_page_thumbnail.scss +53 -0
- package/src/assets/scss/multi_ann_table_overlay.scss +38 -0
- package/src/assets/scss/new_annotation.scss +17 -3
- package/src/assets/scss/scrolling_document.scss +1 -1
- package/src/assets/scss/theme.scss +801 -0
- package/src/assets/scss/variables.scss +5 -663
- package/src/components/App.cy.js +7 -0
- package/src/components/App.vue +98 -11
- package/src/components/DocumentAnnotations/AnnotationActionButtons.vue +168 -0
- package/src/components/DocumentAnnotations/AnnotationContent.vue +50 -84
- package/src/components/DocumentAnnotations/AnnotationDetails.vue +37 -12
- package/src/components/DocumentAnnotations/AnnotationRow.vue +244 -199
- package/src/components/DocumentAnnotations/AnnotationSetActionButtons.vue +89 -0
- package/src/components/DocumentAnnotations/ChooseLabelSetModal.vue +4 -2
- package/src/components/DocumentAnnotations/DocumentAnnotations.cy.js +295 -0
- package/src/components/DocumentAnnotations/DocumentAnnotations.vue +195 -146
- package/src/components/DocumentAnnotations/DocumentLabel.vue +46 -9
- package/src/components/DocumentAnnotations/EmptyAnnotation.vue +59 -88
- package/src/components/DocumentAnnotations/ExtractingData.vue +18 -6
- package/src/components/DocumentAnnotations/MultiAnnotationTableOverlay.vue +337 -0
- package/src/components/DocumentAnnotations/index.js +1 -1
- package/src/components/DocumentCategory.vue +89 -65
- package/src/components/DocumentDashboard.vue +59 -48
- package/src/components/DocumentEdit/DocumentEdit.vue +302 -105
- package/src/components/DocumentEdit/EditConfirmationModal.vue +55 -0
- package/src/components/DocumentEdit/EditPageThumbnail.vue +114 -0
- package/src/components/DocumentEdit/EditPages.vue +60 -103
- package/src/components/DocumentEdit/EditSidebar.vue +101 -48
- package/src/components/DocumentEdit/{SplitOverview.vue → RenameAndCategorize.vue} +15 -13
- package/src/components/DocumentEdit/SidebarButtons.vue +53 -0
- package/src/components/DocumentEdit/SplitInfoBar.vue +21 -0
- package/src/components/DocumentEdit/index.js +1 -1
- package/src/components/{DocumentError.vue → DocumentModals/DocumentErrorModal.vue} +9 -8
- package/src/components/{NotOptimizedViewportModal.vue → DocumentModals/NotOptimizedViewportModal.vue} +2 -2
- package/src/components/DocumentPage/ActionBar.vue +3 -3
- package/src/components/DocumentPage/AnnSetTableOptions.vue +110 -0
- package/src/components/DocumentPage/BoxSelection.vue +4 -1
- package/src/components/DocumentPage/DocumentPage.vue +92 -68
- package/src/components/DocumentPage/DocumentToolbar.vue +105 -16
- package/src/components/DocumentPage/DummyPage.vue +9 -7
- package/src/components/DocumentPage/MultiAnnSelection.vue +96 -27
- package/src/components/DocumentPage/NewAnnotation.vue +31 -35
- package/src/components/DocumentPage/ScrollingDocument.vue +46 -5
- package/src/components/DocumentPage/ScrollingPage.vue +5 -6
- package/src/components/DocumentThumbnails/DocumentThumbnails.cy.js +64 -0
- package/src/components/DocumentThumbnails/DocumentThumbnails.vue +53 -13
- package/src/components/DocumentTopBar/DocumentName.vue +16 -4
- package/src/components/DocumentTopBar/DocumentTopBar.vue +86 -15
- package/src/components/DocumentTopBar/DocumentTopBarButtons.vue +99 -72
- package/src/components/DocumentTopBar/KeyboardActionsDescription.vue +6 -3
- package/src/components/DocumentsList/DocumentsList.vue +6 -2
- package/src/components/index.js +1 -0
- package/src/constants.js +2 -1
- package/src/icons.js +45 -0
- package/src/locales/de.json +48 -21
- package/src/locales/en.json +37 -11
- package/src/locales/es.json +41 -13
- package/src/main.js +5 -66
- package/src/store/category.js +20 -36
- package/src/store/display.js +74 -1
- package/src/store/document.js +305 -109
- package/src/store/edit.js +160 -61
- package/src/store/project.js +46 -16
- package/src/store/selection.js +42 -10
- package/src/utils/utils.js +36 -0
- package/dist/css/chunk-vendors.css +0 -5
- package/src/.DS_Store +0 -0
- package/src/assets/scss/categorize_modal.scss +0 -45
- package/src/assets/scss/main.scss +0 -24
- package/src/components/DocumentAnnotations/ActionButtons.vue +0 -250
- package/src/components/DocumentAnnotations/CategorizeModal.vue +0 -219
- package/src/components/DocumentAnnotations/RejectedLabels.vue +0 -96
- package/src/components/DocumentPage/MultiAnnotationTablePopup.vue +0 -253
|
@@ -1,33 +1,48 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div
|
|
2
|
+
<div id="labels-sidebar">
|
|
3
3
|
<!-- When extracting annotations after editing -->
|
|
4
|
-
<div v-if="recalculatingAnnotations">
|
|
4
|
+
<div v-if="recalculatingAnnotations" class="extracting-data">
|
|
5
5
|
<ExtractingData />
|
|
6
6
|
</div>
|
|
7
7
|
|
|
8
8
|
<!-- When document data is still loading -->
|
|
9
|
-
<div v-else-if="!annotationSets || loading">
|
|
10
|
-
<div v-for="n in numberOfLoadingAnnotations" :key="n">
|
|
9
|
+
<div v-else-if="!annotationSets || loading" class="document-annotations-loading">
|
|
10
|
+
<div v-for="n in numberOfLoadingAnnotations" :key="n" class="loading-annotation-set">
|
|
11
11
|
<LoadingAnnotations />
|
|
12
12
|
</div>
|
|
13
13
|
</div>
|
|
14
14
|
|
|
15
15
|
<!-- When there's no annotations in the label -->
|
|
16
|
-
<div v-else-if="annotationSets.length === 0">
|
|
17
|
-
<CategorizeModal v-if="!publicView" />
|
|
16
|
+
<div v-else-if="annotationSets.length === 0" class="empty-annotation-sets">
|
|
18
17
|
<EmptyState />
|
|
19
18
|
</div>
|
|
20
19
|
|
|
21
|
-
<div
|
|
22
|
-
v-else
|
|
23
|
-
:class="[
|
|
24
|
-
'annotation-set-list',
|
|
25
|
-
missingAnnotations.length && !publicView && 'showing-rejected',
|
|
26
|
-
]"
|
|
27
|
-
>
|
|
28
|
-
<CategorizeModal v-if="!publicView" />
|
|
20
|
+
<div v-else ref="annotationList" :class="['annotation-set-list']">
|
|
29
21
|
<div
|
|
30
|
-
v-
|
|
22
|
+
v-if="Object.entries(annotationSetsInTable()).length > 0"
|
|
23
|
+
class="annotation-set-group"
|
|
24
|
+
>
|
|
25
|
+
<div class="label-set-header">
|
|
26
|
+
<div class="label-set-name">{{ $t("table") }}</div>
|
|
27
|
+
</div>
|
|
28
|
+
<div
|
|
29
|
+
v-for="(tableSet, index) in Object.values(annotationSetsInTable())"
|
|
30
|
+
:key="index"
|
|
31
|
+
class="ann-set-table"
|
|
32
|
+
@click="openAnnotationSetTable(tableSet)"
|
|
33
|
+
>
|
|
34
|
+
<div class="ann-set-table-icon">
|
|
35
|
+
<GridIcon /><span class="ann-set-number">{{
|
|
36
|
+
tableSet.length
|
|
37
|
+
}}</span>
|
|
38
|
+
</div>
|
|
39
|
+
<span class="ann-set-table-label-set-name">{{
|
|
40
|
+
tableSet[0].label_set.name
|
|
41
|
+
}}</span>
|
|
42
|
+
</div>
|
|
43
|
+
</div>
|
|
44
|
+
<div
|
|
45
|
+
v-for="(annotationSet, indexGroup) in annotationSetsToShowInList()"
|
|
31
46
|
:key="indexGroup"
|
|
32
47
|
class="annotation-set-group"
|
|
33
48
|
>
|
|
@@ -39,19 +54,29 @@
|
|
|
39
54
|
)}`
|
|
40
55
|
}}
|
|
41
56
|
</div>
|
|
42
|
-
<div
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
57
|
+
<div
|
|
58
|
+
v-if="annotationSet.labels.length !== 0"
|
|
59
|
+
class="labelset-action-buttons"
|
|
60
|
+
>
|
|
61
|
+
<AnnotationSetActionButtons
|
|
62
|
+
:number-of-empty-labels-in-annotation-set="
|
|
63
|
+
emptyLabelsLength(annotationSet)
|
|
64
|
+
"
|
|
65
|
+
:number-of-pending-annotations-in-annotation-set="
|
|
66
|
+
annotationsWithPendingReviewLength(annotationSet)
|
|
49
67
|
"
|
|
50
|
-
@
|
|
51
|
-
|
|
68
|
+
@mark-all-empty-missing="
|
|
69
|
+
markAnnotationsAsMissing(null, null, annotationSet, true)
|
|
70
|
+
"
|
|
71
|
+
@hover-annotation-set-to-mark-missing="
|
|
72
|
+
handleHoverAnnotationSet(annotationSet, 'missing')
|
|
73
|
+
"
|
|
74
|
+
@leave-annotation-set-to-mark-missing="
|
|
75
|
+
handleHoverAnnotationSet(null)
|
|
76
|
+
"
|
|
77
|
+
@accept-all-pending-annotations="
|
|
78
|
+
acceptPendingAnnotationsInAnnotationSet(annotationSet)
|
|
52
79
|
"
|
|
53
|
-
@leave-annotation-set-to-reject="handleHoverAnnotationSet(null)"
|
|
54
|
-
@accept-group="acceptGroup(annotationSet)"
|
|
55
80
|
@hover-annotation-set-to-accept="
|
|
56
81
|
handleHoverAnnotationSet(annotationSet, 'accept')
|
|
57
82
|
"
|
|
@@ -60,24 +85,34 @@
|
|
|
60
85
|
</div>
|
|
61
86
|
</div>
|
|
62
87
|
|
|
63
|
-
<div v-
|
|
64
|
-
<div v-
|
|
65
|
-
<
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
88
|
+
<div v-if="annotationSet.labels.length > 0">
|
|
89
|
+
<div v-for="label in annotationSet.labels" :key="label.id">
|
|
90
|
+
<div
|
|
91
|
+
v-if="!(label.annotations.length === 0 && publicView)"
|
|
92
|
+
class="labels"
|
|
93
|
+
>
|
|
94
|
+
<DocumentLabel
|
|
95
|
+
:label="label"
|
|
96
|
+
:annotation-set="annotationSet"
|
|
97
|
+
:index-group="indexGroup"
|
|
98
|
+
@handle-missing-annotation="markAnnotationsAsMissing"
|
|
99
|
+
/>
|
|
100
|
+
</div>
|
|
71
101
|
</div>
|
|
72
102
|
</div>
|
|
73
|
-
</div>
|
|
74
|
-
</div>
|
|
75
103
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
104
|
+
<div v-if="annotationSet.labels.length === 0" class="no-labels">
|
|
105
|
+
<span> {{ $t("no_labels_in_set") }}</span>
|
|
106
|
+
<span v-if="!publicView" v-html="$t('link_to_add_labels')"></span>
|
|
107
|
+
</div>
|
|
108
|
+
|
|
109
|
+
<div
|
|
110
|
+
v-else-if="!annotationSetHasAnnotations(annotationSet) && publicView"
|
|
111
|
+
class="no-labels"
|
|
112
|
+
>
|
|
113
|
+
<span> {{ $t("no_annotations_in_annotation_set") }}</span>
|
|
114
|
+
</div>
|
|
115
|
+
</div>
|
|
81
116
|
</div>
|
|
82
117
|
</div>
|
|
83
118
|
</template>
|
|
@@ -85,11 +120,10 @@
|
|
|
85
120
|
import { mapGetters, mapState } from "vuex";
|
|
86
121
|
import EmptyState from "./EmptyState";
|
|
87
122
|
import ExtractingData from "./ExtractingData";
|
|
88
|
-
import
|
|
123
|
+
import AnnotationSetActionButtons from "./AnnotationSetActionButtons";
|
|
89
124
|
import DocumentLabel from "./DocumentLabel";
|
|
90
|
-
import RejectedLabels from "./RejectedLabels";
|
|
91
125
|
import LoadingAnnotations from "./LoadingAnnotations";
|
|
92
|
-
import
|
|
126
|
+
import GridIcon from "../../assets/images/GridIcon";
|
|
93
127
|
|
|
94
128
|
/**
|
|
95
129
|
* This component loads all annotations for one document
|
|
@@ -98,11 +132,10 @@ export default {
|
|
|
98
132
|
components: {
|
|
99
133
|
EmptyState,
|
|
100
134
|
ExtractingData,
|
|
101
|
-
|
|
135
|
+
AnnotationSetActionButtons,
|
|
102
136
|
DocumentLabel,
|
|
103
|
-
RejectedLabels,
|
|
104
137
|
LoadingAnnotations,
|
|
105
|
-
|
|
138
|
+
GridIcon,
|
|
106
139
|
},
|
|
107
140
|
data() {
|
|
108
141
|
return {
|
|
@@ -112,6 +145,7 @@ export default {
|
|
|
112
145
|
};
|
|
113
146
|
},
|
|
114
147
|
computed: {
|
|
148
|
+
...mapState("display", ["showAnnSetTable"]),
|
|
115
149
|
...mapState("document", [
|
|
116
150
|
"documentId",
|
|
117
151
|
"recalculatingAnnotations",
|
|
@@ -123,9 +157,17 @@ export default {
|
|
|
123
157
|
"loading",
|
|
124
158
|
"labels",
|
|
125
159
|
"selectedDocument",
|
|
160
|
+
"splittingSuggestions",
|
|
126
161
|
]),
|
|
127
162
|
...mapGetters("category", ["category"]),
|
|
128
|
-
...mapGetters("document", [
|
|
163
|
+
...mapGetters("document", [
|
|
164
|
+
"numberOfAnnotationSetGroup",
|
|
165
|
+
"emptyLabelsLength",
|
|
166
|
+
"annotationsWithPendingReviewLength",
|
|
167
|
+
"annotationSetsToShowInList",
|
|
168
|
+
"annotationSetsInTable",
|
|
169
|
+
"isDocumentReviewed",
|
|
170
|
+
]),
|
|
129
171
|
isAnnotationBeingEdited() {
|
|
130
172
|
return this.editAnnotation && this.editAnnotation.id;
|
|
131
173
|
},
|
|
@@ -137,7 +179,6 @@ export default {
|
|
|
137
179
|
}
|
|
138
180
|
},
|
|
139
181
|
acceptAnnotation(newValue, oldValue) {
|
|
140
|
-
// TODO: rework this to be more generic
|
|
141
182
|
if (!newValue && oldValue) {
|
|
142
183
|
this.focusOnNextAnnotation();
|
|
143
184
|
this.jumpToNextAnnotation = false;
|
|
@@ -151,23 +192,17 @@ export default {
|
|
|
151
192
|
window.removeEventListener("keydown", this.keyDownHandler);
|
|
152
193
|
},
|
|
153
194
|
methods: {
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
(
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
) {
|
|
161
|
-
return true;
|
|
162
|
-
} else {
|
|
163
|
-
return false;
|
|
164
|
-
}
|
|
195
|
+
annotationSetHasAnnotations(annotationSet) {
|
|
196
|
+
const found = annotationSet.labels.find(
|
|
197
|
+
(label) => label.annotations.length > 0
|
|
198
|
+
);
|
|
199
|
+
|
|
200
|
+
return found;
|
|
165
201
|
},
|
|
166
202
|
|
|
167
203
|
focusOnNextAnnotation() {
|
|
168
|
-
const annotations =
|
|
169
|
-
|
|
170
|
-
);
|
|
204
|
+
const annotations = this.createArray("keyboard-nav");
|
|
205
|
+
|
|
171
206
|
if (annotations[this.count]) {
|
|
172
207
|
annotations[this.count].click();
|
|
173
208
|
} else {
|
|
@@ -209,31 +244,36 @@ export default {
|
|
|
209
244
|
}
|
|
210
245
|
},
|
|
211
246
|
|
|
247
|
+
exitEditMode() {
|
|
248
|
+
this.count = 0;
|
|
249
|
+
this.$store.dispatch("document/resetEditAnnotation");
|
|
250
|
+
this.$store.dispatch("selection/disableSelection");
|
|
251
|
+
this.$store.dispatch("document/endLoading");
|
|
252
|
+
},
|
|
253
|
+
|
|
254
|
+
createArray(className) {
|
|
255
|
+
return Array.from(
|
|
256
|
+
this.$refs.annotationList.getElementsByClassName(className)
|
|
257
|
+
);
|
|
258
|
+
},
|
|
259
|
+
|
|
212
260
|
keyDownHandler(event) {
|
|
213
261
|
// only allow keyboard navigation if we are not in public view mode
|
|
214
|
-
if (this.publicView) return;
|
|
262
|
+
if (this.publicView || this.isDocumentReviewed) return;
|
|
215
263
|
|
|
216
|
-
//
|
|
264
|
+
// Exit edit mode and navigation
|
|
217
265
|
if (event.key === "Escape") {
|
|
218
|
-
this.
|
|
219
|
-
this.$store.dispatch("document/resetEditAnnotation");
|
|
220
|
-
this.$store.dispatch("selection/disableSelection");
|
|
221
|
-
this.$store.dispatch("document/endLoading");
|
|
266
|
+
this.exitEditMode();
|
|
222
267
|
return;
|
|
223
268
|
}
|
|
224
269
|
|
|
225
270
|
// Not allow starting edit mode with ArrowUp key
|
|
226
271
|
if (event.key === "ArrowUp" && !this.isAnnotationBeingEdited) return;
|
|
272
|
+
// Get all the annotation elements
|
|
273
|
+
let annotations = this.createArray("keyboard-nav");
|
|
227
274
|
|
|
228
|
-
// Create an array from the elements selected
|
|
229
|
-
// for easier management of data
|
|
230
|
-
const annotations = Array.from(
|
|
231
|
-
document.getElementsByClassName("annotation-value")
|
|
232
|
-
);
|
|
233
275
|
// Get clicked element to get the index
|
|
234
|
-
const clickedAnnotations =
|
|
235
|
-
document.getElementsByClassName("clicked")
|
|
236
|
-
);
|
|
276
|
+
const clickedAnnotations = this.createArray("clicked-ann");
|
|
237
277
|
|
|
238
278
|
// get index of currently active element
|
|
239
279
|
const currentAnnIndex = annotations.findIndex(
|
|
@@ -242,10 +282,10 @@ export default {
|
|
|
242
282
|
|
|
243
283
|
// navigate with the arrow up or down keys
|
|
244
284
|
if (event.key === "ArrowDown") {
|
|
285
|
+
// Check if we are focusing on the Finish Review button
|
|
245
286
|
if (this.count >= annotations.length) {
|
|
246
|
-
const finishBtn =
|
|
247
|
-
|
|
248
|
-
);
|
|
287
|
+
const finishBtn = this.createArray("finish-review-btn");
|
|
288
|
+
|
|
249
289
|
finishBtn[0].focus();
|
|
250
290
|
this.$store.dispatch("document/resetEditAnnotation");
|
|
251
291
|
this.count = 0;
|
|
@@ -263,12 +303,24 @@ export default {
|
|
|
263
303
|
this.count = currentAnnIndex + 1;
|
|
264
304
|
}
|
|
265
305
|
|
|
266
|
-
annotations[this.count]
|
|
306
|
+
const nextElement = annotations[this.count];
|
|
307
|
+
if (nextElement.className.includes("label-group")) {
|
|
308
|
+
// open group and then click on annotation
|
|
309
|
+
// index is the same since group is removed from keyboard nav
|
|
310
|
+
nextElement.click();
|
|
311
|
+
this.$nextTick(() => {
|
|
312
|
+
annotations = this.createArray("keyboard-nav");
|
|
313
|
+
annotations[this.count].click();
|
|
314
|
+
this.scrollToFocusedAnnotationFromKeyHandler();
|
|
315
|
+
this.count++;
|
|
316
|
+
});
|
|
317
|
+
} else if (annotations[this.count]) {
|
|
318
|
+
annotations[this.count].click();
|
|
319
|
+
this.scrollToFocusedAnnotationFromKeyHandler();
|
|
320
|
+
this.count++;
|
|
321
|
+
}
|
|
267
322
|
|
|
268
323
|
// scroll to current annotation if not empty
|
|
269
|
-
this.scrollToFocusedAnnotationFromKeyHandler();
|
|
270
|
-
|
|
271
|
-
this.count++;
|
|
272
324
|
} else if (event.key === "ArrowUp") {
|
|
273
325
|
// Check if the event happened on the first element from the array
|
|
274
326
|
// If so, reset count to 0
|
|
@@ -285,12 +337,27 @@ export default {
|
|
|
285
337
|
this.count = currentAnnIndex - 1;
|
|
286
338
|
}
|
|
287
339
|
|
|
288
|
-
annotations[this.count]
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
340
|
+
const previousElement = annotations[this.count];
|
|
341
|
+
if (previousElement.className.includes("label-group")) {
|
|
342
|
+
// open group and then click on annotation
|
|
343
|
+
// index is the same since group is removed from keyboard nav
|
|
344
|
+
previousElement.click();
|
|
345
|
+
this.$nextTick(() => {
|
|
346
|
+
annotations = this.createArray("keyboard-nav");
|
|
347
|
+
// since we are going backwards, we need to go to the last annotation of group
|
|
348
|
+
const currentAnnIndex = annotations.findIndex(
|
|
349
|
+
(el) => el === clickedAnnotations[0]
|
|
350
|
+
);
|
|
351
|
+
this.count = currentAnnIndex - 1;
|
|
352
|
+
annotations[this.count].click();
|
|
353
|
+
this.scrollToFocusedAnnotationFromKeyHandler();
|
|
354
|
+
this.count--;
|
|
355
|
+
});
|
|
356
|
+
} else if (annotations[this.count]) {
|
|
357
|
+
annotations[this.count].click();
|
|
358
|
+
this.scrollToFocusedAnnotationFromKeyHandler();
|
|
359
|
+
this.count--;
|
|
360
|
+
}
|
|
294
361
|
} else {
|
|
295
362
|
// Check for ENTER or DELETE
|
|
296
363
|
// Accept annotation
|
|
@@ -311,9 +378,9 @@ export default {
|
|
|
311
378
|
annotations[currentAnnIndex].className.includes("label-empty") &&
|
|
312
379
|
annotations[currentAnnIndex].className.includes("clicked")
|
|
313
380
|
) {
|
|
314
|
-
//
|
|
381
|
+
// Mark annotation as missing
|
|
315
382
|
if (this.editAnnotation.id === annotations[currentAnnIndex].id) {
|
|
316
|
-
this.
|
|
383
|
+
this.markAnnotationsAsMissing();
|
|
317
384
|
}
|
|
318
385
|
this.jumpToNextAnnotation = true;
|
|
319
386
|
} else {
|
|
@@ -322,45 +389,13 @@ export default {
|
|
|
322
389
|
}
|
|
323
390
|
},
|
|
324
391
|
|
|
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
|
-
}
|
|
355
|
-
},
|
|
356
|
-
|
|
357
|
-
rejectMissingAnnotations(label, labelSet, annotationSet, rejectAll) {
|
|
358
|
-
let rejected;
|
|
392
|
+
markAnnotationsAsMissing(label, labelSet, annotationSet, markAllMissing) {
|
|
393
|
+
let missing;
|
|
359
394
|
|
|
360
|
-
if (label && labelSet && !
|
|
361
|
-
// if
|
|
395
|
+
if (label && labelSet && !markAllMissing) {
|
|
396
|
+
// if annotation is marked as missing by clicking the button
|
|
362
397
|
|
|
363
|
-
|
|
398
|
+
missing = [
|
|
364
399
|
{
|
|
365
400
|
document: parseInt(this.documentId),
|
|
366
401
|
label: label,
|
|
@@ -369,24 +404,26 @@ export default {
|
|
|
369
404
|
},
|
|
370
405
|
];
|
|
371
406
|
} else if (this.editAnnotation && this.editAnnotation.id !== null) {
|
|
372
|
-
// if
|
|
407
|
+
// if annotation is marked as missing from "delete" key
|
|
373
408
|
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
409
|
+
missing = [
|
|
410
|
+
{
|
|
411
|
+
document: parseInt(this.documentId),
|
|
412
|
+
label: this.editAnnotation.label,
|
|
413
|
+
label_set: this.editAnnotation.labelSet,
|
|
414
|
+
annotation_set: this.editAnnotation.annotationSet,
|
|
415
|
+
},
|
|
416
|
+
];
|
|
417
|
+
} else if (annotationSet && markAllMissing) {
|
|
418
|
+
// mark all annotations as missing in annotation set
|
|
382
419
|
|
|
383
420
|
const allEmptyLabels = annotationSet.labels.filter(
|
|
384
421
|
(label) => label.annotations.length === 0
|
|
385
422
|
);
|
|
386
423
|
|
|
387
|
-
// Check if any of the empty annotations was already
|
|
424
|
+
// Check if any of the empty annotations was already marked as missing individually
|
|
388
425
|
// and remove them
|
|
389
|
-
const
|
|
426
|
+
const toMarkAsMissing = [];
|
|
390
427
|
|
|
391
428
|
allEmptyLabels.map((label) => {
|
|
392
429
|
const found = this.missingAnnotations.find(
|
|
@@ -397,11 +434,11 @@ export default {
|
|
|
397
434
|
);
|
|
398
435
|
|
|
399
436
|
if (!found) {
|
|
400
|
-
|
|
437
|
+
toMarkAsMissing.push(label);
|
|
401
438
|
}
|
|
402
439
|
});
|
|
403
440
|
|
|
404
|
-
|
|
441
|
+
missing = toMarkAsMissing.map((label) => {
|
|
405
442
|
return {
|
|
406
443
|
document: parseInt(this.documentId),
|
|
407
444
|
label: label.id,
|
|
@@ -411,10 +448,10 @@ export default {
|
|
|
411
448
|
});
|
|
412
449
|
}
|
|
413
450
|
|
|
414
|
-
this.$store.dispatch("document/
|
|
451
|
+
this.$store.dispatch("document/setAnnotationsMarkedAsMissing", missing);
|
|
415
452
|
|
|
416
453
|
this.$store
|
|
417
|
-
.dispatch("document/addMissingAnnotations",
|
|
454
|
+
.dispatch("document/addMissingAnnotations", missing)
|
|
418
455
|
.then((response) => {
|
|
419
456
|
if (response) {
|
|
420
457
|
this.jumpToNextAnnotation = true;
|
|
@@ -430,7 +467,9 @@ export default {
|
|
|
430
467
|
});
|
|
431
468
|
})
|
|
432
469
|
.finally(() => {
|
|
433
|
-
this.$store.dispatch("document/
|
|
470
|
+
this.$store.dispatch("document/setAnnotationsMarkedAsMissing", null);
|
|
471
|
+
this.$store.dispatch("document/resetEditAnnotation");
|
|
472
|
+
this.$store.dispatch("selection/disableSelection");
|
|
434
473
|
});
|
|
435
474
|
},
|
|
436
475
|
|
|
@@ -449,7 +488,7 @@ export default {
|
|
|
449
488
|
this.$store.dispatch("document/setHoveredAnnotationSet", hovered);
|
|
450
489
|
},
|
|
451
490
|
|
|
452
|
-
|
|
491
|
+
acceptPendingAnnotationsInAnnotationSet(annotationSet) {
|
|
453
492
|
const annotationsToAccept = [];
|
|
454
493
|
|
|
455
494
|
annotationSet.labels.map((label) => {
|
|
@@ -480,6 +519,16 @@ export default {
|
|
|
480
519
|
});
|
|
481
520
|
}
|
|
482
521
|
},
|
|
522
|
+
|
|
523
|
+
openAnnotationSetTable(tableSet) {
|
|
524
|
+
this.$store.dispatch("selection/disableSelection");
|
|
525
|
+
this.$store.dispatch("document/resetEditAnnotation");
|
|
526
|
+
if (this.showAnnSetTable && this.showAnnSetTable === tableSet) {
|
|
527
|
+
this.$store.dispatch("display/toggleAnnSetTable", tableSet);
|
|
528
|
+
} else {
|
|
529
|
+
this.$store.dispatch("display/showAnnSetTable", tableSet);
|
|
530
|
+
}
|
|
531
|
+
},
|
|
483
532
|
},
|
|
484
533
|
};
|
|
485
534
|
</script>
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="label">
|
|
3
|
-
<div v-if="enableGroupingFeature &&
|
|
4
|
-
<div
|
|
3
|
+
<div v-if="enableGroupingFeature && nonMultipleAnnotationsExtracted">
|
|
4
|
+
<div
|
|
5
|
+
:class="['label-group', !showAnnotationsGroup && 'keyboard-nav']"
|
|
6
|
+
@click.stop="toggleGroup"
|
|
7
|
+
>
|
|
5
8
|
<div class="label-group-left">
|
|
6
9
|
<b-icon
|
|
7
10
|
:icon="showAnnotationsGroup ? 'angle-up' : 'angle-down'"
|
|
@@ -12,14 +15,14 @@
|
|
|
12
15
|
</div>
|
|
13
16
|
</div>
|
|
14
17
|
<div class="label-group-right">
|
|
15
|
-
<div class="label-annotations-pending">
|
|
18
|
+
<div v-if="!publicView" class="label-annotations-pending" >
|
|
16
19
|
{{
|
|
17
20
|
`${
|
|
18
21
|
label.annotations.length - acceptedAnnotationsGroupCounter
|
|
19
22
|
} ${$t("annotations_pending")}`
|
|
20
23
|
}}
|
|
21
24
|
</div>
|
|
22
|
-
<div class="label-annotations-accepted">
|
|
25
|
+
<div v-if="!publicView" class="label-annotations-accepted">
|
|
23
26
|
{{
|
|
24
27
|
`${acceptedAnnotationsGroupCounter} ${$t("annotations_accepted")}`
|
|
25
28
|
}}
|
|
@@ -36,7 +39,7 @@
|
|
|
36
39
|
/>
|
|
37
40
|
</div>
|
|
38
41
|
</div>
|
|
39
|
-
<div v-else-if="
|
|
42
|
+
<div v-else-if="hasAnnotations">
|
|
40
43
|
<AnnotationRow
|
|
41
44
|
v-for="annotation in label.annotations"
|
|
42
45
|
:key="annotation.id"
|
|
@@ -66,15 +69,17 @@ export default {
|
|
|
66
69
|
components: { AnnotationRow },
|
|
67
70
|
props: {
|
|
68
71
|
label: {
|
|
72
|
+
type: Object,
|
|
69
73
|
required: true,
|
|
70
74
|
},
|
|
71
75
|
annotationSet: {
|
|
76
|
+
type: Object,
|
|
72
77
|
required: true,
|
|
73
78
|
},
|
|
74
79
|
},
|
|
75
80
|
data() {
|
|
76
81
|
return {
|
|
77
|
-
|
|
82
|
+
nonMultipleAnnotationsExtracted: false,
|
|
78
83
|
acceptedAnnotationsGroupCounter: 0,
|
|
79
84
|
showAnnotationsGroup: false,
|
|
80
85
|
};
|
|
@@ -83,6 +88,8 @@ export default {
|
|
|
83
88
|
...mapState("document", [
|
|
84
89
|
"sidebarAnnotationSelected",
|
|
85
90
|
"enableGroupingFeature",
|
|
91
|
+
"hoveredAnnotationSet",
|
|
92
|
+
"publicView",
|
|
86
93
|
]),
|
|
87
94
|
...mapGetters("document", ["numberOfAcceptedAnnotationsInLabel"]),
|
|
88
95
|
singleAnnotation() {
|
|
@@ -103,9 +110,18 @@ export default {
|
|
|
103
110
|
!this.showAnnotationsGroup &&
|
|
104
111
|
newSidebarAnnotationSelected
|
|
105
112
|
) {
|
|
113
|
+
let annotationSelected;
|
|
114
|
+
|
|
115
|
+
if (newSidebarAnnotationSelected.annotation) {
|
|
116
|
+
annotationSelected = newSidebarAnnotationSelected.annotation;
|
|
117
|
+
} else {
|
|
118
|
+
annotationSelected = newSidebarAnnotationSelected;
|
|
119
|
+
}
|
|
120
|
+
|
|
106
121
|
const annotation = this.label.annotations.find(
|
|
107
|
-
(ann) => ann.id ===
|
|
122
|
+
(ann) => ann.id === annotationSelected.id
|
|
108
123
|
);
|
|
124
|
+
|
|
109
125
|
if (annotation) {
|
|
110
126
|
this.showAnnotationsGroup = true;
|
|
111
127
|
this.$store.dispatch("document/setSidebarAnnotationSelected", null);
|
|
@@ -119,6 +135,16 @@ export default {
|
|
|
119
135
|
}
|
|
120
136
|
}
|
|
121
137
|
},
|
|
138
|
+
hoveredAnnotationSet(newValue) {
|
|
139
|
+
// Check if there are some unrevised Annotations within the group
|
|
140
|
+
if (
|
|
141
|
+
newValue &&
|
|
142
|
+
newValue.type === "accept" &&
|
|
143
|
+
this.labelHasPendingAnnotations(newValue)
|
|
144
|
+
) {
|
|
145
|
+
this.showAnnotationsGroup = true;
|
|
146
|
+
}
|
|
147
|
+
},
|
|
122
148
|
},
|
|
123
149
|
mounted() {
|
|
124
150
|
this.updateValues();
|
|
@@ -131,12 +157,23 @@ export default {
|
|
|
131
157
|
this.showAnnotationsGroup = !this.showAnnotationsGroup;
|
|
132
158
|
},
|
|
133
159
|
updateValues() {
|
|
134
|
-
|
|
135
|
-
|
|
160
|
+
// more than 1 Annotation extracted for a non multiple Label
|
|
161
|
+
this.nonMultipleAnnotationsExtracted =
|
|
162
|
+
this.label.annotations.length > 1 &&
|
|
163
|
+
!this.label.has_multiple_top_candidates;
|
|
164
|
+
|
|
165
|
+
if (this.nonMultipleAnnotationsExtracted) {
|
|
136
166
|
this.acceptedAnnotationsGroupCounter =
|
|
137
167
|
this.numberOfAcceptedAnnotationsInLabel(this.label);
|
|
138
168
|
}
|
|
139
169
|
},
|
|
170
|
+
labelHasPendingAnnotations(hoveredSet) {
|
|
171
|
+
if (!hoveredSet) return;
|
|
172
|
+
|
|
173
|
+
const found = this.label.annotations.find((ann) => !ann.revised);
|
|
174
|
+
|
|
175
|
+
return this.annotationSet.id === hoveredSet.annotationSet.id && found;
|
|
176
|
+
},
|
|
140
177
|
},
|
|
141
178
|
};
|
|
142
179
|
</script>
|