@konfuzio/document-validation-ui 0.1.14 → 0.1.16-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 (102) hide show
  1. package/README.md +12 -0
  2. package/cypress.config.js +13 -0
  3. package/dist/css/app.css +1 -1
  4. package/dist/index.html +1 -1
  5. package/dist/js/app.js +1 -1
  6. package/dist/js/app.js.map +1 -1
  7. package/dist/js/chunk-vendors.js +3 -3
  8. package/dist/js/chunk-vendors.js.map +1 -1
  9. package/package.json +5 -1
  10. package/src/api.js +53 -23
  11. package/src/assets/images/DraggableIcon.vue +14 -0
  12. package/src/assets/images/GridIcon.vue +16 -0
  13. package/src/assets/images/MagicWandIcon.vue +16 -0
  14. package/src/assets/images/NotFoundIcon.vue +16 -0
  15. package/src/assets/images/ServerImage.vue +19 -9
  16. package/src/assets/images/SettingsIcon.vue +14 -0
  17. package/src/assets/images/SplitZigZag.vue +47 -14
  18. package/src/assets/images/StarIcon.vue +16 -0
  19. package/src/assets/scss/ann_set_table_options.scss +26 -0
  20. package/src/assets/scss/annotation_details.scss +86 -71
  21. package/src/assets/scss/choose_label_set_modal.scss +1 -1
  22. package/src/assets/scss/document_annotations.scss +242 -229
  23. package/src/assets/scss/document_category.scss +12 -7
  24. package/src/assets/scss/document_dashboard.scss +7 -2
  25. package/src/assets/scss/document_edit.scss +151 -173
  26. package/src/assets/scss/document_name.scss +0 -2
  27. package/src/assets/scss/document_thumbnails.scss +1 -1
  28. package/src/assets/scss/document_toolbar.scss +23 -1
  29. package/src/assets/scss/document_top_bar.scss +40 -1
  30. package/src/assets/scss/edit_page_thumbnail.scss +53 -0
  31. package/src/assets/scss/multi_ann_table_overlay.scss +38 -0
  32. package/src/assets/scss/new_annotation.scss +17 -3
  33. package/src/assets/scss/scrolling_document.scss +1 -1
  34. package/src/assets/scss/theme.scss +801 -0
  35. package/src/assets/scss/variables.scss +5 -663
  36. package/src/components/App.cy.js +7 -0
  37. package/src/components/App.vue +98 -11
  38. package/src/components/DocumentAnnotations/AnnotationActionButtons.vue +168 -0
  39. package/src/components/DocumentAnnotations/AnnotationContent.vue +50 -84
  40. package/src/components/DocumentAnnotations/AnnotationDetails.vue +37 -12
  41. package/src/components/DocumentAnnotations/AnnotationRow.vue +244 -199
  42. package/src/components/DocumentAnnotations/AnnotationSetActionButtons.vue +89 -0
  43. package/src/components/DocumentAnnotations/ChooseLabelSetModal.vue +4 -2
  44. package/src/components/DocumentAnnotations/DocumentAnnotations.cy.js +295 -0
  45. package/src/components/DocumentAnnotations/DocumentAnnotations.vue +195 -146
  46. package/src/components/DocumentAnnotations/DocumentLabel.vue +46 -9
  47. package/src/components/DocumentAnnotations/EmptyAnnotation.vue +59 -88
  48. package/src/components/DocumentAnnotations/ExtractingData.vue +18 -6
  49. package/src/components/DocumentAnnotations/MultiAnnotationTableOverlay.vue +337 -0
  50. package/src/components/DocumentAnnotations/index.js +1 -1
  51. package/src/components/DocumentCategory.vue +89 -65
  52. package/src/components/DocumentDashboard.vue +59 -48
  53. package/src/components/DocumentEdit/DocumentEdit.vue +302 -105
  54. package/src/components/DocumentEdit/EditConfirmationModal.vue +55 -0
  55. package/src/components/DocumentEdit/EditPageThumbnail.vue +114 -0
  56. package/src/components/DocumentEdit/EditPages.vue +60 -103
  57. package/src/components/DocumentEdit/EditSidebar.vue +101 -48
  58. package/src/components/DocumentEdit/{SplitOverview.vue → RenameAndCategorize.vue} +15 -13
  59. package/src/components/DocumentEdit/SidebarButtons.vue +53 -0
  60. package/src/components/DocumentEdit/SplitInfoBar.vue +21 -0
  61. package/src/components/DocumentEdit/index.js +1 -1
  62. package/src/components/{DocumentError.vue → DocumentModals/DocumentErrorModal.vue} +9 -8
  63. package/src/components/{NotOptimizedViewportModal.vue → DocumentModals/NotOptimizedViewportModal.vue} +2 -2
  64. package/src/components/DocumentPage/ActionBar.vue +3 -3
  65. package/src/components/DocumentPage/AnnSetTableOptions.vue +110 -0
  66. package/src/components/DocumentPage/BoxSelection.vue +4 -1
  67. package/src/components/DocumentPage/DocumentPage.vue +92 -68
  68. package/src/components/DocumentPage/DocumentToolbar.vue +105 -16
  69. package/src/components/DocumentPage/DummyPage.vue +9 -7
  70. package/src/components/DocumentPage/MultiAnnSelection.vue +96 -27
  71. package/src/components/DocumentPage/NewAnnotation.vue +31 -35
  72. package/src/components/DocumentPage/ScrollingDocument.vue +46 -5
  73. package/src/components/DocumentPage/ScrollingPage.vue +5 -6
  74. package/src/components/DocumentThumbnails/DocumentThumbnails.cy.js +64 -0
  75. package/src/components/DocumentThumbnails/DocumentThumbnails.vue +53 -13
  76. package/src/components/DocumentTopBar/DocumentName.vue +16 -4
  77. package/src/components/DocumentTopBar/DocumentTopBar.vue +86 -15
  78. package/src/components/DocumentTopBar/DocumentTopBarButtons.vue +99 -72
  79. package/src/components/DocumentTopBar/KeyboardActionsDescription.vue +6 -3
  80. package/src/components/DocumentsList/DocumentsList.vue +6 -2
  81. package/src/components/index.js +1 -0
  82. package/src/constants.js +2 -1
  83. package/src/icons.js +45 -0
  84. package/src/locales/de.json +48 -21
  85. package/src/locales/en.json +37 -11
  86. package/src/locales/es.json +41 -13
  87. package/src/main.js +5 -66
  88. package/src/store/category.js +20 -36
  89. package/src/store/display.js +74 -1
  90. package/src/store/document.js +305 -109
  91. package/src/store/edit.js +160 -61
  92. package/src/store/project.js +46 -16
  93. package/src/store/selection.js +42 -10
  94. package/src/utils/utils.js +36 -0
  95. package/dist/css/chunk-vendors.css +0 -5
  96. package/src/.DS_Store +0 -0
  97. package/src/assets/scss/categorize_modal.scss +0 -45
  98. package/src/assets/scss/main.scss +0 -24
  99. package/src/components/DocumentAnnotations/ActionButtons.vue +0 -250
  100. package/src/components/DocumentAnnotations/CategorizeModal.vue +0 -219
  101. package/src/components/DocumentAnnotations/RejectedLabels.vue +0 -96
  102. package/src/components/DocumentPage/MultiAnnotationTablePopup.vue +0 -253
