@konfuzio/document-validation-ui 0.1.14 → 0.1.15

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 (101) 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/assets/scss/categorize_modal.scss +0 -45
  97. package/src/assets/scss/main.scss +0 -24
  98. package/src/components/DocumentAnnotations/ActionButtons.vue +0 -250
  99. package/src/components/DocumentAnnotations/CategorizeModal.vue +0 -219
  100. package/src/components/DocumentAnnotations/RejectedLabels.vue +0 -96
  101. package/src/components/DocumentPage/MultiAnnotationTablePopup.vue +0 -253
package/src/store/edit.js CHANGED
@@ -1,14 +1,53 @@
1
1
  import myImports from "../api";
2
+ import {
3
+ getURLQueryParam,
4
+ navigateToNewDocumentURL,
5
+ getURLPath,
6
+ } from "../utils/utils";
2
7
 
3
8
  const HTTP = myImports.HTTP;
4
9
 
5
10
  const state = {
6
11
  editMode: false,
7
- splitOverview: false,
8
- isMultipleSelection: false,
9
- documentPagesListForEditMode: [], // TODO: change name
12
+ renameAndCategorize: false,
13
+ isMultipleSelection: true,
14
+ pagesForPostprocess: [],
10
15
  selectedPages: [],
11
16
  updatedDocument: [],
17
+ showEditConfirmationModal: false,
18
+ submitEditChanges: false,
19
+ redirectingUser: false,
20
+ };
21
+
22
+ const getters = {
23
+ isPageSelected: (state) => (id) => {
24
+ return state.selectedPages.find((page) => page.id === id);
25
+ },
26
+
27
+ documentShouldBePostprocessed: (state, _, rootState) => {
28
+ const foundRotatedPage = state.pagesForPostprocess.find(
29
+ (page) => page.angle !== 0
30
+ );
31
+
32
+ let foundReorderedPage = false;
33
+
34
+ state.pagesForPostprocess.map((page, index) => {
35
+ if (
36
+ (page.id === rootState.document.selectedDocument.pages[index].id &&
37
+ page.number !==
38
+ rootState.document.selectedDocument.pages[index].number) ||
39
+ (page.id !== rootState.document.selectedDocument.pages[index].id &&
40
+ page.number ===
41
+ rootState.document.selectedDocument.pages[index].number)
42
+ ) {
43
+ foundReorderedPage = true;
44
+ }
45
+ });
46
+
47
+ return (
48
+ state.updatedDocument.length > 1 || foundRotatedPage || foundReorderedPage
49
+ );
50
+ },
12
51
  };
13
52
 
