@konfuzio/document-validation-ui 0.1.5 → 0.1.6-multi-ann-set-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.
Files changed (73) 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/.DS_Store +0 -0
  7. package/src/assets/images/DraggableIcon.vue +14 -0
  8. package/src/assets/images/GridIcon.vue +16 -0
  9. package/src/assets/images/MagicWandIcon.vue +16 -0
  10. package/src/assets/images/NotFoundIcon.vue +16 -0
  11. package/src/assets/images/SettingsIcon.vue +14 -0
  12. package/src/assets/images/SplitZigZag.vue +47 -14
  13. package/src/assets/images/StarIcon.vue +16 -0
  14. package/src/assets/scss/ann_set_table_options.scss +26 -0
  15. package/src/assets/scss/annotation_details.scss +85 -73
  16. package/src/assets/scss/document_annotations.scss +54 -57
  17. package/src/assets/scss/document_category.scss +0 -1
  18. package/src/assets/scss/document_dashboard.scss +7 -2
  19. package/src/assets/scss/document_edit.scss +90 -46
  20. package/src/assets/scss/main.scss +725 -7
  21. package/src/assets/scss/multi_ann_table_overlay.scss +38 -0
  22. package/src/assets/scss/splitting_confirmation_modal.scss +41 -0
  23. package/src/assets/scss/variables.scss +2 -657
  24. package/src/components/App.vue +9 -3
  25. package/src/components/DocumentAnnotations/AnnotationActionButtons.vue +171 -0
  26. package/src/components/DocumentAnnotations/AnnotationContent.vue +5 -3
  27. package/src/components/DocumentAnnotations/AnnotationDetails.vue +28 -7
  28. package/src/components/DocumentAnnotations/AnnotationRow.vue +133 -41
  29. package/src/components/DocumentAnnotations/AnnotationSetActionButtons.vue +86 -0
  30. package/src/components/DocumentAnnotations/CategorizeModal.vue +28 -2
  31. package/src/components/DocumentAnnotations/DocumentAnnotations.vue +121 -97
  32. package/src/components/DocumentAnnotations/EmptyAnnotation.vue +21 -5
  33. package/src/components/DocumentAnnotations/ExtractingData.vue +3 -3
  34. package/src/components/DocumentAnnotations/index.js +0 -1
  35. package/src/components/DocumentCategory.vue +13 -5
  36. package/src/components/DocumentDashboard.vue +17 -6
  37. package/src/components/DocumentEdit/DocumentEdit.vue +208 -68
  38. package/src/components/DocumentEdit/EditConfirmationModal.vue +54 -0
  39. package/src/components/DocumentEdit/EditPages.vue +29 -18
  40. package/src/components/DocumentEdit/EditSidebar.vue +92 -45
  41. package/src/components/DocumentEdit/SidebarButtons.vue +53 -0
  42. package/src/components/DocumentEdit/SplitInfoBar.vue +19 -0
  43. package/src/components/DocumentEdit/SplitOverview.vue +4 -5
  44. package/src/components/{DocumentError.vue → DocumentModals/DocumentErrorModal.vue} +3 -4
  45. package/src/components/{NotOptimizedViewportModal.vue → DocumentModals/NotOptimizedViewportModal.vue} +2 -2
  46. package/src/components/DocumentModals/SplittingSuggestionsModal.vue +120 -0
  47. package/src/components/DocumentPage/ActionBar.vue +3 -3
  48. package/src/components/DocumentPage/AnnSetTableOptions.vue +107 -0
  49. package/src/components/DocumentPage/DocumentPage.vue +39 -10
  50. package/src/components/DocumentPage/DocumentToolbar.vue +6 -2
  51. package/src/components/DocumentPage/MultiAnnSelection.vue +90 -2
  52. package/src/components/DocumentPage/MultiAnnotationTableOverlay.vue +274 -0
  53. package/src/components/DocumentPage/MultiAnnotationTablePopup.vue +19 -46
  54. package/src/components/DocumentPage/NewAnnotation.vue +1 -1
  55. package/src/components/DocumentPage/ScrollingDocument.vue +43 -4
  56. package/src/components/DocumentPage/ScrollingPage.vue +4 -5
  57. package/src/components/DocumentThumbnails/DocumentThumbnails.vue +14 -11
  58. package/src/components/DocumentTopBar/DocumentName.vue +6 -1
  59. package/src/components/DocumentTopBar/DocumentTopBar.vue +9 -9
  60. package/src/components/DocumentTopBar/DocumentTopBarButtons.vue +38 -32
  61. package/src/components/DocumentTopBar/KeyboardActionsDescription.vue +9 -3
  62. package/src/components/DocumentsList/DocumentsList.vue +11 -2
  63. package/src/locales/de.json +23 -6
  64. package/src/locales/en.json +24 -6
  65. package/src/locales/es.json +23 -6
  66. package/src/store/category.js +1 -1
  67. package/src/store/display.js +51 -0
  68. package/src/store/document.js +181 -24
  69. package/src/store/edit.js +71 -48
  70. package/src/store/project.js +14 -14
  71. package/src/utils/utils.js +13 -0
  72. package/src/components/DocumentAnnotations/ActionButtons.vue +0 -257
  73. package/src/components/DocumentAnnotations/RejectedLabels.vue +0 -96