@@ -1,8 +1,15 @@
1
1
  import myImports from "../api";
2
- import { sleep } from "../utils/utils";
2
+ import { MULTI_ANN_TABLE_FEATURE } from "../constants";
3
+ import {
4
+ sleep,
5
+ getURLQueryParam,
6
+ navigateToNewDocumentURL,
7
+ getURLPath,
8
+ } from "../utils/utils";
3
9
 
4
10
  const HTTP = myImports.HTTP;
5
11
  const documentPollDuration = 1000;
12
+ export const table_reference_api = "api.v3.dvui.table";
6
13
 
7
14
  const state = {
8
15
  loading: true,
@@ -10,7 +17,7 @@ const state = {
10
17
  annotationSets: null,
11
18
  annotations: null,
12
19
  labels: [],
13
- documentId: null,
20
+ documentId: process.env.VUE_APP_DOCUMENT_ID,
14
21
  sidebarAnnotationSelected: null,
15
22
  documentAnnotationSelected: null,
16
23
  selectedDocument: null,
@@ -21,14 +28,13 @@ const state = {
21
28
  showActionError: false,
22
29
  errorMessage: null,
23
30
  showDocumentError: false,
24
- rejectedMissingAnnotations: null,
31
+ annotationsMarkedAsMissing: null,
25
32
  errorMessageWidth: null,
26
33
  hoveredAnnotationSet: null,
27
- finishedReview: false,
28
34
  newAcceptedAnnotations: null,
29
- selectedEntities: null,
30
35
  serverError: false,
31
- categorizeModalIsActive: false,
36
+ splittingSuggestions: null,
37
+ enableGroupingFeature: true,
32
38
  };
33
39
 
34
40
  const getters = {
@@ -158,6 +164,83 @@ const getters = {
158
164
  return state.annotationSets.find((annSet) => annSet.id === annotationSetId);
159
165
  },
160
166
 
167
+ /* Get annotation sets created in table */
168
+ annotationSetsInTable: (state) => () => {
169
+ const annotationSetsList = {};
170
+ if (MULTI_ANN_TABLE_FEATURE) {
171
+ state.annotationSets.forEach((annotationSet) => {
172
+ let addAnnotationSet = false;
173
+ if (annotationSet.labels) {
174
+ annotationSet.labels.forEach((label) => {
175
+ if (
176
+ label.annotations &&
177
+ label.annotations.find(
178
+ (annotation) =>
179
+ annotation.origin && annotation.origin === table_reference_api
180
+ )
181
+ ) {
182
+ addAnnotationSet = true;
183
+ return;
184
+ }
185
+ });
186
+ }
187
+ if (addAnnotationSet) {
188
+ // group by label set
189
+ if (annotationSetsList[`${annotationSet.label_set.id}`]) {
190
+ annotationSetsList[`${annotationSet.label_set.id}`].push(
191
+ annotationSet
192
+ );
193
+ } else {
194
+ annotationSetsList[`${annotationSet.label_set.id}`] = [
195
+ annotationSet,
196
+ ];
197
+ }
198
+ }
199
+ });
200
+ }
201
+ return annotationSetsList;
202
+ },
203
+
204
+ /* Get annotation sets without tables */
205
+ annotationSetsToShowInList: (state) => () => {
206
+ const annotationSetsList = [];
207
+ state.annotationSets.forEach((annotationSet) => {
208
+ let addAnnotationSet = true;
209
+ if (annotationSet.labels) {
210
+ annotationSet.labels.forEach((label) => {
211
+ if (
212
+ MULTI_ANN_TABLE_FEATURE &&
213
+ label.annotations &&
214
+ label.annotations.find(
215
+ (annotation) =>
216
+ annotation.origin && annotation.origin === table_reference_api
217
+ )
218
+ ) {
219
+ addAnnotationSet = false;
220
+ return;
221
+ }
222
+ });
223
+ }
224
+ if (addAnnotationSet) {
225
+ annotationSetsList.push(annotationSet);
226
+ }
227
+ });
228
+ return annotationSetsList;
229
+ },
230
+
231
+ /* Get annotations inside a list of annotation sets */
232
+ annotationsInAnnotationsSets: (state) => (annotationsSets) => {
233
+ const annotations = [];
234
+ annotationsSets.forEach((annotationSet) => {
235
+ annotationSet.labels.forEach((label) => {
236
+ label.annotations.forEach((annotation) => {
237
+ annotations.push(annotation);
238
+ });
239
+ });
240
+ });
241
+ return annotations;
242
+ },
243
+
161
244
  /* Process annotations and extract labels and sets */
162
245
  processAnnotationSets: (state, getters) => (annotationSets) => {
163
246
  // group annotations for sidebar
@@ -165,14 +248,11 @@ const getters = {
165
248
  const labels = [];
166
249
  const processedAnnotationSets = annotationSets.map((annotationSet) => {
167
250
  const annotationSetLabels = annotationSet.labels.map((label) => {
168
- // filter label
169
- const filteredLabel = getters.annotationsInLabelFiltered(label);
170
-
171
251
  // add annotations to the document array
172
- annotations.push(...filteredLabel.annotations);
173
- labels.push(filteredLabel);
252
+ annotations.push(...label.annotations);
253
+ labels.push(label);
174
254
  // add labels to the labels array
175
- return filteredLabel;
255
+ return label;
176
256
  });
177
257
  annotationSet.labels = annotationSetLabels;
178
258
  return annotationSet;
@@ -185,6 +265,18 @@ const getters = {
185
265
  };
186
266
  },
187
267
 
268
+ /* Checks if there are annotations correct in the document */
269
+ documentHasCorrectAnnotations: (state) => () => {
270
+ if (
271
+ !state.annotations ||
272
+ (state.annotations &&
273
+ state.annotations.filter((ann) => ann.is_correct).length > 0)
274
+ ) {
275
+ return true;
276
+ }
277
+ return false;
278
+ },
279
+
188
280
  /* Returns the number of accepted annotations in a label */
189
281
  numberOfAcceptedAnnotationsInLabel: (_) => (label) => {
190
282
  const annotations = label.annotations.filter((annotation) => {
@@ -217,6 +309,7 @@ const getters = {
217
309
  });
218
310
  return found ? `${value + 1}` : "";
219
311
  }
312
+ return "";
220
313
  },
221
314
 
222
315
  /**
@@ -297,14 +390,32 @@ const getters = {
297
390
  return pendingEmpty.length;
298
391
  },
299
392
 
393
+ annotationIsNotFound: (state) => (annotationSet, label) => {
394
+ // Check if the combined label and label set have been marked as missing
395
+ // or if the document is in public mode
396
+ if (state.missingAnnotations.length === 0) {
397
+ return false;
398
+ } else {
399
+ const found = state.missingAnnotations.filter(
400
+ (el) =>
401
+ el.label === label.id &&
402
+ el.annotation_set === annotationSet.id &&
403
+ el.label_set === annotationSet.label_set.id
404
+ );
405
+ return found.length !== 0;
406
+ }
407
+ },
408
+
300
409
  // Check if document is ready to be finished
301
- isDocumentReviewFinished: (state) => () => {
410
+ isDocumentReadyToFinishReview: (state) => {
302
411
  // check if all annotations have been revised
303
412
  let notRevised;
304
413
 
305
414
  const emptyAnnotations = [];
306
415
 
307
- if (state.annotationSets) {
416
+ if (state.labels.length === 0) return false;
417
+
418
+ if (state.annotationSets && state.annotationSets.length > 0) {
308
419
  state.annotationSets.forEach((annSet) => {
309
420
  annSet.labels.map((label) => {
310
421
  // return only labels with empty annotations
@@ -324,7 +435,7 @@ const getters = {
324
435
 
325
436
  // if all annotations have been revised
326
437
  // and if there are no empty annotations or
327
- // all empty annotations were rejected,
438
+ // all empty annotations were marked as missing,
328
439
  // we can finish the review
329
440
  if (
330
441
  !emptyAnnotations ||
@@ -335,10 +446,13 @@ const getters = {
335
446
  ) {
336
447
  return true;
337
448
  }
338
-
339
449
  return false;
340
450
  },
341
451
 
452
+ isDocumentReviewed: (state) => {
453
+ return state.selectedDocument.is_reviewed;
454
+ },
455
+
342
456
  /**
343
457
  * Get number of annotations pending review per annotation set
344
458
  */
@@ -359,12 +473,12 @@ const getters = {
359
473
  annotationsWithPendingReview.push(annotation);
360
474
  });
361
475
  }
362
- });
363
476
 
364
- // Check if we have grouped annotations by same label
365
- if (state.enableGroupingFeature && label.annotations.length < 2) {
366
- return annotationsWithPendingReview.length - label.annotations.length;
367
- }
477
+ // Check if we have grouped annotations by same label
478
+ if (state.enableGroupingFeature && label.annotations.length < 2) {
479
+ return annotationsWithPendingReview.length - label.annotations.length;
480
+ }
481
+ });
368
482
 
