@konfuzio/document-validation-ui 0.1.42-dev.1 → 0.1.42

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.42-dev.1",
3
+ "version": "0.1.42",
4
4
  "repository": "git://github.com:konfuzio-ai/document-validation-ui.git",
5
5
  "main": "dist/app.js",
6
6
  "scripts": {
@@ -16,17 +16,15 @@
16
16
  color: $text-strong;
17
17
  }
18
18
 
19
- .label-set-dropdown {
20
- width: 100%;
21
- border: 1px solid $grey-outline;
22
- height: 40px;
23
- cursor: pointer;
24
- box-shadow: 0px 1px 2px rgba(16, 24, 40, 0.05);
25
- border-radius: 8px;
26
- margin-bottom: 4px;
27
-
28
- &.dropdown-disabled {
29
- cursor: not-allowed;
19
+ .label-set-list {
20
+ max-height: 400px;
21
+ overflow-y: auto;
22
+ display: flex;
23
+ flex-direction: column;
24
+ gap: 16px;
25
+
26
+ button.full-width {
27
+ width: 100%;
30
28
  }
31
29
  }
32
30
 
@@ -35,17 +33,6 @@
35
33
  font-size: 14px;
36
34
  font-weight: 400;
37
35
  line-height: 20px;
38
-
39
- .labels-select {
40
- padding: 12px;
41
- overflow: scroll;
42
- height: 154px;
43
- border: 1px solid $grey-detail;
44
- border-radius: 8px;
45
- display: flex;
46
- flex-direction: column;
47
- gap: 5px;
48
- }
49
36
  }
50
37
 
51
38
  .next-step-description {
@@ -56,10 +43,5 @@
56
43
  color: $text-color;
57
44
  margin-top: 8px;
58
45
  }
59
-
60
- .submit-ann-set {
61
- margin-top: 16px;
62
- width: 100%;
63
- }
64
46
  }
65
47
  }
@@ -49,6 +49,10 @@
49
49
  color: $text-color;
50
50
  }
51
51
 
