@konfuzio/document-validation-ui 0.1.1

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 (131) hide show
  1. package/.eslintrc.js +11 -0
  2. package/.prettierrc.json +1 -0
  3. package/LICENSE +21 -0
  4. package/README.md +13 -0
  5. package/dist/css/app.0c8973f8.css +1 -0
  6. package/dist/css/chunk-vendors.053b6b6e.css +5 -0
  7. package/dist/favicon.ico +0 -0
  8. package/dist/index.html +1 -0
  9. package/dist/js/app.17fe48c4.js +2 -0
  10. package/dist/js/app.17fe48c4.js.map +1 -0
  11. package/dist/js/chunk-vendors.a48fca3f.js +47 -0
  12. package/dist/js/chunk-vendors.a48fca3f.js.map +1 -0
  13. package/jest.config.js +4 -0
  14. package/package.json +60 -0
  15. package/src/.DS_Store +0 -0
  16. package/src/api.js +49 -0
  17. package/src/assets/images/AcceptedCheckMark.vue +8 -0
  18. package/src/assets/images/AcceptedUser.vue +8 -0
  19. package/src/assets/images/ActionIcon.vue +60 -0
  20. package/src/assets/images/ArrowDownKey.vue +11 -0
  21. package/src/assets/images/ArrowUpKey.vue +11 -0
  22. package/src/assets/images/CategoryIconImg.vue +13 -0
  23. package/src/assets/images/CheckMark.vue +8 -0
  24. package/src/assets/images/EditDocIcon.vue +12 -0
  25. package/src/assets/images/EmptyStateImg.vue +129 -0
  26. package/src/assets/images/ErrorIcon.vue +28 -0
  27. package/src/assets/images/EyeIcon.vue +11 -0
  28. package/src/assets/images/FileNameNotSavedImage.vue +26 -0
  29. package/src/assets/images/FileNameSavedImage.vue +14 -0
  30. package/src/assets/images/FitZoomIcon.vue +16 -0
  31. package/src/assets/images/KeyboardIcon.vue +16 -0
  32. package/src/assets/images/MinusIcon.vue +13 -0
  33. package/src/assets/images/NotOptimizedIllustration.vue +651 -0
  34. package/src/assets/images/PlusIcon.vue +13 -0
  35. package/src/assets/images/QuestionMark.vue +12 -0
  36. package/src/assets/images/ServerImage.vue +63 -0
  37. package/src/assets/images/SplitLines.vue +18 -0
  38. package/src/assets/images/SplitZigZag.vue +16 -0
  39. package/src/assets/images/StatusImg.vue +14 -0
  40. package/src/assets/images/UserIcon.vue +8 -0
  41. package/src/assets/scss/annotation_details.scss +126 -0
  42. package/src/assets/scss/categorize_modal.scss +42 -0
  43. package/src/assets/scss/choose_label_set_modal.scss +62 -0
  44. package/src/assets/scss/document_action_bar.scss +37 -0
  45. package/src/assets/scss/document_annotations.scss +472 -0
  46. package/src/assets/scss/document_category.scss +80 -0
  47. package/src/assets/scss/document_dashboard.scss +47 -0
  48. package/src/assets/scss/document_dataset_status.scss +46 -0
  49. package/src/assets/scss/document_edit.scss +431 -0
  50. package/src/assets/scss/document_error.scss +81 -0
  51. package/src/assets/scss/document_handover.scss +200 -0
  52. package/src/assets/scss/document_name.scss +62 -0
  53. package/src/assets/scss/document_page.scss +8 -0
  54. package/src/assets/scss/document_thumbnails.scss +41 -0
  55. package/src/assets/scss/document_toolbar.scss +89 -0
  56. package/src/assets/scss/document_top_bar.scss +139 -0
  57. package/src/assets/scss/document_viewport_modal.scss +25 -0
  58. package/src/assets/scss/documents_list.scss +130 -0
  59. package/src/assets/scss/empty_state.scss +34 -0
  60. package/src/assets/scss/extracting_data.scss +35 -0
  61. package/src/assets/scss/imports.scss +1 -0
  62. package/src/assets/scss/main.scss +24 -0
  63. package/src/assets/scss/multi_ann_table_popup.scss +12 -0
  64. package/src/assets/scss/new_annotation.scss +86 -0
  65. package/src/assets/scss/scrolling_document.scss +19 -0
  66. package/src/assets/scss/variables.scss +696 -0
  67. package/src/components/App.vue +112 -0
  68. package/src/components/DocumentAnnotations/ActionButtons.vue +237 -0
  69. package/src/components/DocumentAnnotations/AnnotationContent.vue +249 -0
  70. package/src/components/DocumentAnnotations/AnnotationDetails.vue +292 -0
  71. package/src/components/DocumentAnnotations/AnnotationRow.vue +616 -0
  72. package/src/components/DocumentAnnotations/CategorizeModal.vue +159 -0
  73. package/src/components/DocumentAnnotations/ChooseLabelSetModal.vue +155 -0
  74. package/src/components/DocumentAnnotations/DocumentAnnotations.vue +502 -0
  75. package/src/components/DocumentAnnotations/DocumentLabel.vue +148 -0
  76. package/src/components/DocumentAnnotations/EmptyAnnotation.vue +222 -0
  77. package/src/components/DocumentAnnotations/EmptyState.vue +21 -0
  78. package/src/components/DocumentAnnotations/ExtractingData.vue +29 -0
  79. package/src/components/DocumentAnnotations/LoadingAnnotations.vue +43 -0
  80. package/src/components/DocumentAnnotations/LoadingLabels.vue +43 -0
  81. package/src/components/DocumentAnnotations/RejectedLabels.vue +96 -0
  82. package/src/components/DocumentAnnotations/index.js +8 -0
  83. package/src/components/DocumentCategory.vue +156 -0
  84. package/src/components/DocumentDashboard.vue +159 -0
  85. package/src/components/DocumentEdit/DocumentEdit.vue +279 -0
  86. package/src/components/DocumentEdit/EditPages.vue +213 -0
  87. package/src/components/DocumentEdit/EditSidebar.vue +118 -0
  88. package/src/components/DocumentEdit/SplitOverview.vue +182 -0
  89. package/src/components/DocumentEdit/index.js +4 -0
  90. package/src/components/DocumentError.vue +53 -0
  91. package/src/components/DocumentPage/ActionBar.vue +48 -0
  92. package/src/components/DocumentPage/BoxSelection.vue +149 -0
  93. package/src/components/DocumentPage/DocumentPage.vue +517 -0
  94. package/src/components/DocumentPage/DocumentToolbar.vue +145 -0
  95. package/src/components/DocumentPage/DummyPage.vue +53 -0
  96. package/src/components/DocumentPage/MultiAnnSelection.vue +302 -0
  97. package/src/components/DocumentPage/MultiAnnotationTablePopup.vue +253 -0
  98. package/src/components/DocumentPage/NewAnnotation.vue +283 -0
  99. package/src/components/DocumentPage/ScrollingDocument.vue +108 -0
  100. package/src/components/DocumentPage/ScrollingPage.vue +184 -0
  101. package/src/components/DocumentPage/index.js +5 -0
  102. package/src/components/DocumentThumbnails/DocumentThumbnails.vue +92 -0
  103. package/src/components/DocumentThumbnails/LoadingThumbnail.vue +25 -0
  104. package/src/components/DocumentThumbnails/index.js +1 -0
  105. package/src/components/DocumentTopBar/DocumentDatasetStatus.vue +103 -0
  106. package/src/components/DocumentTopBar/DocumentHandover.vue +202 -0
  107. package/src/components/DocumentTopBar/DocumentName.vue +224 -0
  108. package/src/components/DocumentTopBar/DocumentTopBar.vue +144 -0
  109. package/src/components/DocumentTopBar/DocumentTopBarButtons.vue +148 -0
  110. package/src/components/DocumentTopBar/KeyboardActionsDescription.vue +71 -0
  111. package/src/components/DocumentTopBar/index.js +5 -0
  112. package/src/components/DocumentsList/DocumentsList.vue +126 -0
  113. package/src/components/DocumentsList/index.js +1 -0
  114. package/src/components/ErrorMessage.vue +40 -0
  115. package/src/components/NotOptimizedViewportModal.vue +54 -0
  116. package/src/constants.js +4 -0
  117. package/src/directives/scroll.js +28 -0
  118. package/src/i18n.js +23 -0
  119. package/src/locales/de.json +114 -0
  120. package/src/locales/en.json +114 -0
  121. package/src/locales/es.json +113 -0
  122. package/src/main.js +87 -0
  123. package/src/store/category.js +193 -0
  124. package/src/store/display.js +238 -0
  125. package/src/store/document.js +1057 -0
  126. package/src/store/edit.js +210 -0
  127. package/src/store/index.js +22 -0
  128. package/src/store/project.js +95 -0
  129. package/src/store/selection.js +179 -0
  130. package/src/utils/utils.js +3 -0
  131. package/vue.config.js +13 -0
