@konfuzio/document-validation-ui 0.1.17-dev.3 → 0.1.18-dev.0

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@konfuzio/document-validation-ui",
3
- "version": "0.1.17-dev.3",
3
+ "version": "0.1.18-dev.0",
4
4
  "repository": "git://github.com:konfuzio-ai/document-validation-ui.git",
5
5
  "main": "dist/app.js",
6
6
  "scripts": {
@@ -1,13 +1,22 @@
1
1
  <template>
2
2
  <svg
3
- id="exchange" xmlns="http://www.w3.org/2000/svg"
3
+ id="exchange"
4
+ xmlns="http://www.w3.org/2000/svg"
4
5
  viewBox="0 0 24 24"
5
6
  width="24"
6
7
  height="24"
7
- >
8
- <path v-if="translation" fill="#1A1A1A" d="M18,10a1,1,0,0,0-1-1H5.41l2.3-2.29A1,1,0,0,0,6.29,5.29l-4,4a1,1,0,0,0-.21,1.09A1,1,0,0,0,3,11H17A1,1,0,0,0,18,10Zm3.92,3.62A1,1,0,0,0,21,13H7a1,1,0,0,0,0,2H18.59l-2.3,2.29a1,1,0,0,0,0,1.42,1,1,0,0,0,1.42,0l4-4A1,1,0,0,0,21.92,13.62Z"></path>
9
- <path v-else fill="#E1E1E1" d="M18,10a1,1,0,0,0-1-1H5.41l2.3-2.29A1,1,0,0,0,6.29,5.29l-4,4a1,1,0,0,0-.21,1.09A1,1,0,0,0,3,11H17A1,1,0,0,0,18,10Zm3.92,3.62A1,1,0,0,0,21,13H7a1,1,0,0,0,0,2H18.59l-2.3,2.29a1,1,0,0,0,0,1.42,1,1,0,0,0,1.42,0l4-4A1,1,0,0,0,21.92,13.62Z"></path>
10
- </svg>
8
+ >
9
+ <path
10
+ v-if="translation"
11
+ fill="#1A1A1A"
12
+ d="M18,10a1,1,0,0,0-1-1H5.41l2.3-2.29A1,1,0,0,0,6.29,5.29l-4,4a1,1,0,0,0-.21,1.09A1,1,0,0,0,3,11H17A1,1,0,0,0,18,10Zm3.92,3.62A1,1,0,0,0,21,13H7a1,1,0,0,0,0,2H18.59l-2.3,2.29a1,1,0,0,0,0,1.42,1,1,0,0,0,1.42,0l4-4A1,1,0,0,0,21.92,13.62Z"
13
+ ></path>
14
+ <path
15
+ v-else
16
+ fill="#E1E1E1"
17
+ d="M18,10a1,1,0,0,0-1-1H5.41l2.3-2.29A1,1,0,0,0,6.29,5.29l-4,4a1,1,0,0,0-.21,1.09A1,1,0,0,0,3,11H17A1,1,0,0,0,18,10Zm3.92,3.62A1,1,0,0,0,21,13H7a1,1,0,0,0,0,2H18.59l-2.3,2.29a1,1,0,0,0,0,1.42,1,1,0,0,0,1.42,0l4-4A1,1,0,0,0,21.92,13.62Z"
18
+ ></path>
19
+ </svg>
11
20
  </template>
12
21
 
13
22
  <script>
@@ -15,10 +24,10 @@ export default {
15
24
  name: "TranslateArrows",
16
25
  props: {
17
26
  translation: {
18
- type: Boolean,
19
- default: false,
27
+ type: String,
28
+ default: null,
20
29
  required: false,
21
30
  },
22
31
  },
23
32
  };
24
- </script>
33
+ </script>
@@ -197,6 +197,10 @@
197
197
  display: flex;
198
198
  padding-left: 20px;
199
199
 
200
+ &.pointer {
201
+ cursor: pointer;
202
+ }
203
+
200
204
  .icon {
201
205
  display: flex;
202
206
  }
@@ -205,29 +209,39 @@
205
209
  display: flex;
206
210
  flex-direction: column;
207
211
  gap: 8px;
208
- min-width: 100px;
212
+ min-width: 216px;
209
213
  text-align: left;
214
+ border-bottom: 1px solid $low-opacity-white;
215
+ padding-bottom: 8px;
216
+ word-wrap: break-all;
217
+ white-space: normal;
210
218
 
211
219
  .translation-title {
212
- font-size: 14px;
213
- font-weight: 500;
214
- }
215
-
216
- .translation-info {
220
+ color: $white;
221
+ font-weight: 400;
222
+ font-size: 12px;
223
+ line-height: 18px;
217
224
  display: flex;
225
+ flex-direction: row;
218
226
  justify-content: space-between;
219
- gap: 8px;
220
- font-size: 12px;
221
-
222
- .annotation-details-link {
223
- color: $primary;
224
-
225
- &:hover {
226
- filter: $hover-style;
227
+ .translated-string {
228
+ font-weight: 500;
229
+ text-align: right;
230
+ &.no-translation {
231
+ color: $red;
232
+ font-weight: 400;
227
233
  }
228
234
  }
229
235
  }
230
236
  }
237
+ .translation-info {
238
+ padding-top: 8px;
239
+ line-height: 18px;
240
+ font-size: 12px;
241
+ opacity: 0.7;
242
+ color: $white;
243
+ font-weight: 400;
244
+ }
231
245
  }
232
246
  }