52
+ a {
53
+ color: $primary;
54
+ }
55
+
52
56
  button {
53
57
  &.is-primary {
54
58
  background-color: $primary !important;
@@ -1,3 +1,4 @@
1
+ <!-- eslint-disable vue/no-v-html -->
1
2
  <template>
2
3
  <section class="choose-label-set-modal">
3
4
  <b-modal
@@ -8,89 +9,57 @@
8
9
  :on-cancel="close"
9
10
  >
10
11
  <section class="modal-card-body">
11
- <div class="content">
12
+ <b-loading :active="loading" :is-full-page="false">
13
+ <b-icon icon="spinner" class="fa-spin loading-icon-size spinner" />
14
+ </b-loading>
15
+ <div v-if="!loading" class="content">
12
16
  <h3>
13
- {{
14
- isMultipleAnnotations
15
- ? $t("new_multi_ann_title")
16
- : $t("new_ann_set_title")
17
- }}
17
+ {{ $t("new_ann_set_title") }}
18
18
  </h3>
19
- <p>
20
- {{
21
- isMultipleAnnotations
22
- ? $t("new_multi_ann_description")
23
- : $t("new_ann_set_description")
24
- }}
25
- </p>
26
- <b-tooltip
27
- multilined
28
- :active="labelSets.length === 0"
29
- size="is-large"
30
- position="is-bottom"
31
- class="bottom-aligned"
32
- :close-delay="5000"
33
- >
34
- <template #content>
35
- <div ref="tooltipContent"></div>
36
- </template>
37
- <b-dropdown
38
- v-model="selectedLabelSet"
39
- aria-role="list"
40
- :disabled="labelSets.length === 0"
41
- :class="[
42
- 'label-set-dropdown',
43
- labelSets.length === 0 && 'dropdown-disabled',
44
- ]"
45
- scrollable
46
- >
47
- <template #trigger>
48
- <div>
49
- <div>
50
- <span v-if="selectedLabelSet">{{
51
- selectedLabelSet.name
52
- }}</span>
53
- <span v-else>{{ $t("select_label_set") }}</span>
19
+ <div>
20
+ <div v-if="labelSets.length === 0">
21
+ <p v-html="$t('no_multi_ann_labelset_model')" />
22
+ </div>
23
+ <div v-else>
24
+ <p>
25
+ {{ $t("new_ann_set_description") }}
26
+ </p>
27
+
28
+ <div class="label-set-list">
29
+ <div
30
+ v-for="labelSetItem in labelSets"
31
+ :key="labelSetItem.id"
32
+ class="label-set-list-row"
33
+ >
34
+ <b-button
35
+ class="full-width"
36
+ type="is-secondary"
37
+ @click="submit(labelSetItem)"
38
+ >
39
+ {{
40
+ `${labelSetItem.name} ${numberOfLabelSetGroup(
41
+ labelSetItem
42
+ )}`
43
+ }}
44
+ </b-button>
45
+ <div class="labels-list">
46
+ <span
47
+ v-for="(label, index) in labelSetItem.labels"
48
+ :key="label.id"
49
+ >{{
50
+ `${label.name}${
51
+ index + 1 !== labelSetItem.labels.length ? ", " : ""
52
+ }`
53
+ }}</span
54
+ >
54
55
  </div>
55
56
  </div>
56
- </template>
57
- <b-dropdown-item
58
- v-for="labelSetItem in labelSets"
59
- :key="labelSetItem.id"
60
- aria-role="listitem"
61
- :value="labelSetItem"
62
- @click="setSelectedLabelSet(labelSetItem)"
63
- >
64
- <span>{{ labelSetItem.name }}</span>
65
- </b-dropdown-item>
66
- </b-dropdown>
67
- </b-tooltip>
68
- <div v-if="selectedLabelSet" class="labels-list">
69
- <div v-if="isMultipleAnnotations" class="labels-select">
70
- <div v-for="label in labels" :key="label.id">
71
- <b-checkbox v-model="label.selected">{{
72
- label.name
73
- }}</b-checkbox>
74
57
  </div>
58
+ <p class="next-step-description">
59
+ {{ $t("new_ann_set_hint") }}
60
+ </p>
75
61
  </div>
76
- <span v-for="(label, index) in labels" v-else :key="label.id">{{
77
- `${label.name}${index + 1 !== labels.length ? ", " : ""}`
78
- }}</span>
79
62
  </div>
80
- <b-button
81
- class="submit-ann-set primary-button"
82
- type="is-primary"
83
- :disabled="!selectedLabelSet"
84
- @click="submit"
85
- >
86
- {{ $t("continue") }}
87
- </b-button>
88
- <p
89
- v-if="!isMultipleAnnotations && selectedLabelSet"
90
- class="next-step-description"
91
- >
92
- {{ $t("new_ann_set_hint") }}
93
- </p>
94
63
  </div>
95
64
  </section>
96
65
  </b-modal>
@@ -106,31 +75,18 @@ import { mapGetters, mapState } from "vuex";
106
75
 
107
76
  export default {
108
77
  name: "CreateAnnotationSetModal",
109
- props: {
110
- isMultipleAnnotations: {
111
- type: Boolean,
112
- default: false,
113
- required: false,
114
- },
115
- },
116
78
  data() {
117
79
  return {
118
- selectedLabelSet: null,
119
80
  labelSets: [],
120
81
  show: true,
121
82
  labels: [],
83
+ loading: true,
122
84
  };
123
85
  },
124
86
  computed: {
125
87
  ...mapState("document", ["annotationSets"]),
126
88
  ...mapGetters("project", ["labelSetsFilteredForAnnotationSetCreation"]),
127
- },
128
- watch: {
129
- labelSets(newValue) {
130
- if (newValue.length === 0) {
131
- this.setTooltipText();
132
- }
133
- },
89
+ ...mapGetters("document", ["numberOfLabelSetGroup"]),
134
90
  },
135
91
  mounted() {
136
92
  this.$store.dispatch("project/fetchLabelSets").then((data) => {
@@ -138,43 +94,18 @@ export default {
138
94
  data,
139
95
  this.annotationSets
140
96
  );
97
+ this.loading = false;
141
98
  });
142
99
  },
143
100
  methods: {
144
- submit() {
145
- // filter labels that were selected (by default all are selected so no issue if the feature is disabled)
146
- const labelsFiltered = this.labels.filter((label) => label.selected);
147
- this.selectedLabelSet.labels = this.selectedLabelSet.labels.filter(
148
- (label) => {
149
- return labelsFiltered.find((filtered) => filtered.id === label.id);
150
- }
151
- );
152
-
153
- this.$emit("finish", this.selectedLabelSet);
101
+ submit(labelSet) {
102
+ this.$emit("finish", labelSet);
154
103
  this.close();
155
104
  },
156
- setSelectedLabelSet(labelSet) {
157
- this.createLabelsList(labelSet.labels);
158
- this.selectedLabelSet = labelSet;
159
- },
160
105
  close() {
161
106
  this.$store.dispatch("display/showChooseLabelSetModal", null);
162
107
  this.$emit("close");
163
108
  },
164
- createLabelsList(labels) {
165
- this.labels = labels.map((label) => {
166
- return {
167
- ...label,
168
- selected: true,
169
- };
170
- });
171
- },
172
- setTooltipText() {
173
- // Text set from innerHTML vs 'label' due to html tag in locales file string
174
- this.$refs.tooltipContent.innerHTML = this.$t(
175
- "no_multi_ann_labelset_model"
176
- );
177
- },
178
109
  },
179
110
  };
180
111
  </script>
@@ -45,132 +45,115 @@
45
45
  >
46
46
  <EmptyState :is-search="true" />
47
47
  </div>
48
-
49
- <div
50
- v-if="Object.entries(annotationSetsInTable()).length > 0"
51
- class="annotation-set-group"
52
- >
53
- <div class="label-set-header">
54
- <div class="label-set-name">{{ $t("table") }}</div>
55
- </div>
48
+ <div v-if="annotationSetsAccordion">
56
49
  <div
57
- v-for="(tableSet, index) in Object.values(annotationSetsInTable())"
58
- :key="index"
59
- class="ann-set-table"
60
- @click="openAnnotationSetTable(tableSet)"
50
+ v-for="(
51
+ annotationSet, indexGroup
52
+ ) in getAnnotationsFiltered.annotationSets"
53
+ :key="indexGroup"
54
+ :class="[
55
+ 'annotation-set-group',
56
+ !annotationSetsAccordion[indexGroup] === true &&
57
+ 'annotation-set-collapsed',
58
+ ]"
61
59
  >