@@ -0,0 +1,616 @@
1
+ <template>
2
+ <div
3
+ :class="[
4
+ 'annotation-row',
5
+ isSelected && 'selected',
6
+ 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
+ ]"
20
+ @click="onAnnotationClick"
21
+ @mouseover="hoveredAnnotation = annotationId()"
22
+ @mouseleave="hoveredAnnotation = null"
23
+ >
24
+ <div
25
+ class="annotation-row-left"
26
+ @mouseenter="onAnnotationHoverEnter(defaultSpan)"
27
+ @mouseleave="onAnnotationHoverLeave"
28
+ >
29
+ <AnnotationDetails
30
+ :description="label.description"
31
+ :annotation="annotation"
32
+ />
33
+ <div class="label-name">
34
+ <span>{{ label.name }} </span>
35
+ </div>
36
+ </div>
37
+ <div class="annotation-row-right">
38
+ <div class="annotation-content">
39
+ <div v-if="annotation">
40
+ <div
41
+ v-for="(span, index) in spanForEditing
42
+ ? spanSelection
43
+ : annotation.span"
44
+ :key="index"
45
+ @mouseenter="onAnnotationHoverEnter(span)"
46
+ @mouseleave="onAnnotationHoverLeave"
47
+ >
48
+ <AnnotationContent
49
+ :annotation="annotation"
50
+ :span="span"
51
+ :span-index="index"
52
+ :label="label"
53
+ :annotation-set="annotationSet"
54
+ :is-hovered="hoveredAnnotation"
55
+ :save-changes="saveChanges"
56
+ @save-annotation-changes="handleSaveAnnotationChanges"
57
+ />
58
+ </div>
59
+ </div>
60
+ <div v-else>
61
+ <div v-if="spanSelection && isAnnotationInEditMode(annotationId())">
62
+ <EmptyAnnotation
63
+ v-for="(span, index) in spanSelection"
64
+ :key="index"
65
+ :span="span"
66
+ :span-index="index"
67
+ :label="label"
68
+ :annotation-set="annotationSet"
69
+ :is-hovered="hoveredAnnotation"
70
+ :save-changes="saveChanges"
71
+ @save-empty-annotation-changes="saveEmptyAnnotationChanges"
72
+ />
73
+ </div>
74
+ <EmptyAnnotation
75
+ v-else
76
+ :label="label"
77
+ :annotation-set="annotationSet"
78
+ :is-hovered="hoveredAnnotation"
79
+ :save-changes="saveChanges"
80
+ @save-empty-annotation-changes="saveEmptyAnnotationChanges"
81
+ />
82
+ </div>
83
+ </div>
84
+ <div class="buttons-container">
85
+ <ActionButtons
86
+ :cancel-btn="showCancelButton()"
87
+ :accept-btn="showAcceptAndDeclineButtons()"
88
+ :decline-btn="showAcceptAndDeclineButtons()"
89
+ :show-reject="showRejectButton()"
90
+ :save-btn="showSaveButton()"
91
+ :is-loading="isLoading"
92
+ @reject="handleReject()"
93
+ @save="handleSaveChanges()"
94
+ @accept="handleSaveChanges()"
95
+ @decline="handleSaveChanges(true)"
96
+ @cancel="handleCancelButton()"
97
+ />
98
+ </div>
99
+ </div>
100
+ </div>
101
+ </template>
102
+ <script>
103
+ import { mapGetters, mapState } from "vuex";
104
+ import AnnotationDetails from "./AnnotationDetails";
105
+ import AnnotationContent from "./AnnotationContent";
106
+ import EmptyAnnotation from "./EmptyAnnotation";
107
+ import ActionButtons from "./ActionButtons";
108
+
109
+ export default {
110
+ name: "AnnotationRow",
111
+ components: {
112
+ AnnotationDetails,
113
+ AnnotationContent,
114
+ EmptyAnnotation,
115
+ ActionButtons,
116
+ },
117
+ props: {
118
+ annotationSet: {
119
+ required: true,
120
+ },
121
+ label: {
122
+ required: true,
123
+ },
124
+ annotation: {
125
+ default: null,
126
+ },
127
+ },
128
+ data() {
129
+ return {
130
+ isLoading: false,
131
+ isSelected: false,
132
+ annotationAnimationTimeout: null,
133
+ hoveredAnnotation: null,
134
+ saveChanges: false,
135
+ toDecline: false,
136
+ };
137
+ },
138
+ computed: {
139
+ ...mapState("document", [
140
+ "editAnnotation",
141
+ "sidebarAnnotationSelected",
142
+ "hoveredAnnotationSet",
143
+ "enableGroupingFeature",
144
+ "publicView",
145
+ "selectedEntities",
146
+ "newAcceptedAnnotations",
147
+ "rejectedMissingAnnotations",
148
+ "documentId",
149
+ "showActionError",
150
+ ]),
151
+ ...mapState("selection", ["spanSelection", "elementSelected"]),
152
+ ...mapGetters("document", ["isAnnotationInEditMode"]),
153
+ ...mapGetters("selection", ["isValueArray"]),
154
+ defaultSpan() {
155
+ if (
156
+ this.annotation &&
157
+ this.annotation.span &&
158
+ this.annotation.span.length > 0
159
+ ) {
160
+ return this.annotation.span[0];
161
+ }
162
+ return null;
163
+ },
164
+ spanForEditing() {
165
+ return (
166
+ this.spanSelection &&
167
+ this.isValueArray(this.spanSelection) &&
168
+ this.isAnnotationInEditMode(this.annotationId())
169
+ );
170
+ },
171
+ spanFromSelectedEntities() {
172
+ return this.selectedEntities.flatMap((ann) => {
173
+ return { ...ann.entity.original, offset_string: ann.content };
174
+ });
175
+ },
176
+ isAnnotation() {
177
+ return (
178
+ this.annotation &&
179
+ this.isAnnotationInEditMode(
180
+ this.annotationId(),
181
+ this.editAnnotation.index
182
+ )
183
+ );
184
+ },
185
+ },
186
+ watch: {
187
+ sidebarAnnotationSelected(newSidebarAnnotationSelected) {
188
+ if (
189
+ newSidebarAnnotationSelected &&
190
+ this.annotation &&
191
+ this.annotation.id === newSidebarAnnotationSelected.id
192
+ ) {
193
+ clearTimeout(this.annotationAnimationTimeout);
194
+
195
+ const runAnimation = () => {
196
+ this.$el.scrollIntoView({
197
+ behavior: "smooth",
198
+ block: "center",
199
+ inline: "nearest",
200
+ });
201
+ this.isSelected = true;
202
+ // remove annotation selection after some time
203
+ this.annotationAnimationTimeout = setTimeout(() => {
204
+ this.$store.dispatch("document/setSidebarAnnotationSelected", null);
205
+ this.isSelected = false;
206
+ }, 1500);
207
+ };
208
+ runAnimation();
209
+ }
210
+ },
211
+ editAnnotation(newValue) {
212
+ if (!newValue) {
213
+ this.saveChanges = false;
214
+ this.isLoading = false;
215
+ }
216
+ },
217
+ newAcceptedAnnotations(newValue) {
218
+ if (newValue) {
219
+ this.enableLoading(newValue);
220
+ } else {
221
+ this.isLoading = false;
222
+ }
223
+ },
224
+ rejectedMissingAnnotations(newValue) {
225
+ if (newValue) {
226
+ this.enableLoading();
227
+ } else {
228
+ this.isLoading = false;
229
+ }
230
+ },
231
+ showActionError(newValue) {
232
+ if (newValue) {
233
+ this.isLoading = false;
234
+ }
235
+ },
236
+ },
237
+ methods: {
238
+ annotationId() {
239
+ if (!this.annotationSet || !this.label) return;
240
+
241
+ if (this.annotation && this.annotation.id) return this.annotation.id;
242
+
243
+ let emptyAnnotationId;
244
+
245
+ if (this.annotationSet.id) {
246
+ emptyAnnotationId = `${this.annotationSet.id}_${this.label.id}`;
247
+ } else {
248
+ emptyAnnotationId = `${this.annotationSet.label_set.id}_${this.label.id}`;
249
+ }
250
+ return emptyAnnotationId;
251
+ },
252
+ onAnnotationHoverEnter(span) {
253
+ if (span) {
254
+ this.$store.dispatch("document/setDocumentAnnotationSelected", {
255
+ annotation: this.annotation,
256
+ label: this.label,
257
+ span,
258
+ scrollTo: false,
259
+ });
260
+ }
261
+ },
262
+ onAnnotationHoverLeave() {
263
+ this.$store.dispatch("document/disableDocumentAnnotationSelected");
264
+ },
265
+ onAnnotationClick() {
266
+ this.$store.dispatch("document/scrollToDocumentAnnotationSelected");
267
+ },
268
+ hoveredEmptyLabels() {
269
+ // This method will change the style of the Empty Annotations in the same Label Set
270
+ // when the "Reject all" button is hovered
271
+ if (!this.hoveredAnnotationSet) return;
272
+
273
+ const labels = this.hoveredAnnotationSet.annotationSet.labels.map(
274
+ (label) => {
275
+ return JSON.parse(JSON.stringify(label));
276
+ }
277
+ );
278
+ const found = labels.find((l) => l.id === this.label.id);
279
+ if (found && found.annotations.length === 0) return found.id;
280
+ return null;
281
+ },
282
+ hoveredPendingAnnotations() {
283
+ // This method will change the style of Annotations in the same Label Set
284
+ // when the "Accept all" button is hovered
285
+ if (!this.hoveredAnnotationSet) return;
286
+
287
+ const annotations =
288
+ this.hoveredAnnotationSet.annotationSet.labels.flatMap((label) => {
289
+ return label.annotations;
290
+ });
291
+
292
+ // Check if there are no annotations OR if there are annotations for the same label (grouped)
293
+ if (
294
+ annotations.length === 0 ||
295
+ (this.label.annotations.length > 1 && this.enableGroupingFeature)
296
+ )
297
+ return;
298
+
299
+ const found = annotations.find(
300
+ (ann) => ann.id === this.annotation.id && !ann.revised
301
+ );
302
+
303
+ if (found) {
304
+ return found.id;
305
+ } else {
306
+ return null;
307
+ }
308
+ },
309
+ showAcceptAndDeclineButtons() {
310
+ return (
311
+ !this.isAnnotationInEditMode(this.annotationId()) &&
312
+ this.annotation &&
313
+ !this.annotation.revised &&
314
+ this.hoveredAnnotation === this.annotation.id
315
+ );
316
+ },
317
+ showRejectButton() {
318
+ return (
319
+ this.hoveredAnnotation &&
320
+ !this.isAnnotationInEditMode(this.annotationId()) &&
321
+ !this.annotation
322
+ );
323
+ },
324
+ showCancelButton() {
325
+ if (!this.editAnnotation || this.isLoading) return;
326
+
327
+ if (this.isAnnotationInEditMode(this.annotationId())) {
328
+ return true;
329
+ }
330
+ },
331
+ showSaveButton() {
332
+ if (!this.editAnnotation || this.isLoading) return;
333
+
334
+ // Check if it's an Annotation or Empty Annotation
335
+ if (this.isAnnotation) {
336
+ return true;
337
+ } else {
338
+ if (!this.isAnnotationInEditMode(this.annotationId())) return;
339
+
340
+ // Check if an entity was selected instead of bbox
341
+ if (this.selectedEntities && this.selectedEntities.length > 0) {
342
+ return this.elementSelected === this.annotationId();
343
+ } else {
344
+ // Check if an entity was selected instead of bbox
345
+ return (
346
+ this.elementSelected === this.annotationId() &&
347
+ this.spanSelection &&
348
+ Array.isArray(this.spanSelection)
349
+ );
350
+ }
351
+ }
352
+ },
353
+ handleReject() {
354
+ if (!this.label || !this.annotationSet) return;
355
+
356
+ // will emit to the DocumentAnnotations component, where the method is handled
357
+ // & dispatched to the store
358
+ this.$parent.$emit(
359
+ "handle-reject",
360
+ this.label.id,
361
+ this.annotationSet.label_set.id,
362
+ this.annotationSet.id,
363
+ false
364
+ );
365
+ },
366
+ handleSaveChanges(decline) {
367
+ if (this.publicView) return;
368
+
369
+ if (
370
+ this.showAcceptAndDeclineButtons() ||
371
+ this.isAnnotationInEditMode(
372
+ this.annotationId(),
373
+ this.editAnnotation.index
374
+ )
375
+ ) {
376
+ this.saveChanges = true;
377
+ if (decline) {
378
+ this.toDecline = true;
379
+ }
380
+ }
381
+
382
+ if (
383
+ !this.annotation &&
384
+ this.isAnnotationInEditMode(this.annotationId())
385
+ ) {
386
+ this.saveEmptyAnnotationChanges();
387
+ }
388
+ },
389
+ handleSaveAnnotationChanges(
390
+ annotation,
391
+ spanIndex,
392
+ annotationSpan,
393
+ annotationText
394
+ ) {
395
+ let updatedString;
396
+
397
+ this.isLoading = true;
398
+
399
+ // Check if we are deleting a single annotation that it's not multi-lined
400
+ let isToDelete =
401
+ annotationText.length === 0 &&
402
+ (!this.isValueArray(annotation.span) || annotation.span.length === 1);
403
+
404
+ let storeAction;
405
+
406
+ if (isToDelete || this.toDecline) {
407
+ storeAction = "document/deleteAnnotation";
408
+ } else {
409
+ storeAction = "document/updateAnnotation";
410
+
411
+ let spans = [...annotation.span];
412
+
413
+ // Validations to consider span as an array (multiline annotations) or object
414
+ if (annotationText.length === 0 && this.isValueArray(annotation.span)) {
415
+ // if the annotation content in one row was deleted
416
+ // check if it it part of an array
417
+ // to only remove that string
418
+ spans.splice(spanIndex, 1);
419
+ } else if (
420
+ this.spanSelection &&
421
+ this.isValueArray(this.spanSelection)
422
+ ) {
423
+ let span;
424
+
425
+ // Check if editing was from selecting an entity
426
+ if (this.selectedEntities && this.selectedEntities.length > 0) {
427
+ span = this.spanFromSelectedEntities;
428
+ } else {
429
+ spans = [...this.spanSelection];
430
+ span = this.createSpan(
431
+ this.spanSelection[spanIndex],
432
+ annotationText
433
+ );
434
+ }
435
+
436
+ // span is array, only update current one
437
+ spans[spanIndex] = {
438
+ ...spans[spanIndex],
439
+ span,
440
+ };
441
+ } else {
442
+ // if span is NOT an array, but an object
443
+ let span;
444
+
445
+ if (this.selectedEntities && this.selectedEntities.length > 0) {
446
+ spans = this.spanFromSelectedEntities;
447
+ } else if (this.spanSelection) {
448
+ span = this.createSpan(this.spanSelection, annotationText);
449
+
450
+ spans[spanIndex] = {
451
+ ...spans[spanIndex],
452
+ ...span,
453
+ };
454
+ } else {
455
+ span = this.createSpan(annotationSpan, annotationText);
456
+
457
+ spans[spanIndex] = {
458
+ ...spans[spanIndex],
459
+ ...span,
460
+ };
461
+ }
462
+ }
463
+
464
+ updatedString = {
465
+ is_correct: true,
466
+ revised: true,
467
+ span: spans,
468
+ };
469
+ }
470
+
471
+ // Send to the store for the http patch/delete request
472
+ this.$store
473
+ .dispatch(storeAction, {
474
+ updatedValues: updatedString,
475
+ annotationId: this.annotation.id,
476
+ })
477
+ .catch((error) => {
478
+ this.$store.dispatch("document/createErrorMessage", {
479
+ error,
480
+ serverErrorMessage: this.$t("server_error"),
481
+ defaultErrorMessage: this.$t("edit_error"),
482
+ });
483
+ })
484
+ .finally(() => {
485
+ this.$store.dispatch("document/resetEditAnnotation");
486
+ this.$store.dispatch("selection/disableSelection");
487
+ this.$store.dispatch("document/setSelectedEntities", null);
488
+ this.toDecline = false;
489
+ });
490
+ },
491
+ createSpan(span, annotationText) {
492
+ return {
493
+ offset_string: annotationText,
494
+ page_index: span.page_index,
495
+ x0: span.x0,
496
+ x1: span.x1,
497
+ y0: span.y0,
498
+ y1: span.y1,
499
+ start_offset: span.start_offset,
500
+ end_offset: span.end_offset,
501
+ };
502
+ },
503
+ saveEmptyAnnotationChanges() {
504
+ let annotationToCreate;
505
+ let span;
506
+
507
+ if (this.selectedEntities && this.selectedEntities.length > 0) {
508
+ span = this.spanFromSelectedEntities;
509
+ } else {
510
+ span = this.spanSelection;
511
+ }
512
+
513
+ if (this.annotationSet.id) {
514
+ annotationToCreate = {
515
+ document: this.documentId,
516
+ span: span,
517
+ label: this.label.id,
518
+ annotation_set: this.annotationSet.id,
519
+ is_correct: true,
520
+ revised: true,
521
+ };
522
+ } else {
523
+ // if annotation set id is null
524
+ annotationToCreate = {
525
+ document: this.documentId,
526
+ span: span,
527
+ label: this.label.id,
528
+ label_set: this.annotationSet.label_set.id,
529
+ is_correct: true,
530
+ revised: true,
531
+ };
532
+ }
533
+ this.isLoading = true;
534
+
535
+ this.$store
536
+ .dispatch("document/createAnnotation", annotationToCreate)
537
+ .catch((error) => {
538
+ this.$store.dispatch("document/createErrorMessage", {
539
+ error,
540
+ serverErrorMessage: this.$t("server_error"),
541
+ defaultErrorMessage: this.$t("edit_error"),
542
+ });
543
+ })
544
+ .finally(() => {
545
+ this.$store.dispatch("document/resetEditAnnotation");
546
+ this.handleCancelButton();
547
+ });
548
+ },
549
+ handleCancelButton() {
550
+ this.$store.dispatch("document/resetEditAnnotation");
551
+ if (this.elementSelected) {
552
+ this.$store.dispatch("selection/disableSelection");
553
+ this.$store.dispatch("document/setSelectedEntities", null);
554
+ }
555
+ },
556
+ enableLoading(annotations) {
557
+ if (annotations && this.annotation) {
558
+ const found = annotations.find(
559
+ (annotation) => annotation === this.annotation.id
560
+ );
561
+
562
+ if (found) {
563
+ this.isLoading = true;
564
+ this.saveChanges = false;
565
+ return;
566
+ }
567
+
568
+ this.isLoading = false;
569
+ this.saveChanges = false;
570
+ return;
571
+ }
572
+
573
+ // Check for what empty annotations we want to show the loading
574
+ // while waiting for it to be removed from the row
575
+ if (!this.rejectedMissingAnnotations) {
576
+ this.isLoading = false;
577
+ this.saveChanges = false;
578
+ return;
579
+ }
580
+
581
+ if (this.rejectedMissingAnnotations.length > 0) {
582
+ this.rejectedMissingAnnotations.map((annotation) => {
583
+ // Check if the annotation set and label are rejected
584
+ if (
585
+ annotation.label_set === this.annotationSet.label_set.id &&
586
+ annotation.annotation_set === this.annotationSet.id &&
587
+ annotation.label === this.label.id
588
+ ) {
589
+ // Check if we wanna add loading to all empty annotations
590
+ if (this.hoveredAnnotationSet) {
591
+ this.isLoading = true;
592
+ this.saveChanges = false;
593
+ return;
594
+ }
595
+
596
+ // or we want to add loading to a single one
597
+ if (
598
+ !this.hoveredAnnotationSet &&
599
+ annotation.label === this.label.id
600
+ ) {
601
+ this.isLoading = true;
602
+ this.saveChanges = false;
603
+ return;
604
+ }
605
+ }
606
+ });
607
+ }
608
+ },
609
+ },
610
+ };
611
+ </script>
612
+ <style
613
+ scoped
614
+ lang="scss"
615
+ src="../../assets/scss/document_annotations.scss"
616
+ ></style>