@@ -0,0 +1,86 @@
1
+ <template>
2
+ <div class="action-buttons">
3
+ <!-- mark all empty labels as missing -->
4
+ <div
5
+ v-if="!publicView && !documentIsReviewed"
6
+ class="missing-decline-button-container all-missing"
7
+ @mouseenter="mouseenterAnnotationSet('missing')"
8
+ @mouseleave="mouseleaveAnnotationSet"
9
+ >
10
+ <b-button
11
+ type="is-ghost"
12
+ class="missing-decline-btn missing-btn all-missing-btn"
13
+ :disabled="numberOfEmptyLabelsInAnnotationSet === 0"
14
+ @click.stop="markAllAsMissing"
15
+ >
16
+ {{ $t("mark_all_missing") }} ({{ numberOfEmptyLabelsInAnnotationSet }})
17
+ </b-button>
18
+ </div>
19
+
20
+ <!-- accept all pending annotations -->
21
+ <div
22
+ v-if="!publicView && !documentIsReviewed"
23
+ class="accept-all"
24
+ @mouseenter="mouseenterAnnotationSet('accept')"
25
+ @mouseleave="mouseleaveAnnotationSet"
26
+ >
27
+ <b-button
28
+ type="is-primary"
29
+ class="accept-all-btn"
30
+ :disabled="numberOfPendingAnnotationsInAnnotationSet === 0"
31
+ @click.stop="acceptAllPending"
32
+ >
33
+ {{ $t("accept_group") }} ({{
34
+ numberOfPendingAnnotationsInAnnotationSet
35
+ }})
36
+ </b-button>
37
+ </div>
38
+ </div>
39
+ </template>
40
+ <script>
41
+ /* Component for showing actions for each Annotation Set */
42
+
43
+ import { mapState } from "vuex";
44
+
45
+ export default {
46
+ name: "AnnotationSetActionButtons",
47
+ props: {
48
+ numberOfEmptyLabelsInAnnotationSet: {
49
+ type: Number,
50
+ },
51
+ numberOfPendingAnnotationsInAnnotationSet: {
52
+ type: Number,
53
+ },
54
+ },
55
+ computed: {
56
+ ...mapState("document", ["publicView", "documentIsReviewed"]),
57
+ },
58
+ methods: {
59
+ mouseenterAnnotationSet(type) {
60
+ if (type == "missing") {
61
+ this.$emit("hover-annotation-set-to-mark-missing");
62
+ }
63
+
64
+ if (type == "accept") {
65
+ this.$emit("hover-annotation-set-to-accept");
66
+ }
67
+ },
68
+ mouseleaveAnnotationSet() {
69
+ this.$emit("leave-annotation-set-to-accept");
70
+ this.$emit("leave-annotation-set-to-mark-missing");
71
+ },
72
+ markAllAsMissing() {
73
+ this.$emit("mark-all-empty-missing");
74
+ },
75
+ acceptAllPending() {
76
+ this.$emit("accept-all-pending-annotations");
77
+ },
78
+ },
79
+ };
80
+ </script>
81
+
82
+ <style
83
+ scoped
84
+ lang="scss"
85
+ src="../../assets/scss/document_annotations.scss"
86
+ ></style>
@@ -105,9 +105,20 @@ 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
+ "publicView",
113
+ "documentIsReviewed",
114
+ ]),
109
115
  ...mapGetters("category", ["category", "projectHasSingleCategory"]),
110
116
  ...mapGetters("document", ["categorizationIsConfirmed"]),
