@konfuzio/document-validation-ui 0.1.32 → 0.1.34

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.
@@ -0,0 +1,186 @@
1
+ <template>
2
+ <section class="document-name-edit-modal">
3
+ <b-modal
4
+ ref="modal"
5
+ v-model="show"
6
+ :can-cancel="['x', 'outside']"
7
+ class="modal-absolute modal-400 modal-no-footer model-overflow-visible"
8
+ :on-cancel="close"
9
+ >
10
+ <section class="modal-card-body">
11
+ <div class="content">
12
+ <h3>
13
+ {{
14
+ isMultipleAnnotations
15
+ ? $t("new_multi_ann_title")
16
+ : $t("new_ann_set_title")
17
+ }}
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>
54
+ </div>
55
+ </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
+ </div>
75
+ </div>
76
+ <span v-for="(label, index) in labels" v-else :key="label.id">{{
77
+ `${label.name}${index + 1 !== labels.length ? ", " : ""}`
78
+ }}</span>
79
+ </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
+ </div>
95
+ </section>
96
+ </b-modal>
97
+ </section>
98
+ </template>
99
+
100
+ <script>
101
+ /**
102
+ * This component shows a modal to choose a label set from the project
103
+ */
104
+
105
+ import { mapGetters, mapState } from "vuex";
106
+
107
+ export default {
108
+ name: "CreateAnnotationSetModal",
109
+ props: {
110
+ isMultipleAnnotations: {
111
+ type: Boolean,
112
+ default: false,
113
+ required: false,
114
+ },
115
+ },
116
+ data() {
117
+ return {
118
+ selectedLabelSet: null,
119
+ labelSets: [],
120
+ show: true,
121
+ labels: [],
122
+ };
123
+ },
124
+ computed: {
125
+ ...mapState("document", ["annotationSets"]),
126
+ ...mapGetters("project", ["labelSetsFilteredForAnnotationSetCreation"]),
127
+ },
128
+ watch: {
129
+ labelSets(newValue) {
130
+ if (newValue.length === 0) {
131
+ this.setTooltipText();
132
+ }
133
+ },
134
+ },
135
+ mounted() {
136
+ this.$store.dispatch("project/fetchLabelSets").then((data) => {
137
+ this.labelSets = this.labelSetsFilteredForAnnotationSetCreation(
138
+ data,
139
+ this.annotationSets
140
+ );
141
+ });
142
+ },
143
+ 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);
154
+ this.close();
155
+ },
156
+ setSelectedLabelSet(labelSet) {
157
+ this.createLabelsList(labelSet.labels);
158
+ this.selectedLabelSet = labelSet;
159
+ },
160
+ close() {
161
+ this.$store.dispatch("display/showChooseLabelSetModal", null);
162
+ this.$emit("close");
163
+ },
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
+ },
179
+ };
180
+ </script>
181
+
182
+ <style
183
+ scoped
184
+ lang="scss"
185
+ src="../../assets/scss/choose_label_set_modal.scss"
186
+ ></style>
@@ -17,7 +17,7 @@
17
17
  ]"
18
18
  >
19
19
  <div
20
- v-if="previousDocument"
20
+ :style="`visibility: ${previousDocument ? 'visible' : 'hidden'}`"
21
21
  class="left-arrow navigation-arrow"
22
22
  type="button"
23
23
  @click="navigateToDocument(previousDocument)"
@@ -28,8 +28,8 @@
28
28
  <DocumentName :data-file-name="selectedDocument.data_file_name" />
29
29
 
30
30
  <div
31
- v-if="nextDocument"
32
31
  class="right-arrow navigation-arrow"
32
+ :style="`visibility: ${nextDocument ? 'visible' : 'hidden'}`"
33
33
  type="button"
34
34
  @click="navigateToDocument(nextDocument)"
35
35
  >
@@ -84,7 +84,7 @@
84
84
  </div>
85
85
  </div>
86
86
  <div v-else class="loading-top-bar">
87
- <b-skeleton position="is-centered" width="25%" height="60%" />
87
+ <b-skeleton position="is-centered" width="20%" height="60%" />
88
88
  </div>
89
89
  </div>
90
90
  </template>
@@ -160,13 +160,7 @@ export default {
160
160
  this.setComponentWidth(this.$refs.documentTopBar.offsetWidth);
161
161
  },
