@konfuzio/document-validation-ui 0.2.6-dev.2 → 0.2.7-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.2.6-dev.2",
3
+ "version": "0.2.7-dev.0",
4
4
  "repository": "https://github.com/konfuzio-ai/document-validation-ui",
5
5
  "main": "dist/app.js",
6
6
  "scripts": {
@@ -96,7 +96,8 @@
96
96
  }
97
97
 
98
98
  .download-file,
99
- .search-icon {
99
+ .search-icon,
100
+ .doc-faq {
100
101
  color: variables.$toolbar-elements;
101
102
 
102
103
  .is-active {
@@ -108,5 +109,8 @@
108
109
  }
109
110
  }
110
111
  }
112
+ .doc-faq {
113
+ cursor: pointer;
114
+ }
111
115
  }
112
116
  }
@@ -600,6 +600,7 @@
600
600
  }
601
601
  &:before {
602
602
  border-bottom-color: variables.$text-color !important;
603
+ border-top-color: variables.$text-color !important;
603
604
  }
604
605
  }
605
606
 
@@ -441,7 +441,9 @@ export default {
441
441
  inline: "nearest",
442
442
  });
443
443
  };
444
- runAnimation();
444
+ setTimeout(() => {
445
+ runAnimation();
446
+ }, 300);
445
447
  } else {
446
448
  this.isSelected = false;
447
449
  }
@@ -48,6 +48,7 @@
48
48
  v-for="(
49
49
  annotationSet, indexGroup
50
50
  ) in getAnnotationsFiltered.annotationSets"
51
+ :id="`annset_${annotationSet.id}`"
51
52
  :key="indexGroup"
52
53
  :class="[
53
54
  'annotation-set-group',