117
+
118
+ singleCategoryInProject() {
119
+ // if only 1 category in the project, we don't enable the dropdown
120
+ return this.categories && this.categories.length === 1;
121
+ },
111
122
  },
112
123
  watch: {
113
124
  selectedDocument(newValue) {
@@ -127,6 +138,13 @@ export default {
127
138
  show(newValue) {
128
139
  this.$store.dispatch("display/setCategorizeModalIsActive", newValue);
129
140
  },
141
+ categorizeModalIsActive(newValue) {
142
+ // Show modal after split suggestion modal
143
+ // if no category confirmed
144
+ if (newValue) {
145
+ this.show = newValue && !this.categorizationIsConfirmed;
146
+ }
147
+ },
130
148
  },
131
149
  mounted() {
132
150
  this.setDocumentValues();
@@ -159,7 +177,15 @@ export default {
159
177
  }
160
178
 
161
179
  this.selectedCategory = category;
162
- this.show = !this.categorizationIsConfirmed;
180
+ this.documentCategory = category;
181
+
182
+ // By default, if the document has no category, the categorize modal is shown
183
+ // But if there is a category, we also need to check if there are splitting suggestions or not
184
+ this.show =
185
+ (!category || (category && !this.splittingSuggestions)) &&
186
+ !this.categorizationIsConfirmed &&
187
+ !this.publicView &&
188
+ !this.documentIsReviewed;
163
189
  }
164
190
  },
165
191
  canCloseModal() {
@@ -14,20 +14,43 @@
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="
19
+ !publicView &&
20
+ !documentIsReviewed &&
21
+ !waitingForSplittingConfirmation(selectedDocument)
22
+ "
23
+ />
18
24
  <EmptyState />
19
25
  </div>
20
26
 
21
- <div
22
- v-else
23
- :class="[
24
- 'annotation-set-list',
25
- missingAnnotations.length && !publicView && 'showing-rejected',
26
- ]"
27
- >
28
- <CategorizeModal v-if="!publicView" />
27
+ <div v-else :class="['annotation-set-list']">
28
+ <CategorizeModal v-if="!publicView || !documentIsReviewed" />
29
29
  <div
30
- v-for="(annotationSet, indexGroup) in annotationSets"
30
+ v-if="Object.entries(annotationSetsInTable()).length > 0"
31
+ class="annotation-set-group"
32
+ >
33
+ <div class="label-set-header">
34
+ <div class="label-set-name">{{ $t("table") }}</div>
35
+ </div>
36
+ <div
37
+ v-for="(tableSet, index) in Object.values(annotationSetsInTable())"
38
+ :key="index"
39
+ class="ann-set-table"
40
+ @click="openAnnotationSetTable(tableSet)"
41
+ >
42
+ <div class="ann-set-table-icon">
43
+ <GridIcon /><span class="ann-set-number">{{
44
+ tableSet.length
45
+ }}</span>
46
+ </div>
47
+ <span class="ann-set-table-label-set-name">{{
48
+ tableSet[0].label_set.name
49
+ }}</span>
50
+ </div>
51
+ </div>
52
+ <div
53
+ v-for="(annotationSet, indexGroup) in annotationSetsToShowInList()"
31
54
  :key="indexGroup"
32
55
  class="annotation-set-group"
33
56
  >
@@ -40,18 +63,25 @@
40
63
  }}
41
64
  </div>
42
65
  <div class="labelset-action-buttons">
43
- <ActionButtons
44
- :reject-all-empty-btn="true"
45
- :annotation-set="annotationSet"
46
- :accept-all-btn="true"
47
- @reject-all-empty="
48
- rejectMissingAnnotations(null, null, annotationSet, true)
66
+ <AnnotationSetActionButtons
67
+ :number-of-empty-labels-in-annotation-set="
68
+ emptyLabelsLength(annotationSet)
69
+ "
70
+ :number-of-pending-annotations-in-annotation-set="
71
+ annotationsWithPendingReviewLength(annotationSet)
72
+ "
73
+ @mark-all-empty-missing="
74
+ markAnnotationsAsMissing(null, null, annotationSet, true)
49
75
  "
