@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
package/src/components/App.vue
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div class="app-container">
|
|
3
|
-
<DocumentsList />
|
|
2
|
+
<div class="dv-ui-app-container dv-ui-theme">
|
|
3
|
+
<DocumentsList v-if="showDocumentsList" />
|
|
4
4
|
<DocumentDashboard />
|
|
5
5
|
</div>
|
|
6
6
|
</template>
|
|
7
7
|
<script>
|
|
8
8
|
import DocumentDashboard from "./DocumentDashboard";
|
|
9
9
|
import { DocumentsList } from "./DocumentsList";
|
|
10
|
-
import {
|
|
10
|
+
import { getURLQueryParam, getURLPath } from "../utils/utils";
|
|
11
11
|
import API from "../api";
|
|
12
12
|
|
|
13
13
|
export default {
|
|
@@ -49,6 +49,8 @@ export default {
|
|
|
49
49
|
documentId() {
|
|
50
50
|
if (getURLQueryParam("document")) {
|
|
51
51
|
return getURLQueryParam("document");
|
|
52
|
+
} else if (getURLPath("docs")) {
|
|
53
|
+
return getURLPath("docs");
|
|
52
54
|
} else if (process.env.VUE_APP_DOCUMENT_ID) {
|
|
53
55
|
return process.env.VUE_APP_DOCUMENT_ID;
|
|
54
56
|
} else if (this.document) {
|
|
@@ -86,6 +88,9 @@ export default {
|
|
|
86
88
|
return true;
|
|
87
89
|
}
|
|
88
90
|
},
|
|
91
|
+
showDocumentsList() {
|
|
92
|
+
return process.env.VUE_APP_SHOW_DOCUMENTS_LIST;
|
|
93
|
+
},
|
|
89
94
|
},
|
|
90
95
|
created() {
|
|
91
96
|
// locale config
|
|
@@ -106,6 +111,7 @@ export default {
|
|
|
106
111
|
});
|
|
107
112
|
|
|
108
113
|
// Add observer for class added to HTML tag when Buefy modals are mounted
|
|
114
|
+
// TODO: check defaultModalScroll property in Buefy constructor https://buefy.org/documentation/constructor-options
|
|
109
115
|
const htmlTag = document.documentElement;
|
|
110
116
|
const observer = new MutationObserver(function (mutations) {
|
|
111
117
|
mutations.forEach(function (mutation) {
|
|
@@ -0,0 +1,171 @@
|
|
|
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="false">
|
|
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 && !documentIsReviewed"
|
|
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 && !documentIsReviewed"
|
|
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="
|
|
37
|
+
declineBtn &&
|
|
38
|
+
!isLoading &&
|
|
39
|
+
!saveBtn &&
|
|
40
|
+
!cancelBtn &&
|
|
41
|
+
!publicView &&
|
|
42
|
+
!documentIsReviewed
|
|
43
|
+
"
|
|
44
|
+
class="missing-decline-button-container"
|
|
45
|
+
>
|
|
46
|
+
<b-button
|
|
47
|
+
type="is-ghost"
|
|
48
|
+
class="missing-decline-btn decline-btn"
|
|
49
|
+
@click.stop="decline"
|
|
50
|
+
>
|
|
51
|
+
{{ $t("decline") }}
|
|
52
|
+
</b-button>
|
|
53
|
+
</div>
|
|
54
|
+
|
|
55
|
+
<!-- accept button -->
|
|
56
|
+
<b-button
|
|
57
|
+
v-if="
|
|
58
|
+
acceptBtn &&
|
|
59
|
+
!isLoading &&
|
|
60
|
+
!saveBtn &&
|
|
61
|
+
!cancelBtn &&
|
|
62
|
+
!publicView &&
|
|
63
|
+
!documentIsReviewed
|
|
64
|
+
"
|
|
65
|
+
class="annotation-accept-btn primary-button"
|
|
66
|
+
type="is-primary"
|
|
67
|
+
@click.stop="accept"
|
|
68
|
+
>
|
|
69
|
+
{{ $t("accept") }}
|
|
70
|
+
</b-button>
|
|
71
|
+
|
|
72
|
+
<!-- missing button -->
|
|
73
|
+
<div
|
|
74
|
+
v-if="
|
|
75
|
+
showMissingBtn &&
|
|
76
|
+
!isLoading &&
|
|
77
|
+
!cancelBtn &&
|
|
78
|
+
!saveBtn &&
|
|
79
|
+
!publicView &&
|
|
80
|
+
!documentIsReviewed
|
|
81
|
+
"
|
|
82
|
+
class="missing-decline-button-container"
|
|
83
|
+
>
|
|
84
|
+
<b-button
|
|
85
|
+
type="is-ghost"
|
|
86
|
+
class="missing-decline-btn missing-btn"
|
|
87
|
+
@click.stop="markAsMissing"
|
|
88
|
+
>
|
|
89
|
+
{{ $t("missing_annotation") }}
|
|
90
|
+
</b-button>
|
|
91
|
+
</div>
|
|
92
|
+
|
|
93
|
+
<!-- Restore not found annotations -->
|
|
94
|
+
<b-button
|
|
95
|
+
v-if="restoreBtn && !isLoading && !publicView && !documentIsReviewed"
|
|
96
|
+
class="restore-btn"
|
|
97
|
+
type="is-primary"
|
|
98
|
+
@click.stop="restore"
|
|
99
|
+
>
|
|
100
|
+
{{ $t("restore") }}
|
|
101
|
+
</b-button>
|
|
102
|
+
</div>
|
|
103
|
+
</template>
|
|
104
|
+
<script>
|
|
105
|
+
/* Component for showing actions for each annotation row */
|
|
106
|
+
import { mapState } from "vuex";
|
|
107
|
+
export default {
|
|
108
|
+
name: "AnnotationActionButtons",
|
|
109
|
+
props: {
|
|
110
|
+
saveBtn: {
|
|
111
|
+
type: Boolean,
|
|
112
|
+
},
|
|
113
|
+
cancelBtn: {
|
|
114
|
+
type: Boolean,
|
|
115
|
+
},
|
|
116
|
+
showMissingBtn: {
|
|
117
|
+
type: Boolean,
|
|
118
|
+
},
|
|
119
|
+
isLoading: {
|
|
120
|
+
type: Boolean,
|
|
121
|
+
},
|
|
122
|
+
acceptBtn: {
|
|
123
|
+
type: Boolean,
|
|
124
|
+
},
|
|
125
|
+
declineBtn: {
|
|
126
|
+
type: Boolean,
|
|
127
|
+
},
|
|
128
|
+
actionBar: {
|
|
129
|
+
type: Boolean,
|
|
130
|
+
required: false,
|
|
131
|
+
},
|
|
132
|
+
restoreBtn: {
|
|
133
|
+
type: Boolean,
|
|
134
|
+
required: false,
|
|
135
|
+
},
|
|
136
|
+
},
|
|
137
|
+
computed: {
|
|
138
|
+
...mapState("document", [
|
|
139
|
+
"publicView",
|
|
140
|
+
"missingAnnotations",
|
|
141
|
+
"documentIsReviewed",
|
|
142
|
+
]),
|
|
143
|
+
},
|
|
144
|
+
methods: {
|
|
145
|
+
save() {
|
|
146
|
+
this.$emit("save");
|
|
147
|
+
},
|
|
148
|
+
cancel() {
|
|
149
|
+
this.$emit("cancel");
|
|
150
|
+
},
|
|
151
|
+
accept() {
|
|
152
|
+
this.$emit("accept");
|
|
153
|
+
},
|
|
154
|
+
markAsMissing() {
|
|
155
|
+
this.$emit("mark-as-missing");
|
|
156
|
+
},
|
|
157
|
+
decline() {
|
|
158
|
+
this.$emit("decline");
|
|
159
|
+
},
|
|
160
|
+
restore() {
|
|
161
|
+
this.$emit("restore");
|
|
162
|
+
},
|
|
163
|
+
},
|
|
164
|
+
};
|
|
165
|
+
</script>
|
|
166
|
+
|
|
167
|
+
<style
|
|
168
|
+
scoped
|
|
169
|
+
lang="scss"
|
|
170
|
+
src="../../assets/scss/document_annotations.scss"
|
|
171
|
+
></style>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div :id="annotation.id" ref="annotation" class="annotation">
|
|
3
3
|
<span
|
|
4
|
-
v-if="!publicView"
|
|
4
|
+
v-if="!publicView || !documentIsReviewed"
|
|
5
5
|
:id="annotation.id"
|
|
6
6
|
ref="contentEditable"
|
|
7
7
|
:class="[
|
|
@@ -82,6 +82,7 @@ export default {
|
|
|
82
82
|
"newAcceptedAnnotations",
|
|
83
83
|
"selectedEntities",
|
|
84
84
|
"showActionError",
|
|
85
|
+
"documentIsReviewed",
|
|
85
86
|
]),
|
|
86
87
|
annotationText() {
|
|
87
88
|
if (this.isAnnotationBeingEdited) {
|
|
@@ -155,7 +156,7 @@ export default {
|
|
|
155
156
|
this.$refs.contentEditable.textContent = text;
|
|
156
157
|
},
|
|
157
158
|
handleEditAnnotation(event) {
|
|
158
|
-
if (this.publicView) return;
|
|
159
|
+
if (this.publicView || this.documentIsReviewed) return;
|
|
159
160
|
|
|
160
161
|
if (event) {
|
|
161
162
|
event.preventDefault();
|
|
@@ -163,6 +164,7 @@ export default {
|
|
|
163
164
|
|
|
164
165
|
if (
|
|
165
166
|
!this.publicView &&
|
|
167
|
+
!this.documentIsReviewed &&
|
|
166
168
|
!this.isAnnotationBeingEdited &&
|
|
167
169
|
!this.isLoading
|
|
168
170
|
) {
|
|
@@ -226,7 +228,7 @@ export default {
|
|
|
226
228
|
event.preventDefault();
|
|
227
229
|
},
|
|
228
230
|
saveAnnotationChanges(event) {
|
|
229
|
-
if (this.publicView) return;
|
|
231
|
+
if (this.publicView || this.documentIsReviewed) return;
|
|
230
232
|
|
|
231
233
|
if (event) {
|
|
232
234
|
event.preventDefault();
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<b-tooltip
|
|
3
3
|
:animated="false"
|
|
4
|
-
position="is-bottom"
|
|
5
|
-
class="left-aligned annotation-details"
|
|
4
|
+
:position="fromTable ? 'is-top' : 'is-bottom'"
|
|
5
|
+
:class="[!fromTable && 'left-aligned', 'annotation-details']"
|
|
6
6
|
>
|
|
7
|
-
<div class="label-icon">
|
|
7
|
+
<div :class="['label-icon', fromTable && 'is-small']">
|
|
8
8
|
<div v-if="created(annotation) || edited(annotation)">
|
|
9
9
|
<div
|
|
10
10
|
v-if="accepted(annotation)"
|
|
@@ -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,18 @@ 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
|
+
},
|
|
182
|
+
fromTable: {
|
|
183
|
+
type: Boolean,
|
|
184
|
+
default: false,
|
|
185
|
+
},
|
|
166
186
|
},
|
|
167
187
|
data() {
|
|
168
188
|
return {
|
|
@@ -172,11 +192,12 @@ export default {
|
|
|
172
192
|
computed: {
|
|
173
193
|
...mapGetters("document", [
|
|
174
194
|
"confidence",
|
|
175
|
-
"
|
|
195
|
+
"notExtracted",
|
|
176
196
|
"created",
|
|
177
197
|
"edited",
|
|
178
198
|
"accepted",
|
|
179
199
|
"getUser",
|
|
200
|
+
"annotationIsNotFound",
|
|
180
201
|
]),
|
|
181
202
|
},
|
|
182
203
|
watch: {
|
|
@@ -200,7 +221,7 @@ export default {
|
|
|
200
221
|
},
|
|
201
222
|
methods: {
|
|
202
223
|
getText() {
|
|
203
|
-
if (this.
|
|
224
|
+
if (this.notExtracted(this.annotation)) {
|
|
204
225
|
return this.$t("not_found_in_document");
|
|
205
226
|
} else if (this.created(this.annotation)) {
|
|
206
227
|
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()"
|
|
@@ -26,11 +17,23 @@
|
|
|
26
17
|
@mouseenter="onAnnotationHoverEnter(defaultSpan)"
|
|
27
18
|
@mouseleave="onAnnotationHoverLeave"
|
|
28
19
|
>
|
|
29
|
-
<
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
20
|
+
<div class="annotation-icon">
|
|
21
|
+
<AnnotationDetails
|
|
22
|
+
:description="label.description"
|
|
23
|
+
:annotation="annotation"
|
|
24
|
+
:annotation-set="annotationSet"
|
|
25
|
+
:label="label"
|
|
26
|
+
:from-table="fromTable"
|
|
27
|
+
/>
|
|
28
|
+
</div>
|
|
29
|
+
|
|
30
|
+
<div
|
|
31
|
+
v-if="showLabel"
|
|
32
|
+
:class="[
|
|
33
|
+
'label-name',
|
|
34
|
+
annotationIsNotFound(annotationSet, label) && 'not-found-text',
|
|
35
|
+
]"
|
|
36
|
+
>
|
|
34
37
|
<span>{{ label.name }} </span>
|
|
35
38
|
</div>
|
|
36
39
|
</div>
|
|
@@ -81,19 +84,21 @@
|
|
|
81
84
|
/>
|
|
82
85
|
</div>
|
|
83
86
|
</div>
|
|
84
|
-
<div class="buttons-container">
|
|
85
|
-
<
|
|
87
|
+
<div v-if="showButtons" class="buttons-container">
|
|
88
|
+
<AnnotationActionButtons
|
|
86
89
|
:cancel-btn="showCancelButton()"
|
|
87
|
-
:accept-btn="
|
|
88
|
-
:decline-btn="
|
|
89
|
-
:show-
|
|
90
|
+
:accept-btn="showAcceptButton()"
|
|
91
|
+
:decline-btn="showDeclineButton()"
|
|
92
|
+
:show-missing-btn="showMissingButton()"
|
|
90
93
|
:save-btn="showSaveButton()"
|
|
94
|
+
:restore-btn="showRestoreButton()"
|
|
91
95
|
:is-loading="isLoading"
|
|
92
|
-
@
|
|
96
|
+
@mark-as-missing="handleMissingAnnotation()"
|
|
93
97
|
@save="handleSaveChanges()"
|
|
94
98
|
@accept="handleSaveChanges()"
|
|
95
99
|
@decline="handleSaveChanges(true)"
|
|
96
100
|
@cancel="handleCancelButton()"
|
|
101
|
+
@restore="handleRestore()"
|
|
97
102
|
/>
|
|
98
103
|
</div>
|
|
99
104
|
</div>
|
|
@@ -104,7 +109,7 @@ import { mapGetters, mapState } from "vuex";
|
|
|
104
109
|
import AnnotationDetails from "./AnnotationDetails";
|
|
105
110
|
import AnnotationContent from "./AnnotationContent";
|
|
106
111
|
import EmptyAnnotation from "./EmptyAnnotation";
|
|
107
|
-
import
|
|
112
|
+
import AnnotationActionButtons from "./AnnotationActionButtons";
|
|
108
113
|
|
|
109
114
|
export default {
|
|
110
115
|
name: "AnnotationRow",
|
|
@@ -112,7 +117,7 @@ export default {
|
|
|
112
117
|
AnnotationDetails,
|
|
113
118
|
AnnotationContent,
|
|
114
119
|
EmptyAnnotation,
|
|
115
|
-
|
|
120
|
+
AnnotationActionButtons,
|
|
116
121
|
},
|
|
117
122
|
props: {
|
|
118
123
|
annotationSet: {
|
|
@@ -127,6 +132,26 @@ export default {
|
|
|
127
132
|
type: Object,
|
|
128
133
|
default: null,
|
|
129
134
|
},
|
|
135
|
+
showLabel: {
|
|
136
|
+
type: Boolean,
|
|
137
|
+
default: true,
|
|
138
|
+
},
|
|
139
|
+
showButtons: {
|
|
140
|
+
type: Boolean,
|
|
141
|
+
default: true,
|
|
142
|
+
},
|
|
143
|
+
isSmall: {
|
|
144
|
+
type: Boolean,
|
|
145
|
+
default: false,
|
|
146
|
+
},
|
|
147
|
+
showHover: {
|
|
148
|
+
type: Boolean,
|
|
149
|
+
default: true,
|
|
150
|
+
},
|
|
151
|
+
fromTable: {
|
|
152
|
+
type: Boolean,
|
|
153
|
+
default: false,
|
|
154
|
+
},
|
|
130
155
|
},
|
|
131
156
|
data() {
|
|
132
157
|
return {
|
|
@@ -147,12 +172,17 @@ export default {
|
|
|
147
172
|
"publicView",
|
|
148
173
|
"selectedEntities",
|
|
149
174
|
"newAcceptedAnnotations",
|
|
150
|
-
"
|
|
175
|
+
"annotationsMarkedAsMissing",
|
|
151
176
|
"documentId",
|
|
152
177
|
"showActionError",
|
|
178
|
+
"missingAnnotations",
|
|
179
|
+
"documentIsReviewed",
|
|
153
180
|
]),
|
|
154
181
|
...mapState("selection", ["spanSelection", "elementSelected"]),
|
|
155
|
-
...mapGetters("document", [
|
|
182
|
+
...mapGetters("document", [
|
|
183
|
+
"isAnnotationInEditMode",
|
|
184
|
+
"annotationIsNotFound",
|
|
185
|
+
]),
|
|
156
186
|
...mapGetters("selection", ["isValueArray"]),
|
|
157
187
|
defaultSpan() {
|
|
158
188
|
if (
|
|
@@ -185,6 +215,25 @@ export default {
|
|
|
185
215
|
)
|
|
186
216
|
);
|
|
187
217
|
},
|
|
218
|
+
hoverEmptyLabelRows() {
|
|
219
|
+
return (
|
|
220
|
+
this.hoveredAnnotationSet &&
|
|
221
|
+
this.hoveredAnnotationSet.type == "missing" &&
|
|
222
|
+
!this.annotationIsNotFound(this.annotationSet, this.label) &&
|
|
223
|
+
this.annotationSet.id === this.hoveredAnnotationSet.annotationSet.id &&
|
|
224
|
+
this.annotationSet.label_set.id ===
|
|
225
|
+
this.hoveredAnnotationSet.annotationSet.label_set.id &&
|
|
226
|
+
this.hoveredEmptyLabels() === this.label.id
|
|
227
|
+
);
|
|
228
|
+
},
|
|
229
|
+
hoverPendingAnnotationRows() {
|
|
230
|
+
return (
|
|
231
|
+
this.hoveredAnnotationSet &&
|
|
232
|
+
this.hoveredAnnotationSet.type == "accept" &&
|
|
233
|
+
this.annotation &&
|
|
234
|
+
this.hoveredPendingAnnotations() === this.annotation.id
|
|
235
|
+
);
|
|
236
|
+
},
|
|
188
237
|
},
|
|
189
238
|
watch: {
|
|
190
239
|
sidebarAnnotationSelected(newSidebarAnnotationSelected) {
|
|
@@ -224,7 +273,7 @@ export default {
|
|
|
224
273
|
this.isLoading = false;
|
|
225
274
|
}
|
|
226
275
|
},
|
|
227
|
-
|
|
276
|
+
annotationsMarkedAsMissing(newValue) {
|
|
228
277
|
if (newValue) {
|
|
229
278
|
this.enableLoading();
|
|
230
279
|
} else {
|
|
@@ -256,7 +305,7 @@ export default {
|
|
|
256
305
|
if (span) {
|
|
257
306
|
this.$store.dispatch("document/setDocumentAnnotationSelected", {
|
|
258
307
|
annotation: this.annotation,
|
|
259
|
-
label: this.label,
|
|
308
|
+
label: this.fromTable ? null : this.label,
|
|
260
309
|
span,
|
|
261
310
|
scrollTo: false,
|
|
262
311
|
});
|
|
@@ -266,11 +315,14 @@ export default {
|
|
|
266
315
|
this.$store.dispatch("document/disableDocumentAnnotationSelected");
|
|
267
316
|
},
|
|
268
317
|
onAnnotationClick() {
|
|
318
|
+
if (!this.fromTable) {
|
|
319
|
+
this.$store.dispatch("display/showAnnSetTable", null);
|
|
320
|
+
}
|
|
269
321
|
this.$store.dispatch("document/scrollToDocumentAnnotationSelected");
|
|
270
322
|
},
|
|
271
323
|
hoveredEmptyLabels() {
|
|
272
324
|
// This method will change the style of the Empty Annotations in the same Label Set
|
|
273
|
-
// when the "
|
|
325
|
+
// when the "mark all as missing" button is hovered
|
|
274
326
|
if (!this.hoveredAnnotationSet) return;
|
|
275
327
|
|
|
276
328
|
const labels = this.hoveredAnnotationSet.annotationSet.labels.map(
|
|
@@ -309,7 +361,7 @@ export default {
|
|
|
309
361
|
return null;
|
|
310
362
|
}
|
|
311
363
|
},
|
|
312
|
-
|
|
364
|
+
showAcceptButton() {
|
|
313
365
|
return (
|
|
314
366
|
!this.isAnnotationInEditMode(this.annotationId()) &&
|
|
315
367
|
this.annotation &&
|
|
@@ -317,11 +369,26 @@ export default {
|
|
|
317
369
|
this.hoveredAnnotation === this.annotation.id
|
|
318
370
|
);
|
|
319
371
|
},
|
|
320
|
-
|
|
372
|
+
showDeclineButton() {
|
|
373
|
+
return (
|
|
374
|
+
!this.isAnnotationInEditMode(this.annotationId()) &&
|
|
375
|
+
this.annotation &&
|
|
376
|
+
this.hoveredAnnotation === this.annotation.id
|
|
377
|
+
);
|
|
378
|
+
},
|
|
379
|
+
showMissingButton() {
|
|
321
380
|
return (
|
|
322
381
|
this.hoveredAnnotation &&
|
|
323
382
|
!this.isAnnotationInEditMode(this.annotationId()) &&
|
|
324
|
-
!this.annotation
|
|
383
|
+
!this.annotation &&
|
|
384
|
+
!this.annotationIsNotFound(this.annotationSet, this.label)
|
|
385
|
+
);
|
|
386
|
+
},
|
|
387
|
+
showRestoreButton() {
|
|
388
|
+
return (
|
|
389
|
+
this.hoveredAnnotation &&
|
|
390
|
+
!this.isAnnotationInEditMode(this.annotationId()) &&
|
|
391
|
+
this.annotationIsNotFound(this.annotationSet, this.label)
|
|
325
392
|
);
|
|
326
393
|
},
|
|
327
394
|
showCancelButton() {
|
|
@@ -353,13 +420,13 @@ export default {
|
|
|
353
420
|
}
|
|
354
421
|
}
|
|
355
422
|
},
|
|
356
|
-
|
|
423
|
+
handleMissingAnnotation() {
|
|
357
424
|
if (!this.label || !this.annotationSet) return;
|
|
358
425
|
|
|
359
426
|
// will emit to the DocumentAnnotations component, where the method is handled
|
|
360
427
|
// & dispatched to the store
|
|
361
428
|
this.$parent.$emit(
|
|
362
|
-
"handle-
|
|
429
|
+
"handle-missing-annotation",
|
|
363
430
|
this.label.id,
|
|
364
431
|
this.annotationSet.label_set.id,
|
|
365
432
|
this.annotationSet.id,
|
|
@@ -367,10 +434,11 @@ export default {
|
|
|
367
434
|
);
|
|
368
435
|
},
|
|
369
436
|
handleSaveChanges(decline) {
|
|
370
|
-
if (this.publicView) return;
|
|
437
|
+
if (this.publicView || this.documentIsReviewed) return;
|
|
371
438
|
|
|
372
439
|
if (
|
|
373
|
-
this.
|
|
440
|
+
this.showAcceptButton() ||
|
|
441
|
+
this.showDeclineButton() ||
|
|
374
442
|
this.isAnnotationInEditMode(
|
|
375
443
|
this.annotationId(),
|
|
376
444
|
this.editAnnotation.index
|
|
@@ -389,6 +457,30 @@ export default {
|
|
|
389
457
|
this.saveEmptyAnnotationChanges();
|
|
390
458
|
}
|
|
391
459
|
},
|
|
460
|
+
handleRestore() {
|
|
461
|
+
this.isLoading = true;
|
|
462
|
+
|
|
463
|
+
const foundItem = this.missingAnnotations.find(
|
|
464
|
+
(item) =>
|
|
465
|
+
item.annotation_set === this.annotationSet.id &&
|
|
466
|
+
item.label === this.label.id &&
|
|
467
|
+
item.label_set === this.annotationSet.label_set.id
|
|
468
|
+
);
|
|
469
|
+
|
|
470
|
+
this.$store
|
|
471
|
+
.dispatch("document/deleteMissingAnnotation", foundItem.id)
|
|
472
|
+
.catch((error) => {
|
|
473
|
+
this.$store.dispatch("document/createErrorMessage", {
|
|
474
|
+
error,
|
|
475
|
+
serverErrorMessage: this.$t("server_error"),
|
|
476
|
+
defaultErrorMessage: this.$t("edit_error"),
|
|
477
|
+
});
|
|
478
|
+
})
|
|
479
|
+
.finally(() => {
|
|
480
|
+
this.isLoading = false;
|
|
481
|
+
this.closedTag = null;
|
|
482
|
+
});
|
|
483
|
+
},
|
|
392
484
|
handleSaveAnnotationChanges(
|
|
393
485
|
annotation,
|
|
394
486
|
spanIndex,
|
|
@@ -575,15 +667,15 @@ export default {
|
|
|
575
667
|
|
|
576
668
|
// Check for what empty annotations we want to show the loading
|
|
577
669
|
// while waiting for it to be removed from the row
|
|
578
|
-
if (!this.
|
|
670
|
+
if (!this.annotationsMarkedAsMissing) {
|
|
579
671
|
this.isLoading = false;
|
|
580
672
|
this.saveChanges = false;
|
|
581
673
|
return;
|
|
582
674
|
}
|
|
583
675
|
|
|
584
|
-
if (this.
|
|
585
|
-
this.
|
|
586
|
-
// Check if the annotation set and label are
|
|
676
|
+
if (this.annotationsMarkedAsMissing.length > 0) {
|
|
677
|
+
this.annotationsMarkedAsMissing.map((annotation) => {
|
|
678
|
+
// Check if the annotation set and label are marked as missing
|
|
587
679
|
if (
|
|
588
680
|
annotation.label_set === this.annotationSet.label_set.id &&
|
|
589
681
|
annotation.annotation_set === this.annotationSet.id &&
|