@@ -198,6 +199,7 @@ export default {
198
199
  computed: {
199
200
  ...mapState("display", ["showAnnSetTable", "showBranding"]),
200
201
  ...mapState("edit", ["editMode"]),
202
+ ...mapState("selection", ["annotationSetSelection"]),
201
203
  ...mapState("document", [
202
204
  "annotationSets",
203
205
  "documentId",
@@ -265,6 +267,27 @@ export default {
265
267
  }
266
268
  }
267
269
  },
270
+ annotationSetSelection(newAnnotationSet) {
271
+ if (newAnnotationSet) {
272
+ const newAnnotationSetsAccordion = {
273
+ ...this.annotationSetsAccordion,
274
+ };
275
+ newAnnotationSetsAccordion[
276
+ newAnnotationSet.id || newAnnotationSet.label_set.id
277
+ ] = true;
278
+ this.annotationSetsAccordion = newAnnotationSetsAccordion;
279
+
280
+ // scroll to element
281
+ const annotationSetElement = document.getElementById(
282
+ `annset_${newAnnotationSet.id}`
283
+ );
284
+ if (annotationSetElement) {
285
+ annotationSetElement.scrollIntoView({ behavior: "smooth" });
286
+ }
287
+
288
+ this.$store.dispatch("selection/setAnnotationSetSelection", null);
289
+ }
290
+ },
268
291
  },
269
292
  created() {
270
293
  window.addEventListener("keydown", this.keyDownHandler);
@@ -76,7 +76,12 @@
76
76
  </v-group>
77
77
  <template v-for="annotationSet in pageAnnotationSets">
78
78
  <v-group>
79
- <v-rect :config="groupAnnotationRect(annotationSet)" />
79
+ <v-rect
80
+ :config="groupAnnotationRect(annotationSet)"
81
+ @click="handleClickedAnnotationSet(annotationSet)"
82
+ @mouseenter="onElementEnter(null, null)"
83
+ @mouseleave="onElementLeave"
84
+ />
80
85
  </v-group>
81
86
  </template>
82
87
  <template v-for="annotation in pageAnnotations">
@@ -403,6 +408,7 @@ export default {
403
408
  if (
404
409
  event.target.name() === "entity" ||
405
410
  event.target.name() === "annotation" ||
411
+ event.target.name() === "annotationSet" ||
406
412
  event.target.name() === "multiAnnBoxSelection" ||
407
413
  event.target.name() === "multiAnnBoxTransformer" ||
408
414
  event.target.name() === "multiAnnButton" ||
@@ -463,6 +469,13 @@ export default {
463
469
  this.$store.dispatch("selection/entityClick", entity);
464
470
  },
465
471
 
472
+ handleClickedAnnotationSet(annotationSet) {
473
+ this.$store.dispatch(
474
+ "selection/setAnnotationSetSelection",
475
+ annotationSet
476
+ );
477
+ },
478
+
466
479
  onElementEnter(annotation = null, span = null) {
467
480
  if (
468
481
  !this.categorizeModalIsActive &&
@@ -590,12 +603,12 @@ export default {
590
603
  return {
591
604
  fill: "#2f80ed",
592
605
  globalCompositeOperation: "multiply",
593
- strokeWidth: 0.2,
606
+ strokeWidth: 1,
594
607
  stroke: "black",
595
608
  name: "annotationSet",
596
609
  cornerRadius: 4,
597
- opacity: 0.3,
598
- ...this.bboxToRect(this.page, box, 4),
610
+ opacity: 0.1,
611
+ ...this.bboxToRect(this.page, box, 1),
599
612
  };
600
613
  },
601
614
  getAnnotationLabelPosition(annotation) {
@@ -82,7 +82,36 @@
82
82
  {{ `${currentPercentage}%` }}
83
83
  </div>
84
84
  </div>
85
+ <div v-if="!publicView" class="toolbar-divider" />
86
+ <div v-if="!publicView && !editMode">
87
+ <b-tooltip
88
+ class="doc-faq"
89
+ position="is-top"
90
+ :label="$t('document_faq_title')"
91
+ >
92
+ <b-icon
93
+ size="is-small"
94
+ icon="question"
95
+ @click="isFaqModalActive = true"
96
+ />
97
+ </b-tooltip>
98
+ </div>
85
99
  </div>
100
+ <section class="faq-modal">
101
+ <b-modal v-model="isFaqModalActive" :width="500">
102
+ <section class="modal-card-body">
103
+ <div class="content">
104
+ <h3>{{ $t("document_faq_title") }}</h3>
105
+ <ul>
106
+ <li>
107
+ <p>{{ $t("document_faq_content") }}</p>
108
+ </li>
109
+ </ul>
110
+ </div>
111
+ </section>
112
+ <footer class="modal-card-foot"></footer>
113
+ </b-modal>
114
+ </section>
86
115
  </div>
87
116
  </template>
88
117
 
@@ -112,6 +141,7 @@ export default {
112
141
  toolbarModalOpen: true,
113
142
  editModeDisabled: false,
114
143
  tooltipInfo: null,
144
+ isFaqModalActive: false,
115
145
  };
116
146
  },
117
147
  computed: {
@@ -139,7 +169,9 @@ export default {
139
169
  },
140
170
  scale(newScale) {
141
171
  if (this.fitWidthScale > 0) {
142
- this.currentPercentage = Math.round((newScale / this.fitWidthScale) * 100);
172
+ this.currentPercentage = Math.round(
173
+ (newScale / this.fitWidthScale) * 100
174
+ );
143
175
  } else {
144
176
  this.currentPercentage = Math.round(newScale * 100);
145
177
  }
package/src/icons.js CHANGED
@@ -27,6 +27,7 @@ import {
27
27
  faCircleExclamation,
28
28
  faLink,
29
29
  faSquareCheck,
30
+ faQuestion,
30
31
  } from "@fortawesome/free-solid-svg-icons";
31
32
  import { FontAwesomeIcon as Icons } from "@fortawesome/vue-fontawesome";
32
33
 
@@ -57,7 +58,8 @@ library.add(
57
58
  faFloppyDisk,
58
59
  faCircleExclamation,
59
60
  faLink,
60
- faSquareCheck
61
+ faSquareCheck,
62
+ faQuestion
61
63
  );
62
64
 
63
65
  export default Icons;
@@ -168,5 +168,7 @@
168
168
  "document_section": "Document Section",
169
169
  "label_size": "Column size:",
170
170
  "powered_by": "powered by Konfuzio",
171
- "nav_label_anns": "Navigate through annotations"
171
+ "nav_label_anns": "Navigate through annotations",
172
+ "document_faq_title": "Document FAQ",
173
+ "document_faq_content": "Annotation Sets grouping only appear when there's no overlap between annotations."
172
174
  }
@@ -279,7 +279,7 @@ const getters = {
279
279
  },
280
280
 
281
281
  /* Get annotation set box to cover all annotations */
282
- annotationSetBoxForPageNumber: (state) => (annotationSet) => {
282
+ annotationSetBoxForPageNumber: (state, getters) => (annotationSet) => {
283
283
  let box = {
284
284
  x0: null,
285
285
  y0: null,
@@ -288,23 +288,47 @@ const getters = {
288
288
  };
289
289
  const annotationIdsOfAnnSet = [];
290
290
  annotationSet.labels.forEach((label) => {
291
- label.annotations.forEach((annotation) => {
292
- annotationIdsOfAnnSet.push(annotation.id);
293
- annotation.span.forEach((span) => {
294
- if (!box.x0 || box.x0 > span.x0) {
295
- box.x0 = span.x0;
296
- }
297
- if (!box.x1 || box.x1 < span.x1) {
298
- box.x1 = span.x1;
299
- }
300
- if (!box.y0 || box.y0 > span.y0) {
301
- box.y0 = span.y0;
302
- }
303
- if (!box.y1 || box.y1 < span.y1) {
304
- box.y1 = span.y1;
305
- }
291
+ if (getters.isLabelMultiFalseAndGroupOfAnns(label)) {
292
+ if (label.annotations && label.annotations[0]) {
293
+ const annotation = label.annotations[0];
294
+ annotation.span.forEach((span) => {
295
+ if (!box.x0 || box.x0 > span.x0) {
296
+ box.x0 = span.x0;
297
+ }
298
+ if (!box.x1 || box.x1 < span.x1) {
299
+ box.x1 = span.x1;
300
+ }
301
+ if (!box.y0 || box.y0 > span.y0) {
302
+ box.y0 = span.y0;
303
+ }
304
+ if (!box.y1 || box.y1 < span.y1) {
305
+ box.y1 = span.y1;
306
+ }
307
+ });
308
+ }
309
+ // add all annotations to not be checked
310
+ label.annotations.forEach((annotation) => {
311
+ annotationIdsOfAnnSet.push(annotation.id);
306
312
  });
307
- });
313
+ } else {
314
+ label.annotations.forEach((annotation) => {
315
+ annotationIdsOfAnnSet.push(annotation.id);
316
+ annotation.span.forEach((span) => {
317
+ if (!box.x0 || box.x0 > span.x0) {
318
+ box.x0 = span.x0;
319
+ }
320
+ if (!box.x1 || box.x1 < span.x1) {
321
+ box.x1 = span.x1;
322
+ }
323
+ if (!box.y0 || box.y0 > span.y0) {
324
+ box.y0 = span.y0;
325
+ }
326
+ if (!box.y1 || box.y1 < span.y1) {
327
+ box.y1 = span.y1;
328
+ }
329
+ });
330
+ });
331
+ }
308
332
  });
309
333
 
310
334
  // check if doesn't cover any other annotation
@@ -15,6 +15,7 @@ const state = {
15
15
  placeholderSelection: [],
16
16
  selectedEntities: [],
17
17
  spanLoading: false,
18
+ annotationSetSelection: null,
18
19
  };
19
20
 
20
21
  const getters = {
@@ -238,6 +239,9 @@ const actions = {
238
239
  setPlaceholderSelection: ({ commit }, span) => {
239
240
  commit("SET_PLACEHOLDER_SELECTION", span);
240
241
  },
242
+ setAnnotationSetSelection: ({ commit }, annotationSet) => {
243
+ commit("SET_ANNOTATION_SET_SELECTED", annotationSet);
244
+ },
241
245
  };
242
246
 
243
247
  const mutations = {
@@ -295,6 +299,9 @@ const mutations = {
295
299
  SET_SPAN_LOADING: (state, loading) => {
296
300
  state.spanLoading = loading;
297
301
  },
302
+ SET_ANNOTATION_SET_SELECTED: (state, annotationSet) => {
303
+ state.annotationSetSelection = annotationSet;
304
+ },
298
305
  };
299
306
 
300
307
  export default {