62
- <div class="ann-set-table-icon">
63
- <GridIcon /><span class="ann-set-number">{{
64
- tableSet.length
65
- }}</span>
66
- </div>
67
- <span class="ann-set-table-label-set-name">{{
68
- tableSet[0].label_set.name
69
- }}</span>
70
- </div>
71
- </div>
72
- <div
73
- v-for="(
74
- annotationSet, indexGroup
75
- ) in getAnnotationsFiltered.annotationSets"
76
- :key="indexGroup"
77
- :class="[
78
- 'annotation-set-group',
79
- !annotationSetsAccordion[indexGroup] === true &&
80
- 'annotation-set-collapsed',
81
- ]"
82
- >
83
- <div class="label-set-header" @click="toggleAccordion(indexGroup)">
84
- <div class="label-set-name">
85
- <b-icon
86
- :icon="
87
- annotationSetsAccordion[indexGroup] ? 'angle-up' : 'angle-down'
88
- "
89
- size="is-12"
90
- />
91
- {{
92
- `${annotationSet.label_set.name} ${numberOfAnnotationSetGroup(
93
- annotationSet
94
- )}`
95
- }}
96
- </div>
97
- <div
98
- v-if="
99
- !publicView &&
100
- !isDocumentReviewed &&
101
- annotationSet.labels.length !== 0
102
- "
103
- class="labelset-action-buttons"
104
- >
105
- <AnnotationSetActionButtons
106
- :is-placeholder="annotationSetsAccordion[indexGroup] === false"
107
- :number-of-empty-labels-in-annotation-set="
108
- emptyLabels(annotationSet).length
109
- "
110
- :number-of-not-correct-annotations-in-annotation-set="
111
- notCorrectAnnotations(annotationSet).length
112
- "
113
- @mark-all-empty-missing="
114
- markAnnotationsAsMissing(null, null, annotationSet, true)
115
- "
116
- @hover-annotation-set-to-mark-missing="
117
- handleHoverAnnotationSet(annotationSet, 'missing')
118
- "
119
- @leave-annotation-set-to-mark-missing="
120
- handleHoverAnnotationSet(null)
121
- "
122
- @accept-all-pending-annotations="
123
- acceptPendingAnnotationsInAnnotationSet(annotationSet)
124
- "
125
- @hover-annotation-set-to-accept="
126
- handleHoverAnnotationSet(annotationSet, 'accept')
60
+ <div class="label-set-header" @click="toggleAccordion(indexGroup)">
61
+ <div class="label-set-name">
62
+ <b-icon
63
+ :icon="
64
+ annotationSetsAccordion[indexGroup]
65
+ ? 'angle-up'
66
+ : 'angle-down'
67
+ "
68
+ size="is-12"
69
+ />
70
+ {{
71
+ `${annotationSet.label_set.name} ${numberOfAnnotationSetGroup(
72
+ annotationSet
73
+ )}`
74
+ }}
75
+ </div>
76
+ <div
77
+ v-if="
78
+ !publicView &&
79
+ !isDocumentReviewed &&
80
+ annotationSet.labels.length !== 0
127
81
  "
