@konfuzio/document-validation-ui 0.1.50-dev.1 → 0.1.51-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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@konfuzio/document-validation-ui",
3
- "version": "0.1.50-dev.1",
3
+ "version": "0.1.51-dev.0",
4
4
  "repository": "git://github.com:konfuzio-ai/document-validation-ui.git",
5
5
  "main": "dist/app.js",
6
6
  "scripts": {
@@ -83,3 +83,8 @@
83
83
  }
84
84
  }
85
85
  }
86
+ .loading-bar {
87
+ height: 100%;
88
+ display: flex;
89
+ align-items: center;
90
+ }
@@ -17,3 +17,9 @@
17
17
  }
18
18
  }
19
19
  }
20
+ .loading-bar {
21
+ height: 100%;
22
+ display: flex;
23
+ align-items: center;
24
+ margin: 0 16px;
25
+ }
@@ -51,17 +51,14 @@
51
51
  :key="indexGroup"
52
52
  :class="[
53
53
  'annotation-set-group',
54
- !annotationSetsAccordion[indexGroup] === true &&
55
- 'annotation-set-collapsed',
54
+ !isAccordionOpen(annotationSet) && 'annotation-set-collapsed',
56
55
  ]"
57
56
  >
58
- <div class="label-set-header" @click="toggleAccordion(indexGroup)">
57
+ <div class="label-set-header" @click="toggleAccordion(annotationSet)">
59
58
  <div class="label-set-name">
60
59
  <b-icon
61
60
  :icon="
62
- annotationSetsAccordion[indexGroup]
63
- ? 'angle-up'
64
- : 'angle-down'
61
+ isAccordionOpen(annotationSet) ? 'angle-up' : 'angle-down'
65
62
  "
66
63
  size="is-12"
67
64
  />
@@ -80,7 +77,7 @@
80
77
  class="labelset-action-buttons"
81
78
  >
82
79
  <AnnotationSetActionButtons
83
- :is-placeholder="annotationSetsAccordion[indexGroup] === false"
80
+ :is-placeholder="!isAccordionOpen(annotationSet)"
84
81
  :number-of-empty-labels-in-annotation-set="
85
82
  emptyLabels(annotationSet).length
86
83
  "
@@ -107,7 +104,7 @@
107
104
  </div>
108
105
  </div>
109
106
 
110
- <b-collapse :open="annotationSetsAccordion[indexGroup] === true">
107
+ <b-collapse :open="isAccordionOpen(annotationSet)">
111
108
  <div v-if="annotationSet.labels.length > 0">
112
109
  <div v-for="label in annotationSet.labels" :key="label.id">
113
110
  <div
@@ -242,11 +239,12 @@ export default {
242
239
  if (newAnnotationId) {
243
240
  const annotationSet = this.annotationSetOfAnnotation(newAnnotationId);
244
241
  if (annotationSet) {
245
- const index = this.annotationSets.findIndex(
246
- (annotationSetToFind) => annotationSetToFind.id === annotationSet.id
247
- );
248
- const newAnnotationSetsAccordion = [...this.annotationSetsAccordion];
249
- newAnnotationSetsAccordion[index] = true;
242
+ const newAnnotationSetsAccordion = {
243
+ ...this.annotationSetsAccordion,
244
+ };
245
+ newAnnotationSetsAccordion[
246
+ annotationSet.id || annotationSet.label_set.id
247
+ ] = true;
250
248
  this.annotationSetsAccordion = newAnnotationSetsAccordion;
251
249
  }
252
250
  }
@@ -272,51 +270,38 @@ export default {
272
270
  annotationSet.labels.length === 0 && this.isSearchingAnnotationList
273
271
  );
274
272
  },
