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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@konfuzio/document-validation-ui",
3
- "version": "0.1.17-dev.2",
3
+ "version": "0.1.17-dev.3",
4
4
  "repository": "git://github.com:konfuzio-ai/document-validation-ui.git",
5
5
  "main": "dist/app.js",
6
6
  "scripts": {
@@ -7,7 +7,7 @@
7
7
  hoverPendingAnnotationRows && 'hovered-pending-annotations',
8
8
  annotationIsNotFound(annotationSet, label) && 'missing',
9
9
  isAnnotationInEditMode(annotationId()) && 'editing',
10
- publicView && 'clickable-cursor'
10
+ publicView && 'clickable-cursor',
11
11
  ]"
12
12
  @click="onAnnotationClick"
13
13
  @mouseover="hoveredAnnotation = annotationId()"
@@ -39,25 +39,36 @@
39
39
  </div>
40
40
 
41
41
  <div v-if="showTranslationsDetails" class="annotation-translation">
42
- <b-tooltip
43
- :animated="false"
44
- position="is-bottom"
45
- :close-delay="2000"
46
- >
42
+ <b-tooltip :animated="false" position="is-bottom" :close-delay="2000">
47
43
  <div class="icon">
48
- <TranslateArrows :translation="annotation.translated_string && true"/>
44
+ <TranslateArrows
45
+ :translation="annotation.translated_string && true"
46
+ />
49
47
  </div>
50
48
 
51
- <template #content>
49
+ <template #content>
52
50
  <div class="translation-details">
53
51
  <div class="translation-title">
54
52
  <span>{{ $t("translated_string_title") }}</span>
55
53
  </div>
56
- <div class="translation-info">
57
- <span class="translated-string">{{ annotation.translated_string ? annotation.translated_string : $t("no_translated_string")}}</span>
58
- <a v-if=!isDocumentReviewed class="annotation-details-link" @click="editAnnotationTranslation(annotation.id)">{{ annotation.translated_string ? $t("edit") : $t("add_translation")}}</a>
54
+ <div class="translation-info">
55
+ <span class="translated-string">{{
56
+ annotation.translated_string
57
+ ? annotation.translated_string
58
+ : $t("no_translated_string")
59
+ }}</span>
60
+ <a
61
+ v-if="!isDocumentReviewed"
62
+ class="annotation-details-link"
63
+ @click="editAnnotationTranslation(annotation.id)"
64
+ >{{
65
+ annotation.translated_string
66
+ ? $t("edit")
67
+ : $t("add_translation")
68
+ }}</a
69
+ >
59
70
  </div>
60
- </div>
71
+ </div>
61
72
  </template>
62
73
  </b-tooltip>
63
74
  </div>
@@ -199,14 +210,12 @@ export default {
199
210
  "elementSelected",
200
211
  "selectedEntities",
201
212
  ]),
202
- ...mapState("project", [
203
- "translationsEnabled"
204
- ]),
213
+ ...mapState("project", ["translationsEnabled"]),
205
214
  ...mapGetters("document", [
206
215
  "isAnnotationInEditMode",
207
216
  "annotationIsNotFound",
208
217
  "isDocumentReviewed",
209
- "isNegative"
218
+ "isNegative",
210
219
  ]),
211
220
  defaultSpan() {
212
221
  if (
@@ -258,8 +267,13 @@ export default {
258
267
  },
259
268
  showTranslationsDetails() {
260
269
  // Only show translation option for filled annotations and if the feature is enabled for the project
261
- return this.annotation && this.translationsEnabled && !this.publicView;
262
- }
270
+ return (
271
+ this.annotation &&
272
+ !this.isNegative(this.annotation) &&
273
+ this.translationsEnabled &&
274
+ !this.publicView
275
+ );
276
+ },
263
277
  },