128
- @leave-annotation-set-to-accept="handleHoverAnnotationSet(null)"
129
- />
82
+ class="labelset-action-buttons"
83
+ >
84
+ <AnnotationSetActionButtons
85
+ :is-placeholder="annotationSetsAccordion[indexGroup] === false"
86
+ :number-of-empty-labels-in-annotation-set="
87
+ emptyLabels(annotationSet).length
88
+ "
89
+ :number-of-not-correct-annotations-in-annotation-set="
90
+ notCorrectAnnotations(annotationSet).length
91
+ "
92
+ @mark-all-empty-missing="
93
+ markAnnotationsAsMissing(null, null, annotationSet, true)
94
+ "
95
+ @hover-annotation-set-to-mark-missing="
96
+ handleHoverAnnotationSet(annotationSet, 'missing')
97
+ "
98
+ @leave-annotation-set-to-mark-missing="
99
+ handleHoverAnnotationSet(null)
100
+ "
101
+ @accept-all-pending-annotations="
102
+ acceptPendingAnnotationsInAnnotationSet(annotationSet)
103
+ "
104
+ @hover-annotation-set-to-accept="
105
+ handleHoverAnnotationSet(annotationSet, 'accept')
106
+ "
107
+ @leave-annotation-set-to-accept="handleHoverAnnotationSet(null)"
108
+ />
109
+ </div>
130
110
  </div>
131
- </div>
132
111
 
133
- <b-collapse :open="annotationSetsAccordion[indexGroup] === true">
134
- <div v-if="annotationSet.labels.length > 0">
135
- <div v-for="label in annotationSet.labels" :key="label.id">
136
- <div
137
- v-if="!(label.annotations.length === 0 && publicView)"
138
- class="labels"
139
- >
140
- <DocumentLabel
141
- :label="label"
142
- :annotation-set="annotationSet"
143
- :index-group="indexGroup"
144
- @handle-missing-annotation="markAnnotationsAsMissing"
145
- />
112
+ <b-collapse :open="annotationSetsAccordion[indexGroup] === true">
113
+ <div v-if="annotationSet.labels.length > 0">
114
+ <div v-for="label in annotationSet.labels" :key="label.id">
115
+ <div
116
+ v-if="!(label.annotations.length === 0 && publicView)"
117
+ class="labels"
118
+ >
119
+ <DocumentLabel
120
+ :label="label"
121
+ :annotation-set="annotationSet"
122
+ :index-group="indexGroup"
123
+ @handle-missing-annotation="markAnnotationsAsMissing"
124
+ />
125
+ </div>
146
126
  </div>
147
127
  </div>
148
- </div>
149
128
 