275
-
276
- toggleAccordion(index) {
277
- const newAnnotationSetsAccordion = [...this.annotationSetsAccordion];
278
- newAnnotationSetsAccordion[index] = !newAnnotationSetsAccordion[index];
273
+ isAccordionOpen(annotationSet) {
274
+ return (
275
+ this.isSearchingAnnotationList ||
276
+ this.annotationSetsAccordion[
277
+ annotationSet.id || annotationSet.label_set.id
278
+ ] === true
279
+ );
280
+ },
281
+ toggleAccordion(annotationSet) {
282
+ const newAnnotationSetsAccordion = { ...this.annotationSetsAccordion };
283
+ newAnnotationSetsAccordion[
284
+ annotationSet.id || annotationSet.label_set.id
285
+ ] =
286
+ !newAnnotationSetsAccordion[
287
+ annotationSet.id || annotationSet.label_set.id
288
+ ];
279
289
  this.annotationSetsAccordion = newAnnotationSetsAccordion;
280
290
  },
281
291
  openAllAccordions() {
282
- const newAnnotationSetsAccordion = [...this.annotationSetsAccordion];
283
- newAnnotationSetsAccordion.forEach((_, index) => {
284
- newAnnotationSetsAccordion[index] = true;
285
- });
292
+ const newAnnotationSetsAccordion = { ...this.annotationSetsAccordion };
293
+ for (var key in newAnnotationSetsAccordion) {
294
+ newAnnotationSetsAccordion[key] = true;
295
+ }
286
296
  this.annotationSetsAccordion = newAnnotationSetsAccordion;
287
297
  },
288
298
  loadAccordions(newAnnotationSets, oldAnnotationSets = null) {
289
299
  if (newAnnotationSets) {
290
300
  const isFirstTime = this.annotationSetsAccordion === null;
291
- const newAnnotationSetsAccordion = [];
301
+ const newAnnotationSetsAccordion = {};
292
302
  const annotationSetsOpened = [];
293
303
  const annotationSetsCreated = [];
294
304
 
295
- if (!isFirstTime) {
296
- // when annotation sets changed, restore old state
297
- // and check if new ones were created to be open by default
298
-
299
- this.annotationSetsAccordion.forEach((isOpen, index) => {
300
- if (isOpen) {
301
- annotationSetsOpened.push(oldAnnotationSets[index]);
302
- }
303
- });
304
-
305
- newAnnotationSets.forEach((newAnnotationSet) => {
306
- const existed = oldAnnotationSets.find(
307
- (oldAnnotationSet) =>
308
- oldAnnotationSet &&
309
- newAnnotationSet &&
310
- oldAnnotationSet.id &&
311
- newAnnotationSet.id &&
312
- oldAnnotationSet.id === newAnnotationSet.id
313
- );
314
- if (!existed && newAnnotationSet && newAnnotationSet.id !== null) {
315
- annotationSetsCreated.push(newAnnotationSet);
316
- }
317
- });
318
- }
319
-
320
305
  newAnnotationSets.forEach((newAnnotationSet, index) => {
321
306
  const wasOpen = annotationSetsOpened.find(
322
307
  (annotationSetOpened) =>
@@ -326,19 +311,25 @@ export default {
326
311
  newAnnotationSet.id === annotationSetOpened.id
327
312
  );
328
313
  if (isFirstTime && this.annotationSetId) {
329
- newAnnotationSetsAccordion[index] =
330
- newAnnotationSet.id == this.annotationSetId;
314
+ newAnnotationSetsAccordion[
315
+ newAnnotationSet.id || newAnnotationSet.label_set.id
316
+ ] = newAnnotationSet.id == this.annotationSetId;
331
317
  } else if (isFirstTime && this.annotationId) {
332
- newAnnotationSetsAccordion[index] =
333
- this.isAnnotationInAnnotationSet(
334
- newAnnotationSet,
335
- this.annotationId
336
- );
318
+ newAnnotationSetsAccordion[
319
+ newAnnotationSet.id || newAnnotationSet.label_set.id
320
+ ] = this.isAnnotationInAnnotationSet(
321
+ newAnnotationSet,
322
+ this.annotationId
323
+ );
337
324
  } else if (isFirstTime && index === 0) {
338
325
  // open first one by default
339
- newAnnotationSetsAccordion[index] = true;
326
+ newAnnotationSetsAccordion[
327
+ newAnnotationSet.id || newAnnotationSet.label_set.id
328
+ ] = true;
340
329
  } else if (wasOpen) {
341
- newAnnotationSetsAccordion[index] = wasOpen !== undefined;
330
+ newAnnotationSetsAccordion[
331
+ newAnnotationSet.id || newAnnotationSet.label_set.id
332
+ ] = wasOpen !== undefined;
342
333
  } else {
343
334
  const wasCreated = annotationSetsCreated.find(
344
335
  (annotationSetCreated) =>
@@ -346,7 +337,9 @@ export default {
346
337
  newAnnotationSet.id &&
347
338
  newAnnotationSet.id === annotationSetCreated.id
348
339
  );
349
- newAnnotationSetsAccordion[index] = wasCreated !== undefined;
340
+ newAnnotationSetsAccordion[
341
+ newAnnotationSet.id || newAnnotationSet.label_set.id
342
+ ] = wasCreated !== undefined;
350
343
  }
351
344
  });
352
345
  this.annotationSetsAccordion = newAnnotationSetsAccordion;
@@ -1,5 +1,6 @@
1
1
  <template>
2
2
  <b-tooltip
3
+ v-if="categories"
3
4
  multilined
4
5
  :active="tooltipIsShown || dropdownIsDisabled"
5
6
  size="is-large"
@@ -67,6 +68,9 @@
67
68
  </b-dropdown-item>
68
69
  </b-dropdown>
69
70
  </b-tooltip>
71
+ <div v-else class="loading-bar">
72
+ <b-skeleton width="auto" height="100%" />
73
+ </div>
70
74
  </template>
71
75
 
72
76
  <script>
@@ -258,21 +262,23 @@ export default {
258
262
  this.$emit("category-change", this.page, category.id);
259
263
  },
260
264
  setTooltipText() {
261
- // Text set from innerHTML vs 'label' due to html tag in locales file string
262
- let tooltipText;
263
- let tooltipDelay = 0;
265
+ if (this.categories) {
266
+ // Text set from innerHTML vs 'label' due to html tag in locales file string
267
+ let tooltipText;
268
+ let tooltipDelay = 0;
264
269
 
265
- if (this.documentCannotBeEdited(this.selectedDocument)) {
266
- tooltipText = this.$t("edit_not_available");
267
- } else if (this.documentHasCorrectAnnotations) {
268
- tooltipText = this.$t("approved_annotations");
269
- } else if (this.projectHasSingleCategory) {
270
- tooltipText = this.$t("single_category_in_project");
271
- tooltipDelay = 5000;
272
- }
270
+ if (this.documentCannotBeEdited(this.selectedDocument)) {
271
+ tooltipText = this.$t("edit_not_available");
272
+ } else if (this.documentHasCorrectAnnotations) {
273
+ tooltipText = this.$t("approved_annotations");
274
+ } else if (this.projectHasSingleCategory) {
275
+ tooltipText = this.$t("single_category_in_project");
276
+ tooltipDelay = 5000;
277
+ }
273
278
 
274
- this.tooltipCloseDelay = tooltipDelay;
275
- this.$refs.tooltipContent.innerHTML = tooltipText;
279
+ this.tooltipCloseDelay = tooltipDelay;
280
+ this.$refs.tooltipContent.innerHTML = tooltipText;
281
+ }
276
282
  },
277
283
  },
278
284
  };
@@ -38,7 +38,9 @@
38
38
  }"
39
39
  :image-url="getImageUrl(page)"
40
40
  class="page-thumbnail"
41
- />
41
+ >
42
+ <b-skeleton width="60px" height="60px" />
43
+ </ServerImage>
42
44
  <div class="icon-container">
43
45
  <div class="action-icon">
44
46
  <EyeIcon />
@@ -1,7 +1,10 @@
1
1
  <template>
2
2
  <b-dropdown
3
3
  v-if="
4
- documentSet && documentSet.documents && documentSet.documents.length > 1
4
+ documentSet &&
5
+ documentSet.documents &&
6
+ documentSet.documents.length > 1 &&
7
+ categories
5
8
  "
6
9
  v-model="selectedDocId"
7
10
  class="document-set-dropdown dropdown-full-width"
@@ -46,6 +49,12 @@
46
49
  >
47
50
  </b-dropdown-item>
48
51
  </b-dropdown>
52
+ <div
53
+ v-else-if="selectedDocument.documentSet !== null && documentSet === null"
54
+ class="loading-bar"
55
+ >
56
+ <b-skeleton width="100px" height="60%" />
57
+ </div>
49
58
  </template>
50
59
 
51
60
  <script>
@@ -66,16 +75,14 @@ export default {
66
75
  ...mapGetters("document", ["numberOfDocumentInSet"]),
67
76
  ...mapGetters("category", ["categoryName"]),
68
77
  ...mapState("document", ["documentSet", "selectedDocument"]),
78
+ ...mapState("category", ["categories"]),
69
79
  },
70
80
  mounted() {
71
81
  this.selectedDocId = this.selectedDocument.id;
72
82
  },
73
83
  methods: {
74
84
  handleDocumentClick(document) {
75
- this.$store.dispatch("document/changeCurrentDocument", {
76
- document,
77
- documentId: document.id,
78
- });
85
+ this.$store.dispatch("document/changeCurrentDocument", document.id);
79
86
  },
80
87
  },
81
88
  };
@@ -181,10 +181,7 @@ export default {
181
181
  },
182
182
  navigateToDocument(document) {
183
183
  if (!document) return;
184
-
185
- this.$store.dispatch("document/changeCurrentDocument", {
186
- documentId: document.id,
187
- });
184
+ this.$store.dispatch("document/changeCurrentDocument", document.id);
188
185
  },
189
186
  },
