@konfuzio/document-validation-ui 0.1.4 → 0.1.5-automatic-document-splitting
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/ServerImage.vue +3 -0
- package/src/assets/images/SplitZigZag.vue +47 -14
- package/src/assets/images/StarIcon.vue +16 -0
- 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 +135 -46
- package/src/assets/scss/splitting_confirmation_modal.scss +41 -0
- package/src/assets/scss/variables.scss +63 -1
- package/src/components/App.vue +11 -1
- package/src/components/DocumentAnnotations/ActionButtons.vue +7 -0
- package/src/components/DocumentAnnotations/AnnotationContent.vue +3 -0
- package/src/components/DocumentAnnotations/AnnotationRow.vue +3 -0
- package/src/components/DocumentAnnotations/CategorizeModal.vue +24 -4
- package/src/components/DocumentAnnotations/DocumentAnnotations.vue +11 -3
- package/src/components/DocumentAnnotations/DocumentLabel.vue +2 -0
- package/src/components/DocumentAnnotations/EmptyAnnotation.vue +6 -1
- package/src/components/DocumentCategory.vue +39 -33
- package/src/components/DocumentDashboard.vue +39 -49
- package/src/components/DocumentEdit/DocumentEdit.vue +207 -69
- package/src/components/DocumentEdit/EditConfirmationModal.vue +54 -0
- package/src/components/DocumentEdit/EditPages.vue +30 -18
- package/src/components/DocumentEdit/EditSidebar.vue +95 -45
- package/src/components/DocumentEdit/SidebarButtons.vue +53 -0
- package/src/components/DocumentEdit/SplitInfoBar.vue +19 -0
- package/src/components/DocumentEdit/SplitOverview.vue +6 -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 +121 -0
- package/src/components/DocumentPage/DocumentPage.vue +9 -3
- package/src/components/DocumentPage/DummyPage.vue +9 -7
- package/src/components/DocumentPage/ScrollingDocument.vue +8 -3
- package/src/components/DocumentThumbnails/DocumentThumbnails.vue +45 -8
- package/src/components/DocumentTopBar/DocumentName.vue +1 -0
- package/src/components/DocumentTopBar/DocumentTopBar.vue +2 -6
- package/src/components/DocumentTopBar/DocumentTopBarButtons.vue +6 -20
- package/src/components/index.js +1 -0
- package/src/locales/de.json +15 -2
- package/src/locales/en.json +15 -1
- package/src/locales/es.json +14 -1
- package/src/store/display.js +8 -0
- package/src/store/document.js +83 -37
- package/src/store/edit.js +66 -48
- package/src/store/project.js +14 -14
|
@@ -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) {
|
|
@@ -125,7 +134,14 @@ export default {
|
|
|
125
134
|
}
|
|
126
135
|
},
|
|
127
136
|
show(newValue) {
|
|
128
|
-
this.$store.dispatch("
|
|
137
|
+
this.$store.dispatch("display/setCategorizeModalIsActive", newValue);
|
|
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
|
+
}
|
|
129
145
|
},
|
|
130
146
|
},
|
|
131
147
|
mounted() {
|
|
@@ -159,7 +175,11 @@ 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 = !category || (category && !this.splittingSuggestions);
|
|
163
183
|
}
|
|
164
184
|
},
|
|
165
185
|
canCloseModal() {
|
|
@@ -194,7 +214,7 @@ export default {
|
|
|
194
214
|
})
|
|
195
215
|
.finally(() => {
|
|
196
216
|
this.$store.dispatch("document/endRecalculatingAnnotations");
|
|
197
|
-
this.$store.dispatch("
|
|
217
|
+
this.$store.dispatch("display/setCategorizeModalIsActive", false);
|
|
198
218
|
});
|
|
199
219
|
} else {
|
|
200
220
|
// if same category, then just accept it
|
|
@@ -14,7 +14,9 @@
|
|
|
14
14
|
|
|
15
15
|
<!-- When there's no annotations in the label -->
|
|
16
16
|
<div v-else-if="annotationSets.length === 0">
|
|
17
|
-
<CategorizeModal
|
|
17
|
+
<CategorizeModal
|
|
18
|
+
v-if="!publicView && !waitingForSplittingConfirmation(selectedDocument)"
|
|
19
|
+
/>
|
|
18
20
|
<EmptyState />
|
|
19
21
|
</div>
|
|
20
22
|
|
|
@@ -25,7 +27,9 @@
|
|
|
25
27
|
missingAnnotations.length && !publicView && 'showing-rejected',
|
|
26
28
|
]"
|
|
27
29
|
>
|
|
28
|
-
<CategorizeModal
|
|
30
|
+
<CategorizeModal
|
|
31
|
+
v-if="!publicView && !waitingForSplittingConfirmation(selectedDocument)"
|
|
32
|
+
/>
|
|
29
33
|
<div
|
|
30
34
|
v-for="(annotationSet, indexGroup) in annotationSets"
|
|
31
35
|
:key="indexGroup"
|
|
@@ -123,9 +127,13 @@ export default {
|
|
|
123
127
|
"loading",
|
|
124
128
|
"labels",
|
|
125
129
|
"selectedDocument",
|
|
130
|
+
"splittingSuggestions",
|
|
126
131
|
]),
|
|
127
132
|
...mapGetters("category", ["category"]),
|
|
128
|
-
...mapGetters("document", [
|
|
133
|
+
...mapGetters("document", [
|
|
134
|
+
"numberOfAnnotationSetGroup",
|
|
135
|
+
"waitingForSplittingConfirmation",
|
|
136
|
+
]),
|
|
129
137
|
isAnnotationBeingEdited() {
|
|
130
138
|
return this.editAnnotation && this.editAnnotation.id;
|
|
131
139
|
},
|
|
@@ -37,17 +37,22 @@ export default {
|
|
|
37
37
|
name: "EmptyAnnotation",
|
|
38
38
|
props: {
|
|
39
39
|
label: {
|
|
40
|
+
type: Object,
|
|
40
41
|
required: true,
|
|
41
42
|
},
|
|
42
43
|
annotationSet: {
|
|
44
|
+
type: Object,
|
|
43
45
|
required: true,
|
|
44
46
|
},
|
|
45
|
-
|
|
46
47
|
span: {
|
|
48
|
+
type: Object,
|
|
49
|
+
default: null,
|
|
47
50
|
required: false,
|
|
48
51
|
},
|
|
49
52
|
spanIndex: {
|
|
53
|
+
type: Number,
|
|
50
54
|
required: false,
|
|
55
|
+
default: 0,
|
|
51
56
|
},
|
|
52
57
|
saveChanges: {
|
|
53
58
|
type: Boolean,
|
|
@@ -29,11 +29,7 @@
|
|
|
29
29
|
{{ $t("category") }}
|
|
30
30
|
</p>
|
|
31
31
|
<div class="category-name">
|
|
32
|
-
{{
|
|
33
|
-
!splitMode
|
|
34
|
-
? categoryName(selectedDocument.category)
|
|
35
|
-
: categoryName(updatedDocument[index].category)
|
|
36
|
-
}}
|
|
32
|
+
{{ setCategoryDefaultText }}
|
|
37
33
|
</div>
|
|
38
34
|
</div>
|
|
39
35
|
<div :class="[!splitMode && 'caret-section']">
|
|
@@ -74,9 +70,11 @@ export default {
|
|
|
74
70
|
},
|
|
75
71
|
page: {
|
|
76
72
|
type: Object,
|
|
73
|
+
default: null,
|
|
77
74
|
},
|
|
78
75
|
index: {
|
|
79
76
|
type: Number,
|
|
77
|
+
default: 0,
|
|
80
78
|
},
|
|
81
79
|
},
|
|
82
80
|
data() {
|
|
@@ -84,8 +82,8 @@ export default {
|
|
|
84
82
|
currentProjectCategories: [],
|
|
85
83
|
categoryError: false,
|
|
86
84
|
tooltipIsShown: false,
|
|
87
|
-
dropdownIsDisabled: false,
|
|
88
85
|
tooltipCloseDelay: 0,
|
|
86
|
+
dropdownIsDisabled: false,
|
|
89
87
|
};
|
|
90
88
|
},
|
|
91
89
|
computed: {
|
|
@@ -100,6 +98,18 @@ export default {
|
|
|
100
98
|
...mapState("document", ["selectedDocument", "annotations"]),
|
|
101
99
|
...mapState("category", ["categories"]),
|
|
102
100
|
...mapState("edit", ["editMode", "updatedDocument"]),
|
|
101
|
+
|
|
102
|
+
setCategoryDefaultText() {
|
|
103
|
+
if (!this.splitMode) {
|
|
104
|
+
return this.categoryName(this.selectedDocument.category);
|
|
105
|
+
} else {
|
|
106
|
+
const categoryName = this.categoryName(
|
|
107
|
+
this.updatedDocument[this.index].category
|
|
108
|
+
);
|
|
109
|
+
|
|
110
|
+
return categoryName ? categoryName : this.$t("choose_category");
|
|
111
|
+
}
|
|
112
|
+
},
|
|
103
113
|
},
|
|
104
114
|
watch: {
|
|
105
115
|
categories(newValue) {
|
|
@@ -114,10 +124,9 @@ export default {
|
|
|
114
124
|
}
|
|
115
125
|
});
|
|
116
126
|
},
|
|
117
|
-
annotations(
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
}
|
|
127
|
+
annotations() {
|
|
128
|
+
this.checkIfDropdownIsDisabled();
|
|
129
|
+
this.setTooltipText();
|
|
121
130
|
},
|
|
122
131
|
},
|
|
123
132
|
mounted() {
|
|
@@ -138,16 +147,26 @@ export default {
|
|
|
138
147
|
this.tooltipIsShown = true;
|
|
139
148
|
}
|
|
140
149
|
|
|
141
|
-
this.showTooltip();
|
|
142
|
-
|
|
143
150
|
this.$nextTick(() => {
|
|
144
151
|
this.setTooltipText();
|
|
152
|
+
this.checkIfDropdownIsDisabled();
|
|
145
153
|
});
|
|
146
154
|
},
|
|
147
155
|
updated() {
|
|
148
156
|
this.setTooltipText();
|
|
149
157
|
},
|
|
150
158
|
methods: {
|
|
159
|
+
checkIfDropdownIsDisabled() {
|
|
160
|
+
if (
|
|
161
|
+
this.projectHasSingleCategory() ||
|
|
162
|
+
this.documentCannotBeEdited(this.selectedDocument) ||
|
|
163
|
+
(this.documentHasCorrectAnnotations() && !this.splitMode)
|
|
164
|
+
) {
|
|
165
|
+
this.dropdownIsDisabled = true;
|
|
166
|
+
} else {
|
|
167
|
+
this.dropdownIsDisabled = false;
|
|
168
|
+
}
|
|
169
|
+
},
|
|
151
170
|
// The current category name will change
|
|
152
171
|
// depending on if we are on edit mode or not
|
|
153
172
|
handleOptionInDropdownDisabled(category) {
|
|
@@ -188,34 +207,21 @@ export default {
|
|
|
188
207
|
this.$emit("category-change", this.page, category.id);
|
|
189
208
|
},
|
|
190
209
|
|
|
191
|
-
showTooltip() {
|
|
192
|
-
if (
|
|
193
|
-
this.documentCannotBeEdited(this.selectedDocument) ||
|
|
194
|
-
(this.documentHasCorrectAnnotations() && !this.splitMode)
|
|
195
|
-
) {
|
|
196
|
-
this.dropdownIsDisabled = true;
|
|
197
|
-
} else {
|
|
198
|
-
this.dropdownIsDisabled = false;
|
|
199
|
-
}
|
|
200
|
-
},
|
|
201
|
-
|
|
202
210
|
setTooltipText() {
|
|
203
211
|
// Text set from innerHTML vs 'label' due to html tag in locales file string
|
|
204
212
|
let tooltipText;
|
|
205
|
-
|
|
206
|
-
tooltipText = this.$t("single_category_in_project");
|
|
213
|
+
let tooltipDelay = 0;
|
|
207
214
|
|
|
215
|
+
if (this.documentCannotBeEdited(this.selectedDocument)) {
|
|
216
|
+
tooltipText = this.$t("edit_not_available");
|
|
217
|
+
} else if (this.documentHasCorrectAnnotations()) {
|
|
218
|
+
tooltipText = this.$t("approved_annotations");
|
|
219
|
+
} else if (this.projectHasSingleCategory()) {
|
|
220
|
+
tooltipText = this.$t("single_category_in_project");
|
|
208
221
|
this.tooltipCloseDelay = 5000;
|
|
209
|
-
} else {
|
|
210
|
-
this.tooltipCloseDelay = 0;
|
|
211
|
-
|
|
212
|
-
if (this.documentHasCorrectAnnotations()) {
|
|
213
|
-
tooltipText = this.$t("approved_annotations");
|
|
214
|
-
} else {
|
|
215
|
-
tooltipText = this.$t("edit_not_available");
|
|
216
|
-
}
|
|
217
222
|
}
|
|
218
223
|
|
|
224
|
+
this.tooltipCloseDelay = tooltipDelay;
|
|
219
225
|
this.$refs.tooltipContent.innerHTML = tooltipText;
|
|
220
226
|
},
|
|
221
227
|
},
|
|
@@ -1,23 +1,11 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="dashboard">
|
|
3
3
|
<DocumentTopBar />
|
|
4
|
-
<div :class="['dashboard-viewer',
|
|
5
|
-
<DocumentThumbnails
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
/>
|
|
9
|
-
<ScrollingDocument
|
|
10
|
-
ref="scrollingDocument"
|
|
11
|
-
class="dashboard-document"
|
|
12
|
-
/>
|
|
13
|
-
<DocumentAnnotations
|
|
14
|
-
v-if="!editMode"
|
|
15
|
-
ref="annotations"
|
|
16
|
-
/>
|
|
17
|
-
<DocumentEdit
|
|
18
|
-
v-else
|
|
19
|
-
ref="editView"
|
|
20
|
-
/>
|
|
4
|
+
<div :class="['dashboard-viewer', splitOverview ? 'edit-mode' : '']">
|
|
5
|
+
<DocumentThumbnails v-if="!editMode" ref="documentPages" />
|
|
6
|
+
<ScrollingDocument ref="scrollingDocument" class="dashboard-document" />
|
|
7
|
+
<DocumentAnnotations v-if="!editMode" ref="annotations" />
|
|
8
|
+
<DocumentEdit v-else ref="editView" />
|
|
21
9
|
|
|
22
10
|
<transition name="slide-fade">
|
|
23
11
|
<div
|
|
@@ -29,26 +17,24 @@
|
|
|
29
17
|
</div>
|
|
30
18
|
</transition>
|
|
31
19
|
</div>
|
|
32
|
-
<div
|
|
33
|
-
|
|
34
|
-
class="error-modal"
|
|
35
|
-
>
|
|
36
|
-
<DocumentError />
|
|
20
|
+
<div v-if="showDocumentError" class="error-modal">
|
|
21
|
+
<DocumentErrorModal />
|
|
37
22
|
</div>
|
|
38
|
-
<div
|
|
39
|
-
v-if="!optimalResolution"
|
|
40
|
-
class="not-optimized"
|
|
41
|
-
>
|
|
23
|
+
<div v-if="!optimalResolution" class="not-optimized">
|
|
42
24
|
<NotOptimizedViewportModal />
|
|
43
25
|
</div>
|
|
44
|
-
<div
|
|
45
|
-
v-if="!isMinimumWidth"
|
|
46
|
-
class="not-supported"
|
|
47
|
-
>
|
|
26
|
+
<div v-if="!isMinimumWidth" class="not-supported">
|
|
48
27
|
<div class="text">
|
|
49
28
|
{{ $t("resolution_not_supported") }}
|
|
50
29
|
</div>
|
|
51
30
|
</div>
|
|
31
|
+
<div
|
|
32
|
+
v-if="
|
|
33
|
+
selectedDocument && waitingForSplittingConfirmation(selectedDocument)
|
|
34
|
+
"
|
|
35
|
+
>
|
|
36
|
+
<SplittingSuggestionsModal />
|
|
37
|
+
</div>
|
|
52
38
|
</div>
|
|
53
39
|
</template>
|
|
54
40
|
|
|
@@ -60,8 +46,9 @@ import { DocumentThumbnails } from "./DocumentThumbnails";
|
|
|
60
46
|
import { DocumentAnnotations } from "./DocumentAnnotations";
|
|
61
47
|
import { DocumentEdit } from "./DocumentEdit";
|
|
62
48
|
import ErrorMessage from "./ErrorMessage";
|
|
63
|
-
import NotOptimizedViewportModal from "
|
|
64
|
-
import
|
|
49
|
+
import NotOptimizedViewportModal from "../components/DocumentModals/NotOptimizedViewportModal";
|
|
50
|
+
import DocumentErrorModal from "../components/DocumentModals/DocumentErrorModal";
|
|
51
|
+
import SplittingSuggestionsModal from "../components/DocumentModals/SplittingSuggestionsModal";
|
|
65
52
|
|
|
66
53
|
/**
|
|
67
54
|
* This component shows the PDF pages in a scrolling component and
|
|
@@ -77,7 +64,14 @@ export default {
|
|
|
77
64
|
DocumentEdit,
|
|
78
65
|
ErrorMessage,
|
|
79
66
|
NotOptimizedViewportModal,
|
|
80
|
-
|
|
67
|
+
DocumentErrorModal,
|
|
68
|
+
SplittingSuggestionsModal,
|
|
69
|
+
},
|
|
70
|
+
data() {
|
|
71
|
+
return {
|
|
72
|
+
resizeObserver: null,
|
|
73
|
+
unwatchSelectedDocument: null,
|
|
74
|
+
};
|
|
81
75
|
},
|
|
82
76
|
computed: {
|
|
83
77
|
...mapState("display", [
|
|
@@ -85,16 +79,18 @@ export default {
|
|
|
85
79
|
"fit",
|
|
86
80
|
"optimalResolution",
|
|
87
81
|
"pageWidthScale",
|
|
88
|
-
"currentPage"
|
|
82
|
+
"currentPage",
|
|
89
83
|
]),
|
|
90
84
|
...mapState("document", [
|
|
91
85
|
"showActionError",
|
|
92
86
|
"showDocumentError",
|
|
93
87
|
"errorMessageWidth",
|
|
94
|
-
"selectedDocument"
|
|
88
|
+
"selectedDocument",
|
|
89
|
+
"splittingSuggestions",
|
|
95
90
|
]),
|
|
96
|
-
...mapState("edit", ["editMode"]),
|
|
97
|
-
...mapGetters("display", ["isMinimumWidth"])
|
|
91
|
+
...mapState("edit", ["editMode", "splitOverview"]),
|
|
92
|
+
...mapGetters("display", ["isMinimumWidth"]),
|
|
93
|
+
...mapGetters("document", ["waitingForSplittingConfirmation"]),
|
|
98
94
|
},
|
|
99
95
|
watch: {
|
|
100
96
|
selectedDocument(newDocument, oldDocument) {
|
|
@@ -104,7 +100,7 @@ export default {
|
|
|
104
100
|
} else if (newDocument) {
|
|
105
101
|
this.onDocumentResize();
|
|
106
102
|
}
|
|
107
|
-
}
|
|
103
|
+
},
|
|
108
104
|
},
|
|
109
105
|
mounted() {
|
|
110
106
|
this.resizeObserver = new ResizeObserver(this.onDocumentResize);
|
|
@@ -114,12 +110,6 @@ export default {
|
|
|
114
110
|
this.resizeObserver.unobserve(this.$refs.scrollingDocument.$el);
|
|
115
111
|
}
|
|
116
112
|
},
|
|
117
|
-
data() {
|
|
118
|
-
return {
|
|
119
|
-
resizeObserver: null,
|
|
120
|
-
unwatchSelectedDocument: null
|
|
121
|
-
};
|
|
122
|
-
},
|
|
123
113
|
methods: {
|
|
124
114
|
elementsWidth() {
|
|
125
115
|
let elementsWidth = 1;
|
|
@@ -144,16 +134,16 @@ export default {
|
|
|
144
134
|
elementsWidth: this.elementsWidth(),
|
|
145
135
|
client: {
|
|
146
136
|
width: this.$el.clientWidth,
|
|
147
|
-
height: this.$el.clientHeight
|
|
137
|
+
height: this.$el.clientHeight,
|
|
148
138
|
},
|
|
149
139
|
viewport: {
|
|
150
140
|
width: this.selectedDocument.pages[0].size[0],
|
|
151
|
-
height: this.selectedDocument.pages[0].size[1]
|
|
152
|
-
}
|
|
141
|
+
height: this.selectedDocument.pages[0].size[1],
|
|
142
|
+
},
|
|
153
143
|
});
|
|
154
144
|
}
|
|
155
|
-
}
|
|
156
|
-
}
|
|
145
|
+
},
|
|
146
|
+
},
|
|
157
147
|
};
|
|
158
148
|
</script>
|
|
159
149
|
<style scoped lang="scss" src="../assets/scss/document_dashboard.scss"></style>
|