@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
@@ -1,13 +1,13 @@
1
1
  <template>
2
- <div class="app-container">
3
- <DocumentsList />
2
+ <div class="dv-ui-app-container dv-ui-theme">
3
+ <DocumentsList v-if="showDocumentsList" />
4
4
  <DocumentDashboard />
5
5
  </div>
6
6
  </template>
7
7
  <script>
8
8
  import DocumentDashboard from "./DocumentDashboard";
9
9
  import { DocumentsList } from "./DocumentsList";
10
- import { changeDocumentURL, getURLQueryParam } from "../utils/utils";
10
+ import { getURLQueryParam, getURLPath } from "../utils/utils";
11
11
  import API from "../api";
12
12
 
13
13
  export default {
@@ -49,6 +49,8 @@ export default {
49
49
  documentId() {
50
50
  if (getURLQueryParam("document")) {
51
51
  return getURLQueryParam("document");
52
+ } else if (getURLPath("docs")) {
53
+ return getURLPath("docs");
52
54
  } else if (process.env.VUE_APP_DOCUMENT_ID) {
53
55
  return process.env.VUE_APP_DOCUMENT_ID;
54
56
  } else if (this.document) {
@@ -86,6 +88,9 @@ export default {
86
88
  return true;
87
89
  }
88
90
  },
91
+ showDocumentsList() {
92
+ return process.env.VUE_APP_SHOW_DOCUMENTS_LIST;
93
+ },
89
94
  },
90
95
  created() {
91
96
  // locale config
@@ -106,6 +111,7 @@ export default {
106
111
  });
107
112
 
108
113
  // Add observer for class added to HTML tag when Buefy modals are mounted
114
+ // TODO: check defaultModalScroll property in Buefy constructor https://buefy.org/documentation/constructor-options
109
115
  const htmlTag = document.documentElement;
110
116
  const observer = new MutationObserver(function (mutations) {
111
117
  mutations.forEach(function (mutation) {
@@ -0,0 +1,171 @@
1
+ <template>
2
+ <div class="action-buttons">
3
+ <!-- loading -->
4
+ <div v-if="isLoading">
5
+ <b-notification :closable="false" class="loading-background">
6
+ <b-loading :active="isLoading" :is-full-page="false">
7
+ <b-icon icon="spinner" class="fa-spin loading-icon-size spinner" />
8
+ </b-loading>
9
+ </b-notification>
10
+ </div>
11
+
12
+ <!-- save button -->
13
+ <b-button
14
+ v-if="saveBtn && !isLoading && !publicView && !documentIsReviewed"
15
+ :class="[
16
+ 'annotation-save-btn text-btn',
17
+ actionBar && 'action-bar-save-btn',
18
+ actionBar ? 'tertiary-button' : 'primary-button',
19
+ ]"
20
+ type="is-primary"
21
+ @click.stop="save"
22
+ >
23
+ {{ $t("save") }}
24
+ </b-button>
25
+
26
+ <!-- cancel button -->
27
+ <b-button
28
+ v-if="cancelBtn && !isLoading && !documentIsReviewed"
29
+ class="is-small annotation-cancel-btn"
30
+ icon-left="xmark"
31
+ @click.stop="cancel"
32
+ />
33
+
34
+ <!-- decline button -->
35
+ <div
36
+ v-if="
37
+ declineBtn &&
38
+ !isLoading &&
39
+ !saveBtn &&
40
+ !cancelBtn &&
41
+ !publicView &&
42
+ !documentIsReviewed
43
+ "
44
+ class="missing-decline-button-container"
45
+ >
46
+ <b-button
47
+ type="is-ghost"
48
+ class="missing-decline-btn decline-btn"
49
+ @click.stop="decline"
50
+ >
51
+ {{ $t("decline") }}
52
+ </b-button>
53
+ </div>
54
+
55
+ <!-- accept button -->
56
+ <b-button
57
+ v-if="
58
+ acceptBtn &&
59
+ !isLoading &&
60
+ !saveBtn &&
61
+ !cancelBtn &&
62
+ !publicView &&
63
+ !documentIsReviewed
64
+ "
65
+ class="annotation-accept-btn primary-button"
66
+ type="is-primary"
67
+ @click.stop="accept"
68
+ >
69
+ {{ $t("accept") }}
70
+ </b-button>
71
+
72
+ <!-- missing button -->
73
+ <div
74
+ v-if="
75
+ showMissingBtn &&
76
+ !isLoading &&
77
+ !cancelBtn &&
78
+ !saveBtn &&
79
+ !publicView &&
80
+ !documentIsReviewed
81
+ "
82
+ class="missing-decline-button-container"
83
+ >
84
+ <b-button
85
+ type="is-ghost"
86
+ class="missing-decline-btn missing-btn"
87
+ @click.stop="markAsMissing"
88
+ >
89
+ {{ $t("missing_annotation") }}
90
+ </b-button>
91
+ </div>
92
+
93
+ <!-- Restore not found annotations -->
94
+ <b-button
95
+ v-if="restoreBtn && !isLoading && !publicView && !documentIsReviewed"
96
+ class="restore-btn"
97
+ type="is-primary"
98
+ @click.stop="restore"
99
+ >
100
+ {{ $t("restore") }}
101
+ </b-button>
102
+ </div>
103
+ </template>
104
+ <script>
105
+ /* Component for showing actions for each annotation row */
106
+ import { mapState } from "vuex";
107
+ export default {
108
+ name: "AnnotationActionButtons",
109
+ props: {
110
+ saveBtn: {
111
+ type: Boolean,
112
+ },
113
+ cancelBtn: {
114
+ type: Boolean,
115
+ },
116
+ showMissingBtn: {
117
+ type: Boolean,
118
+ },
119
+ isLoading: {
120
+ type: Boolean,
121
+ },
122
+ acceptBtn: {
123
+ type: Boolean,
124
+ },
125
+ declineBtn: {
126
+ type: Boolean,
127
+ },
128
+ actionBar: {
129
+ type: Boolean,
130
+ required: false,
131
+ },
132
+ restoreBtn: {
133
+ type: Boolean,
134
+ required: false,
135
+ },
136
+ },
137
+ computed: {
138
+ ...mapState("document", [
139
+ "publicView",
140
+ "missingAnnotations",
141
+ "documentIsReviewed",
142
+ ]),
143
+ },
144
+ methods: {
145
+ save() {
146
+ this.$emit("save");
147
+ },
148
+ cancel() {
149
+ this.$emit("cancel");
150
+ },
151
+ accept() {
152
+ this.$emit("accept");
153
+ },
154
+ markAsMissing() {
155
+ this.$emit("mark-as-missing");
156
+ },
157
+ decline() {
158
+ this.$emit("decline");
159
+ },
160
+ restore() {
161
+ this.$emit("restore");
162
+ },
163
+ },
164
+ };
165
+ </script>
166
+
167
+ <style
168
+ scoped
169
+ lang="scss"
170
+ src="../../assets/scss/document_annotations.scss"
171
+ ></style>
@@ -1,7 +1,7 @@
1
1
  <template>
2
2
  <div :id="annotation.id" ref="annotation" class="annotation">
3
3
  <span
4
- v-if="!publicView"
4
+ v-if="!publicView || !documentIsReviewed"
5
5
  :id="annotation.id"
6
6
  ref="contentEditable"
7
7
  :class="[
@@ -82,6 +82,7 @@ export default {
82
82
  "newAcceptedAnnotations",
83
83
  "selectedEntities",
84
84
  "showActionError",
85
+ "documentIsReviewed",
85
86
  ]),
86
87
  annotationText() {
87
88
  if (this.isAnnotationBeingEdited) {
@@ -155,7 +156,7 @@ export default {
155
156
  this.$refs.contentEditable.textContent = text;
156
157
  },
157
158
  handleEditAnnotation(event) {
158
- if (this.publicView) return;
159
+ if (this.publicView || this.documentIsReviewed) return;
159
160
 
160
161
  if (event) {
161
162
  event.preventDefault();
@@ -163,6 +164,7 @@ export default {
163
164
 
164
165
  if (
165
166
  !this.publicView &&
167
+ !this.documentIsReviewed &&
166
168
  !this.isAnnotationBeingEdited &&
167
169
  !this.isLoading
168
170
  ) {
@@ -226,7 +228,7 @@ export default {
226
228
  event.preventDefault();
227
229
  },
228
230
  saveAnnotationChanges(event) {
229
- if (this.publicView) return;
231
+ if (this.publicView || this.documentIsReviewed) return;
230
232
 
231
233
  if (event) {
232
234
  event.preventDefault();
@@ -1,10 +1,10 @@
1
1
  <template>
2
2
  <b-tooltip
3
3
  :animated="false"
4
- position="is-bottom"
5
- class="left-aligned annotation-details"
4
+ :position="fromTable ? 'is-top' : 'is-bottom'"
5
+ :class="[!fromTable && 'left-aligned', 'annotation-details']"
6
6
  >
7
- <div class="label-icon">
7
+ <div :class="['label-icon', fromTable && 'is-small']">
8
8
  <div v-if="created(annotation) || edited(annotation)">
9
9
  <div
10
10
  v-if="accepted(annotation)"
@@ -28,7 +28,13 @@
28
28
  </div>
29
29
  </div>
30
30
  <div
31
- v-else-if="notFound(annotation)"
31
+ v-else-if="annotationIsNotFound(annotationSet, label)"
32
+ :class="['annotation-details-icon', animate ? 'animated-ripple' : '']"
33
+ >
34
+ <NotFoundIcon />
35
+ </div>
36
+ <div
37
+ v-else-if="notExtracted(annotation)"
32
38
  :class="[
33
39
  'annotation-details-icon',
34
40
  animate ? 'animated-ripple' : '',
@@ -100,7 +106,7 @@
100
106
  </div>
101
107
  </div>
102
108
  <div
103
- v-else-if="notFound(annotation)"
109
+ v-else-if="notExtracted(annotation)"
104
110
  :class="[
105
111
  'annotation-details-icon',
106
112
  animate ? 'animated-ripple' : '',
@@ -143,6 +149,7 @@ import AcceptedCheckMark from "../../assets/images/AcceptedCheckMark";
143
149
  import QuestionMark from "../../assets/images/QuestionMark";
144
150
  import AcceptedUser from "../../assets/images/AcceptedUser";
145
151
  import UserIcon from "../../assets/images/UserIcon";
152
+ import NotFoundIcon from "../../assets/images/NotFoundIcon";
146
153
 
147
154
  export default {
148
155
  name: "AnnotationDetails",
@@ -152,6 +159,7 @@ export default {
152
159
  AcceptedCheckMark,
153
160
  AcceptedUser,
154
161
  UserIcon,
162
+ NotFoundIcon,
155
163
  },
156
164
  props: {
157
165
  description: {
@@ -163,6 +171,18 @@ export default {
163
171
  type: Object,
164
172
  default: null,
165
173
  },
174
+ annotationSet: {
175
+ type: Object,
176
+ default: null,
177
+ },
178
+ label: {
179
+ type: Object,
180
+ default: null,
181
+ },
182
+ fromTable: {
183
+ type: Boolean,
184
+ default: false,
185
+ },
166
186
  },
167
187
  data() {
168
188
  return {
@@ -172,11 +192,12 @@ export default {
172
192
  computed: {
173
193
  ...mapGetters("document", [
174
194
  "confidence",
175
- "notFound",
195
+ "notExtracted",
176
196
  "created",
177
197
  "edited",
178
198
  "accepted",
179
199
  "getUser",
200
+ "annotationIsNotFound",
180
201
  ]),
181
202
  },
182
203
  watch: {
@@ -200,7 +221,7 @@ export default {
200
221
  },
201
222
  methods: {
202
223
  getText() {
203
- if (this.notFound(this.annotation)) {
224
+ if (this.notExtracted(this.annotation)) {
204
225
  return this.$t("not_found_in_document");
205
226
  } else if (this.created(this.annotation)) {
206
227
  return this.getUser(this.annotation)
@@ -3,19 +3,10 @@
3
3
  :class="[
4
4
  'annotation-row',
5
5
  isSelected && 'selected',
6
+ hoverEmptyLabelRows && 'hovered-empty-labels',
7
+ hoverPendingAnnotationRows && 'hovered-pending-annotations',
8
+ annotationIsNotFound(annotationSet, label) && 'missing',
6
9
  isAnnotationInEditMode(annotationId()) && 'editing',
7
- hoveredAnnotationSet &&
8
- hoveredAnnotationSet.type == 'reject' &&
9
- annotationSet.id === hoveredAnnotationSet.annotationSet.id &&
10
- annotationSet.label_set.id ===
11
- hoveredAnnotationSet.annotationSet.label_set.id &&
12
- hoveredEmptyLabels() === label.id &&
13
- 'hovered-empty-labels',
14
- hoveredAnnotationSet &&
15
- hoveredAnnotationSet.type == 'accept' &&
16
- annotation &&
17
- hoveredPendingAnnotations() === annotation.id &&
18
- 'hovered-pending-annotations',
19
10
  ]"
20
11
  @click="onAnnotationClick"
21
12
  @mouseover="hoveredAnnotation = annotationId()"
@@ -26,11 +17,23 @@
26
17
  @mouseenter="onAnnotationHoverEnter(defaultSpan)"
27
18
  @mouseleave="onAnnotationHoverLeave"
28
19
  >
29
- <AnnotationDetails
30
- :description="label.description"
31
- :annotation="annotation"
32
- />
33
- <div class="label-name">
20
+ <div class="annotation-icon">
21
+ <AnnotationDetails
22
+ :description="label.description"
23
+ :annotation="annotation"
24
+ :annotation-set="annotationSet"
25
+ :label="label"
26
+ :from-table="fromTable"
27
+ />
28
+ </div>
29
+
30
+ <div
31
+ v-if="showLabel"
32
+ :class="[
33
+ 'label-name',
34
+ annotationIsNotFound(annotationSet, label) && 'not-found-text',
35
+ ]"
36
+ >
34
37
  <span>{{ label.name }} </span>
35
38
  </div>
36
39
  </div>
@@ -81,19 +84,21 @@
81
84
  />
82
85
  </div>
83
86
  </div>
84
- <div class="buttons-container">
85
- <ActionButtons
87
+ <div v-if="showButtons" class="buttons-container">
88
+ <AnnotationActionButtons
86
89
  :cancel-btn="showCancelButton()"
87
- :accept-btn="showAcceptAndDeclineButtons()"
88
- :decline-btn="showAcceptAndDeclineButtons()"
89
- :show-reject="showRejectButton()"
90
+ :accept-btn="showAcceptButton()"
91
+ :decline-btn="showDeclineButton()"
92
+ :show-missing-btn="showMissingButton()"
90
93
  :save-btn="showSaveButton()"
94
+ :restore-btn="showRestoreButton()"
91
95
  :is-loading="isLoading"
92
- @reject="handleReject()"
96
+ @mark-as-missing="handleMissingAnnotation()"
93
97
  @save="handleSaveChanges()"
94
98
  @accept="handleSaveChanges()"
95
99
  @decline="handleSaveChanges(true)"
96
100
  @cancel="handleCancelButton()"
101
+ @restore="handleRestore()"
97
102
  />
98
103
  </div>
99
104
  </div>
@@ -104,7 +109,7 @@ import { mapGetters, mapState } from "vuex";
104
109
  import AnnotationDetails from "./AnnotationDetails";
105
110
  import AnnotationContent from "./AnnotationContent";
106
111
  import EmptyAnnotation from "./EmptyAnnotation";
107
- import ActionButtons from "./ActionButtons";
112
+ import AnnotationActionButtons from "./AnnotationActionButtons";
108
113
 
109
114
  export default {
110
115
  name: "AnnotationRow",
@@ -112,7 +117,7 @@ export default {
112
117
  AnnotationDetails,
113
118
  AnnotationContent,
114
119
  EmptyAnnotation,
115
- ActionButtons,
120
+ AnnotationActionButtons,
116
121
  },
117
122
  props: {
118
123
  annotationSet: {
@@ -127,6 +132,26 @@ export default {
127
132
  type: Object,
128
133
  default: null,
129
134
  },
135
+ showLabel: {
136
+ type: Boolean,
137
+ default: true,
138
+ },
139
+ showButtons: {
140
+ type: Boolean,
141
+ default: true,
142
+ },
143
+ isSmall: {
144
+ type: Boolean,
145
+ default: false,
146
+ },
147
+ showHover: {
148
+ type: Boolean,
149
+ default: true,
150
+ },
151
+ fromTable: {
152
+ type: Boolean,
153
+ default: false,
154
+ },
130
155
  },
131
156
  data() {
132
157
  return {
@@ -147,12 +172,17 @@ export default {
147
172
  "publicView",
148
173
  "selectedEntities",
149
174
  "newAcceptedAnnotations",
150
- "rejectedMissingAnnotations",
175
+ "annotationsMarkedAsMissing",
151
176
  "documentId",
152
177
  "showActionError",
178
+ "missingAnnotations",
179
+ "documentIsReviewed",
153
180
  ]),
154
181
  ...mapState("selection", ["spanSelection", "elementSelected"]),
155
- ...mapGetters("document", ["isAnnotationInEditMode"]),
182
+ ...mapGetters("document", [
183
+ "isAnnotationInEditMode",
184
+ "annotationIsNotFound",
185
+ ]),
156
186
  ...mapGetters("selection", ["isValueArray"]),
157
187
  defaultSpan() {
158
188
  if (
@@ -185,6 +215,25 @@ export default {
185
215
  )
186
216
  );
187
217
  },
218
+ hoverEmptyLabelRows() {
219
+ return (
220
+ this.hoveredAnnotationSet &&
221
+ this.hoveredAnnotationSet.type == "missing" &&
222
+ !this.annotationIsNotFound(this.annotationSet, this.label) &&
223
+ this.annotationSet.id === this.hoveredAnnotationSet.annotationSet.id &&
224
+ this.annotationSet.label_set.id ===
225
+ this.hoveredAnnotationSet.annotationSet.label_set.id &&
226
+ this.hoveredEmptyLabels() === this.label.id
227
+ );
228
+ },
229
+ hoverPendingAnnotationRows() {
230
+ return (
231
+ this.hoveredAnnotationSet &&
232
+ this.hoveredAnnotationSet.type == "accept" &&
233
+ this.annotation &&
234
+ this.hoveredPendingAnnotations() === this.annotation.id
235
+ );
236
+ },
188
237
  },
189
238
  watch: {
190
239
  sidebarAnnotationSelected(newSidebarAnnotationSelected) {
@@ -224,7 +273,7 @@ export default {
224
273
  this.isLoading = false;
225
274
  }
226
275
  },
227
- rejectedMissingAnnotations(newValue) {
276
+ annotationsMarkedAsMissing(newValue) {
228
277
  if (newValue) {
229
278
  this.enableLoading();
230
279
  } else {
@@ -256,7 +305,7 @@ export default {
256
305
  if (span) {
257
306
  this.$store.dispatch("document/setDocumentAnnotationSelected", {
258
307
  annotation: this.annotation,
259
- label: this.label,
308
+ label: this.fromTable ? null : this.label,
260
309
  span,
261
310
  scrollTo: false,
262
311
  });
@@ -266,11 +315,14 @@ export default {
266
315
  this.$store.dispatch("document/disableDocumentAnnotationSelected");
267
316
  },
268
317
  onAnnotationClick() {
318
+ if (!this.fromTable) {
319
+ this.$store.dispatch("display/showAnnSetTable", null);
320
+ }
269
321
  this.$store.dispatch("document/scrollToDocumentAnnotationSelected");
270
322
  },
271
323
  hoveredEmptyLabels() {
272
324
  // This method will change the style of the Empty Annotations in the same Label Set
273
- // when the "Reject all" button is hovered
325
+ // when the "mark all as missing" button is hovered
274
326
  if (!this.hoveredAnnotationSet) return;
275
327
 
276
328
  const labels = this.hoveredAnnotationSet.annotationSet.labels.map(
@@ -309,7 +361,7 @@ export default {
309
361
  return null;
310
362
  }
311
363
  },
312
- showAcceptAndDeclineButtons() {
364
+ showAcceptButton() {
313
365
  return (
314
366
  !this.isAnnotationInEditMode(this.annotationId()) &&
315
367
  this.annotation &&
@@ -317,11 +369,26 @@ export default {
317
369
  this.hoveredAnnotation === this.annotation.id
318
370
  );
319
371
  },
320
- showRejectButton() {
372
+ showDeclineButton() {
373
+ return (
374
+ !this.isAnnotationInEditMode(this.annotationId()) &&
375
+ this.annotation &&
376
+ this.hoveredAnnotation === this.annotation.id
377
+ );
378
+ },
379
+ showMissingButton() {
321
380
  return (
322
381
  this.hoveredAnnotation &&
323
382
  !this.isAnnotationInEditMode(this.annotationId()) &&
324
- !this.annotation
383
+ !this.annotation &&
384
+ !this.annotationIsNotFound(this.annotationSet, this.label)
385
+ );
386
+ },
387
+ showRestoreButton() {
388
+ return (
389
+ this.hoveredAnnotation &&
390
+ !this.isAnnotationInEditMode(this.annotationId()) &&
391
+ this.annotationIsNotFound(this.annotationSet, this.label)
325
392
  );
326
393
  },
327
394
  showCancelButton() {
@@ -353,13 +420,13 @@ export default {
353
420
  }
354
421
  }
355
422
  },
356
- handleReject() {
423
+ handleMissingAnnotation() {
357
424
  if (!this.label || !this.annotationSet) return;
358
425
 
359
426
  // will emit to the DocumentAnnotations component, where the method is handled
360
427
  // & dispatched to the store
361
428
  this.$parent.$emit(
362
- "handle-reject",
429
+ "handle-missing-annotation",
363
430
  this.label.id,
364
431
  this.annotationSet.label_set.id,
365
432
  this.annotationSet.id,
@@ -367,10 +434,11 @@ export default {
367
434
  );
368
435
  },
369
436
  handleSaveChanges(decline) {
370
- if (this.publicView) return;
437
+ if (this.publicView || this.documentIsReviewed) return;
371
438
 
372
439
  if (
373
- this.showAcceptAndDeclineButtons() ||
440
+ this.showAcceptButton() ||
441
+ this.showDeclineButton() ||
374
442
  this.isAnnotationInEditMode(
375
443
  this.annotationId(),
376
444
  this.editAnnotation.index
@@ -389,6 +457,30 @@ export default {
389
457
  this.saveEmptyAnnotationChanges();
390
458
  }
391
459
  },
460
+ handleRestore() {
461
+ this.isLoading = true;
462
+
463
+ const foundItem = this.missingAnnotations.find(
464
+ (item) =>
465
+ item.annotation_set === this.annotationSet.id &&
466
+ item.label === this.label.id &&
467
+ item.label_set === this.annotationSet.label_set.id
468
+ );
469
+
470
+ this.$store
471
+ .dispatch("document/deleteMissingAnnotation", foundItem.id)
472
+ .catch((error) => {
473
+ this.$store.dispatch("document/createErrorMessage", {
474
+ error,
475
+ serverErrorMessage: this.$t("server_error"),
476
+ defaultErrorMessage: this.$t("edit_error"),
477
+ });
478
+ })
479
+ .finally(() => {
480
+ this.isLoading = false;
481
+ this.closedTag = null;
482
+ });
483
+ },
392
484
  handleSaveAnnotationChanges(
393
485
  annotation,
394
486
  spanIndex,
@@ -575,15 +667,15 @@ export default {
575
667
 
576
668
  // Check for what empty annotations we want to show the loading
577
669
  // while waiting for it to be removed from the row
578
- if (!this.rejectedMissingAnnotations) {
670
+ if (!this.annotationsMarkedAsMissing) {
579
671
  this.isLoading = false;
580
672
  this.saveChanges = false;
581
673
  return;
582
674
  }
583
675
 
584
- if (this.rejectedMissingAnnotations.length > 0) {
585
- this.rejectedMissingAnnotations.map((annotation) => {
586
- // Check if the annotation set and label are rejected
676
+ if (this.annotationsMarkedAsMissing.length > 0) {
677
+ this.annotationsMarkedAsMissing.map((annotation) => {
678
+ // Check if the annotation set and label are marked as missing
587
679
  if (
588
680
  annotation.label_set === this.annotationSet.label_set.id &&
589
681
  annotation.annotation_set === this.annotationSet.id &&