@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.
Files changed (49) hide show
  1. package/dist/css/app.css +1 -1
  2. package/dist/index.html +1 -1
  3. package/dist/js/app.js +1 -1
  4. package/dist/js/app.js.map +1 -1
  5. package/package.json +1 -1
  6. package/src/assets/images/MagicWandIcon.vue +16 -0
  7. package/src/assets/images/ServerImage.vue +3 -0
  8. package/src/assets/images/SplitZigZag.vue +47 -14
  9. package/src/assets/images/StarIcon.vue +16 -0
  10. package/src/assets/scss/document_category.scss +0 -1
  11. package/src/assets/scss/document_dashboard.scss +6 -0
  12. package/src/assets/scss/document_edit.scss +135 -46
  13. package/src/assets/scss/splitting_confirmation_modal.scss +41 -0
  14. package/src/assets/scss/variables.scss +63 -1
  15. package/src/components/App.vue +11 -1
  16. package/src/components/DocumentAnnotations/ActionButtons.vue +7 -0
  17. package/src/components/DocumentAnnotations/AnnotationContent.vue +3 -0
  18. package/src/components/DocumentAnnotations/AnnotationRow.vue +3 -0
  19. package/src/components/DocumentAnnotations/CategorizeModal.vue +24 -4
  20. package/src/components/DocumentAnnotations/DocumentAnnotations.vue +11 -3
  21. package/src/components/DocumentAnnotations/DocumentLabel.vue +2 -0
  22. package/src/components/DocumentAnnotations/EmptyAnnotation.vue +6 -1
  23. package/src/components/DocumentCategory.vue +39 -33
  24. package/src/components/DocumentDashboard.vue +39 -49
  25. package/src/components/DocumentEdit/DocumentEdit.vue +207 -69
  26. package/src/components/DocumentEdit/EditConfirmationModal.vue +54 -0
  27. package/src/components/DocumentEdit/EditPages.vue +30 -18
  28. package/src/components/DocumentEdit/EditSidebar.vue +95 -45
  29. package/src/components/DocumentEdit/SidebarButtons.vue +53 -0
  30. package/src/components/DocumentEdit/SplitInfoBar.vue +19 -0
  31. package/src/components/DocumentEdit/SplitOverview.vue +6 -5
  32. package/src/components/{DocumentError.vue → DocumentModals/DocumentErrorModal.vue} +3 -4
  33. package/src/components/{NotOptimizedViewportModal.vue → DocumentModals/NotOptimizedViewportModal.vue} +2 -2
  34. package/src/components/DocumentModals/SplittingSuggestionsModal.vue +121 -0
  35. package/src/components/DocumentPage/DocumentPage.vue +9 -3
  36. package/src/components/DocumentPage/DummyPage.vue +9 -7
  37. package/src/components/DocumentPage/ScrollingDocument.vue +8 -3
  38. package/src/components/DocumentThumbnails/DocumentThumbnails.vue +45 -8
  39. package/src/components/DocumentTopBar/DocumentName.vue +1 -0
  40. package/src/components/DocumentTopBar/DocumentTopBar.vue +2 -6
  41. package/src/components/DocumentTopBar/DocumentTopBarButtons.vue +6 -20
  42. package/src/components/index.js +1 -0
  43. package/src/locales/de.json +15 -2
  44. package/src/locales/en.json +15 -1
  45. package/src/locales/es.json +14 -1
  46. package/src/store/display.js +8 -0
  47. package/src/store/document.js +83 -37
  48. package/src/store/edit.js +66 -48
  49. 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", ["selectedDocument"]),
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("document/setCategorizeModalIsActive", newValue);
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.show = !this.categorizationIsConfirmed;
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("document/setCategorizeModalIsActive", false);
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 v-if="!publicView" />
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 v-if="!publicView" />
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", ["numberOfAnnotationSetGroup"]),
133
+ ...mapGetters("document", [
134
+ "numberOfAnnotationSetGroup",
135
+ "waitingForSplittingConfirmation",
136
+ ]),
129
137
  isAnnotationBeingEdited() {
130
138
  return this.editAnnotation && this.editAnnotation.id;
131
139
  },
@@ -66,9 +66,11 @@ export default {
66
66
  components: { AnnotationRow },
67
67
  props: {
68
68
  label: {
69
+ type: Object,
69
70
  required: true,
70
71
  },
71
72
  annotationSet: {
73
+ type: Object,
72
74
  required: true,
73
75
  },
74
76
  },
@@ -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(newValue) {
118
- if (newValue) {
119
- this.showTooltip();
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
- if (this.projectHasSingleCategory()) {
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', editMode ? 'edit-mode' : '']">
5
- <DocumentThumbnails
6
- v-if="!editMode"
7
- ref="documentPages"
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
- v-if="showDocumentError"
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 "./NotOptimizedViewportModal";
64
- import DocumentError from "./DocumentError";
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
- DocumentError
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>