190
187
  };
@@ -110,7 +110,7 @@ export default {
110
110
  },
111
111
  methods: {
112
112
  changeDocument(documentId) {
113
- this.$store.dispatch("document/changeCurrentDocument", { documentId });
113
+ this.$store.dispatch("document/changeCurrentDocument", documentId);
114
114
  },
115
115
  requestTrialAccess() {
116
116
  window.open("https://konfuzio.com", "_blank");
@@ -13,9 +13,12 @@ const getters = {
13
13
  */
14
14
  categoryName: (state) => (categoryId) => {
15
15
  if (categoryId && state.categories) {
16
- return state.categories.find(
16
+ const category = state.categories.find(
17
17
  (tempCategory) => tempCategory.id == categoryId
18
- ).name;
18
+ );
19
+ if (category) {
20
+ return category.name;
21
+ }
19
22
  }
20
23
  return "";
21
24
  },
@@ -35,9 +38,12 @@ const getters = {
35
38
  */
36
39
  category: (state) => (categoryId) => {
37
40
  if (categoryId && state.categories) {
38
- return state.categories.find(
41
+ const category = state.categories.find(
39
42
  (tempCategory) => tempCategory.id == categoryId
40
43
  );
44
+ if (category) {
45
+ return category;
46
+ }
41
47
  }
42
48
  return null;
43
49
  },
@@ -441,7 +441,7 @@ const getters = {
441
441
  if (
442
442
  !(
443
443
  (rootState.display.hideEmptyLabelSets || state.publicView) &&
444
- annotationSet.id === null
444
+ annotationSet.labels.length === 0
445
445
  )
446
446
  ) {
447
447
  labels = [];
@@ -542,16 +542,6 @@ const getters = {
542
542
  return found ? `${value + 1}` : "";
543
543
  }
544
544
  return "";
545
- // let index = -1;
546
- // if (state.documentSet && state.documentSet.documents) {
547
- // state.documentSet.documents.forEach((docTemp, indexTemp) => {
548
- // if (docTemp.id == documentId) {
549
- // index = indexTemp;
550
- // return;
551
- // }
552
- // });
553
- // }
554
- // return index === -1 ? "" : `${index + 1}`;
555
545
  },
556
546
 
557
547
  /**
@@ -1071,105 +1061,96 @@ const actions = {
1071
1061
  * Actions that use HTTP requests always return the axios promise,
1072
1062
  * so they can be `await`ed (useful to set the `loading` status).
1073
1063
  */
1074
- fetchDocument: async (
1075
- { commit, state, dispatch, rootState, getters },
1076
- fetchedDocument = null
1077
- ) => {
1078
- let projectId = null;
1079
- let documentSetId = null;
1080
- let categoryId = null;
1064
+ fetchDocument: async ({ commit, state, dispatch, rootState, getters }) => {
1081
1065
  let isRecalculatingAnnotations = false;
1082
-
1083
1066
  const initialPage = 1;
1084
1067
 
1085
1068
  dispatch("startLoading");
1086
1069
  dispatch("display/updateCurrentPage", initialPage, {
1087
1070
  root: true,
1088
1071
  });
1089
- try {
1090
- if (!fetchedDocument) {
1091
- const response = await HTTP.get(`documents/${state.documentId}/`);
1092
- fetchedDocument = response.data;
1093
- }
1094
-
1095
- const { labels, annotations, annotationSets } =
1096
- getters.processAnnotationSets(fetchedDocument.annotation_sets);
1097
1072
 
1098
- // load first page
1099
- if (fetchedDocument.pages.length > 0) {
1100
- dispatch("fetchDocumentPage", initialPage);
1101
- }
1073
+ await HTTP.get(`documents/${state.documentId}/`)
1074
+ .then((response) => {
1075
+ if (response.data) {
1076
+ const fetchedDocument = response.data;
1077
+
1078
+ const { labels, annotations, annotationSets } =
1079
+ getters.processAnnotationSets(fetchedDocument.annotation_sets);
1080
+
1081
+ // load first page
1082
+ // if (fetchedDocument.pages.length > 0) {
1083
+ // dispatch("fetchDocumentPage", initialPage);
1084
+ // }
1085
+
1086
+ // set information on the store
1087
+ commit("SET_ANNOTATION_SETS", annotationSets);
1088
+ commit("SET_ANNOTATIONS", annotations);
1089
+ commit("SET_LABELS", labels);
1090
+ commit("SET_SELECTED_DOCUMENT", fetchedDocument);
1091
+
1092
+ // project
1093
+ if (fetchedDocument.project) {
1094
+ dispatch("project/setProjectId", fetchedDocument.project, {
1095
+ root: true,
1096
+ });
1102
1097
 
1103
- // set information on the store
1104
- commit("SET_ANNOTATION_SETS", annotationSets);
1105
- commit("SET_ANNOTATIONS", annotations);
1106
- commit("SET_LABELS", labels);
1107
- commit("SET_SELECTED_DOCUMENT", fetchedDocument);
1098
+ dispatch(
1099
+ "project/setShowAnnotationTranslations",
1100
+ fetchedDocument.enable_translated_strings,
1101
+ {
1102
+ root: true,
1103
+ }
1104
+ );
1105
+ }
1108
1106
 
1109
- if (fetchedDocument.project) {
1110
- projectId = fetchedDocument.project;
1107
+ if (!state.publicView) {
1108
+ dispatch("fetchMissingAnnotations");
1111
1109
 
1112
- dispatch("project/setProjectId", projectId, {
1113
- root: true,
1114
- });
1110
+ dispatch("project/fetchCurrentUser", null, {
1111
+ root: true,
1112
+ });
1115
1113
 
1116
- dispatch(
1117
- "project/setShowAnnotationTranslations",
1118
- fetchedDocument.enable_translated_strings,
1119
- {
1120
- root: true,
1114
+ if (fetchedDocument.project) {
1115
+ dispatch("category/fetchCategories", fetchedDocument.project, {
1116
+ root: true,
1117
+ });
1118
+ }
1119
+ if (fetchedDocument.document_set) {
1120
+ dispatch("fetchDocumentSet", fetchedDocument.document_set);
1121
+ }
1121
1122
  }
1122
- );
1123
- }
1124
-
1125
- if (getters.documentHasProposedSplit(fetchedDocument)) {
1126
- commit("SET_SPLITTING_SUGGESTIONS", fetchedDocument.proposed_split);
1127
- }
1128
1123
 
1129
- documentSetId = fetchedDocument.document_set;
1130
- categoryId = fetchedDocument.category;
1131
- isRecalculatingAnnotations = fetchedDocument.labeling_available !== 1;
1132
- } catch (error) {
1133
- console.log(error, "Could not fetch document details from the backend");
1134
- dispatch("display/setPageError", error.response.data.detail, {
1135
- root: true,
1136
- });
1137
- return;
1138
- }
1139
-
1140
- if (!state.publicView) {
1141
- await dispatch("fetchMissingAnnotations");
1124
+ if (getters.documentHasProposedSplit(fetchedDocument)) {
1125
+ dispatch("setSplittingSuggestions", fetchedDocument.proposed_split);
1126
+ }
1142
1127
 
1143
- await dispatch("project/fetchCurrentUser", null, {
1144
- root: true,
1128
+ if (fetchedDocument.labeling_available !== 1) {
1129
+ commit("SET_RECALCULATING_ANNOTATIONS", true);
1130
+ dispatch("pollDocumentEndpoint");
1131
+ }
1132
+ }
1133
+ })
1134
+ .catch((error) => {
1135
+ console.log(error, "Could not fetch document details from the backend");
1136
+ dispatch("display/setPageError", error.response.data.detail, {
1137
+ root: true,
1138
+ });
1139
+ return;
1145
1140
  });
1146
1141
 
1147
- // Check if we first open the document dashboard or the edit mode
1148
- if (
1149
- !state.selectedDocument.category ||
1142
+ // Check if we first open the document dashboard or the edit mode
1143
+ if (
1144
+ !state.publicView &&
1145
+ (!state.selectedDocument.category ||
1150
1146
  (!state.selectedDocument.category_is_revised &&
1151
1147
  !getters.documentHasCorrectAnnotations &&
1152
- state.missingAnnotations.length === 0)
1153
- ) {
1154
- dispatch("edit/enableEditMode", null, {
1155
- root: true,
1156
- });
1157
- dispatch("edit/setRenameAndCategorize", true, { root: true });
1158
- }
1159
-
1160
- if (documentSetId) {
1161
- await dispatch("fetchDocumentSet", documentSetId);
1162
- }
1163
-
1164
- if (projectId) {
1165
- await dispatch("category/fetchCategories", projectId, {
1166
- root: true,
1167
- });
1168
- }
1169
- }
1170
- if (isRecalculatingAnnotations) {
1171
- commit("SET_RECALCULATING_ANNOTATIONS", true);
1172
- dispatch("pollDocumentEndpoint");
1148
+ state.missingAnnotations.length === 0))
1149
+ ) {
1150
+ dispatch("edit/enableEditMode", null, {
1151
+ root: true,
1152
+ });
1153
+ dispatch("edit/setRenameAndCategorize", true, { root: true });
1173
1154
  }
1174
1155
  dispatch("endLoading");
1175
1156
  },
@@ -1243,11 +1224,11 @@ const actions = {
1243
1224
  }
1244
1225
  } else {
1245
1226
  commit("ADD_ANNOTATION", response.data);
1246
- if (response.data && response.data.id) {
1247
- dispatch("setAnnotationId", response.data.id);
1248
- }
1249
1227
  }
1250
1228
 
1229
+ if (response.data && response.data.id) {
1230
+ dispatch("setAnnotationId", response.data.id);
1231
+ }
1251
1232
  resolve(response);
1252
1233
  }
1253
1234
  })
@@ -1523,7 +1504,7 @@ const actions = {
1523
1504
 
1524
1505
  changeCurrentDocument: (
1525
1506
  { commit, state, dispatch, rootState },
1526
- { document, documentId }
1507
+ documentId
1527
1508
  ) => {
1528
1509
  // reset splitting suggestions
1529
1510
  if (state.splittingSuggestions) {
@@ -1543,9 +1524,6 @@ const actions = {
1543
1524
 
1544
1525
  if (getURLQueryParam("document") || getURLPath("d")) {
1545
1526
  navigateToNewDocumentURL(state.selectedDocument.id, documentId);
1546
- } else if (document) {
1547
- commit("SET_DOC_ID", document.id);
1548
- dispatch("fetchDocument", document);
1549
1527
  } else {
1550
1528
  commit("SET_DOC_ID", documentId);
1551
1529
  dispatch("fetchDocument");