50
- @hover-annotation-set-to-reject="
51
- handleHoverAnnotationSet(annotationSet, 'reject')
76
+ @hover-annotation-set-to-mark-missing="
77
+ handleHoverAnnotationSet(annotationSet, 'missing')
78
+ "
79
+ @leave-annotation-set-to-mark-missing="
80
+ handleHoverAnnotationSet(null)
81
+ "
82
+ @accept-all-pending-annotations="
83
+ acceptPendingAnnotationsInAnnotationSet(annotationSet)
52
84
  "
53
- @leave-annotation-set-to-reject="handleHoverAnnotationSet(null)"
54
- @accept-group="acceptGroup(annotationSet)"
55
85
  @hover-annotation-set-to-accept="
56
86
  handleHoverAnnotationSet(annotationSet, 'accept')
57
87
  "
@@ -61,35 +91,28 @@
61
91
  </div>
62
92
 
63
93
  <div v-for="label in annotationSet.labels" :key="label.id">
64
- <div v-if="labelNotRejected(annotationSet, label)" class="labels">
94
+ <div class="labels">
65
95
  <DocumentLabel
66
96
  :label="label"
67
97
  :annotation-set="annotationSet"
68
98
  :index-group="indexGroup"
69
- @handle-reject="rejectMissingAnnotations"
99
+ @handle-missing-annotation="markAnnotationsAsMissing"
70
100
  />
71
101
  </div>
72
102
  </div>
73
103
  </div>
74
104
  </div>
75
-
76
- <div
77
- v-if="!publicView && missingAnnotations.length"
78
- class="rejected-labels-list"
79
- >
80
- <RejectedLabels :missing-annotations="missingAnnotations" />
81
- </div>
82
105
  </div>
83
106
  </template>
84
107
  <script>
85
108
  import { mapGetters, mapState } from "vuex";
86
109
  import EmptyState from "./EmptyState";
87
110
  import ExtractingData from "./ExtractingData";
88
- import ActionButtons from "./ActionButtons";
111
+ import AnnotationSetActionButtons from "./AnnotationSetActionButtons";
89
112
  import DocumentLabel from "./DocumentLabel";
90
- import RejectedLabels from "./RejectedLabels";
91
113
  import LoadingAnnotations from "./LoadingAnnotations";
92
114
  import CategorizeModal from "./CategorizeModal";
115
+ import GridIcon from "../../assets/images/GridIcon";
93
116
 