150
- <div v-else-if="annotationSet.labels.length === 0" class="no-labels">
151
- <span>
152
- {{
153
- isSearchingAnnotationList
154
- ? $t("no_results")
155
- : $t("no_labels_in_set")
156
- }}</span
129
+ <div
130
+ v-else-if="annotationSet.labels.length === 0"
131
+ class="no-labels"
157
132
  >
158
- <!-- eslint-disable vue/no-v-html -->
159
- <span
160
- v-if="isDocumentEditable && !isSearchingAnnotationList"
161
- v-html="$t('link_to_add_labels')"
162
- />
163
- </div>
133
+ <span>
134
+ {{
135
+ isSearchingAnnotationList
136
+ ? $t("no_results")
137
+ : $t("no_labels_in_set")
138
+ }}</span
139
+ >
140
+ <!-- eslint-disable vue/no-v-html -->
141
+ <span
142
+ v-if="isDocumentEditable && !isSearchingAnnotationList"
143
+ v-html="$t('link_to_add_labels')"
144
+ />
145
+ </div>
164
146
 
165
- <div
166
- v-else-if="
167
- !annotationSetHasAnnotations(annotationSet) && publicView
168
- "
169
- class="no-labels"
170
- >
171
- <span> {{ $t("no_annotations_in_annotation_set") }}</span>
172
- </div>
173
- </b-collapse>
147
+ <div
148
+ v-else-if="
149
+ !annotationSetHasAnnotations(annotationSet) && publicView
150
+ "
151
+ class="no-labels"
152
+ >
153
+ <span> {{ $t("no_annotations_in_annotation_set") }}</span>
154
+ </div>
155
+ </b-collapse>
156
+ </div>
174
157
  </div>
175
158
  </div>
176
159
  </div>
@@ -183,7 +166,6 @@ import AnnotationSetActionButtons from "./AnnotationSetActionButtons";
183
166
  import DocumentLabel from "./DocumentLabel";
184
167
  import AnnotationFilters from "./AnnotationFilters";
185
168
  import LoadingAnnotations from "./LoadingAnnotations";
186
- import GridIcon from "../../assets/images/GridIcon";
187
169
 
