@konfuzio/document-validation-ui 0.1.59-dev.0 → 0.1.59-dev.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cypress.config.js +6 -6
- package/dist/css/app.css +1 -1
- package/dist/index.html +1 -1
- package/dist/js/app.js +1 -1
- package/dist/js/app.js.map +1 -1
- package/dist/js/chunk-vendors.js +66 -23
- package/dist/js/chunk-vendors.js.map +1 -1
- package/jest.config.js +22 -2
- package/package.json +32 -38
- package/src/assets/scss/ann_set_table_options.scss +4 -4
- package/src/assets/scss/annotation_action_buttons.scss +7 -7
- package/src/assets/scss/annotation_details.scss +9 -9
- package/src/assets/scss/choose_label_set_modal.scss +5 -5
- package/src/assets/scss/document_action_bar.scss +3 -3
- package/src/assets/scss/document_annotations.scss +44 -43
- package/src/assets/scss/document_category.scss +8 -8
- package/src/assets/scss/document_dashboard.scss +1 -1
- package/src/assets/scss/document_edit.scss +30 -30
- package/src/assets/scss/document_error.scss +6 -6
- package/src/assets/scss/document_name.scss +6 -6
- package/src/assets/scss/document_page.scss +3 -3
- package/src/assets/scss/document_search_bar.scss +7 -7
- package/src/assets/scss/document_set_chooser.scss +3 -3
- package/src/assets/scss/document_thumbnails.scss +7 -7
- package/src/assets/scss/document_toolbar.scss +10 -10
- package/src/assets/scss/document_top_bar.scss +11 -11
- package/src/assets/scss/document_viewport_modal.scss +3 -3
- package/src/assets/scss/documents_list.scss +11 -12
- package/src/assets/scss/edit_page_thumbnail.scss +6 -6
- package/src/assets/scss/empty_state.scss +4 -4
- package/src/assets/scss/error_page.scss +2 -2
- package/src/assets/scss/extracting_data.scss +3 -3
- package/src/assets/scss/multi_ann_table_overlay.scss +3 -3
- package/src/assets/scss/multi_ann_table_popup.scss +1 -1
- package/src/assets/scss/new_annotation.scss +25 -19
- package/src/assets/scss/scrolling_document.scss +1 -1
- package/src/assets/scss/theme.scss +64 -52
- package/src/assets/scss/variables.scss +2 -0
- package/src/components/App.vue +9 -14
- package/src/components/DocumentAnnotations/AnnotationActionButtons.vue +4 -6
- package/src/components/DocumentAnnotations/AnnotationContent.vue +25 -52
- package/src/components/DocumentAnnotations/AnnotationRow.vue +106 -50
- package/src/components/DocumentAnnotations/DocumentAnnotations.vue +12 -6
- package/src/components/DocumentAnnotations/EmptyAnnotation.vue +31 -70
- package/src/components/DocumentDashboard.vue +12 -17
- package/src/components/DocumentEdit/EditPages.vue +51 -46
- package/src/components/DocumentPage/{NewAnnotation.vue → AnnotationPopup.vue} +122 -94
- package/src/components/DocumentPage/BoxSelection.vue +16 -49
- package/src/components/DocumentPage/DocumentPage.vue +56 -153
- package/src/components/DocumentPage/DocumentToolbar.vue +0 -1
- package/src/components/DocumentPage/PlaceholderSelection.vue +51 -0
- package/src/components/DocumentPage/SpanSelection.vue +259 -0
- package/src/components/DocumentThumbnails/LoadingThumbnail.vue +3 -6
- package/src/components/DocumentTopBar/DocumentTopBar.vue +4 -2
- package/src/constants.js +1 -7
- package/src/i18n.js +2 -5
- package/src/main.js +14 -16
- package/src/store/display.js +33 -22
- package/src/store/document.js +1 -0
- package/src/store/index.js +5 -8
- package/src/store/selection.js +152 -76
- package/src/assets/scss/imports.scss +0 -1
- package/src/components/DocumentPage/EditAnnotation.vue +0 -372
|
@@ -3,24 +3,19 @@
|
|
|
3
3
|
<DocumentTopBar />
|
|
4
4
|
<div :class="['dashboard-viewer', renameAndCategorize ? 'edit-mode' : '']">
|
|
5
5
|
<DocumentThumbnails v-if="!editMode" ref="documentPages" />
|
|
6
|
-
<
|
|
7
|
-
<
|
|
6
|
+
<splitpanes class="default-theme">
|
|
7
|
+
<pane :size="50" :min-size="10">
|
|
8
8
|
<ScrollingDocument
|
|
9
9
|
ref="scrollingDocument"
|
|
10
10
|
class="dashboard-document"
|
|
11
11
|
/>
|
|
12
|
-
</
|
|
13
|
-
<
|
|
12
|
+
</pane>
|
|
13
|
+
<pane :size="50">
|
|
14
14
|
<DocumentAnnotations v-if="!editMode" ref="annotations" />
|
|
15
15
|
<DocumentEdit v-else ref="editView" />
|
|
16
|
-
</
|
|
17
|
-
</
|
|
16
|
+
</pane>
|
|
17
|
+
</splitpanes>
|
|
18
18
|
|
|
19
|
-
<MultiAnnotationTableOverlay
|
|
20
|
-
v-if="showAnnSetTable"
|
|
21
|
-
:left="documentContainerLeftPadding"
|
|
22
|
-
:width="documentContainerWidth"
|
|
23
|
-
/>
|
|
24
19
|
<ChooseLabelSetModal
|
|
25
20
|
v-if="showChooseLabelSetModal && showChooseLabelSetModal.show"
|
|
26
21
|
:is-multiple-annotations="showChooseLabelSetModal.isMultipleAnnotations"
|
|
@@ -59,16 +54,15 @@ import { mapGetters, mapState } from "vuex";
|
|
|
59
54
|
import { DocumentTopBar } from "./DocumentTopBar";
|
|
60
55
|
import { ScrollingDocument } from "./DocumentPage";
|
|
61
56
|
import { DocumentThumbnails } from "./DocumentThumbnails";
|
|
62
|
-
import {
|
|
63
|
-
DocumentAnnotations,
|
|
64
|
-
MultiAnnotationTableOverlay,
|
|
65
|
-
} from "./DocumentAnnotations";
|
|
57
|
+
import { DocumentAnnotations } from "./DocumentAnnotations";
|
|
66
58
|
import { DocumentEdit } from "./DocumentEdit";
|
|
67
59
|
import ErrorMessage from "./ErrorMessage";
|
|
68
60
|
import NotOptimizedViewportModal from "../components/DocumentModals/NotOptimizedViewportModal";
|
|
69
61
|
import AnnotationDeletedModal from "../components/DocumentModals/AnnotationDeletedModal";
|
|
70
62
|
import DocumentErrorModal from "../components/DocumentModals/DocumentErrorModal";
|
|
71
63
|
import ChooseLabelSetModal from "../components/DocumentAnnotations/ChooseLabelSetModal";
|
|
64
|
+
import { Splitpanes, Pane } from "splitpanes";
|
|
65
|
+
import "splitpanes/dist/splitpanes.css";
|
|
72
66
|
|
|
73
67
|
/**
|
|
74
68
|
* This component shows the PDF pages in a scrolling component and
|
|
@@ -77,6 +71,8 @@ import ChooseLabelSetModal from "../components/DocumentAnnotations/ChooseLabelSe
|
|
|
77
71
|
export default {
|
|
78
72
|
name: "DocumentDashboard",
|
|
79
73
|
components: {
|
|
74
|
+
Splitpanes,
|
|
75
|
+
Pane,
|
|
80
76
|
DocumentTopBar,
|
|
81
77
|
ScrollingDocument,
|
|
82
78
|
DocumentThumbnails,
|
|
@@ -85,7 +81,6 @@ export default {
|
|
|
85
81
|
ErrorMessage,
|
|
86
82
|
NotOptimizedViewportModal,
|
|
87
83
|
DocumentErrorModal,
|
|
88
|
-
MultiAnnotationTableOverlay,
|
|
89
84
|
ChooseLabelSetModal,
|
|
90
85
|
AnnotationDeletedModal,
|
|
91
86
|
},
|
|
@@ -136,7 +131,7 @@ export default {
|
|
|
136
131
|
mounted() {
|
|
137
132
|
this.resizeObserver = new ResizeObserver(this.onDocumentResize);
|
|
138
133
|
},
|
|
139
|
-
|
|
134
|
+
unmounted() {
|
|
140
135
|
if (this.$refs.scrollingDocument) {
|
|
141
136
|
this.resizeObserver.unobserve(this.$refs.scrollingDocument.$el);
|
|
142
137
|
}
|
|
@@ -7,60 +7,64 @@
|
|
|
7
7
|
v-model="editPages"
|
|
8
8
|
class="document-grid"
|
|
9
9
|
easing="cubic-bezier(0.37, 0, 0.63, 1)"
|
|
10
|
+
item-key="id"
|
|
11
|
+
:move="checkMove"
|
|
10
12
|
@start="dragging = true"
|
|
11
13
|
@end="handleDragEnd"
|
|
12
|
-
@move="checkMove"
|
|
13
14
|
>
|
|
14
|
-
<
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
<
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
:class="[
|
|
28
|
-
'splitting-lines',
|
|
29
|
-
splittingLines &&
|
|
30
|
-
splittingLines[index].page === page.number &&
|
|
31
|
-
'active-split',
|
|
32
|
-
]"
|
|
33
|
-
@click="handleSplittingLines(page.number, 'manual')"
|
|
34
|
-
>
|
|
35
|
-
<div class="scissors-icon">
|
|
36
|
-
<b-icon icon="scissors" class="is-small" />
|
|
37
|
-
</div>
|
|
15
|
+
<template #item="{ element, index }">
|
|
16
|
+
<div
|
|
17
|
+
:id="element.id"
|
|
18
|
+
:key="element.id"
|
|
19
|
+
class="image-section"
|
|
20
|
+
tabindex="0"
|
|
21
|
+
>
|
|
22
|
+
<div class="top-section">
|
|
23
|
+
<EditPageThumbnail
|
|
24
|
+
:page="element"
|
|
25
|
+
:index="index"
|
|
26
|
+
:rotation="getRotation(element.id)"
|
|
27
|
+
/>
|
|
38
28
|
<div
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
29
|
+
:class="[
|
|
30
|
+
'splitting-lines',
|
|
31
|
+
splittingLines &&
|
|
32
|
+
splittingLines[index].page === element.number &&
|
|
33
|
+
'active-split',
|
|
34
|
+
]"
|
|
35
|
+
@click="handleSplittingLines(element.number, 'manual')"
|
|
43
36
|
>
|
|
44
|
-
<
|
|
45
|
-
|
|
37
|
+
<div class="scissors-icon">
|
|
38
|
+
<b-icon icon="scissors" class="is-small" />
|
|
39
|
+
</div>
|
|
40
|
+
<div
|
|
41
|
+
v-if="
|
|
46
42
|
splittingLines &&
|
|
47
|
-
splittingLines[index].
|
|
48
|
-
splittingLines[index].origin === 'AI' &&
|
|
49
|
-
splitSuggestionsEnabled
|
|
50
|
-
? 'green'
|
|
51
|
-
: 'dark'
|
|
43
|
+
splittingLines[index].page === element.number
|
|
52
44
|
"
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
45
|
+
class="lines active-split"
|
|
46
|
+
>
|
|
47
|
+
<SplitZigZag
|
|
48
|
+
:color="
|
|
49
|
+
splittingLines &&
|
|
50
|
+
splittingLines[index].origin &&
|
|
51
|
+
splittingLines[index].origin === 'AI' &&
|
|
52
|
+
splitSuggestionsEnabled
|
|
53
|
+
? 'green'
|
|
54
|
+
: 'dark'
|
|
55
|
+
"
|
|
56
|
+
/>
|
|
57
|
+
</div>
|
|
58
|
+
<div v-else class="lines not-active-split">
|
|
59
|
+
<SplitLines />
|
|
60
|
+
</div>
|
|
57
61
|
</div>
|
|
58
62
|
</div>
|
|
63
|
+
<div class="bottom-section">
|
|
64
|
+
<span class="page-number">{{ element.number }}</span>
|
|
65
|
+
</div>
|
|
59
66
|
</div>
|
|
60
|
-
|
|
61
|
-
<span class="page-number">{{ page.number }}</span>
|
|
62
|
-
</div>
|
|
63
|
-
</div>
|
|
67
|
+
</template>
|
|
64
68
|
</draggable>
|
|
65
69
|
</div>
|
|
66
70
|
</template>
|
|
@@ -75,7 +79,6 @@ import { mapState } from "vuex";
|
|
|
75
79
|
import SplitLines from "../../assets/images/SplitLines";
|
|
76
80
|
import SplitZigZag from "../../assets/images/SplitZigZag";
|
|
77
81
|
import EditPageThumbnail from "./EditPageThumbnail";
|
|
78
|
-
|
|
79
82
|
import draggable from "vuedraggable";
|
|
80
83
|
|
|
81
84
|
export default {
|
|
@@ -133,7 +136,9 @@ export default {
|
|
|
133
136
|
},
|
|
134
137
|
},
|
|
135
138
|
mounted() {
|
|
136
|
-
this.
|
|
139
|
+
if (this.pagesForPostprocess.length > 0) {
|
|
140
|
+
this.editPages = this.pagesForPostprocess;
|
|
141
|
+
}
|
|
137
142
|
},
|
|
138
143
|
methods: {
|
|
139
144
|
deselect() {
|
|
@@ -1,10 +1,24 @@
|
|
|
1
1
|
<!-- eslint-disable vue/no-v-html -->
|
|
2
2
|
<template>
|
|
3
|
-
<div
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
<div
|
|
4
|
+
class="annotation-popup"
|
|
5
|
+
:style="{
|
|
6
|
+
left: `${left}px`,
|
|
7
|
+
top: `${top}px`,
|
|
8
|
+
height: `${heightOfPopup}px`,
|
|
9
|
+
}"
|
|
10
|
+
>
|
|
11
|
+
<div v-if="!editAnnotation">
|
|
12
|
+
<div v-if="spanLoading" class="popup-input">
|
|
13
|
+
<b-icon icon="spinner" class="fa-spin loading-icon-size spinner" />
|
|
14
|
+
</div>
|
|
15
|
+
<input
|
|
16
|
+
v-else
|
|
17
|
+
v-model="textFromEntities"
|
|
18
|
+
class="popup-input"
|
|
19
|
+
type="text"
|
|
20
|
+
/>
|
|
6
21
|
</div>
|
|
7
|
-
<input v-else v-model="textFromEntities" class="popup-input" type="text" />
|
|
8
22
|
<b-dropdown
|
|
9
23
|
v-model="selectedSet"
|
|
10
24
|
:disabled="!textFromEntities"
|
|
@@ -27,17 +41,19 @@
|
|
|
27
41
|
]"
|
|
28
42
|
type="is-text"
|
|
29
43
|
>
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
44
|
+
<span class="input-text">
|
|
45
|
+
{{
|
|
46
|
+
selectedSet
|
|
47
|
+
? `${selectedSet.label_set.name} ${
|
|
48
|
+
selectedSet.id
|
|
49
|
+
? numberOfAnnotationSetGroup(selectedSet)
|
|
50
|
+
: `${numberOfLabelSetGroup(selectedSet.label_set)} (${$t(
|
|
51
|
+
"new"
|
|
52
|
+
)})`
|
|
53
|
+
}`
|
|
54
|
+
: $t("select_annotation_set")
|
|
55
|
+
}}</span
|
|
56
|
+
>
|
|
41
57
|
<span class="caret-icon">
|
|
42
58
|
<b-icon icon="angle-down" size="is-small" class="caret" />
|
|
43
59
|
</span>
|
|
@@ -72,7 +88,6 @@
|
|
|
72
88
|
size="is-large"
|
|
73
89
|
position="is-bottom"
|
|
74
90
|
class="bottom-aligned"
|
|
75
|
-
:close-delay="5000"
|
|
76
91
|
>
|
|
77
92
|
<template #content>
|
|
78
93
|
<div
|
|
@@ -99,13 +114,13 @@
|
|
|
99
114
|
]"
|
|
100
115
|
type="is-text"
|
|
101
116
|
>
|
|
102
|
-
{{
|
|
117
|
+
<span class="input-text">{{
|
|
103
118
|
selectedLabel
|
|
104
119
|
? selectedLabel.name
|
|
105
120
|
: labels && labels.length === 0
|
|
106
121
|
? $t("no_labels_to_choose")
|
|
107
122
|
: $t("select_label")
|
|
108
|
-
}}
|
|
123
|
+
}}</span>
|
|
109
124
|
<span class="caret-icon">
|
|
110
125
|
<b-icon icon="angle-down" size="is-small" class="caret" />
|
|
111
126
|
</span>
|
|
@@ -144,15 +159,12 @@
|
|
|
144
159
|
* This component is used to show a popup
|
|
145
160
|
* for creating a new annotation.
|
|
146
161
|
*/
|
|
147
|
-
const heightOfPopup = 192;
|
|
148
|
-
const margin = 12;
|
|
149
|
-
const widthOfPopup = 205;
|
|
150
162
|
|
|
151
163
|
import { mapGetters, mapState } from "vuex";
|
|
152
164
|
|
|
153
165
|
export default {
|
|
154
166
|
props: {
|
|
155
|
-
|
|
167
|
+
spans: {
|
|
156
168
|
required: true,
|
|
157
169
|
type: Array,
|
|
158
170
|
},
|
|
@@ -171,6 +183,9 @@ export default {
|
|
|
171
183
|
},
|
|
172
184
|
data() {
|
|
173
185
|
return {
|
|
186
|
+
heightOfPopup: 192,
|
|
187
|
+
margin: 12,
|
|
188
|
+
widthOfPopup: 205,
|
|
174
189
|
selectedLabel: null,
|
|
175
190
|
selectedSet: null,
|
|
176
191
|
labels: null,
|
|
@@ -180,51 +195,48 @@ export default {
|
|
|
180
195
|
};
|
|
181
196
|
},
|
|
182
197
|
computed: {
|
|
183
|
-
...mapState("document", ["annotationSets", "documentId"]),
|
|
198
|
+
...mapState("document", ["annotationSets", "documentId", "editAnnotation"]),
|
|
184
199
|
...mapGetters("document", [
|
|
185
200
|
"numberOfAnnotationSetGroup",
|
|
186
201
|
"numberOfLabelSetGroup",
|
|
187
202
|
"labelsFilteredForAnnotationCreation",
|
|
188
203
|
]),
|
|
189
204
|
...mapState("display", ["showBranding"]),
|
|
190
|
-
...mapGetters("display", ["clientToBbox"]),
|
|
191
|
-
...mapState("selection", ["spanSelection", "selection"]),
|
|
205
|
+
...mapGetters("display", ["clientToBbox", "bboxToRect"]),
|
|
206
|
+
...mapState("selection", ["spanSelection", "selection", "spanLoading"]),
|
|
192
207
|
top() {
|
|
193
208
|
if (this.selection && this.selection.end) {
|
|
194
|
-
const top = this.selection.end.y + margin;
|
|
209
|
+
const top = this.selection.end.y + this.margin;
|
|
195
210
|
//check if the popup will not go off the container on the top
|
|
196
|
-
return top + heightOfPopup < this.containerHeight
|
|
211
|
+
return top + this.heightOfPopup < this.containerHeight
|
|
197
212
|
? top
|
|
198
|
-
: this.selection.end.y - heightOfPopup;
|
|
213
|
+
: this.selection.end.y - this.heightOfPopup;
|
|
199
214
|
} else {
|
|
200
|
-
const
|
|
215
|
+
const normalizedSpan = this.bboxToRect(this.page, this.spans[0]);
|
|
216
|
+
const top = normalizedSpan.y - this.heightOfPopup; // subtract the height of the popup plus some margin
|
|
201
217
|
|
|
202
218
|
//check if the popup will not go off the container on the top
|
|
203
|
-
return
|
|
219
|
+
return normalizedSpan.y > this.heightOfPopup
|
|
204
220
|
? top
|
|
205
|
-
:
|
|
206
|
-
this.newAnnotation[0].scaled.height +
|
|
207
|
-
margin;
|
|
221
|
+
: normalizedSpan.y + normalizedSpan.height + this.margin;
|
|
208
222
|
}
|
|
209
223
|
},
|
|
210
224
|
left() {
|
|
211
225
|
if (this.selection && this.selection.start && this.selection.end) {
|
|
212
226
|
const left = this.selection.start.x;
|
|
213
227
|
//check if the popup will not go off the container on the right
|
|
214
|
-
return left + widthOfPopup < this.containerWidth
|
|
228
|
+
return left + this.widthOfPopup < this.containerWidth
|
|
215
229
|
? left
|
|
216
|
-
: this.containerWidth - widthOfPopup;
|
|
217
|
-
return this.selection.start.x;
|
|
230
|
+
: this.containerWidth - this.widthOfPopup;
|
|
218
231
|
} else {
|
|
232
|
+
const normalizedSpan = this.bboxToRect(this.page, this.spans[0]);
|
|
219
233
|
const left =
|
|
220
|
-
|
|
221
|
-
this.newAnnotation[0].scaled.width / 2 -
|
|
222
|
-
widthOfPopup / 2; // add the entity half width to be centered and then subtract half the width of the popup
|
|
234
|
+
normalizedSpan.x + normalizedSpan.width / 2 - this.widthOfPopup / 2; // add the entity half width to be centered and then subtract half the width of the popup
|
|
223
235
|
|
|
224
236
|
//check if the popup will not go off the container
|
|
225
|
-
if (left + widthOfPopup > this.containerWidth) {
|
|
237
|
+
if (left + this.widthOfPopup > this.containerWidth) {
|
|
226
238
|
// on the right side
|
|
227
|
-
return this.containerWidth - widthOfPopup;
|
|
239
|
+
return this.containerWidth - this.widthOfPopup;
|
|
228
240
|
} else {
|
|
229
241
|
// on the left side
|
|
230
242
|
return left > 0 ? left : 0;
|
|
@@ -232,10 +244,8 @@ export default {
|
|
|
232
244
|
}
|
|
233
245
|
},
|
|
234
246
|
textFromEntities() {
|
|
235
|
-
if (!this.spanSelection) return;
|
|
236
|
-
|
|
237
247
|
let text = "";
|
|
238
|
-
this.
|
|
248
|
+
this.spans.forEach((span) => {
|
|
239
249
|
text = `${text} ${span.offset_string}`;
|
|
240
250
|
});
|
|
241
251
|
|
|
@@ -243,17 +253,23 @@ export default {
|
|
|
243
253
|
},
|
|
244
254
|
},
|
|
245
255
|
watch: {
|
|
246
|
-
selectedSet(newValue) {
|
|
256
|
+
selectedSet(newValue, oldValue) {
|
|
247
257
|
this.selectedLabel = null;
|
|
248
258
|
this.labels = this.labelsFilteredForAnnotationCreation(newValue);
|
|
249
|
-
if (
|
|
259
|
+
if (oldValue === null && this.editAnnotation) {
|
|
260
|
+
this.selectedLabel = this.editAnnotation.label;
|
|
261
|
+
} else if (this.labels.length === 1) {
|
|
250
262
|
this.selectedLabel = this.labels[0];
|
|
251
263
|
}
|
|
252
264
|
},
|
|
253
265
|
},
|
|
254
266
|
mounted() {
|
|
255
267
|
this.setsList = this.orderedSetList([...this.annotationSets]);
|
|
256
|
-
|
|
268
|
+
|
|
269
|
+
if (this.editAnnotation) {
|
|
270
|
+
this.heightOfPopup = 142;
|
|
271
|
+
this.selectedSet = this.editAnnotation.annotationSet;
|
|
272
|
+
} else if (this.setsList.length === 1) {
|
|
257
273
|
this.selectedSet = this.setsList[0];
|
|
258
274
|
}
|
|
259
275
|
|
|
@@ -262,7 +278,7 @@ export default {
|
|
|
262
278
|
document.body.addEventListener("click", this.clickOutside);
|
|
263
279
|
}, 200);
|
|
264
280
|
},
|
|
265
|
-
|
|
281
|
+
unmounted() {
|
|
266
282
|
document.body.removeEventListener("click", this.clickOutside);
|
|
267
283
|
},
|
|
268
284
|
methods: {
|
|
@@ -283,61 +299,73 @@ export default {
|
|
|
283
299
|
return setsList;
|
|
284
300
|
},
|
|
285
301
|
close() {
|
|
286
|
-
this
|
|
287
|
-
|
|
302
|
+
if (this.editAnnotation) {
|
|
303
|
+
this.$store.dispatch("document/resetEditAnnotation");
|
|
304
|
+
}
|
|
305
|
+
this.$store.dispatch("selection/disableSelection");
|
|
288
306
|
this.$emit("close");
|
|
289
307
|
},
|
|
290
308
|
save() {
|
|
291
|
-
this.
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
309
|
+
if (this.editAnnotation) {
|
|
310
|
+
this.loading = true;
|
|
311
|
+
this.$store.dispatch("document/setEditAnnotation", {
|
|
312
|
+
id: this.editAnnotation.id,
|
|
313
|
+
index: this.editAnnotation.index,
|
|
314
|
+
label: this.selectedLabel,
|
|
315
|
+
labelSet: this.selectedSet.label_set,
|
|
316
|
+
annotationSet: this.selectedSet,
|
|
317
|
+
pageNumber: this.editAnnotation.pageNumber,
|
|
318
|
+
});
|
|
298
319
|
|
|
299
|
-
|
|
320
|
+
document.getElementById("save-ann").click();
|
|
300
321
|
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
this.selection.start,
|
|
305
|
-
this.selection.end
|
|
306
|
-
);
|
|
307
|
-
}
|
|
322
|
+
return;
|
|
323
|
+
} else {
|
|
324
|
+
this.loading = true;
|
|
308
325
|
|
|
309
|
-
|
|
310
|
-
document: this.documentId,
|
|
311
|
-
span: span,
|
|
312
|
-
label: this.selectedLabel.id,
|
|
313
|
-
is_correct: true,
|
|
314
|
-
revised: false,
|
|
315
|
-
};
|
|
326
|
+
let selection_bbox = null;
|
|
316
327
|
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
328
|
+
if (this.selection && this.selection.start && this.selection.end) {
|
|
329
|
+
selection_bbox = this.clientToBbox(
|
|
330
|
+
this.page,
|
|
331
|
+
this.selection.start,
|
|
332
|
+
this.selection.end
|
|
333
|
+
);
|
|
334
|
+
}
|
|
320
335
|
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
336
|
+
const annotationToCreate = {
|
|
337
|
+
document: this.documentId,
|
|
338
|
+
span: this.spans,
|
|
339
|
+
label: this.selectedLabel.id,
|
|
340
|
+
is_correct: true,
|
|
341
|
+
revised: false,
|
|
342
|
+
};
|
|
343
|
+
|
|
344
|
+
if (selection_bbox) {
|
|
345
|
+
annotationToCreate.selection_bbox = selection_bbox;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
if (this.selectedSet.id) {
|
|
349
|
+
annotationToCreate.annotation_set = this.selectedSet.id;
|
|
350
|
+
} else {
|
|
351
|
+
annotationToCreate.label_set = this.selectedSet.label_set.id;
|
|
352
|
+
}
|
|
353
|
+
this.$store
|
|
354
|
+
.dispatch("document/createAnnotation", {
|
|
355
|
+
annotation: annotationToCreate,
|
|
356
|
+
})
|
|
357
|
+
.catch((error) => {
|
|
358
|
+
this.$store.dispatch("document/createErrorMessage", {
|
|
359
|
+
error,
|
|
360
|
+
serverErrorMessage: this.$t("server_error"),
|
|
361
|
+
defaultErrorMessage: this.$t("error_creating_annotation"),
|
|
362
|
+
});
|
|
363
|
+
})
|
|
364
|
+
.finally(() => {
|
|
365
|
+
this.close();
|
|
366
|
+
this.loading = false;
|
|
335
367
|
});
|
|
336
|
-
|
|
337
|
-
.finally(() => {
|
|
338
|
-
this.close();
|
|
339
|
-
this.loading = false;
|
|
340
|
-
});
|
|
368
|
+
}
|
|
341
369
|
},
|
|
342
370
|
chooseLabelSet(labelSet) {
|
|
343
371
|
// check if there's already a new entry for that label set to be created
|
|
@@ -13,11 +13,6 @@
|
|
|
13
13
|
ref="boxTransformer"
|
|
14
14
|
:config="transformerConfig"
|
|
15
15
|
/>
|
|
16
|
-
<v-rect
|
|
17
|
-
v-if="selection.placeholderBox"
|
|
18
|
-
ref="placeholderSelection"
|
|
19
|
-
:config="placeholderConfig"
|
|
20
|
-
/>
|
|
21
16
|
</v-group>
|
|
22
17
|
</template>
|
|
23
18
|
|
|
@@ -56,21 +51,7 @@ export default {
|
|
|
56
51
|
draggable: true,
|
|
57
52
|
};
|
|
58
53
|
},
|
|
59
|
-
|
|
60
|
-
return {
|
|
61
|
-
x: this.selection.placeholderBox.x,
|
|
62
|
-
y: this.selection.placeholderBox.y,
|
|
63
|
-
width: this.selection.placeholderBox.width,
|
|
64
|
-
height: this.selection.placeholderBox.height,
|
|
65
|
-
fill: "transparent",
|
|
66
|
-
stroke: "#41af85",
|
|
67
|
-
strokeWidth: 3,
|
|
68
|
-
globalCompositeOperation: "multiply",
|
|
69
|
-
shadowForStrokeEnabled: false,
|
|
70
|
-
name: "placeholderSelection",
|
|
71
|
-
draggable: false,
|
|
72
|
-
};
|
|
73
|
-
},
|
|
54
|
+
|
|
74
55
|
transformerConfig() {
|
|
75
56
|
return {
|
|
76
57
|
borderEnabled: false,
|
|
@@ -87,7 +68,8 @@ export default {
|
|
|
87
68
|
"elementSelected",
|
|
88
69
|
"spanSelection",
|
|
89
70
|
]),
|
|
90
|
-
...
|
|
71
|
+
...mapState("document", ["editAnnotation"]),
|
|
72
|
+
...mapGetters("display", ["clientToBbox", "scaledEntities"]),
|
|
91
73
|
...mapGetters("selection", ["isSelectionValid", "entitiesOnSelection"]),
|
|
92
74
|
},
|
|
93
75
|
watch: {
|
|
@@ -106,19 +88,19 @@ export default {
|
|
|
106
88
|
},
|
|
107
89
|
methods: {
|
|
108
90
|
handleSelection() {
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
this.entitiesOnSelection(box, this.page)
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
}
|
|
91
|
+
const box = this.clientToBbox(
|
|
92
|
+
this.page,
|
|
93
|
+
this.selection.start,
|
|
94
|
+
this.selection.end
|
|
95
|
+
);
|
|
96
|
+
|
|
97
|
+
this.$store.dispatch("selection/entitySelection", {
|
|
98
|
+
entities: this.scaledEntities(
|
|
99
|
+
this.entitiesOnSelection(box, this.page),
|
|
100
|
+
this.page
|
|
101
|
+
),
|
|
102
|
+
selection: box,
|
|
103
|
+
});
|
|
122
104
|
},
|
|
123
105
|
updateTransformer() {
|
|
124
106
|
// here we need to manually attach or detach Transformer node
|
|
@@ -152,21 +134,6 @@ export default {
|
|
|
152
134
|
transformerNode.getLayer().batchDraw();
|
|
153
135
|
},
|
|
154
136
|
|
|
155
|
-
getBoxSelectionContent() {
|
|
156
|
-
if (!this.isSelecting) {
|
|
157
|
-
const box = this.clientToBbox(
|
|
158
|
-
this.page,
|
|
159
|
-
this.selection.start,
|
|
160
|
-
this.selection.end
|
|
161
|
-
);
|
|
162
|
-
this.$emit("selectEntities", this.entitiesOnSelection(box, this.page));
|
|
163
|
-
this.$store.dispatch("selection/getTextFromBboxes", {
|
|
164
|
-
box,
|
|
165
|
-
entities: false,
|
|
166
|
-
});
|
|
167
|
-
}
|
|
168
|
-
},
|
|
169
|
-
|
|
170
137
|
/**
|
|
171
138
|
* This method is used for both transforms and drags since it just
|
|
172
139
|
* retrieves the rect's new attributes from the event and uses those
|