@konfuzio/document-validation-ui 0.1.59 → 0.2.0-dev.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/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 +29 -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 +45 -45
- package/src/assets/scss/document_category.scss +8 -8
- package/src/assets/scss/document_dashboard.scss +6 -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 +31 -7
- package/src/components/DocumentAnnotations/AnnotationContent.vue +25 -52
- package/src/components/DocumentAnnotations/AnnotationRow.vue +108 -51
- package/src/components/DocumentAnnotations/DocumentAnnotations.vue +12 -6
- package/src/components/DocumentAnnotations/DocumentLabel.vue +12 -122
- 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/DocumentEdit/EditSidebar.vue +0 -9
- package/src/components/DocumentPage/{NewAnnotation.vue → AnnotationPopup.vue} +123 -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/locales/de.json +2 -1
- package/src/locales/en.json +2 -1
- package/src/locales/es.json +2 -1
- package/src/main.js +14 -16
- package/src/store/display.js +33 -22
- package/src/store/document.js +131 -10
- 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
|
@@ -1,39 +1,33 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div class="empty-annotation">
|
|
2
|
+
<div v-if="!publicView && !isDocumentReviewed" class="empty-annotation">
|
|
3
3
|
<span
|
|
4
|
-
v-if="!publicView && !isDocumentReviewed"
|
|
5
4
|
:id="emptyAnnotationId()"
|
|
6
5
|
ref="emptyAnnotation"
|
|
7
6
|
:class="[
|
|
8
7
|
'annotation-value',
|
|
9
|
-
showActionError &&
|
|
10
|
-
editAnnotation &&
|
|
11
|
-
editAnnotation.id === emptyAnnotationId() &&
|
|
12
|
-
'error-editing',
|
|
13
|
-
!isEmptyAnnotationEditable() && !isMissingAnnotation && 'label-empty',
|
|
8
|
+
showActionError && isAnnotationBeingEdited() && 'error-editing',
|
|
14
9
|
isAnnotationBeingEdited() && 'clicked-ann',
|
|
15
10
|
isMissingAnnotation && 'missing-annotation',
|
|
16
11
|
!isMissingAnnotation && 'keyboard-nav',
|
|
17
12
|
]"
|
|
18
|
-
:contenteditable="
|
|
13
|
+
:contenteditable="isAnnotationBeingEdited()"
|
|
19
14
|
@keypress.enter="saveEmptyAnnotationChanges"
|
|
20
15
|
@click="handleEditEmptyAnnotation"
|
|
21
16
|
@focus="handleEditEmptyAnnotation"
|
|
22
17
|
><!-- eslint-disable vue/no-v-html -->
|
|
23
18
|
<span
|
|
24
19
|
v-if="isFindingAnnotation"
|
|
20
|
+
class="label-empty-clicked"
|
|
25
21
|
v-html="$t('draw_box_document', { label_name: label.name })"
|
|
26
22
|
>
|
|
27
23
|
</span>
|
|
28
24
|
<span v-else-if="isMissingAnnotation" class="not-found-text">
|
|
29
25
|
{{ $t("missing_from_document") }}
|
|
30
26
|
</span>
|
|
31
|
-
<span
|
|
32
|
-
v-else-if="span && span.offset_string && isEmptyAnnotationEditable()"
|
|
33
|
-
>
|
|
27
|
+
<span v-else-if="span && span.offset_string">
|
|
34
28
|
{{ span.offset_string }}
|
|
35
29
|
</span>
|
|
36
|
-
<span v-else>
|
|
30
|
+
<span v-else class="label-empty">
|
|
37
31
|
{{ $t("no_data_found") }}
|
|
38
32
|
</span>
|
|
39
33
|
<!--eslint-enable-->
|
|
@@ -42,7 +36,6 @@
|
|
|
42
36
|
</template>
|
|
43
37
|
<script>
|
|
44
38
|
import { mapState, mapGetters } from "vuex";
|
|
45
|
-
import { isElementArray } from "../../utils/utils";
|
|
46
39
|
|
|
47
40
|
/**
|
|
48
41
|
* This component is responsible for managing empty annotations (labels with no annotations).
|
|
@@ -80,7 +73,7 @@ export default {
|
|
|
80
73
|
},
|
|
81
74
|
computed: {
|
|
82
75
|
...mapGetters("document", ["isAnnotationInEditMode", "isDocumentReviewed"]),
|
|
83
|
-
...mapState("selection", ["spanSelection"
|
|
76
|
+
...mapState("selection", ["spanSelection"]),
|
|
84
77
|
...mapState("document", [
|
|
85
78
|
"editAnnotation",
|
|
86
79
|
"publicView",
|
|
@@ -97,17 +90,17 @@ export default {
|
|
|
97
90
|
|
|
98
91
|
watch: {
|
|
99
92
|
span(newValue) {
|
|
100
|
-
if (
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
}
|
|
93
|
+
// if (newValue) {
|
|
94
|
+
// if (isElementArray(newValue))
|
|
95
|
+
// newValue.map((span) => {
|
|
96
|
+
// if (span.offset_string) {
|
|
97
|
+
// span.offset_string =
|
|
98
|
+
// this.$refs.emptyAnnotation.textContent.trim();
|
|
99
|
+
// span.offset_string_original =
|
|
100
|
+
// this.$refs.emptyAnnotation.textContent.trim();
|
|
101
|
+
// }
|
|
102
|
+
// });
|
|
103
|
+
// }
|
|
111
104
|
},
|
|
112
105
|
spanSelection(newValue) {
|
|
113
106
|
if (!newValue) return;
|
|
@@ -123,59 +116,27 @@ export default {
|
|
|
123
116
|
methods: {
|
|
124
117
|
emptyAnnotationId() {
|
|
125
118
|
if ((!this.annotationSet && !this.labelSet) || !this.label) return;
|
|
126
|
-
|
|
127
|
-
|
|
119
|
+
const id =
|
|
120
|
+
this.annotationSet && this.annotationSet.id != null
|
|
121
|
+
? this.annotationSet.id
|
|
122
|
+
: this.labelSet.id;
|
|
128
123
|
return `${id}_${this.label.id}`;
|
|
129
124
|
},
|
|
130
125
|
isAnnotationBeingEdited() {
|
|
131
126
|
return this.isAnnotationInEditMode(this.emptyAnnotationId());
|
|
132
127
|
},
|
|
133
128
|
handleEditEmptyAnnotation() {
|
|
134
|
-
if (
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
this.
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
!this.isDocumentReviewed &&
|
|
144
|
-
this.elementSelected !== this.emptyAnnotationId()
|
|
145
|
-
) {
|
|
146
|
-
this.$store.dispatch("selection/disableSelection");
|
|
147
|
-
this.$store.dispatch("selection/setSelectedEntities", null);
|
|
148
|
-
this.$store.dispatch(
|
|
149
|
-
"selection/selectElement",
|
|
150
|
-
this.emptyAnnotationId()
|
|
151
|
-
);
|
|
152
|
-
this.$store.dispatch("document/setEditAnnotation", {
|
|
153
|
-
id: this.emptyAnnotationId(),
|
|
154
|
-
index: this.spanIndex,
|
|
155
|
-
label: this.label,
|
|
156
|
-
labelSet: this.labelSet,
|
|
157
|
-
annotationSet: this.annotationSet,
|
|
158
|
-
});
|
|
159
|
-
}
|
|
160
|
-
},
|
|
161
|
-
isEmptyAnnotationEditable() {
|
|
162
|
-
if (
|
|
163
|
-
(this.spanSelection && this.spanSelection[this.spanIndex] === 0) ||
|
|
164
|
-
this.isMissingAnnotation
|
|
165
|
-
) {
|
|
166
|
-
return false;
|
|
167
|
-
} else {
|
|
168
|
-
return (
|
|
169
|
-
this.elementSelected === this.emptyAnnotationId() &&
|
|
170
|
-
this.spanSelection &&
|
|
171
|
-
this.spanSelection[this.spanIndex] &&
|
|
172
|
-
this.spanSelection[this.spanIndex].offset_string != null
|
|
173
|
-
);
|
|
174
|
-
}
|
|
129
|
+
if (this.isMissingAnnotation) return;
|
|
130
|
+
this.$store.dispatch("selection/disableSelection");
|
|
131
|
+
this.$store.dispatch("document/setEditAnnotation", {
|
|
132
|
+
id: this.emptyAnnotationId(),
|
|
133
|
+
index: this.spanIndex,
|
|
134
|
+
label: this.label,
|
|
135
|
+
labelSet: this.labelSet,
|
|
136
|
+
annotationSet: this.annotationSet,
|
|
137
|
+
});
|
|
175
138
|
},
|
|
176
139
|
saveEmptyAnnotationChanges(event) {
|
|
177
|
-
if (this.publicView || this.isDocumentReviewed) return;
|
|
178
|
-
|
|
179
140
|
if (event) {
|
|
180
141
|
event.preventDefault();
|
|
181
142
|
}
|
|
@@ -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" class="document-sidebar">
|
|
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() {
|
|
@@ -59,11 +59,6 @@
|
|
|
59
59
|
/>
|
|
60
60
|
<div class="switch-info">
|
|
61
61
|
<span class="switch-text">{{ $t("smart_split") }}</span>
|
|
62
|
-
<span
|
|
63
|
-
v-if="documentHasProposedSplit(selectedDocument)"
|
|
64
|
-
class="new-badge"
|
|
65
|
-
>{{ newText }}</span
|
|
66
|
-
>
|
|
67
62
|
</div>
|
|
68
63
|
</b-field>
|
|
69
64
|
</b-tooltip>
|
|
@@ -93,7 +88,6 @@ export default {
|
|
|
93
88
|
return {
|
|
94
89
|
buttonDisabled: true,
|
|
95
90
|
tooltipInfo: null,
|
|
96
|
-
newText: this.$t("new"),
|
|
97
91
|
switchStatus: true,
|
|
98
92
|
};
|
|
99
93
|
},
|
|
@@ -129,9 +123,6 @@ export default {
|
|
|
129
123
|
this.$nextTick(() => {
|
|
130
124
|
this.switchStatus = this.splitSuggestionsEnabled;
|
|
131
125
|
this.tooltipInfo = this.$t("no_splitting_suggestions");
|
|
132
|
-
if (this.newText) {
|
|
133
|
-
this.newText = this.$t("new").toUpperCase();
|
|
134
|
-
}
|
|
135
126
|
});
|
|
136
127
|
},
|
|
137
128
|
methods: {
|