188
170
  /**
189
171
  * This component loads all annotations for one document
@@ -195,7 +177,6 @@ export default {
195
177
  AnnotationSetActionButtons,
196
178
  DocumentLabel,
197
179
  LoadingAnnotations,
198
- GridIcon,
199
180
  AnnotationFilters,
200
181
  },
201
182
  data() {
@@ -203,9 +184,10 @@ export default {
203
184
  count: 0,
204
185
  jumpToNextAnnotation: false,
205
186
  numberOfLoadingAnnotations: 3,
206
- annotationSetsAccordion: [],
187
+ annotationSetsAccordion: null,
207
188
  };
208
189
  },
190
+
209
191
  computed: {
210
192
  ...mapState("display", ["showAnnSetTable"]),
211
193
  ...mapState("document", [
@@ -226,7 +208,6 @@ export default {
226
208
  "getAnnotationsFiltered",
227
209
  "emptyLabels",
228
210
  "notCorrectAnnotations",
229
- "annotationSetsInTable",
230
211
  "isDocumentReviewed",
231
212
  "annotationSetOfAnnotation",
232
213
  "isAnnotationInAnnotationSet",
@@ -251,12 +232,7 @@ export default {
251
232
  this.jumpToNextAnnotation = false;
252
233
  }
253
234
  },
254
- annotationSets(newAnnotationSets, oldAnnotationSets) {
255
- this.loadAccordions(
256
- this.getAnnotationsFiltered.annotationSets,
257
- oldAnnotationSets
258
- );
259
- },
235
+
260
236
  getAnnotationsFiltered(newFiltered, oldFiltered) {
261
237
  this.loadAccordions(
262
238
  newFiltered.annotationSets,
@@ -279,7 +255,12 @@ export default {
279
255
  },
280
256
  created() {
281
257
  window.addEventListener("keydown", this.keyDownHandler);
282
- if (this.getAnnotationsFiltered.annotationSets) {
258
+
259
+ // validation for when page is hot reloaded and data reinitialize
260
+ if (
261
+ this.getAnnotationsFiltered.annotationSets &&
262
+ this.getAnnotationsFiltered.annotationSets.length > 0
263
+ ) {
283
264
  this.loadAccordions(this.getAnnotationsFiltered.annotationSets);
284
265
  }
285
266
  },
@@ -292,6 +273,7 @@ export default {
292
273
  annotationSet.labels.length === 0 && this.isSearchingAnnotationList
293
274
  );
294
275
  },
276
+
295
277
  toggleAccordion(index) {
296
278
  const newAnnotationSetsAccordion = [...this.annotationSetsAccordion];
297
279
  newAnnotationSetsAccordion[index] = !newAnnotationSetsAccordion[index];
@@ -306,12 +288,11 @@ export default {
306
288
  },
307
289
  loadAccordions(newAnnotationSets, oldAnnotationSets = null) {
308
290
  if (newAnnotationSets) {
291
+ const isFirstTime = this.annotationSetsAccordion === null;
309
292
  const newAnnotationSetsAccordion = [];
310
293
  const annotationSetsOpened = [];
311
294
  const annotationSetsCreated = [];
312
295
 
313
- const isFirstTime = oldAnnotationSets === null;
314
-
315
296
  if (!isFirstTime) {
316
297
  // when annotation sets changed, restore old state
317
298
  // and check if new ones were created to be open by default
@@ -179,13 +179,6 @@
179
179
  @selectEntities="handleEntitiesFromSelection"
180
180
  />
181
181
  </v-layer>
182
- <v-layer v-if="isMultiSelection">
183
- <multi-ann-selection
184
- :page="page"
185
- @buttonEnter="onElementEnter"
186
- @buttonLeave="onElementLeave"
187
- />
188
- </v-layer>
189
182
  </v-stage>
190
183
  <b-skeleton
191
184
  v-else
@@ -197,10 +190,9 @@
197
190
  </template>
198
191
  <script>
199
192
  import { mapState, mapGetters, mapActions } from "vuex";
200
- import { PIXEL_RATIO, MULTI_ANN_TABLE_FEATURE } from "../../constants";
193
+ import { PIXEL_RATIO } from "../../constants";
201
194
  import api from "../../api";
202
195
  import BoxSelection from "./BoxSelection";
203
- import MultiAnnSelection from "./MultiAnnSelection";
204
196
  import NewAnnotation from "./NewAnnotation";
205
197
  import EditAnnotation from "./EditAnnotation";
206
198
  import AnnSetTableOptions from "./AnnSetTableOptions";
@@ -209,7 +201,6 @@ export default {
209
201
  name: "DocumentPage",
210
202
  components: {
211
203
  BoxSelection,
212
- MultiAnnSelection,
213
204
  NewAnnotation,
214
205
  EditAnnotation,
215
206
  AnnSetTableOptions,
@@ -269,19 +260,6 @@ export default {
269
260
  selectionPage() {
270
261
  return this.selection && this.selection.pageNumber;
271
262
  },
272
- isBoxSelection() {
273
- if (!MULTI_ANN_TABLE_FEATURE) {
274
- return (
275
- true &&
276
- this.selection &&
277
- this.selection.pageNumber === this.currentPage
278
- );
279
- }
280
- return this.selection && !this.isSelecting && this.isElementSelected;
281
- },
282
- isMultiSelection() {
283
- return MULTI_ANN_TABLE_FEATURE && this.selection && this.isSelectionValid;
284
- },
285
263
  showFocusedAnnotation() {
286
264
  return (
287
265
  this.documentAnnotationSelected &&
@@ -125,7 +125,6 @@ const margin = 12;
125
125
  const widthOfPopup = 205;
126
126
 
127
127
  import { mapGetters, mapState } from "vuex";
128
- import { MULTI_ANN_TABLE_FEATURE } from "../../constants";
129
128
 
130
129
  export default {
131
130
  props: {
@@ -334,7 +333,6 @@ export default {
334
333
  openAnnotationSetCreation() {
335
334
  this.$store.dispatch("display/showChooseLabelSetModal", {
336
335
  show: true,
337
- isMultipleAnnotations: MULTI_ANN_TABLE_FEATURE,
338
336
  finish: this.chooseLabelSet,
339
337
  });
340
338
  },