233
247
 
@@ -28,6 +28,8 @@
28
28
  width: 100%;
29
29
  justify-content: space-between;
30
30
  position: relative;
31
+ text-wrap: wrap;
32
+ text-align: left;
31
33
 
32
34
  .caret-icon {
33
35
  position: absolute;
@@ -38,35 +38,41 @@
38
38
  <span>{{ label.name }} </span>
39
39
  </div>
40
40
 
41
- <div v-if="showTranslationsDetails" class="annotation-translation">
42
- <b-tooltip :animated="false" position="is-bottom" :close-delay="2000">
41
+ <div
42
+ v-if="showTranslationsDetails"
43
+ :class="['annotation-translation', !isDocumentReviewed && 'pointer']"
44
+ @click="editAnnotationTranslation(annotation.id)"
45
+ >
46
+ <b-tooltip :animated="false" position="is-bottom">
43
47
  <div class="icon">
44
- <TranslateArrows
45
- :translation="annotation.translated_string && true"
46
- />
48
+ <TranslateArrows :translation="annotation.translated_string" />
47
49
  </div>
48
50
 
49
51
  <template #content>
50
52
  <div class="translation-details">
51
53
  <div class="translation-title">
52
54
  <span>{{ $t("translated_string_title") }}</span>
55
+ <span
56
+ :class="[
57
+ 'translated-string',
58
+ !annotation.translated_string && 'no-translation',
59
+ ]"
60
+ >
61
+ {{
62
+ annotation.translated_string
63
+ ? annotation.translated_string
64
+ : $t("no_translated_string")
65
+ }}
66
+ </span>
53
67
  </div>
54
- <div class="translation-info">
55
- <span class="translated-string">{{
68
+ </div>
69
+ <div class="translation-info">
70
+ <div v-if="!isDocumentReviewed" class="annotation-details-link">
71
+ {{
56
72
  annotation.translated_string
57
- ? annotation.translated_string
58
- : $t("no_translated_string")
59
- }}</span>
60
- <a
61
- v-if="!isDocumentReviewed"
62
- class="annotation-details-link"
63
- @click="editAnnotationTranslation(annotation.id)"
64
- >{{
65
- annotation.translated_string
66
- ? $t("edit")
67
- : $t("add_translation")
68
- }}</a
69
- >
73
+ ? $t("edit_translation")
74
+ : $t("add_translation")
75
+ }}
70
76
  </div>
71
77
  </div>
72
78
  </template>
@@ -679,7 +685,7 @@ export default {
679
685
  }
680
686
  },
