@konfuzio/document-validation-ui 0.1.59-dev.3 → 0.1.60-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.
Files changed (65) hide show
  1. package/cypress.config.js +6 -6
  2. package/dist/css/app.css +1 -1
  3. package/dist/index.html +1 -1
  4. package/dist/js/app.js +1 -1
  5. package/dist/js/app.js.map +1 -1
  6. package/dist/js/chunk-vendors.js +23 -66
  7. package/dist/js/chunk-vendors.js.map +1 -1
  8. package/jest.config.js +2 -22
  9. package/package.json +38 -32
  10. package/src/api.js +12 -0
  11. package/src/assets/scss/ann_set_table_options.scss +4 -4
  12. package/src/assets/scss/annotation_action_buttons.scss +7 -7
  13. package/src/assets/scss/annotation_details.scss +9 -9
  14. package/src/assets/scss/choose_label_set_modal.scss +5 -5
  15. package/src/assets/scss/document_action_bar.scss +3 -3
  16. package/src/assets/scss/document_annotations.scss +43 -45
  17. package/src/assets/scss/document_category.scss +8 -8
  18. package/src/assets/scss/document_dashboard.scss +1 -1
  19. package/src/assets/scss/document_edit.scss +30 -30
  20. package/src/assets/scss/document_error.scss +6 -6
  21. package/src/assets/scss/document_name.scss +6 -6
  22. package/src/assets/scss/document_page.scss +3 -3
  23. package/src/assets/scss/document_search_bar.scss +7 -7
  24. package/src/assets/scss/document_set_chooser.scss +3 -3
  25. package/src/assets/scss/document_thumbnails.scss +7 -7
  26. package/src/assets/scss/document_toolbar.scss +10 -10
  27. package/src/assets/scss/document_top_bar.scss +11 -11
  28. package/src/assets/scss/document_viewport_modal.scss +3 -3
  29. package/src/assets/scss/documents_list.scss +12 -11
  30. package/src/assets/scss/edit_page_thumbnail.scss +6 -6
  31. package/src/assets/scss/empty_state.scss +4 -4
  32. package/src/assets/scss/error_page.scss +2 -2
  33. package/src/assets/scss/extracting_data.scss +3 -3
  34. package/src/assets/scss/imports.scss +1 -0
  35. package/src/assets/scss/multi_ann_table_overlay.scss +3 -3
  36. package/src/assets/scss/multi_ann_table_popup.scss +1 -1
  37. package/src/assets/scss/new_annotation.scss +19 -25
  38. package/src/assets/scss/scrolling_document.scss +1 -1
  39. package/src/assets/scss/theme.scss +52 -64
  40. package/src/assets/scss/variables.scss +0 -2
  41. package/src/components/App.vue +14 -9
  42. package/src/components/DocumentAnnotations/AnnotationActionButtons.vue +6 -4
  43. package/src/components/DocumentAnnotations/AnnotationContent.vue +52 -25
  44. package/src/components/DocumentAnnotations/AnnotationRow.vue +50 -106
  45. package/src/components/DocumentAnnotations/DocumentAnnotations.vue +6 -12
  46. package/src/components/DocumentAnnotations/EmptyAnnotation.vue +70 -31
  47. package/src/components/DocumentDashboard.vue +17 -12
  48. package/src/components/DocumentEdit/EditPages.vue +46 -51
  49. package/src/components/DocumentPage/BoxSelection.vue +49 -16
  50. package/src/components/DocumentPage/DocumentPage.vue +153 -56
  51. package/src/components/DocumentPage/DocumentToolbar.vue +15 -5
  52. package/src/components/DocumentPage/EditAnnotation.vue +372 -0
  53. package/src/components/DocumentPage/{AnnotationPopup.vue → NewAnnotation.vue} +94 -122
  54. package/src/components/DocumentPage/ScrollingPage.vue +10 -2
  55. package/src/components/DocumentThumbnails/LoadingThumbnail.vue +6 -3
  56. package/src/components/DocumentTopBar/DocumentTopBar.vue +2 -4
  57. package/src/constants.js +7 -1
  58. package/src/i18n.js +5 -2
  59. package/src/main.js +16 -14
  60. package/src/store/display.js +24 -38
  61. package/src/store/document.js +6 -1
  62. package/src/store/index.js +8 -5
  63. package/src/store/selection.js +76 -152
  64. package/src/components/DocumentPage/PlaceholderSelection.vue +0 -51
  65. package/src/components/DocumentPage/SpanSelection.vue +0 -259