264
278
  watch: {
265
279
  sidebarAnnotationSelected(newSidebarAnnotationSelected) {
@@ -273,7 +287,11 @@ export default {
273
287
  annotationSelected = newSidebarAnnotationSelected;
274
288
  }
275
289
 
276
- if (this.annotation && !this.isNegative(this.annotation) && this.annotation.id === annotationSelected.id) {
290
+ if (
291
+ this.annotation &&
292
+ !this.isNegative(this.annotation) &&
293
+ this.annotation.id === annotationSelected.id
294
+ ) {
277
295
  clearTimeout(this.annotationAnimationTimeout);
278
296
 
279
297
  let timeout;
@@ -347,7 +365,12 @@ export default {
347
365
  annotationId() {
348
366
  if (!this.annotationSet || !this.label) return;
349
367
 
350
- if (this.annotation && this.annotation.id && !this.isNegative(this.annotation)) return this.annotation.id;
368
+ if (
369
+ this.annotation &&
370
+ this.annotation.id &&
371
+ !this.isNegative(this.annotation)
372
+ )
373
+ return this.annotation.id;
351
374
 
352
375
  let emptyAnnotationId;
353
376
 
@@ -388,9 +411,12 @@ export default {
388
411
  }
389
412
  );
390
413
  const found = labels.find((l) => l.id === this.label.id);
391
- const negativeAnnotations = found.annotations.find(annotation => this.isNegative(annotation));
414
+ const negativeAnnotations = found.annotations.find((annotation) =>
415
+ this.isNegative(annotation)
416
+ );
392
417
 
393
- if ((found && found.annotations.length === 0) || negativeAnnotations) return found.id;
418
+ if ((found && found.annotations.length === 0) || negativeAnnotations)
419
+ return found.id;
394
420
  return null;
395
421
  },
396
422
  hoveredNotCorrectAnnotations() {
@@ -407,7 +433,7 @@ export default {
407
433
  if (annotations.length === 0) return;
408
434
 
409
435
  const found = annotations.find(
410
- (ann) => ann.id === this.annotation.id && !ann.revised
436
+ (ann) => ann.id === this.annotation.id && !ann.is_correct
411
437
  );
412
438
 
413
439
  if (found) {
@@ -494,7 +520,8 @@ export default {
494
520
 
495
521
  // Verify if we are editing a filled or empty annotation
496
522
  if (
497
- this.annotation && !this.isNegative(this.annotation) &&
523
+ this.annotation &&
524
+ !this.isNegative(this.annotation) &&
498
525
  (this.showAcceptButton() ||
499
526
  this.showDeclineButton() ||
500
527
  this.isAnnotationInEditMode(
@@ -623,12 +650,15 @@ export default {
623
650
 
624
651
  // check if the annotation to create comes from a negative annotation
625
652
  // so we can create the new one and remove the negative one from the annotations array
626
- if(this.isNegative(this.annotation)) {
653
+ if (this.isNegative(this.annotation)) {
627
654
  negativeAnnotationId = this.annotation.id;
628
655
  }
629
656
 
630
657
  this.$store
631
- .dispatch("document/createAnnotation", {annotation: annotationToCreate, negativeAnnotationId: negativeAnnotationId})
658
+ .dispatch("document/createAnnotation", {
659
+ annotation: annotationToCreate,
660
+ negativeAnnotationId: negativeAnnotationId,
661
+ })
632
662
  .catch((error) => {
633
663
  this.$store.dispatch("document/createErrorMessage", {
634
664
  error,
@@ -697,14 +727,14 @@ export default {
697
727
  }
698
728
  },
699
729
  editAnnotationTranslation(annotationId) {
700
- if(!annotationId) return;
730
+ if (!annotationId) return;
731
+
732
+ const baseUrl = api.FILE_URL ? api.FILE_URL : api.DEFAULT_URL;
701
733
 
702
- const baseUrl = api.FILE_URL ? api.FILE_URL : api.DEFAULT_URL;
703
-
704
734
  const annotationDetailsUrl = `${baseUrl}/admin/server/sequenceannotation/${annotationId}/change/`;
705
735
 
706
736
  window.open(annotationDetailsUrl, "_blank");
707
- }
737
+ },
708
738
  },
709
739
  };
710
740
  </script>
@@ -15,7 +15,7 @@
15
15
  </div>
16
16
  </div>
17
17
  <div class="label-group-right">
18
- <div v-if="!publicView" class="label-annotations-pending" >
18
+ <div v-if="!publicView" class="label-annotations-pending">
19
19
  {{
20
20
  `${
21
21
  label.annotations.length - acceptedAnnotationsGroupCounter
@@ -149,7 +149,7 @@ export default {
149
149
  mounted() {
150
150
  this.updateValues();
151
151
 
152
- if(this.publicView) {
152
+ if (this.publicView) {
153
153
  this.showAnnotationsGroup = true;
154
154
  }
155
155
  },
@@ -174,7 +174,7 @@ export default {
174
174
  labelHasPendingAnnotations(hoveredSet) {
175
175
  if (!hoveredSet) return;
176
176
 
177
- const found = this.label.annotations.find((ann) => !ann.revised);
177
+ const found = this.label.annotations.find((ann) => !ann.is_correct);
178
178
 
179
179
  return this.annotationSet.id === hoveredSet.annotationSet.id && found;
180
180
  },
@@ -161,6 +161,7 @@ export default {
161
161
  ...mapGetters("document", [
162
162
  "numberOfAnnotationSetGroup",
163
163
  "labelsFilteredForAnnotationCreation",
164
+ "isNegative",
164
165
  ]),
165
166
  ...mapState("selection", ["spanSelection"]),
166
167
  top() {
@@ -247,8 +248,24 @@ export default {
247
248
  annotationToCreate.label_set = this.selectedSet.label_set.id;
248
249
  }
249
250
 
251
+ // check if the selected label already has a negative annotation
252
+ let negativeAnnotationId;
253
+
254
+ if (this.selectedLabel.annotations.length > 0) {
255
+ const negativeAnnotation = this.selectedLabel.annotations.find(
256
+ (annotation) => this.isNegative(annotation)
257
+ );
258
+
259
+ if (negativeAnnotation) {
260
+ negativeAnnotationId = negativeAnnotation.id;
261
+ }
262
+ }
263
+
250
264
  this.$store
251
- .dispatch("document/createAnnotation", annotationToCreate)
265
+ .dispatch("document/createAnnotation", {
266
+ annotation: annotationToCreate,
267
+ negativeAnnotationId: negativeAnnotationId,
268
+ })
252
269
  .catch((error) => {
253
270
  this.$store.dispatch("document/createErrorMessage", {
254
271
  error,
@@ -4,16 +4,16 @@ describe("Document Top Bar", () => {
4
4
  let currentDocument;
5
5
 
6
6
  beforeEach(() => {
7
- cy.fetchDocument().then(() => {
7
+ cy.fetchDocument().then(() => {
8
8
  cy.getStore("document")
9
9
  .then($document => {
10
10
  currentDocument = $document.selectedDocument;
11
11
  });
12
-
12
+
13
13
  cy.getStore("project")
14
14
  .then($project => {
15
- cy.fetchCategories($project.projectId);
16
- });
15
+ cy.fetchCategories($project.projectId);
16
+ });
17
17
  });
18
18
  cy.dispatchAction("document", "setPublicView", false);
19
19
  cy.dispatchAction("edit", "disableEditMode");
@@ -30,7 +30,7 @@ describe("Document Top Bar", () => {
30
30
  });
31
31
 
32
32
  it("Shows correct file name", () => {
33
- const fileName = currentDocument.data_file_name
33
+ const fileName = currentDocument.data_file_name;
34
34
 
35
35
  cy.get("#document-top-bar-component")
36
36
  .find(".center-bar-components")
@@ -44,27 +44,27 @@ describe("Document Top Bar", () => {
44
44
  .contains(fileName);
45
45
  });
46
46
 
47
- it("Shows arrows if available documents to navigate to", () => {
47
+ it("Shows arrows if available documents to navigate to", () => {
48
48
  cy.fetchDocumentList();
49
49
  const assignee = currentDocument.assignee;
50
-
50
+
51
51
  cy.getStore("project")
52
- .then($project => {
52
+ .then($project => {
53
53
  cy.gettersStore().then(($getters) => {
54
54
  const filtered = $project.documentsInProject.filter(
55
55
  (document) =>
56
56
  ($getters["document/waitingForSplittingConfirmation"](document) || $getters["document/isDocumentReadyToBeReviewed"](document)
57
- ) && document.assignee === assignee
57
+ ) && document.assignee === assignee
58
58
  );
59
59
 
60
- if(filtered.length > 0) {
60
+ if (filtered.length > 0) {
61
61
  cy.get("#document-top-bar-component")
62
- .find(".center-bar-components")
63
- .find(".navigation-arrow")
64
- .should("be.visible");
62
+ .find(".center-bar-components")
63
+ .find(".navigation-arrow")
64
+ .should("be.visible");
65
65
  }
66
+ });
66
67
  });
67
- });
68
68
  });
69
69
 
70
70
  it("Shows keyboard icon", () => {
@@ -74,7 +74,7 @@ describe("Document Top Bar", () => {
74
74
  .should("be.visible");
75
75
  });
76
76
 
77
- it("Shows disabled finish review button", () => {
77
+ it("Shows disabled finish review button", () => {
78
78
  cy.get("#document-top-bar-component")
79
79
  .find(".right-bar-components")
80
80
  .find(".top-bar-buttons")
@@ -106,7 +106,7 @@ describe("Document Top Bar", () => {
106
106
  });
107
107
 
108
108
  it("Edits file name", () => {
109
- const fileName = currentDocument.data_file_name.split(".").slice(0, -1).join(".");
109
+ const newName = "test-name";
110
110
 
111
111
  cy.get("#document-top-bar-component")
112
112
  .find(".center-bar-components")
@@ -119,15 +119,15 @@ describe("Document Top Bar", () => {
119
119
  .find(".document-name-component")
120
120
  .find(".document-name")
121
121
  .should("have.class", "is-editable");
122
-
122
+
123
123
  cy.get("#document-top-bar-component")
124
124
  .find(".center-bar-components")
125
125
  .find(".document-name-component")
126
126
  .find(".document-name")
127
127
  .type('{selectAll}')
128
128
  .type('{backspace}')
129
- .type("test-name");
130
-
129
+ .type(newName);
130
+
131
131
  cy.get("#document-top-bar-component")
132
132
  .find(".center-bar-components")
133
133
  .find(".document-name-component")
@@ -141,7 +141,7 @@ describe("Document Top Bar", () => {
141
141
  .click();
142
142
 
143
143
  cy.wait(1000);
144
-
144
+
145
145
  cy.get("#document-top-bar-component")
146
146
  .find(".center-bar-components")
147
147
  .find(".document-name-component")
@@ -153,7 +153,7 @@ describe("Document Top Bar", () => {
153
153
  cy.get("#document-top-bar-component")
154
154
  .find(".center-bar-components")
155
155
  .find(".document-name-component")
156
- .contains(fileName);
156
+ .contains(newName);
157
157
  });
158
158
 
159
159
  it("Shows tooltip when hovering over keyboard info", () => {
@@ -167,14 +167,14 @@ describe("Document Top Bar", () => {
167
167
  .find(".keyboard-actions-info")
168
168
  .find(".keyboard-actions-description")
169
169
  .should("be.visible");
170
-
170
+
171
171
  cy.get("#document-top-bar-component")
172
172
  .find(".right-bar-components")
173
173
  .find(".keyboard-actions-info")
174
174
  .trigger("mouseleave");
175
175
  });
176
176
 
177
- it("Closes edit mode when clicking 'back to annotaiton view' button", () => {
177
+ it("Closes edit mode when clicking 'back to annotaiton view' button", () => {
178
178
  cy.dispatchAction("edit", "enableEditMode");
179
179
 
180
180
  cy.get("#document-top-bar-component")
@@ -21,7 +21,10 @@
21
21
  <b-button
22
22
  :label="editMode && !renameAndCategorize ? $t('next') : $t('submit')"
23
23
  type="is-primary"
24
- :class="['button-next primary-button edit-mode-btn', renameAndCategorize && 'submit-btn']"
24
+ :class="[
25
+ 'button-next primary-button edit-mode-btn',
26
+ renameAndCategorize && 'submit-btn',
27
+ ]"
25
28
  :disabled="renameAndCategorize && !enableSubmit"
26
29
  @click="handleButton"
27
30
  />
@@ -117,30 +117,37 @@ const getters = {
117
117
  /**
118
118
  * Gets labels for an annotation creation from a label/annotation set
119
119
  */
120
- labelsFilteredForAnnotationCreation: (state) => (set) => {
121
- let returnLabels = [];
120
+ labelsFilteredForAnnotationCreation: (_, getters) => (set) => {
121
+ let availableLabels = [];
122
122
  if (set.id && set.labels) {
123
- // if existing ann set, check for multiple
124
- returnLabels = set.labels.filter((label) => {
125
- // check if label has multiple and if not, if there's already an annotation created
126
- if (!label.has_multiple_top_candidates) {
127
- const existingLabel = state.labels.find((documentLabel) => {
128
- return documentLabel.id === label.id;
129
- });
130
- return (
131
- existingLabel &&
132
- existingLabel.annotations &&
133
- existingLabel.annotations.length === 0
134
- );
123
+ // check if label can be multiple, if there's already an annotation created & if it's a negative annotation
124
+ set.labels.map(label => {
125
+ // check if we already added the same label to the array
126
+ const found = availableLabels.find(l => l.id === label.id);
127
+
128
+ if (found) return;
129
+
130
+ if (label.annotations.length === 0) {
131
+ availableLabels.push(label);
135
132
  } else {
136
- return true;
133
+ if (label.has_multiple_top_candidates) {
134
+ availableLabels.push(label);
135
+ } else {
136
+ // if the label has negative annotations, we show the label
137
+ label.annotations.map(annotation => {
138
+ if (getters.isNegative(annotation)) {
139
+ availableLabels.push(label);
140
+ }
141
+ });
142
+ }
143
+
137
144
  }
138
145
  });
139
146
  } else if (set.labels) {
140
147
  // if not existing ann set, then return all labels
141
- returnLabels = set.labels;
148
+ availableLabels = set.labels;
142
149
  }
143
- return returnLabels;
150
+ return availableLabels;
144
151
  },
145
152
 
146
153
  /* Checks if annotation is in deleted state */
@@ -248,7 +255,7 @@ const getters = {
248
255
  const labels = [];
249
256
  const processedAnnotationSets = annotationSets.map((annotationSet) => {
250
257
  const annotationSetLabels = annotationSet.labels.map((label) => {
251
-
258
+
252
259
  // add annotations to the document array
253
260
  annotations.push(...label.annotations);
254
261
  labels.push(label);
@@ -328,7 +335,7 @@ const getters = {
328
335
  // check which one has more confidence or if it's the same, then check if one is revised or not
329
336
  if (
330
337
  highestConfidenceAnnotation.confidence <
331
- label.annotations[i].confidence ||
338
+ label.annotations[i].confidence ||
332
339
  (highestConfidenceAnnotation.confidence ===
333
340
  label.annotations[i].confidence &&
334
341
  label.annotations[i].revised)
@@ -353,17 +360,17 @@ const getters = {
353
360
  */
354
361
  isAnnotationInEditMode:
355
362
  (state) =>
356
- (annotationId, index = null) => {
357
- if (state.editAnnotation && annotationId) {
358
- if (index != null) {
359
- return (
360
- state.editAnnotation.id === annotationId &&
361
- state.editAnnotation.index === index
362
- );
363
+ (annotationId, index = null) => {
364
+ if (state.editAnnotation && annotationId) {
365
+ if (index != null) {
366
+ return (
367
+ state.editAnnotation.id === annotationId &&
368
+ state.editAnnotation.index === index
369
+ );
370
+ }
371
+ return state.editAnnotation.id === annotationId;
363
372
  }
364
- return state.editAnnotation.id === annotationId;
365
- }
366
- },
373
+ },
367
374
 
368
375
  /**
369
376
  * Get number of empty labels per annotation set
@@ -379,7 +386,7 @@ const getters = {
379
386
  annotationSet.label_set.id === l.label_set
380
387
  );
381
388
 
382
- const foundNegative = label.annotations.find(annotation =>
389
+ const foundNegative = label.annotations.find(annotation =>
383
390
  getters.isNegative(annotation)
384
391
  );
385
392
 
@@ -433,18 +440,22 @@ const getters = {
433
440
 
434
441
  if (state.annotations) {
435
442
  notCorrect = state.annotations.filter((a) => !a.is_correct);
443
+
444
+ if (notCorrect) {
445
+ notCorrect.map(annotation => {
446
+ emptyAnnotations.push(annotation);
447
+ });
448
+ }
436
449
  }
437
450
 
438
- // if all annotations have been revised
451
+ // if all annotations are correct
439
452
  // and if there are no empty annotations or
440
- // all empty annotations were marked as missing,
453
+ // all empty annotations or negative annotations were marked as missing,
441
454
  // we can finish the review
442
455
  if (
443
456
  !emptyAnnotations ||
444
457
  !state.missingAnnotations ||
445
- !notCorrect ||
446
- (notCorrect.length === 0 &&
447
- state.missingAnnotations.length === emptyAnnotations.length)
458
+ state.missingAnnotations.length === emptyAnnotations.length
448
459
  ) {
449
460
  return true;
450
461
  }
@@ -506,14 +517,14 @@ const getters = {
506
517
  */
507
518
  documentCannotBeEdited:
508
519
  (state) =>
509
- (document = state.selectedDocument) => {
510
- return (
511
- document.dataset_status === 1 ||
512
- document.dataset_status === 2 ||
513
- document.dataset_status === 3 ||
514
- document.is_reviewed
515
- );
516
- },
520
+ (document = state.selectedDocument) => {
521
+ return (
522
+ document.dataset_status === 1 ||
523
+ document.dataset_status === 2 ||
524
+ document.dataset_status === 3 ||
525
+ document.is_reviewed
526
+ );
527
+ },
517
528
 
518
529
  /**
519
530
  * If automatic splitting is enabled for the project
@@ -580,8 +591,8 @@ const getters = {
580
591
  }
581
592
  },
582
593
  isNegative: () => (annotation) => {
583
- if(annotation) {
584
- return !annotation.is_correct && annotation.revised
594
+ if (annotation) {
595
+ return !annotation.is_correct && annotation.revised;
585
596
  } else {
586
597
  return null;
587
598
  }
@@ -731,7 +742,7 @@ const actions = {
731
742
  commit("SET_LABELS", labels);
732
743
  commit("SET_SELECTED_DOCUMENT", response.data);
733
744
 
734
- if(response.data.project) {
745
+ if (response.data.project) {
735
746
  projectId = response.data.project;
736
747
 
737
748
  dispatch("project/setProjectId", projectId, {
@@ -840,7 +851,7 @@ const actions = {
840
851
  commit("SET_DOCUMENT_ANNOTATION_SELECTED", null);
841
852
  },
842
853
 
843
- createAnnotation: ({ commit, getters, dispatch }, {annotation, negativeAnnotationId}) => {
854
+ createAnnotation: ({ commit, getters, dispatch }, { annotation, negativeAnnotationId }) => {
844
855
  return new Promise((resolve, reject) => {
845
856
  HTTP.post(`/annotations/`, annotation)
846
857
  .then(async (response) => {
@@ -858,7 +869,7 @@ const actions = {
858
869
  }
859
870
  } else {
860
871
  commit("ADD_ANNOTATION", response.data);
861
- if(negativeAnnotationId) {
872
+ if (negativeAnnotationId) {
862
873
  commit("DELETE_ANNOTATION", negativeAnnotationId);
863
874
  }
864
875
  }
@@ -1156,7 +1167,7 @@ const mutations = {
1156
1167
  const exists = label.annotations.find(
1157
1168
  (existingAnnotation) => existingAnnotation.id === annotation.id
1158
1169
  );
1159
-
1170
+
1160
1171
  if (!exists) {
1161
1172
  label.annotations.push(annotation);
1162
1173
  return;