162
162
  getPreviousAndNextDocuments() {
163
- // Only consider documents who have a status of "ready"
164
- const filteredDocuments =
165
- this.documentsInProject; /*this.documentsInProject.filter(
166
- (document) =>
167
- (this.isDocumentReadyToBeReviewed(document)) ||
168
- this.waitingForSplittingConfirmation(document)
169
- );*/
163
+ const filteredDocuments = this.documentsInProject;
170
164
 
171
165
  if (!filteredDocuments) return;
172
166
 
package/src/constants.js CHANGED
@@ -2,5 +2,11 @@ export const PIXEL_RATIO = window.devicePixelRatio || 1;
2
2
  export const VIEWPORT_RATIO = 0.98;
3
3
  export const MINIMUM_APP_WIDTH = 600;
4
4
  export const MINIMUM_OPTIMIZED_APP_WIDTH = 950;
5
- export const TEXT_BREAKPOINT_WIDTH = 1350;
5
+ export const TEXT_BREAKPOINT_WIDTH = (locale) => {
6
+ if (locale === "en") {
7
+ return 1350;
8
+ } else {
9
+ return 1800;
10
+ }
11
+ };
6
12
  export const MULTI_ANN_TABLE_FEATURE = false;
@@ -87,6 +87,31 @@ const getters = {
87
87
  return currentResult;
88
88
  },
89
89
 
90
+ /**
91
+ * We take the entities from the backend and resize them according
92
+ * to the `scale` (zoom), the `imageScale` (proportion between the original
93
+ * document and the served image) and `PIXEL_RATIO` (in case of retina displays).
94
+ * We also change the original bbox format to something that can be used with CSS.
95
+ * The original is stored inside the `original` property, since it can be reused
96
+ * when we're sending the entity to the backend for selection or saving.
97
+ */
98
+ scaledEntities: (state, getters) => (entities, page) => {
99
+ // entities are either not loaded yet or empty
100
+ if (!entities || entities.length === 0) {
101
+ return [];
102
+ }
103
+
104
+ return entities.map((entity) => {
105
+ const box = getters.bboxToRect(page, entity);
106
+ return {
107
+ original: entity,
108
+ scaled: {
109
+ ...box,
110
+ },
111
+ };
112
+ });
113
+ },
114
+
90
115
  /**
91
116
  * The proportion between the original size of the page and the
92
117
  * image rendering.
@@ -55,19 +55,6 @@ const state = {
55
55
  },
56
56
  };
57
57
  const getters = {
58
- /**
59
- * Get entities inside a box
60
- */
61
- entitiesOnSelection: (state) => (box, page) => {
62
- return page.entities.filter(
63
- (entity) =>
64
- box.x0 <= entity.x0 &&
65
- box.x1 >= entity.x1 &&
66
- box.y0 <= entity.y0 &&
67
- box.y1 >= entity.y1
68
- );
69
- },
70
-
71
58
  /**
72
59
  * Number of pages. If the pages array doesn't exist yet, return 0.
73
60
  */
@@ -1345,6 +1332,7 @@ const actions = {
1345
1332
  if (state.splittingSuggestions) {
1346
1333
  commit("SET_SPLITTING_SUGGESTIONS", null);
1347
1334
  }
1335
+ commit("SET_RECALCULATING_ANNOTATIONS", false);
1348
1336
 
1349
1337
  if (getURLQueryParam("document") || getURLPath("d")) {
1350
1338
  navigateToNewDocumentURL(state.selectedDocument.id, newDocumentId);
@@ -93,7 +93,7 @@ const actions = {
93
93
 
94
94
  fetchDocumentList: ({ commit, state }, parameters) => {
95
95
  return HTTP.get(
96
- `documents/?project=${state.projectId}&assignee=${state.currentUser.username}&limit=100&${parameters}`
96
+ `documents/?project=${state.projectId}&limit=100&${parameters}`
97
97
  )
98
98
  .then((response) => {
99
99
  if (response.data.results) {
@@ -38,6 +38,19 @@ const getters = {
38
38
  }
39
39
  return null;
40
40
  },
41
+
42
+ /**
43
+ * Get entities inside a box
44
+ */
45
+ entitiesOnSelection: (state) => (box, page) => {
46
+ return page.entities.filter(
47
+ (entity) =>
48
+ box.x0 <= entity.x0 &&
49
+ box.x1 >= entity.x1 &&
50
+ box.y0 <= entity.y0 &&
51
+ box.y1 >= entity.y1
52
+ );
53
+ },
41
54
  };
42
55
 
43
56
  const actions = {