681
687
  enableLoading(annotations) {
682
- if (annotations && this.annotation) {
688
+ if (annotations && this.annotation && !this.annotation.is_correct) {
683
689
  const found = annotations.find(
684
690
  (annotation) => annotation === this.annotation.id
685
691
  );
@@ -727,7 +733,7 @@ export default {
727
733
  }
728
734
  },
729
735
  editAnnotationTranslation(annotationId) {
730
- if (!annotationId) return;
736
+ if (!annotationId || this.isDocumentReviewed) return;
731
737
 
732
738
  const baseUrl = api.FILE_URL ? api.FILE_URL : api.DEFAULT_URL;
733
739
 
@@ -110,7 +110,8 @@
110
110
 
111
111
  <div v-if="annotationSet.labels.length === 0" class="no-labels">
112
112
  <span> {{ $t("no_labels_in_set") }}</span>
113
- <span v-if="!publicView && !isDocumentReviewed" v-html="$t('link_to_add_labels')"></span>
113
+ <!-- eslint-disable-next-line vue/no-v-html -->
114
+ <span v-if="isDocumentEditable" v-html="$t('link_to_add_labels')" />
114
115
  </div>
115
116
 
116
117
  <div
@@ -178,6 +179,9 @@ export default {
178
179
  isAnnotationBeingEdited() {
179
180
  return this.editAnnotation && this.editAnnotation.id;
180
181
  },
182
+ isDocumentEditable() {
183
+ return !this.publicView && !this.isDocumentReviewed;
184
+ },
181
185
  },
182
186
  watch: {
183
187
  editAnnotation(newValue) {
@@ -266,7 +270,7 @@ export default {
266
270
 
267
271
  keyDownHandler(event) {
268
272
  // only allow keyboard navigation if we are not in public view mode
269
- if (this.publicView || this.isDocumentReviewed) return;
273
+ if (!this.isDocumentEditable) return;
270
274
 
271
275
  // Exit edit mode and navigation
272
276
  if (event.key === "Escape") {
@@ -18,7 +18,7 @@
18
18
  :class="[
19
19
  'category-chooser',
20
20
  splitMode && 'split-mode',
21
- selectedDocument.is_reviewed && 'disabled',
21
+ isDocumentReviewed && 'disabled',
22
22
  ]"
23
23
  aria-role="list"
24
24
  scrollable
@@ -60,7 +60,9 @@
60
60
  @click="handleChangeCategory(category)"
61
61
  >
62
62
  <span>{{ category.name }}</span>
63
- <span v-if="splitMode && category.confidence >= 0">{{ ` (${ category.confidence }%)` }}</span>
63
+ <span v-if="splitMode && category.confidence >= 0">{{
64
+ ` (${category.confidence}%)`
65
+ }}</span>
64
66
  </b-dropdown-item>
65
67
  </b-dropdown>
66
68
  </b-tooltip>
@@ -79,14 +81,14 @@ export default {
79
81
  splitMode: {
80
82
  type: Boolean,
81
83
  },
82
- page: {
83
- type: Object,
84
- default: null,
85
- },
86
- index: {
87
- type: Number,
88
- default: 0,
89
- },
84
+ page: {
85
+ type: Object,
86
+ default: null,
87
+ },
88
+ index: {
89
+ type: Number,
90
+ default: 0,
91
+ },
90
92
  },
91
93
  data() {
92
94
  return {
@@ -101,6 +103,7 @@ export default {
101
103
  ...mapGetters("document", [
102
104
  "documentCannotBeEdited",
103
105
  "documentHasCorrectAnnotations",
106
+ "isDocumentReviewed",
104
107
  ]),
105
108
  ...mapState("document", ["selectedDocument", "annotations"]),
106
109
  ...mapState("category", ["categories"]),
@@ -117,7 +120,7 @@ export default {
117
120
  // if there is just 1 category in the project,
118
121
  // and one or more sub-documents has no category,
119
122
  // assign the only category by default
120
- if (this.projectHasSingleCategory() && missingCategory) {
123
+ if (this.projectHasSingleCategory && missingCategory) {
121
124
  const updatedValuesForDocuments = this.updatedDocument.map(
122
125
  (document) => {
123
126
  if (!document.category && this.categories) {
@@ -146,14 +149,18 @@ export default {
146
149
  },
147
150
 
148
151
  setCategoryConfidence() {
149
- if (!this.updatedDocument[this.index].categories || !this.categoryName(
150
- this.updatedDocument[this.index].category
151
- )) return;
152
+ if (
153
+ !this.updatedDocument[this.index].categories ||
154
+ !this.categoryName(this.updatedDocument[this.index].category)
155
+ )
156
+ return;
157
+
158
+ const found = this.updatedDocument[this.index].categories.find(
159
+ (category) => category.id === this.updatedDocument[this.index].category
160
+ );
152
161
 
153
- const found = this.updatedDocument[this.index].categories.find(category => category.id === this.updatedDocument[this.index].category);
154
-
155
162
  return this.handleCategoryConfidence(found.confidence);
156
- }
163
+ },
157
164
  },
158
165
  watch: {
159
166
  annotations() {
@@ -162,7 +169,7 @@ export default {
162
169
  },
163
170
  },
164
171
  mounted() {
165
- if (this.projectHasSingleCategory()) {
172
+ if (this.projectHasSingleCategory) {
166
173
  this.tooltipIsShown = true;
167
174
  }
168
175
  },
@@ -174,10 +181,14 @@ export default {
174
181
  listOfCategories() {
175
182
  let list;
176
183
 
177
- if(this.splitMode && this.updatedDocument[this.index].categories) {
178
- list = this.handleCategories(this.updatedDocument[this.index].categories);
184
+ if (this.splitMode && this.updatedDocument[this.index].categories) {
185
+ list = this.handleCategories(
186
+ this.updatedDocument[this.index].categories
187
+ );
179
188
  } else if (this.categories) {
180
- const filtered = this.categories.filter(category => category.project === this.selectedDocument.project)
189
+ const filtered = this.categories.filter(
190
+ (category) => category.project === this.selectedDocument.project
191
+ );
181
192
  list = this.handleCategories(filtered);
182
193
  }
183
194
 
@@ -185,12 +196,16 @@ export default {
185
196
  },
186
197
  handleCategories(categories) {
187
198
  return categories.map((category) => {
188
- return {id: category.id, name: this.categoryName(category.id), confidence: this.handleCategoryConfidence(category.confidence)};
189
- });
199
+ return {
200
+ id: category.id,
201
+ name: this.categoryName(category.id),
202
+ confidence: this.handleCategoryConfidence(category.confidence),
203
+ };
204
+ });
190
205
  },
191
206
  handleCategoryConfidence(confidence) {
192
- if(!confidence) {
193
- if(confidence === 0) return confidence.toFixed(2);
207
+ if (!confidence) {
208
+ if (confidence === 0) return confidence.toFixed(2);
194
209
 
195
210
  return;
196
211
  }
@@ -199,9 +214,9 @@ export default {
199
214
  },
200
215
  checkIfDropdownIsDisabled() {
201
216
  if (
202
- this.projectHasSingleCategory() ||
217
+ this.projectHasSingleCategory ||
203
218
  this.documentCannotBeEdited(this.selectedDocument) ||
204
- (this.documentHasCorrectAnnotations() && !this.splitMode)
219
+ (this.documentHasCorrectAnnotations && !this.splitMode)
205
220
  ) {
206
221
  this.dropdownIsDisabled = true;
207
222
  } else {
@@ -253,9 +268,9 @@ export default {
253
268
 
254
269
  if (this.documentCannotBeEdited(this.selectedDocument)) {
255
270
  tooltipText = this.$t("edit_not_available");
256
- } else if (this.documentHasCorrectAnnotations()) {
271
+ } else if (this.documentHasCorrectAnnotations) {
257
272
  tooltipText = this.$t("approved_annotations");
258
- } else if (this.projectHasSingleCategory()) {
273
+ } else if (this.projectHasSingleCategory) {
259
274
  tooltipText = this.$t("single_category_in_project");
260
275
  tooltipDelay = 5000;
261
276
  }
@@ -232,7 +232,8 @@ export default {
232
232
  if (
233
233
  annotation.span.find(
234
234
  (span) => span.page_index + 1 === this.page.number
235
- ) && !this.isNegative(annotation)
235
+ ) &&
236
+ !this.isNegative(annotation)
236
237
  ) {
237
238
  annotations.push(annotation);
238
239
  }
@@ -385,6 +386,8 @@ export default {
385
386
 
386
387
  if (trigger && trigger === "click") {
387
388
  this.closePopups(true);
389
+ } else {
390
+ this.onElementEnter();
388
391
  }
389
392
  },
390
393
 
@@ -143,5 +143,6 @@
143
143
  "redirecting_to_documents_list": "Wir führen Sie zur Dokumentenliste, sodass Sie Ihre Dokumente weiter überprüfen können, während wir die vorgenommenen Änderungen verarbeiten.",
144
144
  "translated_string_title": "Übersetzter Text",
145
145
  "no_translated_string": "Es existiert noch keine Übersetzung.",
146
- "add_translation": "Eins hinzufügen"
146
+ "add_translation": "Klicken Sie zum hinzufügen",
147
+ "edit_translation": "Zum Bearbeiten anklicken"
147
148
  }
@@ -143,5 +143,6 @@
143
143
  "redirecting_to_documents_list": "We are taking you to the documents list, so you can continue reviewing your documents while we process the changes made.",
144
144
  "translated_string_title": "Translated text",
145
145
  "no_translated_string": "No translation exists yet.",
146
- "add_translation": "Add one"
146
+ "add_translation": "Click to add one",
147
+ "edit_translation": "Click to edit"
147
148
  }
@@ -143,5 +143,6 @@
143
143
  "redirecting_to_documents_list": "Lo estamos redirigiendo a la lista de documentos, para que pueda continuar la revisión de sus documentos mientras procesamos los cambios realizados.",
144
144
  "translated_string_title": "Texto traducido",
145
145
  "no_translated_string": "Aún no existe traducción.",
146
- "add_translation": "Agregar"
146
+ "add_translation": "Clic para agregar",
147
+ "edit_translation": "Clic para editar"
147
148
  }
@@ -33,7 +33,7 @@ const getters = {
33
33
  return null;
34
34
  },
35
35
 
36
- projectHasSingleCategory: (state) => () => {
36
+ projectHasSingleCategory: (state) => {
37
37
  return state.categories && state.categories.length === 1;
38
38
  },
39
39
  };
@@ -121,9 +121,9 @@ const getters = {
121
121
  let availableLabels = [];
122
122
  if (set.id && set.labels) {
123
123
  // check if label can be multiple, if there's already an annotation created & if it's a negative annotation
124
- set.labels.map(label => {
124
+ set.labels.map((label) => {
125
125
  // check if we already added the same label to the array
126
- const found = availableLabels.find(l => l.id === label.id);
126
+ const found = availableLabels.find((l) => l.id === label.id);
127
127
 
128
128
  if (found) return;
129
129
 
@@ -134,13 +134,12 @@ const getters = {
134
134
  availableLabels.push(label);
135
135
  } else {
136
136
  // if the label has negative annotations, we show the label
137
- label.annotations.map(annotation => {
137
+ label.annotations.map((annotation) => {
138
138
  if (getters.isNegative(annotation)) {
139
139
  availableLabels.push(label);
140
140
  }
141
141
  });
142
142
  }
143
-
144
143
  }
145
144
  });
146
145
  } else if (set.labels) {
@@ -255,7 +254,6 @@ const getters = {
255
254
  const labels = [];
256
255
  const processedAnnotationSets = annotationSets.map((annotationSet) => {
257
256
  const annotationSetLabels = annotationSet.labels.map((label) => {
258
-
259
257
  // add annotations to the document array
260
258
  annotations.push(...label.annotations);
261
259
  labels.push(label);
@@ -274,7 +272,7 @@ const getters = {
274
272
  },
275
273
 
276
274
  /* Checks if there are annotations correct in the document */
277
- documentHasCorrectAnnotations: (state) => () => {
275
+ documentHasCorrectAnnotations: (state) => {
278
276
  if (
279
277
  !state.annotations ||
280
278
  (state.annotations &&
@@ -335,7 +333,7 @@ const getters = {
335
333
  // check which one has more confidence or if it's the same, then check if one is revised or not
336
334
  if (
337
335
  highestConfidenceAnnotation.confidence <
338
- label.annotations[i].confidence ||
336
+ label.annotations[i].confidence ||
339
337
  (highestConfidenceAnnotation.confidence ===
340
338
  label.annotations[i].confidence &&
341
339
  label.annotations[i].revised)
@@ -360,17 +358,17 @@ const getters = {
360
358
  */
361
359
  isAnnotationInEditMode:
362
360
  (state) =>
363
- (annotationId, index = null) => {
364
- if (state.editAnnotation && annotationId) {
365
- if (index != null) {
366
- return (
367
- state.editAnnotation.id === annotationId &&
368
- state.editAnnotation.index === index
369
- );
370
- }
371
- return state.editAnnotation.id === annotationId;
361
+ (annotationId, index = null) => {
362
+ if (state.editAnnotation && annotationId) {
363
+ if (index != null) {
364
+ return (
365
+ state.editAnnotation.id === annotationId &&
366
+ state.editAnnotation.index === index
367
+ );
372
368
  }
373
- },
369
+ return state.editAnnotation.id === annotationId;
370
+ }
371
+ },
374
372
 
375
373
  /**
376
374
  * Get number of empty labels per annotation set
@@ -386,14 +384,13 @@ const getters = {
386
384
  annotationSet.label_set.id === l.label_set
387
385
  );
388
386
 
389
- const foundNegative = label.annotations.find(annotation =>
387
+ const foundNegative = label.annotations.find((annotation) =>
390
388
  getters.isNegative(annotation)
391
389
  );
392
390
 
393
391
  if (!foundMissing && (label.annotations.length === 0 || foundNegative)) {
394
392
  pendingEmpty.push(label);
395
393
  }
396
-
397
394
  });
398
395
 
399
396
  return pendingEmpty;
@@ -442,7 +439,7 @@ const getters = {
442
439
  notCorrect = state.annotations.filter((a) => !a.is_correct);
443
440
 
444
441
  if (notCorrect) {
445
- notCorrect.map(annotation => {
442
+ notCorrect.map((annotation) => {
446
443
  emptyAnnotations.push(annotation);
447
444
  });
448
445
  }
@@ -517,14 +514,14 @@ const getters = {
517
514
  */
518
515
  documentCannotBeEdited:
519
516
  (state) =>
520
- (document = state.selectedDocument) => {
521
- return (
522
- document.dataset_status === 1 ||
523
- document.dataset_status === 2 ||
524
- document.dataset_status === 3 ||
525
- document.is_reviewed
526
- );
527
- },
517
+ (document = state.selectedDocument) => {
518
+ return (
519
+ document.dataset_status === 1 ||
520
+ document.dataset_status === 2 ||
521
+ document.dataset_status === 3 ||
522
+ document.is_reviewed
523
+ );
524
+ },
528
525
 
529
526
  /**
530
527
  * If automatic splitting is enabled for the project
@@ -778,7 +775,7 @@ const actions = {
778
775
  if (
779
776
  !state.selectedDocument.category ||
780
777
  (!state.selectedDocument.category_is_revised &&
781
- !getters.documentHasCorrectAnnotations() &&
778
+ !getters.documentHasCorrectAnnotations &&
782
779
  state.missingAnnotations.length === 0)
783
780
  ) {
784
781
  dispatch("edit/enableEditMode", null, {
@@ -851,7 +848,10 @@ const actions = {
851
848
  commit("SET_DOCUMENT_ANNOTATION_SELECTED", null);
852
849
  },
853
850
 
854
- createAnnotation: ({ commit, getters, dispatch }, { annotation, negativeAnnotationId }) => {
851
+ createAnnotation: (
852
+ { commit, getters, dispatch },
853
+ { annotation, negativeAnnotationId }
854
+ ) => {
855
855
  return new Promise((resolve, reject) => {
856
856
  HTTP.post(`/annotations/`, annotation)
857
857
  .then(async (response) => {