369
483
  return annotationsWithPendingReview.length;
370
484
  },
@@ -397,23 +511,18 @@ const getters = {
397
511
  );
398
512
  },
399
513
 
400
- documentHasCorrectAnnotations: (state) => () => {
401
- return (
402
- state.annotations &&
403
- state.annotations.filter((ann) => ann.is_correct).length > 0
404
- );
514
+ /**
515
+ * If automatic splitting is enabled for the project
516
+ */
517
+ waitingForSplittingConfirmation: () => (document) => {
518
+ return document && document.status_data === 41;
405
519
  },
406
520
 
407
521
  /**
408
- * Joins all strings in a multi-entity Annotation array
409
- * to look like a single string
522
+ * Show the Smart Split switch or not
410
523
  */
411
- getTextFromEntities: (state) => () => {
412
- return state.selectedEntities
413
- .map((entity) => {
414
- return entity.content;
415
- })
416
- .join(" ");
524
+ documentHasProposedSplit: () => (document) => {
525
+ return document.proposed_split && document.proposed_split.length > 0;
417
526
  },
418
527
 
419
528
  /**
@@ -430,7 +539,7 @@ const getters = {
430
539
  /**
431
540
  * Check status of annotation
432
541
  */
433
- notFound: () => (annotation) => {
542
+ notExtracted: () => (annotation) => {
434
543
  if (annotation) {
435
544
  return !annotation.span;
436
545
  } else {
@@ -559,8 +668,8 @@ const actions = {
559
668
  setDocumentError: ({ commit }, value) => {
560
669
  commit("SET_DOCUMENT_ERROR", value);
561
670
  },
562
- setRejectedMissingAnnotations: ({ commit }, annotations) => {
563
- commit("SET_REJECTED_MISSING_ANNOTATIONS", annotations);
671
+ setAnnotationsMarkedAsMissing: ({ commit }, annotations) => {
672
+ commit("SET_ANNOTATIONS_MARKED_AS_MISSING", annotations);
564
673
  },
565
674
  setErrorMessageWidth: ({ commit }, width) => {
566
675
  commit("SET_ERROR_MESSAGE_WIDTH", width);
@@ -571,11 +680,8 @@ const actions = {
571
680
  setNewAcceptedAnnotations: ({ commit }, annotations) => {
572
681
  commit("SET_NEW_ACCEPTED_ANNOTATIONS", annotations);
573
682
  },
574
- setSelectedEntities: ({ commit }, entities) => {
575
- commit("SET_SELECTED_ENTITIES", entities);
576
- },
577
- setCategorizeModalIsActive: ({ commit }, value) => {
578
- commit("SET_CATEGORIZE_MODAL_IS_ACTIVE", value);
683
+ setSplittingSuggestions: ({ commit }, value) => {
684
+ commit("SET_SPLITTING_SUGGESTIONS", value);
579
685
  },
580
686
 
581
687
  /**
@@ -605,14 +711,14 @@ const actions = {
605
711
 
606
712
  // load first page
607
713
  if (response.data.pages.length > 0) {
608
- await dispatch("fetchDocumentPage", initialPage);
714
+ dispatch("fetchDocumentPage", initialPage);
609
715
  }
716
+
610
717
  // set information on the store
611
718
  commit("SET_ANNOTATION_SETS", annotationSets);
612
719
  commit("SET_ANNOTATIONS", annotations);
613
720
  commit("SET_LABELS", labels);
614
721
  commit("SET_SELECTED_DOCUMENT", response.data);
615
- commit("SET_FINISHED_REVIEW", getters.isDocumentReviewFinished());
616
722
 
617
723
  if (rootState.project.projectId) {
618
724
  projectId = rootState.project.projectId;
@@ -623,6 +729,10 @@ const actions = {
623
729
  });
624
730
  }
625
731
 
732
+ if (getters.documentHasProposedSplit(response.data)) {
733
+ commit("SET_SPLITTING_SUGGESTIONS", response.data.proposed_split);
734
+ }
735
+
626
736
  categoryId = response.data.category;
627
737
  // TODO: add this validation to a method
628
738
  isRecalculatingAnnotations = response.data.labeling_available !== 1;
@@ -634,23 +744,41 @@ const actions = {
634
744
  });
635
745
 
636
746
  if (!state.publicView) {
747
+ await dispatch("fetchMissingAnnotations");
748
+
637
749
  await dispatch("project/fetchCurrentUser", null, {
638
750
  root: true,
639
751
  });
640
752
 
641
- await dispatch("fetchMissingAnnotations");
753
+ // Check if we first open the document dashboard or the edit mode
754
+ if (
755
+ !state.selectedDocument.category ||
756
+ (!state.selectedDocument.category_is_revised &&
757
+ !getters.documentHasCorrectAnnotations() &&
758
+ state.missingAnnotations.length === 0)
759
+ ) {
760
+ dispatch("edit/enableEditMode", null, {
761
+ root: true,
762
+ });
763
+ dispatch("edit/setRenameAndCategorize", true, { root: true });
764
+ }
642
765
 
643
766
  if (projectId) {
644
767
  await dispatch("category/fetchCategories", projectId, {
645
768
  root: true,
646
769
  });
770
+
771
+ // get list of documents not reviewed
772
+ await dispatch("project/fetchDocumentList", "is_reviewed=false", {
773
+ root: true,
774
+ });
647
775
  }
648
- if (categoryId) {
776
+ if (categoryId && rootState.category.createAvailableListOfDocuments) {
649
777
  await dispatch(
650
778
  "category/createAvailableDocumentsList",
651
779
  {
652
780
  categoryId,
653
- user: rootState.project.currentUser,
781
+ user: rootState.project.currentUser.username,
654
782
  poll: pollDocumentList,
655
783
  },
656
784
  {
@@ -686,7 +814,7 @@ const actions = {
686
814
  id: annotation.id,
687
815
  span,
688
816
  page: span.page_index + 1,
689
- labelName: label.name,
817
+ labelName: label ? label.name : "",
690
818
  };
691
819
  commit("SET_DOCUMENT_ANNOTATION_SELECTED", value);
692
820
  },
@@ -704,8 +832,7 @@ const actions = {
704
832
  HTTP.post(`/annotations/`, annotation)
705
833
  .then(async (response) => {
706
834
  if (response.status === 201) {
707
- dispatch("fetchMissingAnnotations");
708
- commit("SET_FINISHED_REVIEW", getters.isDocumentReviewFinished());
835
+ await dispatch("fetchMissingAnnotations");
709
836
 
710
837
  if (!getters.annotationSetExists(response.data.annotation_set)) {
711
838
  const documentData = await dispatch("fetchDocumentData");
@@ -719,6 +846,7 @@ const actions = {
719
846
  } else {
720
847
  commit("ADD_ANNOTATION", response.data);
721
848
  }
849
+
722
850
  resolve(response);
723
851
  }
724
852
  })
@@ -729,16 +857,19 @@ const actions = {
729
857
  });
730
858
  },
731
859
 
732
- updateAnnotation: ({ commit, getters }, { updatedValues, annotationId }) => {
860
+ updateAnnotation: (
861
+ { commit, getters, dispatch },
862
+ { updatedValues, annotationId }
863
+ ) => {
733
864
  commit("SET_NEW_ACCEPTED_ANNOTATIONS", [annotationId]);
734
865
 
735
866
  return new Promise((resolve, reject) => {
736
867
  HTTP.patch(`/annotations/${annotationId}/`, updatedValues)
737
- .then((response) => {
868
+ .then(async (response) => {
738
869
  if (response.status === 200) {
739
870
  commit("UPDATE_ANNOTATION", response.data);
740
- commit("SET_FINISHED_REVIEW", getters.isDocumentReviewFinished());
741
871
  commit("SET_NEW_ACCEPTED_ANNOTATIONS", null);
872
+
742
873
  resolve(true);
743
874
  }
744
875
  })
@@ -749,13 +880,13 @@ const actions = {
749
880
  });
750
881
  },
751
882
 
752
- deleteAnnotation: ({ commit, getters }, { annotationId }) => {
883
+ deleteAnnotation: ({ commit, getters, dispatch }, { annotationId }) => {
753
884
  return new Promise((resolve, reject) => {
754
885
  HTTP.delete(`/annotations/${annotationId}/`)
755
- .then((response) => {
886
+ .then(async (response) => {
756
887
  if (response.status === 204) {
757
888
  commit("DELETE_ANNOTATION", annotationId);
758
- commit("SET_FINISHED_REVIEW", getters.isDocumentReviewFinished());
889
+
759
890
  resolve(true);
760
891
  }
761
892
  })
@@ -777,7 +908,6 @@ const actions = {
777
908
  commit("UPDATE_FILE_NAME", response.data.data_file_name);
778
909
  } else {
779
910
  commit("SET_SELECTED_DOCUMENT", response.data);
780
- commit("SET_FINISHED_REVIEW", getters.isDocumentReviewFinished());
781
911
 
782
912
  dispatch("pollDocumentEndpoint");
783
913
  }
@@ -786,32 +916,50 @@ const actions = {
786
916
  }
787
917
  })
788
918
  .catch((error) => {
789
- reject(error.response);
790
919
  console.log(error);
920
+ // check if review error
921
+ if (
922
+ error.response &&
923
+ error.response.request &&
924
+ error.response.request.response
925
+ ) {
926
+ const is_reviewed = JSON.parse(error.request.response).is_reviewed;
927
+ if (is_reviewed && is_reviewed.length > 0) {
928
+ const errorData = {
929
+ data: [...is_reviewed],
930
+ };
931
+ reject(errorData);
932
+ return;
933
+ }
934
+ }
935
+ reject(error.response);
791
936
  });
792
937
  });
793
938
  },
794
939
 
795
940
  fetchMissingAnnotations: ({ commit, state, getters }) => {
796
- return HTTP.get(
797
- `/missing-annotations/?document=${state.documentId}&limit=100`
798
- )
799
- .then((response) => {
800
- commit("SET_MISSING_ANNOTATIONS", response.data.results);
801
- commit("SET_FINISHED_REVIEW", getters.isDocumentReviewFinished());
802
- })
803
- .catch((error) => {
804
- console.log(error);
805
- });
941
+ return new Promise((resolve, reject) => {
942
+ return HTTP.get(
943
+ `/missing-annotations/?document=${state.documentId}&limit=100`
944
+ )
945
+ .then((response) => {
946
+ commit("SET_MISSING_ANNOTATIONS", response.data.results);
947
+ resolve(true);
948
+ })
949
+ .catch((error) => {
950
+ reject(error.response);
951
+ console.log(error);
952
+ });
953
+ });
806
954
  },
807
955
 
808
- addMissingAnnotations: ({ commit, dispatch }, missingAnnotations) => {
956
+ addMissingAnnotations: ({ commit, getters }, missingAnnotations) => {
809
957
  return new Promise((resolve, reject) => {
810
- return HTTP.post(`/missing-annotations/`, missingAnnotations)
811
- .then((response) => {
958
+ HTTP.post(`/missing-annotations/`, missingAnnotations)
959
+ .then(async (response) => {
812
960
  if (response.status === 201) {
813
- commit("SET_REJECTED_MISSING_ANNOTATIONS", null);
814
- dispatch("fetchMissingAnnotations");
961
+ commit("SET_ANNOTATIONS_MARKED_AS_MISSING", null);
962
+ commit("ADD_MISSING_ANNOTATIONS", response.data);
815
963
  }
816
964
 
817
965
  resolve(response);
@@ -823,17 +971,17 @@ const actions = {
823
971
  });
824
972
  },
825
973
 
826
- deleteMissingAnnotation: ({ commit, getters, dispatch }, id) => {
827
- return new Promise((resolve) => {
974
+ deleteMissingAnnotation: ({ commit, getters }, id) => {
975
+ return new Promise((resolve, reject) => {
828
976
  return HTTP.delete(`/missing-annotations/${id}/`)
829
977
  .then((response) => {
830
978
  if (response.status === 204) {
831
- dispatch("fetchMissingAnnotations");
979
+ commit("DELETE_MISSING_ANNOTATION", id);
832
980
  resolve(true);
833
981
  }
834
982
  })
835
983
  .catch((error) => {
836
- resolve(error.response);
984
+ reject(error.response);
837
985
  console.log(error);
838
986
  });
839
987
  });
@@ -869,8 +1017,11 @@ const actions = {
869
1017
  `documents/${state.documentId}/?fields=status_data,labeling_available`
870
1018
  )
871
1019
  .then((response) => {
872
- if (getters.isDocumentReadyToBeReviewed(response.data)) {
873
- // ready
1020
+ if (
1021
+ getters.isDocumentReadyToBeReviewed(response.data) ||
1022
+ getters.waitingForSplittingConfirmation(response.data)
1023
+ ) {
1024
+ // ready or has splitting suggestions
874
1025
  return resolve(true);
875
1026
  } else if (getters.documentHadErrorDuringExtraction(response.data)) {
876
1027
  // error
@@ -881,6 +1032,7 @@ const actions = {
881
1032
  }
882
1033
  })
883
1034
  .catch((error) => {
1035
+ reject(error.response);
884
1036
  console.log(error);
885
1037
  });
886
1038
  });
@@ -924,14 +1076,8 @@ const actions = {
924
1076
  { commit, dispatch },
925
1077
  { error, serverErrorMessage, defaultErrorMessage }
926
1078
  ) => {
927
- let errorAsString;
928
-
929
- if (error && error.status) {
930
- errorAsString = error.status.toString();
931
- }
932
-
933
1079
  // check type of error
934
- if (error && error.status === 500) {
1080
+ if (error && error.status >= 500 && error.status < 600) {
935
1081
  dispatch("setErrorMessage", serverErrorMessage);
936
1082
  commit("SET_SERVER_ERROR", true);
937
1083
  } else if (error.data && error.data.length > 0) {
@@ -950,12 +1096,26 @@ const actions = {
950
1096
  },
951
1097
 
952
1098
  contactSupport: ({ rootState }, error) => {
953
- const url = "https://konfuzio.com/en/support/";
954
- const params = `project=${rootState.project.projectId}&email=${rootState.project.currentUser}&issue=${error}`;
1099
+ const url = "https://konfuzio.com/support/";
1100
+ const params = `project=${rootState.project.projectId}&email=${rootState.project.currentUser.username}&issue=${error}`;
955
1101
  const fullUrl = `${url}?${params}`;
956
1102
 
957
1103
  window.open(fullUrl, "_blank");
958
1104
  },
1105
+
1106
+ changeCurrentDocument: ({ commit, state, dispatch }, newDocumentId) => {
1107
+ // reset splitting suggestions
1108
+ if (state.splittingSuggestions) {
1109
+ commit("SET_SPLITTING_SUGGESTIONS", null);
1110
+ }
1111
+
1112
+ if (getURLQueryParam("document") || getURLPath("d")) {
1113
+ navigateToNewDocumentURL(state.selectedDocument.id, newDocumentId);
1114
+ } else {
1115
+ commit("SET_DOC_ID", newDocumentId);
1116
+ dispatch("fetchDocument");
1117
+ }
1118
+ },
959
1119
  };
960
1120
 
961
1121
  const mutations = {
@@ -994,7 +1154,7 @@ const mutations = {
994
1154
  (existingAnnotation) => existingAnnotation.id === annotation.id
995
1155
  );
996
1156
  if (indexOfAnnotationInAnnotations > -1) {
997
- state.annotations[indexOfAnnotationInAnnotations] = annotation;
1157
+ state.annotations.splice(indexOfAnnotationInAnnotations, 1, annotation);
998
1158
  }
999
1159
  let updatedAnnotation = false;
1000
1160
  state.annotationSets.forEach((annotationSet) => {
@@ -1006,11 +1166,21 @@ const mutations = {
1006
1166
  (existingAnnotation) => existingAnnotation.id === annotation.id
1007
1167
  );
1008
1168
  if (indexOfAnnotationAnnotationSets > -1) {
1009
- label.annotations.splice(
1010
- indexOfAnnotationAnnotationSets,
1011
- 1,
1012
- annotation
1013
- );
1169
+ // checks if an annotation label was changed and add it to the new label
1170
+ if (annotation.label && annotation.label.id !== label.id) {
1171
+ label.annotations.splice(indexOfAnnotationAnnotationSets, 1);
1172
+
1173
+ const labelToAdd = annotationSet.labels.find(
1174
+ (labelToAdd) => labelToAdd.id === annotation.label.id
1175
+ );
1176
+ labelToAdd.annotations.push(annotation);
1177
+ } else {
1178
+ label.annotations.splice(
1179
+ indexOfAnnotationAnnotationSets,
1180
+ 1,
1181
+ annotation
1182
+ );
1183
+ }
1014
1184
  updatedAnnotation = true;
1015
1185
  return;
1016
1186
  }
@@ -1056,9 +1226,6 @@ const mutations = {
1056
1226
  SET_EDIT_ANNOTATION: (state, editAnnotation) => {
1057
1227
  state.editAnnotation = editAnnotation;
1058
1228
  },
1059
- SET_FINISHED_REVIEW: (state, finishedReview) => {
1060
- state.finishedReview = finishedReview;
1061
- },
1062
1229
  RESET_EDIT_ANNOTATION: (state) => {
1063
1230
  state.editAnnotation = null;
1064
1231
  },
@@ -1086,13 +1253,12 @@ const mutations = {
1086
1253
  }
1087
1254
  },
1088
1255
  SET_SELECTED_DOCUMENT: (state, document) => {
1089
- if (document.is_reviewed === true) {
1090
- state.publicView = true;
1091
- }
1092
1256
  state.selectedDocument = document;
1093
1257
 
1094
1258
  // this is to handle cache when a document is edited or changed
1095
- state.selectedDocument.downloaded_at = Date.now();
1259
+ if (state.selectedDocument) {
1260
+ state.selectedDocument.downloaded_at = Date.now();
1261
+ }
1096
1262
  },
1097
1263
  SET_RECALCULATING_ANNOTATIONS: (state, recalculatingAnnotations) => {
1098
1264
  state.recalculatingAnnotations = recalculatingAnnotations;
@@ -1100,7 +1266,39 @@ const mutations = {
1100
1266
  SET_MISSING_ANNOTATIONS: (state, missingAnnotations) => {
1101
1267
  state.missingAnnotations = missingAnnotations;
1102
1268
  },
1269
+ ADD_MISSING_ANNOTATIONS: (state, annotations) => {
1270
+ if (annotations && annotations.length > 0) {
1271
+ annotations.map((annotation) => {
1272
+ // check if already in missingAnnotations
1273
+ const found = state.missingAnnotations.find(
1274
+ (missingAnnotation) => missingAnnotation.id === annotation.id
1275
+ );
1103
1276
 
1277
+ if (found) {
1278
+ const indexOfAnnotation = state.missingAnnotations.findIndex(
1279
+ (missingAnnotation) => missingAnnotation.id === annotation.id
1280
+ );
1281
+
1282
+ if (indexOfAnnotation > -1) {
1283
+ state.missingAnnotations.splice(indexOfAnnotation, 1, annotation);
1284
+ }
1285
+ } else {
1286
+ state.missingAnnotations.push(annotation);
1287
+ }
1288
+ });
1289
+ } else {
1290
+ state.missingAnnotations.push(annotations);
1291
+ }
1292
+ },
1293
+ DELETE_MISSING_ANNOTATION: (state, id) => {
1294
+ const indexOfAnnotationToDelete = state.missingAnnotations.findIndex(
1295
+ (annotation) => annotation.id === id
1296
+ );
1297
+
1298
+ if (indexOfAnnotationToDelete > -1) {
1299
+ state.missingAnnotations.splice(indexOfAnnotationToDelete, 1);
1300
+ }
1301
+ },
1104
1302
  SET_SHOW_ACTION_ERROR: (state, value) => {
1105
1303
  state.showActionError = value;
1106
1304
  },
@@ -1110,8 +1308,8 @@ const mutations = {
1110
1308
  SET_DOCUMENT_ERROR: (state, value) => {
1111
1309
  state.showDocumentError = value;
1112
1310
  },
1113
- SET_REJECTED_MISSING_ANNOTATIONS: (state, annotations) => {
1114
- state.rejectedMissingAnnotations = annotations;
1311
+ SET_ANNOTATIONS_MARKED_AS_MISSING: (state, annotations) => {
1312
+ state.annotationsMarkedAsMissing = annotations;
1115
1313
  },
1116
1314
  SET_ERROR_MESSAGE_WIDTH: (state, width) => {
1117
1315
  state.errorMessageWidth = width;
@@ -1131,18 +1329,16 @@ const mutations = {
1131
1329
  SET_NEW_ACCEPTED_ANNOTATIONS: (state, annotations) => {
1132
1330
  state.newAcceptedAnnotations = annotations;
1133
1331
  },
1134
- SET_SELECTED_ENTITIES: (state, entities) => {
1135
- state.selectedEntities = entities;
1136
- },
1137
1332
  SET_SERVER_ERROR: (state, value) => {
1138
1333
  state.serverError = value;
1139
1334
  },
1140
- SET_CATEGORIZE_MODAL_IS_ACTIVE: (state, value) => {
1141
- state.categorizeModalIsActive = value;
1142
- },
1335
+
1143
1336
  UPDATE_FILE_NAME: (state, value) => {
1144
1337
  state.selectedDocument.data_file_name = value;
1145
1338
  },
1339
+ SET_SPLITTING_SUGGESTIONS: (state, array) => {
1340
+ state.splittingSuggestions = array;
1341
+ },
1146
1342
  };
1147
1343
 
1148
1344
  export default {