@@ -106,7 +106,6 @@
106
106
  <!-- save button -->
107
107
  <b-button
108
108
  v-if="showSave"
109
- id="save-ann"
110
109
  :class="`button-action ${showText ? 'is-button-text' : 'is-button-icon'}`"
111
110
  :type="showText ? 'is-primary' : 'is-ghost'"
112
111
  @click.stop="save"
@@ -206,7 +205,9 @@ export default {
206
205
  data() {
207
206
  return {
208
207
  tooltipDelay: 700,
209
- showText: window.innerWidth > TEXT_BREAKPOINT_WIDTH,
208
+ showText:
209
+ window.innerWidth >
210
+ TEXT_BREAKPOINT_WIDTH(this.$i18n ? this.$i18n.locale : "en"),
210
211
  };
211
212
  },
212
213
  computed: {
@@ -226,12 +227,13 @@ export default {
226
227
  window.addEventListener("resize", this.resize);
227
228
  },
228
229
 
229
- unmounted() {
230
+ destroyed() {
230
231
  window.removeEventListener("resize", this.resize);
231
232
  },
232
233
  methods: {
233
234
  resize() {
234
- this.showText = window.innerWidth > TEXT_BREAKPOINT_WIDTH;
235
+ this.showText =
236
+ window.innerWidth > TEXT_BREAKPOINT_WIDTH(this.$i18n.locale);
235
237
  },
236
238
  search() {
237
239
  this.$emit("search");
@@ -11,10 +11,10 @@
11
11
  editAnnotation &&
12
12
  editAnnotation.id === annotation.id &&
13
13
  'error-editing',
14
- isSpanBeingEdited && 'clicked-ann',
14
+ isAnnotationBeingEdited && 'clicked-ann',
15
15
  ]"
16
16
  role="textbox"
17
- :contenteditable="isSpanBeingEdited"
17
+ :contenteditable="isAnnotationBeingEdited"
18
18
  @click="handleEditAnnotation"
19
19
  @paste="handlePaste"
20
20
  @keypress.enter="saveAnnotationChanges"
@@ -61,7 +61,11 @@ export default {
61
61
  };
62
62
  },
63
63
  computed: {
64
- ...mapGetters("document", ["isAnnotationInEditMode", "isDocumentReviewed"]),
64
+ ...mapGetters("document", [
65
+ "isAnnotationInEditMode",
66
+ "pageAtIndex",
67
+ "isDocumentReviewed",
68
+ ]),
65
69
  ...mapGetters("display", ["bboxToRect"]),
66
70
  ...mapState("document", [
67
71
  "editAnnotation",
@@ -70,17 +74,19 @@ export default {
70
74
  "newAcceptedAnnotations",
71
75
  "showActionError",
72
76
  ]),
73
- isSpanBeingEdited() {
74
- return this.isAnnotationInEditMode(this.annotation.id, this.spanIndex);
75
- },
76
77
  isAnnotationBeingEdited() {
77
- return (
78
- this.editAnnotation && this.annotation.id === this.editAnnotation.id
79
- );
78
+ return this.isAnnotationInEditMode(this.annotation.id, this.spanIndex);
80
79
  },
81
80
  },
82
81
 
83
82
  watch: {
83
+ isAnnotationBeingEdited(newState, oldState) {
84
+ // verify if new annotation in edit mode is not this one and if this
85
+ // one was selected before so we set the state to the previous one (like a cancel)
86
+ if (!newState && oldState) {
87
+ this.handleCancel();
88
+ }
89
+ },
84
90
  span() {
85
91
  // span content changed, ex. from click on entity
86
92
  this.setText(this.span.offset_string);
@@ -104,15 +110,10 @@ export default {
104
110
  if (
105
111
  !this.publicView &&
106
112
  !this.isDocumentReviewed &&
107
- !this.isSpanBeingEdited &&
113
+ !this.isAnnotationBeingEdited &&
108
114
  !this.isLoading
109
115
  ) {
110
- if (!this.isAnnotationBeingEdited) {
111
- this.$store.dispatch(
112
- "selection/setSpanSelection",
113
- this.annotation.span
114
- );
115
- }
116
+ this.$store.dispatch("selection/selectElement", this.annotation.id);
116
117
 
117
118
  this.$store
118
119
  .dispatch("document/setEditAnnotation", {
@@ -124,18 +125,44 @@ export default {
124
125
  pageNumber: this.span.page_index + 1,
125
126
  })
126
127
  .then(() => {
127
- if (this.$refs.contentEditable) {
128
- this.$refs.contentEditable.focus();
129
- }
128
+ this.$refs.contentEditable.focus();
130
129
  })
131
130
  .catch((error) => {
132
131
  console.log(error);
133
132
  });
134
- // check if this is part of a group of spans to show the whole bounding box as a placeholder
135
- if (this.annotation.selection_bbox && this.annotation.span.length > 1) {
136
- this.$store.dispatch("selection/setPlaceholderSelection", [
137
- this.annotation.selection_bbox,
138
- ]);
133
+
134
+ const page = this.pageAtIndex(this.span.page_index);
135
+ if (page) {
136
+ const { x, y, width, height } = this.bboxToRect(page, this.span);
137
+
138
+ const selection = {
139
+ start: {
140
+ x,
141
+ y,
142
+ },
143
+ end: {
144
+ x: x + width,
145
+ y: y + height,
146
+ },
147
+ pageNumber: page.number,
148
+ custom: false,
149
+ };
150
+
151
+ // check if this is part of a group of spans to show the whole bounding box as a placeholder
152
+ if (
153
+ this.annotation.selection_bbox &&
154
+ this.annotation.span.length > 1
155
+ ) {
156
+ selection.placeholderBox = this.bboxToRect(
157
+ page,
158
+ this.annotation.selection_bbox
159
+ );
160
+ }
161
+
162
+ this.$store.dispatch("selection/setSelection", {
163
+ selection,
164
+ span: this.span,
165
+ });
139
166
  }
140
167
  }
141
168
  },
@@ -146,7 +173,7 @@ export default {
146
173
  this.$refs.contentEditable.blur();
147
174
  }
148
175
 
149
- this.$store.dispatch("selection/setSpanSelection", null);
176
+ this.$store.dispatch("selection/setSelectedEntities", null);
150
177
  },
151
178
  handlePaste(event) {
152
179
  // TODO: modify to only paste plain text
@@ -15,13 +15,14 @@
15
15
  >
16
16
  <div class="annotations-width-slider">
17
17
  <b-slider
18
- v-model="labelContainerWidth"
18
+ :value="labelWidth"
19
19
  type="is-move"
20
20
  :min="20"
21
21
  :max="80"
22
22
  :custom-formatter="(val) => `${$t('label_size')} ${val}%`"
23
23
  class="is-full-height show-hover show-line"
24
24
  :disabled="isAnnotationInEditMode()"
25
+ @input="setLabelWidth"
25
26
  />
26
27
  </div>
27
28
  <div
@@ -97,12 +98,7 @@
97
98
 
98
99
  <div class="annotation-row-right" :style="`width:${annotationWidth}%`">
99
100
  <div class="annotation-content">
100
- <div
101
- v-if="isAnnotationInEditMode(currentAnnotationId()) && spanLoading"
102
- >
103
- <b-icon style="width: 16px" icon="spinner" class="fa-spin" />
104
- </div>
105
- <div v-else-if="annotation" class="annotation-items">
101
+ <div v-if="annotation" class="annotation-items">
106
102
  <b-checkbox
107
103
  v-if="annotation.metadata && annotation.metadata.checkbox"
108
104
  v-model="isChecked"
@@ -133,8 +129,7 @@
133
129
  <div v-else>
134
130
  <div
135
131
  v-if="
136
- spanSelection.length > 0 &&
137
- isAnnotationInEditMode(currentAnnotationId())
132
+ spanSelection && isAnnotationInEditMode(currentAnnotationId())
138
133
  "
139
134
  >
140
135
  <EmptyAnnotation
@@ -249,7 +244,6 @@ export default {
249
244
  checkboxDefaultValue: checkboxValue,
250
245
  isCheckboxAvailable: false,
251
246
  isChecked: checkboxValue,
252
- labelContainerWidth: 0,
253
247
  };
254
248
  },
255
249
  computed: {
@@ -267,8 +261,8 @@ export default {
267
261
  ]),
268
262
  ...mapState("selection", [
269
263
  "spanSelection",
264
+ "elementSelected",
270
265
  "selectedEntities",
271
- "spanLoading",
272
266
  ]),
273
267
  ...mapState("display", ["labelWidth", "annotationWidth"]),
274
268
  ...mapState("project", ["showAnnotationTranslations"]),
@@ -325,12 +319,6 @@ export default {
325
319
  },
326
320
  },
327
321
  watch: {
328
- labelWidth(width) {
329
- this.labelContainerWidth = width;
330
- },
331
- labelContainerWidth(width) {
332
- this.setLabelWidth(width);
333
- },
334
322
  annotationId(newAnnotationId) {
335
323
  this.checkAnnotationSelection(newAnnotationId);
336
324
  },
@@ -395,7 +383,6 @@ export default {
395
383
  },
396
384
  mounted() {
397
385
  this.checkAnnotationSelection(this.annotationId);
398
- this.labelContainerWidth = this.labelWidth;
399
386
  },
400
387
  methods: {
401
388
  ...mapActions("display", ["setLabelWidth"]),
@@ -451,10 +438,9 @@ export default {
451
438
 
452
439
  if (this.annotation && this.annotation.id) return this.annotation.id;
453
440
 
454
- const setId =
455
- this.annotationSet && this.annotationSet.id
456
- ? this.annotationSet.id
457
- : this.labelSet.id;
441
+ const setId = this.annotationSet
442
+ ? this.annotationSet.id
443
+ : this.labelSet.id;
458
444
 
459
445
  return `${setId}_${this.label.id}`;
460
446
  },
@@ -587,8 +573,11 @@ export default {
587
573
  } else {
588
574
  if (!this.isAnnotationInEditMode(this.currentAnnotationId())) return;
589
575
 
590
- // check if spans are selected
591
- return this.spanSelection && this.spanSelection.length > 0;
576
+ return (
577
+ this.elementSelected === this.currentAnnotationId() &&
578
+ this.spanSelection &&
579
+ Array.isArray(this.spanSelection)
580
+ );
592
581
  }
593
582
  },
594
583
  handleMissingAnnotation() {
@@ -689,92 +678,44 @@ export default {
689
678
  this.isLoading = true;
690
679
  }, 100);
691
680
 
692
- // check if annotation set was changed
693
- if (
694
- (this.editAnnotation.annotationSet &&
695
- (this.editAnnotation.annotationSet.id !== this.annotationSet.id ||
696
- (this.editAnnotation.annotationSet.id == null &&
697
- this.labelSet.id !== this.editAnnotation.labelSet.id))) ||
698
- (this.editAnnotation.label &&
699
- this.editAnnotation.label.id !== this.label.id)
700
- ) {
701
- // first delete annotation, then create new one
702
- this.$store
703
- .dispatch("document/deleteAnnotation", {
704
- annotationId: this.annotation.id,
705
- })
706
- .then(() => {
707
- const annotationToCreate = {
708
- document: this.documentId,
709
- span: spans,
710
- label: this.editAnnotation.label.id,
711
- is_correct: true,
712
- revised: false,
713
- };
714
-
715
- if (this.editAnnotation.annotationSet.id) {
716
- annotationToCreate.annotation_set =
717
- this.editAnnotation.annotationSet.id;
718
- } else {
719
- annotationToCreate.label_set = this.editAnnotation.labelSet.id;
720
- }
681
+ let updatedString; // what will be sent to the API
682
+ let storeAction; // if it will be 'delete' or 'patch'
721
683
 
722
- this.$store
723
- .dispatch("document/createAnnotation", {
724
- annotation: annotationToCreate,
725
- })
726
- .catch((error) => {
727
- this.$store.dispatch("document/createErrorMessage", {
728
- error,
729
- serverErrorMessage: this.$t("server_error"),
730
- defaultErrorMessage: this.$t("error_creating_annotation"),
731
- });
732
- })
733
- .finally(() => {
734
- this.$store.dispatch("document/resetEditAnnotation");
735
- this.$store.dispatch("selection/disableSelection");
736
- this.loading = false;
737
- });
738
- });
684
+ // Verify if we delete the entire Annotation or a part of the text
685
+ if (isToDecline || spans.length === 0) {
686
+ storeAction = "document/deleteAnnotation";
739
687
  } else {
740
- let updatedString; // what will be sent to the API
741
- let storeAction; // if it will be 'delete' or 'patch'
688
+ // Editing the Annotation
689
+ // Deleting part of multi-line Annotation
690
+ storeAction = "document/updateAnnotation";
742
691
 
743
- // Verify if we delete the entire Annotation or a part of the text
744
- if (isToDecline || spans.length === 0) {
745
- storeAction = "document/deleteAnnotation";
746
- } else {
747
- // Editing the Annotation
748
- // Deleting part of multi-line Annotation
749
- storeAction = "document/updateAnnotation";
750
-
751
- updatedString = {
752
- is_correct: true,
753
- revised: true,
754
- span: spans,
755
- };
756
- }
692
+ updatedString = {
693
+ is_correct: true,
694
+ revised: true,
695
+ span: spans,
696
+ };
697
+ }
757
698
 
758
- // Send to the store for the http patch/delete request
759
- this.$store
760
- .dispatch(storeAction, {
761
- updatedValues: updatedString,
762
- annotationId: this.annotation.id,
763
- annotationSet: this.annotationSet,
764
- })
765
- .catch((error) => {
766
- this.$store.dispatch("document/createErrorMessage", {
767
- error,
768
- serverErrorMessage: this.$t("server_error"),
769
- defaultErrorMessage: this.$t("edit_error"),
770
- });
771
- })
772
- .finally(() => {
773
- this.$store.dispatch("document/resetEditAnnotation");
774
- this.$store.dispatch("selection/disableSelection");
775
- this.isLoading = false;
699
+ // Send to the store for the http patch/delete request
700
+ this.$store
701
+ .dispatch(storeAction, {
702
+ updatedValues: updatedString,
703
+ annotationId: this.annotation.id,
704
+ annotationSet: this.annotationSet,
705
+ })
706
+ .catch((error) => {
707
+ this.$store.dispatch("document/createErrorMessage", {
708
+ error,
709
+ serverErrorMessage: this.$t("server_error"),
710
+ defaultErrorMessage: this.$t("edit_error"),
776
711
  });
777
- }
712
+ })
713
+ .finally(() => {
714
+ this.$store.dispatch("document/resetEditAnnotation");
715
+ this.$store.dispatch("selection/disableSelection");
716
+ this.$store.dispatch("selection/setSelectedEntities", null);
717
+ this.isLoading = false;
718
+ });
778
719
  },
779
720
  saveEmptyAnnotationChanges() {
780
721
  let annotationToCreate;
@@ -819,7 +760,10 @@ export default {
819
760
  },
820
761
  handleCancelButton() {
821
762
  this.$store.dispatch("document/resetEditAnnotation");
822
- this.$store.dispatch("selection/disableSelection");
763
+ if (this.elementSelected) {
764
+ this.$store.dispatch("selection/disableSelection");
765
+ this.$store.dispatch("selection/setSelectedEntities", null);
766
+ }
823
767
  this.isLoading = false;
824
768
  },
825
769
  enableLoading(annotations) {
@@ -105,10 +105,7 @@
105
105
  </div>
106
106
  </div>
107
107
 
108
- <b-collapse
109
- :model-value="isAccordionOpen(annotationSet)"
110
- animation="slide"
111
- >
108
+ <b-collapse :open="isAccordionOpen(annotationSet)">
112
109
  <div
113
110
  v-if="annotationSet.labels.length > 0"
114
111
  class="annotation-sets-list"
@@ -197,7 +194,6 @@ export default {
197
194
 
198
195
  computed: {
199
196
  ...mapState("display", ["showAnnSetTable", "showBranding"]),
200
- ...mapState("edit", ["editMode"]),
201
197
  ...mapState("document", [
202
198
  "annotationSets",
203
199
  "documentId",
@@ -225,7 +221,7 @@ export default {
225
221
  return this.editAnnotation && this.editAnnotation.id;
226
222
  },
227
223
  isDocumentEditable() {
228
- return !this.publicView && !this.isDocumentReviewed && !this.editMode;
224
+ return !this.publicView && !this.isDocumentReviewed;
229
225
  },
230
226
  },
231
227
  watch: {
@@ -277,7 +273,7 @@ export default {
277
273
  this.loadAccordions(this.getAnnotationsFiltered.annotationSets);
278
274
  }
279
275
  },
280
- unmounted() {
276
+ destroyed() {
281
277
  window.removeEventListener("keydown", this.keyDownHandler);
282
278
  },
283
279
  methods: {
@@ -408,11 +404,9 @@ export default {
408
404
  },
409
405
 
410
406
  createArray(className) {
411
- if (this.$refs.annotationList) {
412
- return Array.from(
413
- this.$refs.annotationList.getElementsByClassName(className)
414
- );
415
- }
407
+ return Array.from(
408
+ this.$refs.annotationList.getElementsByClassName(className)
409
+ );
416
410
  },
417
411
 
418
412
  keyDownHandler(event) {
@@ -1,33 +1,39 @@
1
1
  <template>
2
- <div v-if="!publicView && !isDocumentReviewed" class="empty-annotation">
2
+ <div class="empty-annotation">
3
3
  <span
4
+ v-if="!publicView && !isDocumentReviewed"
4
5
  :id="emptyAnnotationId()"
5
6
  ref="emptyAnnotation"
6
7
  :class="[
7
8
  'annotation-value',
8
- showActionError && isAnnotationBeingEdited() && 'error-editing',
9
+ showActionError &&
10
+ editAnnotation &&
11
+ editAnnotation.id === emptyAnnotationId() &&
12
+ 'error-editing',
13
+ !isEmptyAnnotationEditable() && !isMissingAnnotation && 'label-empty',
9
14
  isAnnotationBeingEdited() && 'clicked-ann',
10
15
  isMissingAnnotation && 'missing-annotation',
11
16
  !isMissingAnnotation && 'keyboard-nav',
12
17
  ]"
13
- :contenteditable="isAnnotationBeingEdited()"
18
+ :contenteditable="isEmptyAnnotationEditable()"
14
19
  @keypress.enter="saveEmptyAnnotationChanges"
15
20
  @click="handleEditEmptyAnnotation"
16
21
  @focus="handleEditEmptyAnnotation"
17
22
  ><!-- eslint-disable vue/no-v-html -->
18
23
  <span
19
24
  v-if="isFindingAnnotation"
20
- class="label-empty-clicked"
21
25
  v-html="$t('draw_box_document', { label_name: label.name })"
22
26
  >
23
27
  </span>
24
28
  <span v-else-if="isMissingAnnotation" class="not-found-text">
25
29
  {{ $t("missing_from_document") }}
26
30
  </span>
27
- <span v-else-if="span && span.offset_string">
31
+ <span
32
+ v-else-if="span && span.offset_string && isEmptyAnnotationEditable()"
33
+ >
28
34
  {{ span.offset_string }}
29
35
  </span>
30
- <span v-else class="label-empty">
36
+ <span v-else>
31
37
  {{ $t("no_data_found") }}
32
38
  </span>
33
39
  <!--eslint-enable-->
@@ -36,6 +42,7 @@
36
42
  </template>
37
43
  <script>
38
44
  import { mapState, mapGetters } from "vuex";
45
+ import { isElementArray } from "../../utils/utils";
39
46
 
40
47
  /**
41
48
  * This component is responsible for managing empty annotations (labels with no annotations).
@@ -73,7 +80,7 @@ export default {
73
80
  },
74
81
  computed: {
75
82
  ...mapGetters("document", ["isAnnotationInEditMode", "isDocumentReviewed"]),
76
- ...mapState("selection", ["spanSelection"]),
83
+ ...mapState("selection", ["spanSelection", "elementSelected"]),
77
84
  ...mapState("document", [
78
85
  "editAnnotation",
79
86
  "publicView",
@@ -90,17 +97,17 @@ export default {
90
97
 
91
98
  watch: {
92
99
  span(newValue) {
93
- // if (newValue) {
94
- // if (isElementArray(newValue))
95
- // newValue.map((span) => {
96
- // if (span.offset_string) {
97
- // span.offset_string =
98
- // this.$refs.emptyAnnotation.textContent.trim();
99
- // span.offset_string_original =
100
- // this.$refs.emptyAnnotation.textContent.trim();
101
- // }
102
- // });
103
- // }
100
+ if (this.elementSelected === this.emptyAnnotationId() && newValue) {
101
+ if (isElementArray(newValue))
102
+ newValue.map((span) => {
103
+ if (span.offset_string) {
104
+ span.offset_string =
105
+ this.$refs.emptyAnnotation.textContent.trim();
106
+ span.offset_string_original =
107
+ this.$refs.emptyAnnotation.textContent.trim();
108
+ }
109
+ });
110
+ }
104
111
  },
105
112
  spanSelection(newValue) {
106
113
  if (!newValue) return;
@@ -116,27 +123,59 @@ export default {
116
123
  methods: {
117
124
  emptyAnnotationId() {
118
125
  if ((!this.annotationSet && !this.labelSet) || !this.label) return;
119
- const id =
120
- this.annotationSet && this.annotationSet.id != null
121
- ? this.annotationSet.id
122
- : this.labelSet.id;
126
+
127
+ const id = this.annotationSet ? this.annotationSet.id : this.labelSet.id;
123
128
  return `${id}_${this.label.id}`;
124
129
  },
125
130
  isAnnotationBeingEdited() {
126
131
  return this.isAnnotationInEditMode(this.emptyAnnotationId());
127
132
  },
128
133
  handleEditEmptyAnnotation() {
129
- if (this.isMissingAnnotation) return;
130
- this.$store.dispatch("selection/disableSelection");
131
- this.$store.dispatch("document/setEditAnnotation", {
132
- id: this.emptyAnnotationId(),
133
- index: this.spanIndex,
134
- label: this.label,
135
- labelSet: this.labelSet,
136
- annotationSet: this.annotationSet,
137
- });
134
+ if (
135
+ this.publicView ||
136
+ this.isDocumentReviewed ||
137
+ this.isMissingAnnotation
138
+ )
139
+ return;
140
+
141
+ if (
142
+ !this.publicView &&
143
+ !this.isDocumentReviewed &&
144
+ this.elementSelected !== this.emptyAnnotationId()
145
+ ) {
146
+ this.$store.dispatch("selection/disableSelection");
147
+ this.$store.dispatch("selection/setSelectedEntities", null);
148
+ this.$store.dispatch(
149
+ "selection/selectElement",
150
+ this.emptyAnnotationId()
151
+ );
152
+ this.$store.dispatch("document/setEditAnnotation", {
153
+ id: this.emptyAnnotationId(),
154
+ index: this.spanIndex,
155
+ label: this.label,
156
+ labelSet: this.labelSet,
157
+ annotationSet: this.annotationSet,
158
+ });
159
+ }
160
+ },
161
+ isEmptyAnnotationEditable() {
162
+ if (
163
+ (this.spanSelection && this.spanSelection[this.spanIndex] === 0) ||
164
+ this.isMissingAnnotation
165
+ ) {
166
+ return false;
167
+ } else {
168
+ return (
169
+ this.elementSelected === this.emptyAnnotationId() &&
170
+ this.spanSelection &&
171
+ this.spanSelection[this.spanIndex] &&
172
+ this.spanSelection[this.spanIndex].offset_string != null
173
+ );
174
+ }
138
175
  },
139
176
  saveEmptyAnnotationChanges(event) {
177
+ if (this.publicView || this.isDocumentReviewed) return;
178
+
140
179
  if (event) {
141
180
  event.preventDefault();
142
181
  }