14
53
  const actions = {
@@ -18,21 +57,46 @@ const actions = {
18
57
 
19
58
  disableEditMode: ({ commit }) => {
20
59
  commit("SET_EDIT_MODE", false);
21
- commit("SET_SPLIT_OVERVIEW", false);
60
+ commit("SET_RENAME_AND_CATEGORIZE", false);
22
61
  },
23
62
 
24
- setSplitOverview: ({ commit }, overview) => {
25
- commit("SET_SPLIT_OVERVIEW", overview);
63
+ setRenameAndCategorize: ({ commit }, value) => {
64
+ commit("SET_RENAME_AND_CATEGORIZE", value);
26
65
  },
27
66
 
28
- setDocumentPagesListForEditMode: ({ commit }, pages) => {
29
- commit("SET_DOCUMENT_PAGES_FOR_EDIT_MODE", pages);
67
+ setPagesForPostprocess: ({ commit }, pages) => {
68
+ commit("SET_PAGES_FOR_POSTPROCESS", pages);
30
69
  },
31
70
 
32
71
  setUpdatedDocument: ({ commit }, updatedDocument) => {
33
72
  commit("SET_UPDATED_DOCUMENT", updatedDocument);
34
73
  },
35
74
 
75
+ setSubmitEditChanges: ({ commit }, value) => {
76
+ commit("SET_SUBMIT_EDIT_CHANGES", value);
77
+ },
78
+
79
+ selectPage: ({ state, commit }, page) => {
80
+ if (state.isMultipleSelection) {
81
+ commit("ADD_SELECTED_PAGE", page);
82
+ } else {
83
+ commit("SET_SELECTED_PAGES", []);
84
+ commit("ADD_SELECTED_PAGE", page);
85
+ }
86
+ },
87
+
88
+ unselectPage: ({ state, commit }, selectedPage) => {
89
+ const found = state.selectedPages.find(
90
+ (page) => page.id === selectedPage.id
91
+ );
92
+ if (found) {
93
+ const filtered = state.selectedPages.filter(
94
+ (page) => page.id !== selectedPage.id
95
+ );
96
+ commit("SET_SELECTED_PAGES", filtered);
97
+ }
98
+ },
99
+
36
100
  setSelectedPages: ({ state, commit }, selectedPage) => {
37
101
  if (!selectedPage) {
38
102
  commit("SET_SELECTED_PAGES", []);
@@ -57,42 +121,41 @@ const actions = {
57
121
  },
58
122
 
59
123
  rotatePage: ({ state, commit }, { page, direction }) => {
60
- if (state.documentPagesListForEditMode.find((p) => p.id === page[0].id)) {
61
- const documentPagesListForEditMode =
62
- state.documentPagesListForEditMode.map((p) => {
63
- let rotatedAngle;
64
- if (direction === "left") {
65
- rotatedAngle = p.angle - 90;
66
- if (p.id === page[0].id) {
67
- if (rotatedAngle === -270) {
68
- rotatedAngle = 90;
69
- }
70
- return {
71
- ...p,
72
- angle: rotatedAngle,
73
- };
124
+ if (state.pagesForPostprocess.find((p) => p.id === page.id)) {
125
+ const pagesForPostprocess = state.pagesForPostprocess.map((p) => {
126
+ let rotatedAngle;
127
+ if (direction === "left") {
128
+ rotatedAngle = p.angle - 90;
129
+ if (p.id === page.id) {
130
+ if (rotatedAngle === -270) {
131
+ rotatedAngle = 90;
74
132
  }
75
- return p;
133
+ return {
134
+ ...p,
135
+ angle: rotatedAngle,
136
+ };
76
137
  }
77
- if (direction === "right") {
78
- rotatedAngle = p.angle + 90;
79
- if (p.id === page[0].id) {
80
- if (rotatedAngle === 270) {
81
- rotatedAngle = -90;
82
- }
83
- return {
84
- ...p,
85
- angle: rotatedAngle,
86
- };
138
+ return p;
139
+ }
140
+ if (direction === "right") {
141
+ rotatedAngle = p.angle + 90;
142
+ if (p.id === page.id) {
143
+ if (rotatedAngle === 270) {
144
+ rotatedAngle = -90;
87
145
  }
88
- return p;
146
+ return {
147
+ ...p,
148
+ angle: rotatedAngle,
149
+ };
89
150
  }
90
- });
151
+ return p;
152
+ }
153
+ });
91
154
 
92
- commit("SET_DOCUMENT_PAGES_FOR_EDIT_MODE", documentPagesListForEditMode);
155
+ commit("SET_PAGES_FOR_POSTPROCESS", pagesForPostprocess);
93
156
  } else {
94
157
  if (direction === "left") {
95
- state.documentPagesListForEditMode.push({
158
+ state.pagesForPostprocess.push({
96
159
  id: page.id,
97
160
  number: page.number,
98
161
  angle: -90,
@@ -102,7 +165,7 @@ const actions = {
102
165
  }
103
166
 
104
167
  if (direction === "right") {
105
- state.documentPagesListForEditMode.push({
168
+ state.pagesForPostprocess.push({
106
169
  id: page.id,
107
170
  number: page.number,
108
171
  angle: 90,
@@ -115,7 +178,7 @@ const actions = {
115
178
 
116
179
  updateRotationToTheLeft: ({ state, commit }) => {
117
180
  // updated the angles that will be sent to the backend
118
- const array = state.documentPagesListForEditMode.map((p) => {
181
+ const array = state.pagesForPostprocess.map((p) => {
119
182
  let rotatedAngle = p.angle - 90;
120
183
  if (rotatedAngle === -270) {
121
184
  rotatedAngle = 90;
@@ -126,12 +189,12 @@ const actions = {
126
189
  };
127
190
  });
128
191
 
129
- commit("SET_DOCUMENT_PAGES_FOR_EDIT_MODE", array);
192
+ commit("SET_PAGES_FOR_POSTPROCESS", array);
130
193
  },
131
194
 
132
195
  updateRotationToTheRight: ({ state, commit }) => {
133
196
  // updated the angles that will be sent to the backend
134
- const array = state.documentPagesListForEditMode.map((p) => {
197
+ const array = state.pagesForPostprocess.map((p) => {
135
198
  let rotatedAngle = p.angle + 90;
136
199
  if (rotatedAngle === 270) {
137
200
  rotatedAngle = -90;
@@ -142,40 +205,66 @@ const actions = {
142
205
  };
143
206
  });
144
207
 
145
- commit("SET_DOCUMENT_PAGES_FOR_EDIT_MODE", array);
208
+ commit("SET_PAGES_FOR_POSTPROCESS", array);
146
209
  },
147
210
 
148
- editDocument: ({ rootState, dispatch }, editedDocument) => {
211
+ editDocument: ({ rootState, commit, dispatch }, editedDocument) => {
149
212
  dispatch("document/startRecalculatingAnnotations", null, {
150
213
  root: true,
151
214
  });
152
- return new Promise((resolve) => {
215
+
216
+ const oldId = rootState.document.documentId;
217
+
218
+ return new Promise((resolve, reject) => {
153
219
  HTTP.post(
154
220
  `/documents/${rootState.document.documentId}/postprocess/`,
155
221
  editedDocument
156
222
  )
157
223
  .then(async (response) => {
158
224
  if (response && response.status === 200) {
159
- const newDocument = response.data[0];
160
- const newId = newDocument.id;
161
-
162
- await dispatch("document/setDocId", newId, {
163
- root: true,
164
- });
165
- dispatch("document/pollDocumentEndpoint", null, {
166
- root: true,
167
- });
168
- resolve(null);
169
- } else {
170
- resolve(response);
225
+ const newId = response.data[0].id;
226
+ dispatch("document/setSplittingSuggestions", null, { root: true });
227
+
228
+ commit("SET_SUBMIT_EDIT_CHANGES", false);
229
+
230
+ if (newId != oldId) {
231
+ if (getURLQueryParam("document") || getURLPath("docs")) {
232
+ navigateToNewDocumentURL(oldId, newId);
233
+ } else {
234
+ await dispatch("document/setDocId", newId, {
235
+ root: true,
236
+ });
237
+
238
+ dispatch("document/pollDocumentEndpoint", null, {
239
+ root: true,
240
+ });
241
+ }
242
+ } else {
243
+ dispatch("document/setSelectedDocument", response.data[0], {
244
+ root: true,
245
+ });
246
+
247
+ dispatch("document/pollDocumentEndpoint", null, {
248
+ root: true,
249
+ });
250
+ }
171
251
  }
252
+ resolve(response);
172
253
  })
173
254
  .catch((error) => {
174
- resolve(error.response);
255
+ reject(error.response);
175
256
  console.log(error);
176
257
  });
177
258
  });
178
259
  },
260
+
261
+ setShowEditConfirmationModal: ({ commit }, value) => {
262
+ commit("SET_SHOW_EDIT_CONFIRMATION_MODAL", value);
263
+ },
264
+
265
+ setRedirectingUser: ({ commit }, value) => {
266
+ commit("SET_REDIRECTING_USER", value);
267
+ },
179
268
  };
180
269
 
181
270
  const mutations = {
@@ -183,12 +272,12 @@ const mutations = {
183
272
  state.editMode = option;
184
273
  },
185
274
 
186
- SET_SPLIT_OVERVIEW: (state, overview) => {
187
- state.splitOverview = overview;
275
+ SET_RENAME_AND_CATEGORIZE: (state, value) => {
276
+ state.renameAndCategorize = value;
188
277
  },
189
278
 
190
- SET_DOCUMENT_PAGES_FOR_EDIT_MODE: (state, pages) => {
191
- state.documentPagesListForEditMode = pages;
279
+ SET_PAGES_FOR_POSTPROCESS: (state, pages) => {
280
+ state.pagesForPostprocess = pages;
192
281
  },
193
282
 
194
283
  SET_UPDATED_DOCUMENT: (state, updatedDocument) => {
@@ -200,6 +289,15 @@ const mutations = {
200
289
  ADD_SELECTED_PAGE: (state, selectedPage) => {
201
290
  state.selectedPages.push(selectedPage);
202
291
  },
292
+ SET_SHOW_EDIT_CONFIRMATION_MODAL: (state, value) => {
293
+ state.showEditConfirmationModal = value;
294
+ },
295
+ SET_SUBMIT_EDIT_CHANGES: (state, value) => {
296
+ state.submitEditChanges = value;
297
+ },
298
+ SET_REDIRECTING_USER: (state, value) => {
299
+ state.redirectingUser = value;
300
+ },
203
301
  };
204
302
 
205
303
  export default {
@@ -207,4 +305,5 @@ export default {
207
305
  state,
208
306
  actions,
209
307
  mutations,
308
+ getters,
210
309
  };
@@ -2,8 +2,10 @@ import myImports from "../api";
2
2
  const HTTP = myImports.HTTP;
3
3
 
4
4
  const state = {
5
- projectId: null,
6
- currentUser: null
5
+ projectId: process.env.VUE_APP_PROJECT_ID,
6
+ currentUser: null,
7
+ documentsListPath: null,
8
+ documentsInProject: null,
7
9
  };
8
10
 
9
11
  const getters = {
@@ -11,13 +13,13 @@ const getters = {
11
13
  * Gets label sets for an annotation set creation
12
14
  */
13
15
  labelSetsFilteredForAnnotationSetCreation:
14
- state => (labelsSet, annotationSets) => {
16
+ (state) => (labelsSet, annotationSets) => {
15
17
  let returnLabels = [];
16
18
  if (labelsSet) {
17
- returnLabels = labelsSet.filter(labelSet => {
19
+ returnLabels = labelsSet.filter((labelSet) => {
18
20
  // check if label set has multiple and if not, if there's already an annotation set created
19
21
  if (!labelSet.has_multiple_annotation_sets) {
20
- const existingAnnotationSet = annotationSets.find(annSet => {
22
+ const existingAnnotationSet = annotationSets.find((annSet) => {
21
23
  return annSet.id === labelSet.id;
22
24
  });
23
25
  return existingAnnotationSet;
@@ -27,7 +29,7 @@ const getters = {
27
29
  });
28
30
  }
29
31
  return returnLabels;
30
- }
32
+ },
31
33
  };
32
34
 
33
35
  const actions = {
@@ -38,10 +40,10 @@ const actions = {
38
40
  fetchLabelSetDetails: ({ commit, state }, labelSetId) => {
39
41
  return new Promise((resolve, reject) => {
40
42
  HTTP.get(`label-sets/${labelSetId}/`)
41
- .then(response => {
43
+ .then((response) => {
42
44
  return resolve(response.data);
43
45
  })
44
- .catch(error => {
46
+ .catch((error) => {
45
47
  reject(error);
46
48
  console.log(error);
47
49
  });
@@ -52,10 +54,10 @@ const actions = {
52
54
  fetchLabelSets: ({ state }) => {
53
55
  return new Promise((resolve, reject) => {
54
56
  HTTP.get(`label-sets/?project=${state.projectId}`)
55
- .then(response => {
57
+ .then((response) => {
56
58
  return resolve(response.data.results);
57
59
  })
58
- .catch(error => {
60
+ .catch((error) => {
59
61
  reject(error);
60
62
  console.log(error);
61
63
  });
@@ -64,17 +66,39 @@ const actions = {
64
66
 
65
67
  fetchCurrentUser: ({ commit }) => {
66
68
  return HTTP.get(`/auth/me/`)
67
- .then(response => {
68
- commit("SET_CURRENT_USER", response.data.username);
69
+ .then((response) => {
70
+ commit("SET_CURRENT_USER", response.data);
69
71
  })
70
- .catch(error => {
72
+ .catch((error) => {
71
73
  console.log(error);
72
74
  });
73
75
  },
74
76
 
75
77
  setCurrentUser: ({ commit }, currentUser) => {
76
78
  commit("SET_CURRENT_USER", currentUser);
77
- }
79
+ },
80
+
81
+ setDocumentsListPath: ({ commit }, path) => {
82
+ commit("SET_DOCUMENTS_LIST_PATH", path);
83
+ },
84
+
85
+ setDocumentsInProject: ({ commit }, documents) => {
86
+ commit("SET_DOCUMENTS_IN_PROJECT", documents);
87
+ },
88
+
89
+ fetchDocumentList: ({ commit, state }, parameters) => {
90
+ return HTTP.get(
91
+ `documents/?project=${state.projectId}&assignee=${state.currentUser.username}&limit=100&${parameters}`
92
+ )
93
+ .then((response) => {
94
+ if (response.data.results) {
95
+ commit("SET_DOCUMENTS_IN_PROJECT", response.data.results);
96
+ }
97
+ })
98
+ .catch((error) => {
99
+ console.log(error, "Could not fetch document list from the backend");
100
+ });
101
+ },
78
102
  };
79
103
 
80
104
  const mutations = {
@@ -83,7 +107,13 @@ const mutations = {
83
107
  },
84
108
  SET_CURRENT_USER: (state, currentUser) => {
85
109
  state.currentUser = currentUser;
86
- }
110
+ },
111
+ SET_DOCUMENTS_LIST_PATH: (state, path) => {
112
+ state.documentsListPath = path;
113
+ },
114
+ SET_DOCUMENTS_IN_PROJECT: (state, documents) => {
115
+ state.documentsInProject = documents;
116
+ },
87
117
  };
88
118
 
89
119
  export default {
@@ -91,5 +121,5 @@ export default {
91
121
  state,
92
122
  actions,
93
123
  mutations,
94
- getters
124
+ getters,
95
125
  };
@@ -14,6 +14,7 @@ const state = {
14
14
  isSelecting: false,
15
15
  spanSelection: null,
16
16
  elementSelected: null, // selected element id
17
+ selectedEntities: null,
17
18
  };
18
19
 
19
20
  const getters = {
@@ -37,9 +38,6 @@ const getters = {
37
38
  }
38
39
  return null;
39
40
  },
40
- isValueArray: () => (value) => {
41
- return Array.isArray(value);
42
- },
43
41
  };
44
42
 
45
43
  const actions = {
@@ -70,15 +68,22 @@ const actions = {
70
68
  commit("MOVE_SELECTION", points);
71
69
  }
72
70
 
73
- dispatch("document/setSelectedEntities", null, { root: true });
71
+ commit("SET_SELECTED_ENTITIES", null);
74
72
  },
75
73
 
76
74
  endSelection: ({ commit, state }, end) => {
77
- const xDiff = Math.abs(state.selection.start.x - end.x);
78
- const yDiff = Math.abs(state.selection.start.y - end.y);
79
- // if start and end points are the same, or if we have a selection smaller than 5x5,
75
+ let xDiff;
76
+ let yDiff;
77
+
78
+ if (end) {
79
+ xDiff = Math.abs(state.selection.start.x - end.x);
80
+ yDiff = Math.abs(state.selection.start.y - end.y);
81
+ }
82
+
83
+ // if "end" is not provided, start and end points are the same, or if we have a selection smaller than 5x5,
80
84
  // just reset
81
85
  if (
86
+ !end ||
82
87
  (yDiff <= 5 && xDiff <= 5) ||
83
88
  (state.selection.start.x === end.x && state.selection.start.y == end.y)
84
89
  ) {
@@ -99,9 +104,23 @@ const actions = {
99
104
  commit("SET_SPAN_SELECTION", span);
100
105
  },
101
106
 
102
- getTextFromBboxes: ({ commit, rootState }, box) => {
107
+ setSelectedEntities: ({ commit }, entities) => {
108
+ commit("SET_SELECTED_ENTITIES", entities);
109
+ },
110
+
111
+ getTextFromBboxes: ({ commit, rootState }, { box, entities }) => {
112
+ let span;
113
+
114
+ if (entities) {
115
+ span = box.flatMap((s) => {
116
+ return s.original;
117
+ });
118
+ } else {
119
+ span = [box];
120
+ }
121
+
103
122
  return HTTP.post(`documents/${rootState.document.documentId}/bbox/`, {
104
- span: [box],
123
+ span,
105
124
  })
106
125
  .then((response) => {
107
126
  if (response.data.span.length && response.data.span.length > 0) {
@@ -119,13 +138,23 @@ const actions = {
119
138
  * an annotation on this empty area, adding the offset_string
120
139
  * attribute, ready to be filled.
121
140
  */
122
- commit("SET_SPAN_SELECTION", box);
141
+ commit("SET_SPAN_SELECTION", span);
123
142
  }
124
143
  })
125
144
  .catch((error) => {
126
145
  alert("Could not fetch the selected text from the backend");
127
146
  });
128
147
  },
148
+
149
+ getTextFromEntities: ({ commit, dispatch }, selectedEntities) => {
150
+ if (!selectedEntities) return;
151
+
152
+ return dispatch("getTextFromBboxes", {
153
+ box: selectedEntities,
154
+ entities: true,
155
+ });
156
+ },
157
+
129
158
  setSpanSelection: ({ commit }, span) => {
130
159
  commit("SET_SPAN_SELECTION", span);
131
160
  },
@@ -167,6 +196,9 @@ const mutations = {
167
196
  SET_SELECTION: (state, selection) => {
168
197
  state.selection = selection;
169
198
  },
199
+ SET_SELECTED_ENTITIES: (state, entities) => {
200
+ state.selectedEntities = entities;
201
+ },
170
202
  };
171
203
 
172
204
  export default {
@@ -5,14 +5,50 @@ export function sleep(duration) {
5
5
  export function getURLQueryParam(param) {
6
6
  const queryString = window.location.search;
7
7
  const urlParams = new URLSearchParams(queryString);
8
+
8
9
  if (urlParams.has(param)) {
9
10
  return urlParams.get(param);
10
11
  }
11
12
  return undefined;
12
13
  }
13
14
 
15
+ export function getURLPath(value) {
16
+ const path = window.location.pathname;
17
+
18
+ if (!path.includes(`/${value}/`)) return;
19
+
20
+ const id = path.split(value)[1].split("/")[1];
21
+
22
+ if (id === "") return;
23
+
24
+ return id;
25
+ }
26
+
14
27
  export function navigateToNewDocumentURL(oldId, newId) {
15
28
  const url = window.location.href;
16
29
  const newUrl = url.replace(oldId, newId);
17
30
  window.location.replace(newUrl);
18
31
  }
32
+
33
+ export function navigateToDocumentsList(path, projectId, userId) {
34
+ if (!path) return;
35
+
36
+ const lastCharOfString = path.charAt(path.length - 1);
37
+ let slash = "/";
38
+
39
+ if (lastCharOfString === slash) {
40
+ slash = "";
41
+ }
42
+
43
+ const parameters = `?project=${projectId}&is_reviewed__exact=0&assignee__id__exact=${userId}`;
44
+
45
+ const newPath = `${path}${slash}${parameters}`;
46
+
47
+ window.location.href = newPath;
48
+
49
+ return true;
50
+ }
51
+
52
+ export function isElementArray(element) {
53
+ return Array.isArray(element);
54
+ }