94
117
  /**
95
118
  * This component loads all annotations for one document
@@ -98,11 +121,11 @@ export default {
98
121
  components: {
99
122
  EmptyState,
100
123
  ExtractingData,
101
- ActionButtons,
124
+ AnnotationSetActionButtons,
102
125
  DocumentLabel,
103
- RejectedLabels,
104
126
  LoadingAnnotations,
105
127
  CategorizeModal,
128
+ GridIcon,
106
129
  },
107
130
  data() {
108
131
  return {
@@ -112,6 +135,7 @@ export default {
112
135
  };
113
136
  },
114
137
  computed: {
138
+ ...mapState("display", ["showAnnSetTable"]),
115
139
  ...mapState("document", [
116
140
  "documentId",
117
141
  "recalculatingAnnotations",
@@ -123,9 +147,18 @@ export default {
123
147
  "loading",
124
148
  "labels",
125
149
  "selectedDocument",
150
+ "splittingSuggestions",
151
+ "documentIsReviewed",
126
152
  ]),
127
153
  ...mapGetters("category", ["category"]),
128
- ...mapGetters("document", ["numberOfAnnotationSetGroup"]),
154
+ ...mapGetters("document", [
155
+ "numberOfAnnotationSetGroup",
156
+ "emptyLabelsLength",
157
+ "annotationsWithPendingReviewLength",
158
+ "waitingForSplittingConfirmation",
159
+ "annotationSetsToShowInList",
160
+ "annotationSetsInTable",
161
+ ]),
129
162
  isAnnotationBeingEdited() {
130
163
  return this.editAnnotation && this.editAnnotation.id;
131
164
  },
@@ -151,19 +184,6 @@ export default {
151
184
  window.removeEventListener("keydown", this.keyDownHandler);
152
185
  },
153
186
  methods: {
154
- showMissingAnnotations() {
155
- if (
156
- (this.publicView &&
157
- this.selectedDocument &&
158
- this.selectedDocument.is_reviewed) ||
159
- !this.publicView
160
- ) {
161
- return true;
162
- } else {
163
- return false;
164
- }
165
- },
166
-
167
187
  focusOnNextAnnotation() {
168
188
  const annotations = Array.from(
169
189
  document.getElementsByClassName("annotation-value")
@@ -211,7 +231,7 @@ export default {
211
231
 
212
232
  keyDownHandler(event) {
213
233
  // only allow keyboard navigation if we are not in public view mode
214
- if (this.publicView) return;
234
+ if (this.publicView || this.documentIsReviewed) return;
215
235
 
216
236
  // get out of edit mode and navigation
217
237
  if (event.key === "Escape") {
@@ -263,6 +283,18 @@ export default {
263
283
  this.count = currentAnnIndex + 1;
264
284
  }
265
285
 
286
+ // Skip missing annotations
287
+ if (this.focusedAnnotationIsMarkedAsMissing(annotations, this.count)) {
288
+ for (let i = this.count; i < annotations.length; i++) {
289
+ if (!this.focusedAnnotationIsMarkedAsMissing(annotations, i)) {
290
+ break;
291
+ }
292
+ this.count++;
293
+ }
294
+ }
295
+
296
+ if (!annotations[this.count]) return;
297
+
266
298
  annotations[this.count].click();
267
299
 
268
300
  // scroll to current annotation if not empty
@@ -285,6 +317,18 @@ export default {
285
317
  this.count = currentAnnIndex - 1;
286
318
  }
287
319
 
320
+ // Skip missing annotations
321
+ if (this.focusedAnnotationIsMarkedAsMissing(annotations, this.count)) {
322
+ for (let i = this.count; i < annotations.length; i--) {
323
+ if (!this.focusedAnnotationIsMarkedAsMissing(annotations, i)) {
324
+ break;
325
+ }
326
+ this.count--;
327
+ }
328
+ }
329
+
330
+ if (!annotations[this.count]) return;
331
+
288
332
  annotations[this.count].click();
289
333
 
290
334
  // scroll to current annotation if not empty
@@ -311,9 +355,9 @@ export default {
311
355
  annotations[currentAnnIndex].className.includes("label-empty") &&
312
356
  annotations[currentAnnIndex].className.includes("clicked")
313
357
  ) {
314
- // Reject annotation
358
+ // Mark annotation as missing
315
359
  if (this.editAnnotation.id === annotations[currentAnnIndex].id) {
316
- this.rejectMissingAnnotations();
360
+ this.markAnnotationsAsMissing();
317
361
  }
318
362
  this.jumpToNextAnnotation = true;
319
363
  } else {
@@ -322,45 +366,17 @@ export default {
322
366
  }
323
367
  },
324
368
 
325
- labelNotRejected(annotationSet, label) {
326
- // Check if the combined label and label set have been rejected
327
- // or if the document is in public mode
328
- if (
329
- this.missingAnnotations.length === 0 ||
330
- !this.showMissingAnnotations()
331
- ) {
332
- return true;
333
- } else {
334
- let found;
335
-
336
- if (annotationSet && annotationSet.id) {
337
- found = this.missingAnnotations.filter(
338
- (el) =>
339
- el.label === label.id && el.annotation_set === annotationSet.id
340
- );
341
- } else {
342
- found = this.missingAnnotations.filter(
343
- (el) =>
344
- el.label === label.id &&
345
- el.label_set === annotationSet.label_set.id
346
- );
347
- }
348
-
349
- if (found.length !== 0) {
350
- return false;
351
- } else {
352
- return true;
353
- }
354
- }
369
+ focusedAnnotationIsMarkedAsMissing(annotations, index) {
370
+ return annotations[index].classList.value.includes("missing-annotation");
355
371
  },
356
372
 
357
- rejectMissingAnnotations(label, labelSet, annotationSet, rejectAll) {
358
- let rejected;
373
+ markAnnotationsAsMissing(label, labelSet, annotationSet, markAllMissing) {
374
+ let missing;
359
375
 
360
- if (label && labelSet && !rejectAll) {
361
- // if single rejection is triggered by clicking the button
376
+ if (label && labelSet && !markAllMissing) {
377
+ // if annotation is marked as missing by clicking the button
362
378
 
363
- rejected = [
379
+ missing = [
364
380
  {
365
381
  document: parseInt(this.documentId),
366
382
  label: label,
@@ -369,24 +385,24 @@ export default {
369
385
  },
370
386
  ];
371
387
  } else if (this.editAnnotation && this.editAnnotation.id !== null) {
372
- // if single rejection is triggered from "delete" key
388
+ // iif annotation is marked as missing from "delete" key
373
389
 
374
- rejected = {
390
+ missing = {
375
391
  document: parseInt(this.documentId),
376
392
  label: this.editAnnotation.label,
377
393
  label_set: this.editAnnotation.labelSet,
378
394
  annotation_set: this.editAnnotation.annotationSet,
379
395
  };
380
- } else if (annotationSet && rejectAll) {
381
- // reject all labels in annotation set
396
+ } else if (annotationSet && markAllMissing) {
397
+ // mark all annotations as missing in annotation set
382
398
 
383
399
  const allEmptyLabels = annotationSet.labels.filter(
384
400
  (label) => label.annotations.length === 0
385
401
  );
386
402
 
387
- // Check if any of the empty annotations was already rejected individually
403
+ // Check if any of the empty annotations was already marked as missing individually
388
404
  // and remove them
389
- const toReject = [];
405
+ const toMarkAsMissing = [];
390
406
 
391
407
  allEmptyLabels.map((label) => {
392
408
  const found = this.missingAnnotations.find(
@@ -397,11 +413,11 @@ export default {
397
413
  );
398
414
 
399
415
  if (!found) {
400
- toReject.push(label);
416
+ toMarkAsMissing.push(label);
401
417
  }
402
418
  });
403
419
 
404
- rejected = toReject.map((label) => {
420
+ missing = toMarkAsMissing.map((label) => {
405
421
  return {
406
422
  document: parseInt(this.documentId),
407
423
  label: label.id,
@@ -411,10 +427,10 @@ export default {
411
427
  });
412
428
  }
413
429
 
414
- this.$store.dispatch("document/setRejectedMissingAnnotations", rejected);
430
+ this.$store.dispatch("document/setAnnotationsMarkedAsMissing", missing);
415
431
 
416
432
  this.$store
417
- .dispatch("document/addMissingAnnotations", rejected)
433
+ .dispatch("document/addMissingAnnotations", missing)
418
434
  .then((response) => {
419
435
  if (response) {
420
436
  this.jumpToNextAnnotation = true;
@@ -430,7 +446,7 @@ export default {
430
446
  });
431
447
  })
432
448
  .finally(() => {
433
- this.$store.dispatch("document/setRejectedMissingAnnotations", null);
449
+ this.$store.dispatch("document/setAnnotationsMarkedAsMissing", null);
434
450
  });
435
451
  },
436
452
 
@@ -449,7 +465,7 @@ export default {
449
465
  this.$store.dispatch("document/setHoveredAnnotationSet", hovered);
450
466
  },
451
467
 
452
- acceptGroup(annotationSet) {
468
+ acceptPendingAnnotationsInAnnotationSet(annotationSet) {
453
469
  const annotationsToAccept = [];
454
470
 
455
471
  annotationSet.labels.map((label) => {
@@ -480,6 +496,14 @@ export default {
480
496
  });
481
497
  }
482
498
  },
499
+
500
+ openAnnotationSetTable(tableSet) {
501
+ if (this.showAnnSetTable && this.showAnnSetTable === tableSet) {
502
+ this.$store.dispatch("display/toggleAnnSetTable", tableSet);
503
+ } else {
504
+ this.$store.dispatch("display/showAnnSetTable", tableSet);
505
+ }
506
+ },
483
507
  },
484
508
  };
485
509
  </script>
@@ -1,7 +1,7 @@
1
1
  <template>
2
2
  <div class="empty-annotation">
3
3
  <span
4
- v-if="!publicView"
4
+ v-if="!publicView && !documentIsReviewed"
5
5
  :id="emptyAnnotationId()"
6
6
  ref="emptyAnnotation"
7
7
  :class="[
@@ -12,6 +12,7 @@
12
12
  'error-editing',
13
13
  isEmptyAnnotationEditable() ? '' : 'label-empty',
14
14
  isAnnotationBeingEdited() && 'clicked',
15
+ annotationIsNotFound(annotationSet, label) && 'missing-annotation',
15
16
  ]"
16
17
  :contenteditable="isEmptyAnnotationEditable()"
17
18
  @keypress.enter="saveEmptyAnnotationChanges"
@@ -21,6 +22,12 @@
21
22
  <span v-if="span && span.offset_string && isEmptyAnnotationEditable()">
22
23
  {{ span.offset_string }}
23
24
  </span>
25
+ <span
26
+ v-else-if="annotationIsNotFound(annotationSet, label)"
27
+ class="not-found-text"
28
+ >
29
+ {{ $t("missing_from_document") }}
30
+ </span>
24
31
  <span v-else>
25
32
  {{ $t("no_data_found") }}
26
33
  </span>
@@ -68,6 +75,7 @@ export default {
68
75
  ...mapGetters("document", [
69
76
  "isAnnotationInEditMode",
70
77
  "getTextFromEntities",
78
+ "annotationIsNotFound",
71
79
  ]),
72
80
  ...mapGetters("selection", ["isValueArray"]),
73
81
  ...mapState("selection", ["spanSelection", "elementSelected"]),
@@ -76,6 +84,7 @@ export default {
76
84
  "publicView",
77
85
  "selectedEntities",
78
86
  "showActionError",
87
+ "documentIsReviewed",
79
88
  ]),
80
89
  },
81
90
  watch: {
@@ -133,6 +142,7 @@ export default {
133
142
  }
134
143
  },
135
144
  },
145
+
136
146
  methods: {
137
147
  emptyAnnotationId() {
138
148
  if (!this.annotationSet || !this.label) return;
@@ -147,10 +157,16 @@ export default {
147
157
  return this.isAnnotationInEditMode(this.emptyAnnotationId());
148
158
  },
149
159
  handleEditEmptyAnnotation() {
150
- if (this.publicView) return;
160
+ if (
161
+ this.publicView ||
162
+ this.documentIsReviewed ||
163
+ this.annotationIsNotFound(this.annotationSet, this.label)
164
+ )
165
+ return;
151
166
 
152
167
  if (
153
168
  !this.publicView &&
169
+ !this.documentIsReviewed &&
154
170
  !this.isLoading &&
155
171
  this.elementSelected !== this.emptyAnnotationId()
156
172
  ) {
@@ -190,8 +206,8 @@ export default {
190
206
  this.elementSelected === this.emptyAnnotationId() && !this.isLoading
191
207
  );
192
208
  } else if (
193
- this.spanSelection &&
194
- this.spanSelection[this.spanIndex] === 0
209
+ (this.spanSelection && this.spanSelection[this.spanIndex] === 0) ||
210
+ this.annotationIsNotFound(this.annotationSet, this.label)
195
211
  ) {
196
212
  return false;
197
213
  } else {
@@ -205,7 +221,7 @@ export default {
205
221
  }
206
222
  },
207
223
  saveEmptyAnnotationChanges(event) {
208
- if (this.publicView) return;
224
+ if (this.publicView || this.documentIsReviewed) return;
209
225
 
210
226
  if (event) {
211
227
  event.preventDefault();
@@ -1,7 +1,7 @@
1
1
  <template>
2
2
  <div class="data-extraction-container">
3
3
  <div class="loading-container">
4
- <ActionButtons
4
+ <AnnotationActionButtons
5
5
  :is-loading="true"
6
6
  :save-btn="false"
7
7
  :cancel-btn="false"
@@ -19,11 +19,11 @@
19
19
  </div>
20
20
  </template>
21
21
  <script>
22
- import ActionButtons from "./ActionButtons";
22
+ import AnnotationActionButtons from "./AnnotationActionButtons";
23
23
 
24
24
  export default {
25
25
  name: "ExtractingData",
26
- components: { ActionButtons }
26
+ components: { AnnotationActionButtons },
27
27
  };
28
28
  </script>
29
29
  <style scoped lang="scss" src="../../assets/scss/extracting_data.scss"></style>
@@ -3,6 +3,5 @@ export { default as AnnotationContent } from "./AnnotationContent";
3
3
  export { default as EmptyAnnotation } from "./EmptyAnnotation";
4
4
  export { default as DocumentLabel } from "./DocumentLabel";
5
5
  export { default as AnnotationDetails } from "./AnnotationDetails";
6
- export { default as RejectedLabels } from "./RejectedLabels";
7
6
  export { default as ChooseLabelSetModal } from "./ChooseLabelSetModal";
8
7
  export { default as AnnotationRow } from "./AnnotationRow";
@@ -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']">
@@ -102,6 +98,18 @@ export default {
102
98
  ...mapState("document", ["selectedDocument", "annotations"]),
103
99
  ...mapState("category", ["categories"]),
104
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
+ },
105
113
  },
106
114
  watch: {
107
115
  categories(newValue) {