@konfuzio/document-validation-ui 0.1.5 → 0.1.6-pre-release-1
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/assets/images/MagicWandIcon.vue +16 -0
- package/src/assets/images/NotFoundIcon.vue +16 -0
- package/src/assets/images/SplitZigZag.vue +47 -14
- package/src/assets/images/StarIcon.vue +16 -0
- package/src/assets/scss/document_annotations.scss +9 -59
- package/src/assets/scss/document_category.scss +0 -1
- package/src/assets/scss/document_dashboard.scss +6 -0
- package/src/assets/scss/document_edit.scss +90 -46
- package/src/assets/scss/main.scss +689 -7
- package/src/assets/scss/splitting_confirmation_modal.scss +41 -0
- package/src/assets/scss/variables.scss +0 -657
- package/src/components/App.vue +3 -2
- package/src/components/DocumentAnnotations/AnnotationActionButtons.vue +153 -0
- package/src/components/DocumentAnnotations/AnnotationDetails.vue +21 -4
- package/src/components/DocumentAnnotations/AnnotationRow.vue +97 -34
- package/src/components/DocumentAnnotations/AnnotationSetActionButtons.vue +86 -0
- package/src/components/DocumentAnnotations/CategorizeModal.vue +24 -2
- package/src/components/DocumentAnnotations/DocumentAnnotations.vue +77 -81
- package/src/components/DocumentAnnotations/EmptyAnnotation.vue +16 -3
- 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/ScrollingDocument.vue +38 -4
- package/src/components/DocumentPage/ScrollingPage.vue +4 -5
- package/src/components/DocumentThumbnails/DocumentThumbnails.vue +14 -11
- package/src/components/DocumentTopBar/DocumentTopBarButtons.vue +35 -30
- package/src/components/DocumentTopBar/KeyboardActionsDescription.vue +3 -1
- package/src/locales/de.json +19 -6
- package/src/locales/en.json +20 -6
- package/src/locales/es.json +19 -6
- package/src/store/display.js +7 -0
- package/src/store/document.js +81 -17
- package/src/store/edit.js +67 -48
- package/src/store/project.js +14 -14
- package/src/components/DocumentAnnotations/ActionButtons.vue +0 -257
- package/src/components/DocumentAnnotations/RejectedLabels.vue +0 -96
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="action-buttons">
|
|
3
|
+
<!-- loading -->
|
|
4
|
+
<div v-if="isLoading">
|
|
5
|
+
<b-notification :closable="false" class="loading-background">
|
|
6
|
+
<b-loading :active="isLoading" :is-full-page="loadingOnFullPage">
|
|
7
|
+
<b-icon icon="spinner" class="fa-spin loading-icon-size spinner" />
|
|
8
|
+
</b-loading>
|
|
9
|
+
</b-notification>
|
|
10
|
+
</div>
|
|
11
|
+
|
|
12
|
+
<!-- save button -->
|
|
13
|
+
<b-button
|
|
14
|
+
v-if="saveBtn && !isLoading && !publicView"
|
|
15
|
+
:class="[
|
|
16
|
+
'annotation-save-btn text-btn',
|
|
17
|
+
actionBar && 'action-bar-save-btn',
|
|
18
|
+
actionBar ? 'tertiary-button' : 'primary-button',
|
|
19
|
+
]"
|
|
20
|
+
type="is-primary"
|
|
21
|
+
@click.stop="save"
|
|
22
|
+
>
|
|
23
|
+
{{ $t("save") }}
|
|
24
|
+
</b-button>
|
|
25
|
+
|
|
26
|
+
<!-- cancel button -->
|
|
27
|
+
<b-button
|
|
28
|
+
v-if="cancelBtn && !isLoading"
|
|
29
|
+
class="is-small annotation-cancel-btn"
|
|
30
|
+
icon-left="xmark"
|
|
31
|
+
@click.stop="cancel"
|
|
32
|
+
/>
|
|
33
|
+
|
|
34
|
+
<!-- decline button -->
|
|
35
|
+
<div
|
|
36
|
+
v-if="declineBtn && !isLoading && !saveBtn && !cancelBtn && !publicView"
|
|
37
|
+
class="missing-decline-button-container"
|
|
38
|
+
>
|
|
39
|
+
<b-button
|
|
40
|
+
type="is-ghost"
|
|
41
|
+
class="missing-decline-btn decline-btn"
|
|
42
|
+
@click.stop="decline"
|
|
43
|
+
>
|
|
44
|
+
{{ $t("decline") }}
|
|
45
|
+
</b-button>
|
|
46
|
+
</div>
|
|
47
|
+
|
|
48
|
+
<!-- accept button -->
|
|
49
|
+
<b-button
|
|
50
|
+
v-if="acceptBtn && !isLoading && !saveBtn && !cancelBtn && !publicView"
|
|
51
|
+
class="annotation-accept-btn primary-button"
|
|
52
|
+
type="is-primary"
|
|
53
|
+
@click.stop="accept"
|
|
54
|
+
>
|
|
55
|
+
{{ $t("accept") }}
|
|
56
|
+
</b-button>
|
|
57
|
+
|
|
58
|
+
<!-- missing button -->
|
|
59
|
+
<div
|
|
60
|
+
v-if="
|
|
61
|
+
showMissingBtn && !isLoading && !cancelBtn && !saveBtn && !publicView
|
|
62
|
+
"
|
|
63
|
+
class="missing-decline-button-container"
|
|
64
|
+
>
|
|
65
|
+
<b-button
|
|
66
|
+
type="is-ghost"
|
|
67
|
+
class="missing-decline-btn missing-btn"
|
|
68
|
+
@click.stop="markAsMissing"
|
|
69
|
+
>
|
|
70
|
+
{{ $t("missing_annotation") }}
|
|
71
|
+
</b-button>
|
|
72
|
+
</div>
|
|
73
|
+
|
|
74
|
+
<!-- Restore not found annotations -->
|
|
75
|
+
<b-button
|
|
76
|
+
v-if="restoreBtn && !isLoading && !publicView"
|
|
77
|
+
class="restore-btn"
|
|
78
|
+
type="is-primary"
|
|
79
|
+
@click.stop="restore"
|
|
80
|
+
>
|
|
81
|
+
{{ $t("restore") }}
|
|
82
|
+
</b-button>
|
|
83
|
+
</div>
|
|
84
|
+
</template>
|
|
85
|
+
<script>
|
|
86
|
+
/* Component for showing actions for each annotation row */
|
|
87
|
+
import { mapState } from "vuex";
|
|
88
|
+
export default {
|
|
89
|
+
name: "AnnotationActionButtons",
|
|
90
|
+
props: {
|
|
91
|
+
saveBtn: {
|
|
92
|
+
type: Boolean,
|
|
93
|
+
},
|
|
94
|
+
cancelBtn: {
|
|
95
|
+
type: Boolean,
|
|
96
|
+
},
|
|
97
|
+
showMissingBtn: {
|
|
98
|
+
type: Boolean,
|
|
99
|
+
},
|
|
100
|
+
isLoading: {
|
|
101
|
+
type: Boolean,
|
|
102
|
+
},
|
|
103
|
+
acceptBtn: {
|
|
104
|
+
type: Boolean,
|
|
105
|
+
},
|
|
106
|
+
declineBtn: {
|
|
107
|
+
type: Boolean,
|
|
108
|
+
},
|
|
109
|
+
actionBar: {
|
|
110
|
+
type: Boolean,
|
|
111
|
+
required: false,
|
|
112
|
+
},
|
|
113
|
+
restoreBtn: {
|
|
114
|
+
type: Boolean,
|
|
115
|
+
required: false,
|
|
116
|
+
},
|
|
117
|
+
},
|
|
118
|
+
data() {
|
|
119
|
+
return {
|
|
120
|
+
loadingOnFullPage: false,
|
|
121
|
+
};
|
|
122
|
+
},
|
|
123
|
+
computed: {
|
|
124
|
+
...mapState("document", ["publicView", "missingAnnotations"]),
|
|
125
|
+
},
|
|
126
|
+
methods: {
|
|
127
|
+
save() {
|
|
128
|
+
this.$emit("save");
|
|
129
|
+
},
|
|
130
|
+
cancel() {
|
|
131
|
+
this.$emit("cancel");
|
|
132
|
+
},
|
|
133
|
+
accept() {
|
|
134
|
+
this.$emit("accept");
|
|
135
|
+
},
|
|
136
|
+
markAsMissing() {
|
|
137
|
+
this.$emit("mark-as-missing");
|
|
138
|
+
},
|
|
139
|
+
decline() {
|
|
140
|
+
this.$emit("decline");
|
|
141
|
+
},
|
|
142
|
+
restore() {
|
|
143
|
+
this.$emit("restore");
|
|
144
|
+
},
|
|
145
|
+
},
|
|
146
|
+
};
|
|
147
|
+
</script>
|
|
148
|
+
|
|
149
|
+
<style
|
|
150
|
+
scoped
|
|
151
|
+
lang="scss"
|
|
152
|
+
src="../../assets/scss/document_annotations.scss"
|
|
153
|
+
></style>
|
|
@@ -28,7 +28,13 @@
|
|
|
28
28
|
</div>
|
|
29
29
|
</div>
|
|
30
30
|
<div
|
|
31
|
-
v-else-if="
|
|
31
|
+
v-else-if="annotationIsNotFound(annotationSet, label)"
|
|
32
|
+
:class="['annotation-details-icon', animate ? 'animated-ripple' : '']"
|
|
33
|
+
>
|
|
34
|
+
<NotFoundIcon />
|
|
35
|
+
</div>
|
|
36
|
+
<div
|
|
37
|
+
v-else-if="notExtracted(annotation)"
|
|
32
38
|
:class="[
|
|
33
39
|
'annotation-details-icon',
|
|
34
40
|
animate ? 'animated-ripple' : '',
|
|
@@ -100,7 +106,7 @@
|
|
|
100
106
|
</div>
|
|
101
107
|
</div>
|
|
102
108
|
<div
|
|
103
|
-
v-else-if="
|
|
109
|
+
v-else-if="notExtracted(annotation)"
|
|
104
110
|
:class="[
|
|
105
111
|
'annotation-details-icon',
|
|
106
112
|
animate ? 'animated-ripple' : '',
|
|
@@ -143,6 +149,7 @@ import AcceptedCheckMark from "../../assets/images/AcceptedCheckMark";
|
|
|
143
149
|
import QuestionMark from "../../assets/images/QuestionMark";
|
|
144
150
|
import AcceptedUser from "../../assets/images/AcceptedUser";
|
|
145
151
|
import UserIcon from "../../assets/images/UserIcon";
|
|
152
|
+
import NotFoundIcon from "../../assets/images/NotFoundIcon";
|
|
146
153
|
|
|
147
154
|
export default {
|
|
148
155
|
name: "AnnotationDetails",
|
|
@@ -152,6 +159,7 @@ export default {
|
|
|
152
159
|
AcceptedCheckMark,
|
|
153
160
|
AcceptedUser,
|
|
154
161
|
UserIcon,
|
|
162
|
+
NotFoundIcon,
|
|
155
163
|
},
|
|
156
164
|
props: {
|
|
157
165
|
description: {
|
|
@@ -163,6 +171,14 @@ export default {
|
|
|
163
171
|
type: Object,
|
|
164
172
|
default: null,
|
|
165
173
|
},
|
|
174
|
+
annotationSet: {
|
|
175
|
+
type: Object,
|
|
176
|
+
default: null,
|
|
177
|
+
},
|
|
178
|
+
label: {
|
|
179
|
+
type: Object,
|
|
180
|
+
default: null,
|
|
181
|
+
},
|
|
166
182
|
},
|
|
167
183
|
data() {
|
|
168
184
|
return {
|
|
@@ -172,11 +188,12 @@ export default {
|
|
|
172
188
|
computed: {
|
|
173
189
|
...mapGetters("document", [
|
|
174
190
|
"confidence",
|
|
175
|
-
"
|
|
191
|
+
"notExtracted",
|
|
176
192
|
"created",
|
|
177
193
|
"edited",
|
|
178
194
|
"accepted",
|
|
179
195
|
"getUser",
|
|
196
|
+
"annotationIsNotFound",
|
|
180
197
|
]),
|
|
181
198
|
},
|
|
182
199
|
watch: {
|
|
@@ -200,7 +217,7 @@ export default {
|
|
|
200
217
|
},
|
|
201
218
|
methods: {
|
|
202
219
|
getText() {
|
|
203
|
-
if (this.
|
|
220
|
+
if (this.notExtracted(this.annotation)) {
|
|
204
221
|
return this.$t("not_found_in_document");
|
|
205
222
|
} else if (this.created(this.annotation)) {
|
|
206
223
|
return this.getUser(this.annotation)
|
|
@@ -3,19 +3,10 @@
|
|
|
3
3
|
:class="[
|
|
4
4
|
'annotation-row',
|
|
5
5
|
isSelected && 'selected',
|
|
6
|
+
hoverEmptyLabelRows && 'hovered-empty-labels',
|
|
7
|
+
hoverPendingAnnotationRows && 'hovered-pending-annotations',
|
|
8
|
+
annotationIsNotFound(annotationSet, label) && 'missing',
|
|
6
9
|
isAnnotationInEditMode(annotationId()) && 'editing',
|
|
7
|
-
hoveredAnnotationSet &&
|
|
8
|
-
hoveredAnnotationSet.type == 'reject' &&
|
|
9
|
-
annotationSet.id === hoveredAnnotationSet.annotationSet.id &&
|
|
10
|
-
annotationSet.label_set.id ===
|
|
11
|
-
hoveredAnnotationSet.annotationSet.label_set.id &&
|
|
12
|
-
hoveredEmptyLabels() === label.id &&
|
|
13
|
-
'hovered-empty-labels',
|
|
14
|
-
hoveredAnnotationSet &&
|
|
15
|
-
hoveredAnnotationSet.type == 'accept' &&
|
|
16
|
-
annotation &&
|
|
17
|
-
hoveredPendingAnnotations() === annotation.id &&
|
|
18
|
-
'hovered-pending-annotations',
|
|
19
10
|
]"
|
|
20
11
|
@click="onAnnotationClick"
|
|
21
12
|
@mouseover="hoveredAnnotation = annotationId()"
|
|
@@ -29,8 +20,15 @@
|
|
|
29
20
|
<AnnotationDetails
|
|
30
21
|
:description="label.description"
|
|
31
22
|
:annotation="annotation"
|
|
23
|
+
:annotation-set="annotationSet"
|
|
24
|
+
:label="label"
|
|
32
25
|
/>
|
|
33
|
-
<div
|
|
26
|
+
<div
|
|
27
|
+
:class="[
|
|
28
|
+
'label-name',
|
|
29
|
+
annotationIsNotFound(annotationSet, label) && 'not-found-text',
|
|
30
|
+
]"
|
|
31
|
+
>
|
|
34
32
|
<span>{{ label.name }} </span>
|
|
35
33
|
</div>
|
|
36
34
|
</div>
|
|
@@ -82,18 +80,20 @@
|
|
|
82
80
|
</div>
|
|
83
81
|
</div>
|
|
84
82
|
<div class="buttons-container">
|
|
85
|
-
<
|
|
83
|
+
<AnnotationActionButtons
|
|
86
84
|
:cancel-btn="showCancelButton()"
|
|
87
|
-
:accept-btn="
|
|
88
|
-
:decline-btn="
|
|
89
|
-
:show-
|
|
85
|
+
:accept-btn="showAcceptButton()"
|
|
86
|
+
:decline-btn="showDeclineButton()"
|
|
87
|
+
:show-missing-btn="showMissingButton()"
|
|
90
88
|
:save-btn="showSaveButton()"
|
|
89
|
+
:restore-btn="showRestoreButton()"
|
|
91
90
|
:is-loading="isLoading"
|
|
92
|
-
@
|
|
91
|
+
@mark-as-missing="handleMissingAnnotation()"
|
|
93
92
|
@save="handleSaveChanges()"
|
|
94
93
|
@accept="handleSaveChanges()"
|
|
95
94
|
@decline="handleSaveChanges(true)"
|
|
96
95
|
@cancel="handleCancelButton()"
|
|
96
|
+
@restore="handleRestore()"
|
|
97
97
|
/>
|
|
98
98
|
</div>
|
|
99
99
|
</div>
|
|
@@ -104,7 +104,7 @@ import { mapGetters, mapState } from "vuex";
|
|
|
104
104
|
import AnnotationDetails from "./AnnotationDetails";
|
|
105
105
|
import AnnotationContent from "./AnnotationContent";
|
|
106
106
|
import EmptyAnnotation from "./EmptyAnnotation";
|
|
107
|
-
import
|
|
107
|
+
import AnnotationActionButtons from "./AnnotationActionButtons";
|
|
108
108
|
|
|
109
109
|
export default {
|
|
110
110
|
name: "AnnotationRow",
|
|
@@ -112,7 +112,7 @@ export default {
|
|
|
112
112
|
AnnotationDetails,
|
|
113
113
|
AnnotationContent,
|
|
114
114
|
EmptyAnnotation,
|
|
115
|
-
|
|
115
|
+
AnnotationActionButtons,
|
|
116
116
|
},
|
|
117
117
|
props: {
|
|
118
118
|
annotationSet: {
|
|
@@ -147,12 +147,16 @@ export default {
|
|
|
147
147
|
"publicView",
|
|
148
148
|
"selectedEntities",
|
|
149
149
|
"newAcceptedAnnotations",
|
|
150
|
-
"
|
|
150
|
+
"annotationsMarkedAsMissing",
|
|
151
151
|
"documentId",
|
|
152
152
|
"showActionError",
|
|
153
|
+
"missingAnnotations",
|
|
153
154
|
]),
|
|
154
155
|
...mapState("selection", ["spanSelection", "elementSelected"]),
|
|
155
|
-
...mapGetters("document", [
|
|
156
|
+
...mapGetters("document", [
|
|
157
|
+
"isAnnotationInEditMode",
|
|
158
|
+
"annotationIsNotFound",
|
|
159
|
+
]),
|
|
156
160
|
...mapGetters("selection", ["isValueArray"]),
|
|
157
161
|
defaultSpan() {
|
|
158
162
|
if (
|
|
@@ -185,6 +189,25 @@ export default {
|
|
|
185
189
|
)
|
|
186
190
|
);
|
|
187
191
|
},
|
|
192
|
+
hoverEmptyLabelRows() {
|
|
193
|
+
return (
|
|
194
|
+
this.hoveredAnnotationSet &&
|
|
195
|
+
this.hoveredAnnotationSet.type == "missing" &&
|
|
196
|
+
!this.annotationIsNotFound(this.annotationSet, this.label) &&
|
|
197
|
+
this.annotationSet.id === this.hoveredAnnotationSet.annotationSet.id &&
|
|
198
|
+
this.annotationSet.label_set.id ===
|
|
199
|
+
this.hoveredAnnotationSet.annotationSet.label_set.id &&
|
|
200
|
+
this.hoveredEmptyLabels() === this.label.id
|
|
201
|
+
);
|
|
202
|
+
},
|
|
203
|
+
hoverPendingAnnotationRows() {
|
|
204
|
+
return (
|
|
205
|
+
this.hoveredAnnotationSet &&
|
|
206
|
+
this.hoveredAnnotationSet.type == "accept" &&
|
|
207
|
+
this.annotation &&
|
|
208
|
+
this.hoveredPendingAnnotations() === this.annotation.id
|
|
209
|
+
);
|
|
210
|
+
},
|
|
188
211
|
},
|
|
189
212
|
watch: {
|
|
190
213
|
sidebarAnnotationSelected(newSidebarAnnotationSelected) {
|
|
@@ -224,7 +247,7 @@ export default {
|
|
|
224
247
|
this.isLoading = false;
|
|
225
248
|
}
|
|
226
249
|
},
|
|
227
|
-
|
|
250
|
+
annotationsMarkedAsMissing(newValue) {
|
|
228
251
|
if (newValue) {
|
|
229
252
|
this.enableLoading();
|
|
230
253
|
} else {
|
|
@@ -270,7 +293,7 @@ export default {
|
|
|
270
293
|
},
|
|
271
294
|
hoveredEmptyLabels() {
|
|
272
295
|
// This method will change the style of the Empty Annotations in the same Label Set
|
|
273
|
-
// when the "
|
|
296
|
+
// when the "mark all as missing" button is hovered
|
|
274
297
|
if (!this.hoveredAnnotationSet) return;
|
|
275
298
|
|
|
276
299
|
const labels = this.hoveredAnnotationSet.annotationSet.labels.map(
|
|
@@ -309,7 +332,7 @@ export default {
|
|
|
309
332
|
return null;
|
|
310
333
|
}
|
|
311
334
|
},
|
|
312
|
-
|
|
335
|
+
showAcceptButton() {
|
|
313
336
|
return (
|
|
314
337
|
!this.isAnnotationInEditMode(this.annotationId()) &&
|
|
315
338
|
this.annotation &&
|
|
@@ -317,11 +340,26 @@ export default {
|
|
|
317
340
|
this.hoveredAnnotation === this.annotation.id
|
|
318
341
|
);
|
|
319
342
|
},
|
|
320
|
-
|
|
343
|
+
showDeclineButton() {
|
|
344
|
+
return (
|
|
345
|
+
!this.isAnnotationInEditMode(this.annotationId()) &&
|
|
346
|
+
this.annotation &&
|
|
347
|
+
this.hoveredAnnotation === this.annotation.id
|
|
348
|
+
);
|
|
349
|
+
},
|
|
350
|
+
showMissingButton() {
|
|
321
351
|
return (
|
|
322
352
|
this.hoveredAnnotation &&
|
|
323
353
|
!this.isAnnotationInEditMode(this.annotationId()) &&
|
|
324
|
-
!this.annotation
|
|
354
|
+
!this.annotation &&
|
|
355
|
+
!this.annotationIsNotFound(this.annotationSet, this.label)
|
|
356
|
+
);
|
|
357
|
+
},
|
|
358
|
+
showRestoreButton() {
|
|
359
|
+
return (
|
|
360
|
+
this.hoveredAnnotation &&
|
|
361
|
+
!this.isAnnotationInEditMode(this.annotationId()) &&
|
|
362
|
+
this.annotationIsNotFound(this.annotationSet, this.label)
|
|
325
363
|
);
|
|
326
364
|
},
|
|
327
365
|
showCancelButton() {
|
|
@@ -353,13 +391,13 @@ export default {
|
|
|
353
391
|
}
|
|
354
392
|
}
|
|
355
393
|
},
|
|
356
|
-
|
|
394
|
+
handleMissingAnnotation() {
|
|
357
395
|
if (!this.label || !this.annotationSet) return;
|
|
358
396
|
|
|
359
397
|
// will emit to the DocumentAnnotations component, where the method is handled
|
|
360
398
|
// & dispatched to the store
|
|
361
399
|
this.$parent.$emit(
|
|
362
|
-
"handle-
|
|
400
|
+
"handle-missing-annotation",
|
|
363
401
|
this.label.id,
|
|
364
402
|
this.annotationSet.label_set.id,
|
|
365
403
|
this.annotationSet.id,
|
|
@@ -370,7 +408,8 @@ export default {
|
|
|
370
408
|
if (this.publicView) return;
|
|
371
409
|
|
|
372
410
|
if (
|
|
373
|
-
this.
|
|
411
|
+
this.showAcceptButton() ||
|
|
412
|
+
this.showDeclineButton() ||
|
|
374
413
|
this.isAnnotationInEditMode(
|
|
375
414
|
this.annotationId(),
|
|
376
415
|
this.editAnnotation.index
|
|
@@ -389,6 +428,30 @@ export default {
|
|
|
389
428
|
this.saveEmptyAnnotationChanges();
|
|
390
429
|
}
|
|
391
430
|
},
|
|
431
|
+
handleRestore() {
|
|
432
|
+
this.isLoading = true;
|
|
433
|
+
|
|
434
|
+
const foundItem = this.missingAnnotations.find(
|
|
435
|
+
(item) =>
|
|
436
|
+
item.annotation_set === this.annotationSet.id &&
|
|
437
|
+
item.label === this.label.id &&
|
|
438
|
+
item.label_set === this.annotationSet.label_set.id
|
|
439
|
+
);
|
|
440
|
+
|
|
441
|
+
this.$store
|
|
442
|
+
.dispatch("document/deleteMissingAnnotation", foundItem.id)
|
|
443
|
+
.catch((error) => {
|
|
444
|
+
this.$store.dispatch("document/createErrorMessage", {
|
|
445
|
+
error,
|
|
446
|
+
serverErrorMessage: this.$t("server_error"),
|
|
447
|
+
defaultErrorMessage: this.$t("edit_error"),
|
|
448
|
+
});
|
|
449
|
+
})
|
|
450
|
+
.finally(() => {
|
|
451
|
+
this.isLoading = false;
|
|
452
|
+
this.closedTag = null;
|
|
453
|
+
});
|
|
454
|
+
},
|
|
392
455
|
handleSaveAnnotationChanges(
|
|
393
456
|
annotation,
|
|
394
457
|
spanIndex,
|
|
@@ -575,15 +638,15 @@ export default {
|
|
|
575
638
|
|
|
576
639
|
// Check for what empty annotations we want to show the loading
|
|
577
640
|
// while waiting for it to be removed from the row
|
|
578
|
-
if (!this.
|
|
641
|
+
if (!this.annotationsMarkedAsMissing) {
|
|
579
642
|
this.isLoading = false;
|
|
580
643
|
this.saveChanges = false;
|
|
581
644
|
return;
|
|
582
645
|
}
|
|
583
646
|
|
|
584
|
-
if (this.
|
|
585
|
-
this.
|
|
586
|
-
// Check if the annotation set and label are
|
|
647
|
+
if (this.annotationsMarkedAsMissing.length > 0) {
|
|
648
|
+
this.annotationsMarkedAsMissing.map((annotation) => {
|
|
649
|
+
// Check if the annotation set and label are marked as missing
|
|
587
650
|
if (
|
|
588
651
|
annotation.label_set === this.annotationSet.label_set.id &&
|
|
589
652
|
annotation.annotation_set === this.annotationSet.id &&
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="action-buttons">
|
|
3
|
+
<!-- mark all empty labels as missing -->
|
|
4
|
+
<div
|
|
5
|
+
v-if="!publicView"
|
|
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"
|
|
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"]),
|
|
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,18 @@ 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
|
+
]),
|
|
109
113
|
...mapGetters("category", ["category", "projectHasSingleCategory"]),
|
|
110
114
|
...mapGetters("document", ["categorizationIsConfirmed"]),
|
|
115
|
+
|
|
116
|
+
singleCategoryInProject() {
|
|
117
|
+
// if only 1 category in the project, we don't enable the dropdown
|
|
118
|
+
return this.categories && this.categories.length === 1;
|
|
119
|
+
},
|
|
111
120
|
},
|
|
112
121
|
watch: {
|
|
113
122
|
selectedDocument(newValue) {
|
|
@@ -127,6 +136,13 @@ export default {
|
|
|
127
136
|
show(newValue) {
|
|
128
137
|
this.$store.dispatch("display/setCategorizeModalIsActive", newValue);
|
|
129
138
|
},
|
|
139
|
+
categorizeModalIsActive(newValue) {
|
|
140
|
+
// Show modal after split suggestion modal
|
|
141
|
+
// if no category confirmed
|
|
142
|
+
if (newValue) {
|
|
143
|
+
this.show = newValue && !this.categorizationIsConfirmed;
|
|
144
|
+
}
|
|
145
|
+
},
|
|
130
146
|
},
|
|
131
147
|
mounted() {
|
|
132
148
|
this.setDocumentValues();
|
|
@@ -159,7 +175,13 @@ export default {
|
|
|
159
175
|
}
|
|
160
176
|
|
|
161
177
|
this.selectedCategory = category;
|
|
162
|
-
this.
|
|
178
|
+
this.documentCategory = category;
|
|
179
|
+
|
|
180
|
+
// By default, if the document has no category, the categorize modal is shown
|
|
181
|
+
// But if there is a category, we also need to check if there are splitting suggestions or not
|
|
182
|
+
this.show =
|
|
183
|
+
(!category || (category && !this.splittingSuggestions)) &&
|
|
184
|
+
!this.categorizationIsConfirmed;
|
|
163
185
|
}
|
|
164
186
|
},
|
|
165
187
|
canCloseModal() {
|