@konfuzio/document-validation-ui 0.1.19 → 0.1.20
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/.eslintrc.js +10 -10
- package/.prettierrc.json +1 -1
- package/LICENSE +21 -21
- package/README.md +24 -24
- package/cypress.config.js +13 -13
- package/dist/js/app.js +1 -1
- package/dist/js/app.js.map +1 -1
- package/dist/js/chunk-vendors.js +1 -1
- package/dist/js/chunk-vendors.js.map +1 -1
- package/jest.config.js +4 -4
- package/package.json +66 -66
- package/src/api.js +82 -82
- package/src/assets/images/AcceptedCheckMark.vue +8 -8
- package/src/assets/images/AcceptedUser.vue +8 -8
- package/src/assets/images/ActionIcon.vue +60 -60
- package/src/assets/images/ArrowDownKey.vue +11 -11
- package/src/assets/images/ArrowUpKey.vue +11 -11
- package/src/assets/images/CategoryIconImg.vue +13 -13
- package/src/assets/images/CheckMark.vue +8 -8
- package/src/assets/images/DraggableIcon.vue +14 -14
- package/src/assets/images/EditDocIcon.vue +12 -12
- package/src/assets/images/EmptyStateImg.vue +129 -129
- package/src/assets/images/ErrorIcon.vue +28 -28
- package/src/assets/images/EyeIcon.vue +11 -11
- package/src/assets/images/FileNameNotSavedImage.vue +26 -26
- package/src/assets/images/FileNameSavedImage.vue +14 -14
- package/src/assets/images/FitZoomIcon.vue +16 -16
- package/src/assets/images/GridIcon.vue +16 -16
- package/src/assets/images/KeyboardIcon.vue +16 -16
- package/src/assets/images/MagicWandIcon.vue +16 -16
- package/src/assets/images/MinusIcon.vue +13 -13
- package/src/assets/images/NotFoundIcon.vue +16 -16
- package/src/assets/images/NotOptimizedIllustration.vue +651 -651
- package/src/assets/images/PlusIcon.vue +13 -13
- package/src/assets/images/QuestionMark.vue +12 -12
- package/src/assets/images/ServerImage.vue +73 -73
- package/src/assets/images/SettingsIcon.vue +14 -14
- package/src/assets/images/SplitLines.vue +18 -18
- package/src/assets/images/SplitZigZag.vue +49 -49
- package/src/assets/images/StarIcon.vue +16 -16
- package/src/assets/images/StatusImg.vue +14 -14
- package/src/assets/images/TranslateArrows.vue +33 -33
- package/src/assets/scss/ann_set_table_options.scss +26 -26
- package/src/assets/scss/annotation_details.scss +141 -141
- package/src/assets/scss/choose_label_set_modal.scss +65 -65
- package/src/assets/scss/document_action_bar.scss +37 -37
- package/src/assets/scss/document_annotations.scss +558 -558
- package/src/assets/scss/document_category.scss +85 -85
- package/src/assets/scss/document_dashboard.scss +52 -52
- package/src/assets/scss/document_edit.scss +410 -410
- package/src/assets/scss/document_error.scss +81 -81
- package/src/assets/scss/document_name.scss +60 -60
- package/src/assets/scss/document_page.scss +12 -12
- package/src/assets/scss/document_thumbnails.scss +41 -41
- package/src/assets/scss/document_toolbar.scss +111 -111
- package/src/assets/scss/document_top_bar.scss +171 -171
- package/src/assets/scss/document_viewport_modal.scss +25 -25
- package/src/assets/scss/documents_list.scss +141 -141
- package/src/assets/scss/edit_page_thumbnail.scss +53 -53
- package/src/assets/scss/empty_state.scss +34 -34
- package/src/assets/scss/extracting_data.scss +35 -35
- package/src/assets/scss/imports.scss +1 -1
- package/src/assets/scss/multi_ann_table_overlay.scss +38 -38
- package/src/assets/scss/multi_ann_table_popup.scss +12 -12
- package/src/assets/scss/new_annotation.scss +102 -102
- package/src/assets/scss/scrolling_document.scss +19 -19
- package/src/assets/scss/theme.scss +801 -801
- package/src/assets/scss/variables.scss +66 -66
- package/src/components/App.cy.js +7 -7
- package/src/components/App.vue +187 -187
- package/src/components/DocumentAnnotations/AnnotationActionButtons.vue +152 -152
- package/src/components/DocumentAnnotations/AnnotationContent.vue +210 -210
- package/src/components/DocumentAnnotations/AnnotationDetails.vue +251 -251
- package/src/components/DocumentAnnotations/AnnotationRow.vue +752 -752
- package/src/components/DocumentAnnotations/AnnotationSetActionButtons.vue +89 -89
- package/src/components/DocumentAnnotations/ChooseLabelSetModal.vue +186 -186
- package/src/components/DocumentAnnotations/DocumentAnnotations.cy.js +441 -441
- package/src/components/DocumentAnnotations/DocumentAnnotations.vue +534 -534
- package/src/components/DocumentAnnotations/DocumentLabel.vue +189 -189
- package/src/components/DocumentAnnotations/EmptyAnnotation.vue +193 -193
- package/src/components/DocumentAnnotations/EmptyState.vue +21 -21
- package/src/components/DocumentAnnotations/ExtractingData.vue +41 -41
- package/src/components/DocumentAnnotations/LoadingAnnotations.vue +43 -43
- package/src/components/DocumentAnnotations/LoadingLabels.vue +43 -43
- package/src/components/DocumentAnnotations/MultiAnnotationTableOverlay.vue +338 -338
- package/src/components/DocumentAnnotations/index.js +8 -8
- package/src/components/DocumentCategory.vue +281 -281
- package/src/components/DocumentDashboard.vue +170 -170
- package/src/components/DocumentEdit/DocumentEdit.cy.js +541 -541
- package/src/components/DocumentEdit/DocumentEdit.vue +503 -503
- package/src/components/DocumentEdit/EditConfirmationModal.vue +55 -55
- package/src/components/DocumentEdit/EditPageThumbnail.vue +114 -114
- package/src/components/DocumentEdit/EditPages.vue +161 -161
- package/src/components/DocumentEdit/EditSidebar.vue +154 -154
- package/src/components/DocumentEdit/RenameAndCategorize.vue +184 -184
- package/src/components/DocumentEdit/SidebarButtons.vue +53 -53
- package/src/components/DocumentEdit/SplitInfoBar.vue +21 -21
- package/src/components/DocumentEdit/index.js +4 -4
- package/src/components/DocumentModals/DocumentErrorModal.vue +58 -58
- package/src/components/DocumentModals/NotOptimizedViewportModal.vue +51 -51
- package/src/components/DocumentPage/ActionBar.vue +48 -48
- package/src/components/DocumentPage/AnnSetTableOptions.vue +111 -111
- package/src/components/DocumentPage/BoxSelection.vue +152 -152
- package/src/components/DocumentPage/DocumentPage.cy.js +92 -92
- package/src/components/DocumentPage/DocumentPage.vue +568 -568
- package/src/components/DocumentPage/DocumentToolbar.cy.js +215 -215
- package/src/components/DocumentPage/DocumentToolbar.vue +228 -228
- package/src/components/DocumentPage/DummyPage.vue +55 -55
- package/src/components/DocumentPage/MultiAnnSelection.vue +371 -371
- package/src/components/DocumentPage/NewAnnotation.vue +308 -308
- package/src/components/DocumentPage/ScrollingDocument.vue +149 -149
- package/src/components/DocumentPage/ScrollingPage.vue +179 -179
- package/src/components/DocumentPage/index.js +5 -5
- package/src/components/DocumentThumbnails/DocumentThumbnails.cy.js +67 -67
- package/src/components/DocumentThumbnails/DocumentThumbnails.vue +132 -132
- package/src/components/DocumentThumbnails/LoadingThumbnail.vue +25 -25
- package/src/components/DocumentThumbnails/index.js +1 -1
- package/src/components/DocumentTopBar/DocumentName.vue +236 -236
- package/src/components/DocumentTopBar/DocumentTopBar.cy.js +222 -222
- package/src/components/DocumentTopBar/DocumentTopBar.vue +202 -202
- package/src/components/DocumentTopBar/DocumentTopBarButtons.vue +183 -183
- package/src/components/DocumentTopBar/KeyboardActionsDescription.vue +74 -74
- package/src/components/DocumentTopBar/index.js +3 -3
- package/src/components/DocumentsList/DocumentsList.vue +121 -121
- package/src/components/DocumentsList/index.js +1 -1
- package/src/components/ErrorMessage.vue +40 -40
- package/src/components/index.js +1 -1
- package/src/constants.js +5 -5
- package/src/directives/scroll.js +28 -28
- package/src/i18n.js +22 -22
- package/src/icons.js +45 -45
- package/src/locales/de.json +148 -148
- package/src/locales/en.json +148 -148
- package/src/main.js +26 -26
- package/src/store/category.js +191 -191
- package/src/store/display.js +311 -311
- package/src/store/document.js +1438 -1438
- package/src/store/edit.js +316 -316
- package/src/store/index.js +21 -21
- package/src/store/project.js +143 -143
- package/src/store/selection.js +210 -210
- package/src/utils/utils.js +54 -54
- package/vue.config.js +25 -25
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
export { default as DocumentAnnotations } from "./DocumentAnnotations";
|
|
2
|
-
export { default as AnnotationContent } from "./AnnotationContent";
|
|
3
|
-
export { default as EmptyAnnotation } from "./EmptyAnnotation";
|
|
4
|
-
export { default as DocumentLabel } from "./DocumentLabel";
|
|
5
|
-
export { default as AnnotationDetails } from "./AnnotationDetails";
|
|
6
|
-
export { default as ChooseLabelSetModal } from "./ChooseLabelSetModal";
|
|
7
|
-
export { default as AnnotationRow } from "./AnnotationRow";
|
|
8
|
-
export { default as MultiAnnotationTableOverlay } from "./MultiAnnotationTableOverlay";
|
|
1
|
+
export { default as DocumentAnnotations } from "./DocumentAnnotations";
|
|
2
|
+
export { default as AnnotationContent } from "./AnnotationContent";
|
|
3
|
+
export { default as EmptyAnnotation } from "./EmptyAnnotation";
|
|
4
|
+
export { default as DocumentLabel } from "./DocumentLabel";
|
|
5
|
+
export { default as AnnotationDetails } from "./AnnotationDetails";
|
|
6
|
+
export { default as ChooseLabelSetModal } from "./ChooseLabelSetModal";
|
|
7
|
+
export { default as AnnotationRow } from "./AnnotationRow";
|
|
8
|
+
export { default as MultiAnnotationTableOverlay } from "./MultiAnnotationTableOverlay";
|
|
@@ -1,281 +1,281 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<b-tooltip
|
|
3
|
-
multilined
|
|
4
|
-
:active="tooltipIsShown || dropdownIsDisabled"
|
|
5
|
-
size="is-large"
|
|
6
|
-
position="is-bottom"
|
|
7
|
-
:class="[
|
|
8
|
-
editMode
|
|
9
|
-
? 'right-aligned full-height-tooltip'
|
|
10
|
-
: 'left-aligned full-height-tooltip',
|
|
11
|
-
]"
|
|
12
|
-
:close-delay="tooltipCloseDelay"
|
|
13
|
-
>
|
|
14
|
-
<template #content>
|
|
15
|
-
<div ref="tooltipContent"></div>
|
|
16
|
-
</template>
|
|
17
|
-
<b-dropdown
|
|
18
|
-
:class="[
|
|
19
|
-
'category-chooser',
|
|
20
|
-
splitMode && 'split-mode',
|
|
21
|
-
isDocumentReviewed && 'disabled',
|
|
22
|
-
]"
|
|
23
|
-
aria-role="list"
|
|
24
|
-
scrollable
|
|
25
|
-
:disabled="dropdownIsDisabled"
|
|
26
|
-
>
|
|
27
|
-
<template #trigger>
|
|
28
|
-
<div class="category-drop-down">
|
|
29
|
-
<div class="icon">
|
|
30
|
-
<CategoryIcon />
|
|
31
|
-
</div>
|
|
32
|
-
<div class="category-info">
|
|
33
|
-
<p v-if="!splitMode" class="category-title">
|
|
34
|
-
{{ $t("category") }}
|
|
35
|
-
</p>
|
|
36
|
-
<div class="category-name">
|
|
37
|
-
<span>
|
|
38
|
-
{{ setCategoryDefaultText }}
|
|
39
|
-
</span>
|
|
40
|
-
<span v-if="splitMode && setCategoryConfidence >= 0">
|
|
41
|
-
{{ `(${setCategoryConfidence}%)` }}
|
|
42
|
-
</span>
|
|
43
|
-
</div>
|
|
44
|
-
</div>
|
|
45
|
-
<div :class="[!splitMode && 'caret-section']">
|
|
46
|
-
<b-icon
|
|
47
|
-
icon="angle-down"
|
|
48
|
-
size="is-small"
|
|
49
|
-
:class="['caret', splitMode && 'split-mode-caret']"
|
|
50
|
-
/>
|
|
51
|
-
</div>
|
|
52
|
-
</div>
|
|
53
|
-
</template>
|
|
54
|
-
|
|
55
|
-
<b-dropdown-item
|
|
56
|
-
v-for="category in listOfCategories()"
|
|
57
|
-
:key="category.id"
|
|
58
|
-
aria-role="listitem"
|
|
59
|
-
class="list-item"
|
|
60
|
-
:disabled="handleOptionInDropdownDisabled(category)"
|
|
61
|
-
@click="handleChangeCategory(category)"
|
|
62
|
-
>
|
|
63
|
-
<span>{{ category.name }}</span>
|
|
64
|
-
<span v-if="splitMode && category.confidence >= 0">{{
|
|
65
|
-
` (${category.confidence}%)`
|
|
66
|
-
}}</span>
|
|
67
|
-
</b-dropdown-item>
|
|
68
|
-
</b-dropdown>
|
|
69
|
-
</b-tooltip>
|
|
70
|
-
</template>
|
|
71
|
-
|
|
72
|
-
<script>
|
|
73
|
-
import { mapGetters, mapState } from "vuex";
|
|
74
|
-
import CategoryIcon from "../assets/images/CategoryIconImg";
|
|
75
|
-
|
|
76
|
-
export default {
|
|
77
|
-
name: "DocumentCategory",
|
|
78
|
-
components: {
|
|
79
|
-
CategoryIcon,
|
|
80
|
-
},
|
|
81
|
-
props: {
|
|
82
|
-
splitMode: {
|
|
83
|
-
type: Boolean,
|
|
84
|
-
},
|
|
85
|
-
page: {
|
|
86
|
-
type: Object,
|
|
87
|
-
default: null,
|
|
88
|
-
},
|
|
89
|
-
index: {
|
|
90
|
-
type: Number,
|
|
91
|
-
default: 0,
|
|
92
|
-
},
|
|
93
|
-
},
|
|
94
|
-
data() {
|
|
95
|
-
return {
|
|
96
|
-
categoryError: false,
|
|
97
|
-
tooltipIsShown: false,
|
|
98
|
-
tooltipCloseDelay: 0,
|
|
99
|
-
dropdownIsDisabled: false,
|
|
100
|
-
};
|
|
101
|
-
},
|
|
102
|
-
computed: {
|
|
103
|
-
...mapGetters("category", [
|
|
104
|
-
"categoryName",
|
|
105
|
-
"projectHasSingleCategory",
|
|
106
|
-
"categoryConfidence",
|
|
107
|
-
]),
|
|
108
|
-
...mapGetters("document", [
|
|
109
|
-
"documentCannotBeEdited",
|
|
110
|
-
"documentHasCorrectAnnotations",
|
|
111
|
-
"isDocumentReviewed",
|
|
112
|
-
]),
|
|
113
|
-
...mapState("document", ["selectedDocument", "annotations"]),
|
|
114
|
-
...mapState("category", ["categories"]),
|
|
115
|
-
...mapState("edit", ["editMode", "updatedDocument"]),
|
|
116
|
-
|
|
117
|
-
setCategoryDefaultText() {
|
|
118
|
-
if (!this.splitMode) {
|
|
119
|
-
return this.categoryName(this.selectedDocument.category);
|
|
120
|
-
} else {
|
|
121
|
-
const missingCategory = this.updatedDocument.find(
|
|
122
|
-
(item) => !item.category
|
|
123
|
-
);
|
|
124
|
-
|
|
125
|
-
// if there is just 1 category in the project,
|
|
126
|
-
// and one or more sub-documents has no category,
|
|
127
|
-
// assign the only category by default
|
|
128
|
-
if (this.projectHasSingleCategory && missingCategory) {
|
|
129
|
-
const updatedValuesForDocuments = this.updatedDocument.map(
|
|
130
|
-
(document) => {
|
|
131
|
-
if (!document.category && this.categories) {
|
|
132
|
-
document.category = this.categories[0].id;
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
return document;
|
|
136
|
-
}
|
|
137
|
-
);
|
|
138
|
-
|
|
139
|
-
// update the store state
|
|
140
|
-
// so that if the changes are saved the data sent to the API is updated
|
|
141
|
-
// instead of only handling the category name in this component
|
|
142
|
-
this.$store.dispatch(
|
|
143
|
-
"edit/setUpdatedDocument",
|
|
144
|
-
updatedValuesForDocuments
|
|
145
|
-
);
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
const categoryName = this.categoryName(
|
|
149
|
-
this.updatedDocument[this.index].category
|
|
150
|
-
);
|
|
151
|
-
|
|
152
|
-
return categoryName ? categoryName : this.$t("choose_category");
|
|
153
|
-
}
|
|
154
|
-
},
|
|
155
|
-
|
|
156
|
-
setCategoryConfidence() {
|
|
157
|
-
if (
|
|
158
|
-
!this.updatedDocument[this.index].categories ||
|
|
159
|
-
!this.categoryName(this.updatedDocument[this.index].category)
|
|
160
|
-
)
|
|
161
|
-
return;
|
|
162
|
-
|
|
163
|
-
const found = this.updatedDocument[this.index].categories.find(
|
|
164
|
-
(category) => category.id === this.updatedDocument[this.index].category
|
|
165
|
-
);
|
|
166
|
-
|
|
167
|
-
return this.categoryConfidence(found.confidence);
|
|
168
|
-
},
|
|
169
|
-
},
|
|
170
|
-
watch: {
|
|
171
|
-
annotations() {
|
|
172
|
-
this.checkIfDropdownIsDisabled();
|
|
173
|
-
this.setTooltipText();
|
|
174
|
-
},
|
|
175
|
-
},
|
|
176
|
-
mounted() {
|
|
177
|
-
if (this.projectHasSingleCategory) {
|
|
178
|
-
this.tooltipIsShown = true;
|
|
179
|
-
}
|
|
180
|
-
},
|
|
181
|
-
updated() {
|
|
182
|
-
this.setTooltipText();
|
|
183
|
-
this.checkIfDropdownIsDisabled();
|
|
184
|
-
},
|
|
185
|
-
methods: {
|
|
186
|
-
listOfCategories() {
|
|
187
|
-
let list;
|
|
188
|
-
|
|
189
|
-
if (this.splitMode && this.updatedDocument[this.index].categories) {
|
|
190
|
-
list = this.handleCategories(
|
|
191
|
-
this.updatedDocument[this.index].categories
|
|
192
|
-
);
|
|
193
|
-
} else if (this.categories) {
|
|
194
|
-
const filtered = this.categories.filter(
|
|
195
|
-
(category) => category.project === this.selectedDocument.project
|
|
196
|
-
);
|
|
197
|
-
list = this.handleCategories(filtered);
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
return list;
|
|
201
|
-
},
|
|
202
|
-
handleCategories(categories) {
|
|
203
|
-
return categories.map((category) => {
|
|
204
|
-
return {
|
|
205
|
-
id: category.id,
|
|
206
|
-
name: this.categoryName(category.id),
|
|
207
|
-
confidence: this.categoryConfidence(category.confidence),
|
|
208
|
-
};
|
|
209
|
-
});
|
|
210
|
-
},
|
|
211
|
-
checkIfDropdownIsDisabled() {
|
|
212
|
-
if (
|
|
213
|
-
this.projectHasSingleCategory ||
|
|
214
|
-
this.documentCannotBeEdited(this.selectedDocument) ||
|
|
215
|
-
(this.documentHasCorrectAnnotations && !this.splitMode)
|
|
216
|
-
) {
|
|
217
|
-
this.dropdownIsDisabled = true;
|
|
218
|
-
} else {
|
|
219
|
-
this.dropdownIsDisabled = false;
|
|
220
|
-
}
|
|
221
|
-
},
|
|
222
|
-
// The current category name will change
|
|
223
|
-
// depending on if we are on edit mode or not
|
|
224
|
-
handleOptionInDropdownDisabled(category) {
|
|
225
|
-
if (!this.splitMode)
|
|
226
|
-
return category.id === this.selectedDocument.category;
|
|
227
|
-
|
|
228
|
-
return category.id === this.updatedDocument[this.index].category;
|
|
229
|
-
},
|
|
230
|
-
handleChangeCategory(category) {
|
|
231
|
-
// handling the category change will be different based on
|
|
232
|
-
// the dropdown being on the topbar or the Rename and Categorize view
|
|
233
|
-
const updatedCategory = {
|
|
234
|
-
category: category.id,
|
|
235
|
-
};
|
|
236
|
-
|
|
237
|
-
if (!this.splitMode) {
|
|
238
|
-
this.$store.dispatch("document/startRecalculatingAnnotations");
|
|
239
|
-
|
|
240
|
-
this.$store
|
|
241
|
-
.dispatch("document/updateDocument", updatedCategory)
|
|
242
|
-
.catch((error) => {
|
|
243
|
-
this.$store.dispatch("document/createErrorMessage", {
|
|
244
|
-
error,
|
|
245
|
-
serverErrorMessage: this.$t("server_error"),
|
|
246
|
-
defaultErrorMessage: this.$t("edit_error"),
|
|
247
|
-
});
|
|
248
|
-
})
|
|
249
|
-
.finally(() => {
|
|
250
|
-
this.$store.dispatch("document/endRecalculatingAnnotations");
|
|
251
|
-
});
|
|
252
|
-
|
|
253
|
-
return;
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
// Send the category ID to the Rename and Categorize view
|
|
257
|
-
// to update the new document category
|
|
258
|
-
this.$emit("category-change", this.page, category.id);
|
|
259
|
-
},
|
|
260
|
-
setTooltipText() {
|
|
261
|
-
// Text set from innerHTML vs 'label' due to html tag in locales file string
|
|
262
|
-
let tooltipText;
|
|
263
|
-
let tooltipDelay = 0;
|
|
264
|
-
|
|
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
|
-
}
|
|
273
|
-
|
|
274
|
-
this.tooltipCloseDelay = tooltipDelay;
|
|
275
|
-
this.$refs.tooltipContent.innerHTML = tooltipText;
|
|
276
|
-
},
|
|
277
|
-
},
|
|
278
|
-
};
|
|
279
|
-
</script>
|
|
280
|
-
|
|
281
|
-
<style scoped lang="scss" src="../assets/scss/document_category.scss"></style>
|
|
1
|
+
<template>
|
|
2
|
+
<b-tooltip
|
|
3
|
+
multilined
|
|
4
|
+
:active="tooltipIsShown || dropdownIsDisabled"
|
|
5
|
+
size="is-large"
|
|
6
|
+
position="is-bottom"
|
|
7
|
+
:class="[
|
|
8
|
+
editMode
|
|
9
|
+
? 'right-aligned full-height-tooltip'
|
|
10
|
+
: 'left-aligned full-height-tooltip',
|
|
11
|
+
]"
|
|
12
|
+
:close-delay="tooltipCloseDelay"
|
|
13
|
+
>
|
|
14
|
+
<template #content>
|
|
15
|
+
<div ref="tooltipContent"></div>
|
|
16
|
+
</template>
|
|
17
|
+
<b-dropdown
|
|
18
|
+
:class="[
|
|
19
|
+
'category-chooser',
|
|
20
|
+
splitMode && 'split-mode',
|
|
21
|
+
isDocumentReviewed && 'disabled',
|
|
22
|
+
]"
|
|
23
|
+
aria-role="list"
|
|
24
|
+
scrollable
|
|
25
|
+
:disabled="dropdownIsDisabled"
|
|
26
|
+
>
|
|
27
|
+
<template #trigger>
|
|
28
|
+
<div class="category-drop-down">
|
|
29
|
+
<div class="icon">
|
|
30
|
+
<CategoryIcon />
|
|
31
|
+
</div>
|
|
32
|
+
<div class="category-info">
|
|
33
|
+
<p v-if="!splitMode" class="category-title">
|
|
34
|
+
{{ $t("category") }}
|
|
35
|
+
</p>
|
|
36
|
+
<div class="category-name">
|
|
37
|
+
<span>
|
|
38
|
+
{{ setCategoryDefaultText }}
|
|
39
|
+
</span>
|
|
40
|
+
<span v-if="splitMode && setCategoryConfidence >= 0">
|
|
41
|
+
{{ `(${setCategoryConfidence}%)` }}
|
|
42
|
+
</span>
|
|
43
|
+
</div>
|
|
44
|
+
</div>
|
|
45
|
+
<div :class="[!splitMode && 'caret-section']">
|
|
46
|
+
<b-icon
|
|
47
|
+
icon="angle-down"
|
|
48
|
+
size="is-small"
|
|
49
|
+
:class="['caret', splitMode && 'split-mode-caret']"
|
|
50
|
+
/>
|
|
51
|
+
</div>
|
|
52
|
+
</div>
|
|
53
|
+
</template>
|
|
54
|
+
|
|
55
|
+
<b-dropdown-item
|
|
56
|
+
v-for="category in listOfCategories()"
|
|
57
|
+
:key="category.id"
|
|
58
|
+
aria-role="listitem"
|
|
59
|
+
class="list-item"
|
|
60
|
+
:disabled="handleOptionInDropdownDisabled(category)"
|
|
61
|
+
@click="handleChangeCategory(category)"
|
|
62
|
+
>
|
|
63
|
+
<span>{{ category.name }}</span>
|
|
64
|
+
<span v-if="splitMode && category.confidence >= 0">{{
|
|
65
|
+
` (${category.confidence}%)`
|
|
66
|
+
}}</span>
|
|
67
|
+
</b-dropdown-item>
|
|
68
|
+
</b-dropdown>
|
|
69
|
+
</b-tooltip>
|
|
70
|
+
</template>
|
|
71
|
+
|
|
72
|
+
<script>
|
|
73
|
+
import { mapGetters, mapState } from "vuex";
|
|
74
|
+
import CategoryIcon from "../assets/images/CategoryIconImg";
|
|
75
|
+
|
|
76
|
+
export default {
|
|
77
|
+
name: "DocumentCategory",
|
|
78
|
+
components: {
|
|
79
|
+
CategoryIcon,
|
|
80
|
+
},
|
|
81
|
+
props: {
|
|
82
|
+
splitMode: {
|
|
83
|
+
type: Boolean,
|
|
84
|
+
},
|
|
85
|
+
page: {
|
|
86
|
+
type: Object,
|
|
87
|
+
default: null,
|
|
88
|
+
},
|
|
89
|
+
index: {
|
|
90
|
+
type: Number,
|
|
91
|
+
default: 0,
|
|
92
|
+
},
|
|
93
|
+
},
|
|
94
|
+
data() {
|
|
95
|
+
return {
|
|
96
|
+
categoryError: false,
|
|
97
|
+
tooltipIsShown: false,
|
|
98
|
+
tooltipCloseDelay: 0,
|
|
99
|
+
dropdownIsDisabled: false,
|
|
100
|
+
};
|
|
101
|
+
},
|
|
102
|
+
computed: {
|
|
103
|
+
...mapGetters("category", [
|
|
104
|
+
"categoryName",
|
|
105
|
+
"projectHasSingleCategory",
|
|
106
|
+
"categoryConfidence",
|
|
107
|
+
]),
|
|
108
|
+
...mapGetters("document", [
|
|
109
|
+
"documentCannotBeEdited",
|
|
110
|
+
"documentHasCorrectAnnotations",
|
|
111
|
+
"isDocumentReviewed",
|
|
112
|
+
]),
|
|
113
|
+
...mapState("document", ["selectedDocument", "annotations"]),
|
|
114
|
+
...mapState("category", ["categories"]),
|
|
115
|
+
...mapState("edit", ["editMode", "updatedDocument"]),
|
|
116
|
+
|
|
117
|
+
setCategoryDefaultText() {
|
|
118
|
+
if (!this.splitMode) {
|
|
119
|
+
return this.categoryName(this.selectedDocument.category);
|
|
120
|
+
} else {
|
|
121
|
+
const missingCategory = this.updatedDocument.find(
|
|
122
|
+
(item) => !item.category
|
|
123
|
+
);
|
|
124
|
+
|
|
125
|
+
// if there is just 1 category in the project,
|
|
126
|
+
// and one or more sub-documents has no category,
|
|
127
|
+
// assign the only category by default
|
|
128
|
+
if (this.projectHasSingleCategory && missingCategory) {
|
|
129
|
+
const updatedValuesForDocuments = this.updatedDocument.map(
|
|
130
|
+
(document) => {
|
|
131
|
+
if (!document.category && this.categories) {
|
|
132
|
+
document.category = this.categories[0].id;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
return document;
|
|
136
|
+
}
|
|
137
|
+
);
|
|
138
|
+
|
|
139
|
+
// update the store state
|
|
140
|
+
// so that if the changes are saved the data sent to the API is updated
|
|
141
|
+
// instead of only handling the category name in this component
|
|
142
|
+
this.$store.dispatch(
|
|
143
|
+
"edit/setUpdatedDocument",
|
|
144
|
+
updatedValuesForDocuments
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const categoryName = this.categoryName(
|
|
149
|
+
this.updatedDocument[this.index].category
|
|
150
|
+
);
|
|
151
|
+
|
|
152
|
+
return categoryName ? categoryName : this.$t("choose_category");
|
|
153
|
+
}
|
|
154
|
+
},
|
|
155
|
+
|
|
156
|
+
setCategoryConfidence() {
|
|
157
|
+
if (
|
|
158
|
+
!this.updatedDocument[this.index].categories ||
|
|
159
|
+
!this.categoryName(this.updatedDocument[this.index].category)
|
|
160
|
+
)
|
|
161
|
+
return;
|
|
162
|
+
|
|
163
|
+
const found = this.updatedDocument[this.index].categories.find(
|
|
164
|
+
(category) => category.id === this.updatedDocument[this.index].category
|
|
165
|
+
);
|
|
166
|
+
|
|
167
|
+
return this.categoryConfidence(found.confidence);
|
|
168
|
+
},
|
|
169
|
+
},
|
|
170
|
+
watch: {
|
|
171
|
+
annotations() {
|
|
172
|
+
this.checkIfDropdownIsDisabled();
|
|
173
|
+
this.setTooltipText();
|
|
174
|
+
},
|
|
175
|
+
},
|
|
176
|
+
mounted() {
|
|
177
|
+
if (this.projectHasSingleCategory) {
|
|
178
|
+
this.tooltipIsShown = true;
|
|
179
|
+
}
|
|
180
|
+
},
|
|
181
|
+
updated() {
|
|
182
|
+
this.setTooltipText();
|
|
183
|
+
this.checkIfDropdownIsDisabled();
|
|
184
|
+
},
|
|
185
|
+
methods: {
|
|
186
|
+
listOfCategories() {
|
|
187
|
+
let list;
|
|
188
|
+
|
|
189
|
+
if (this.splitMode && this.updatedDocument[this.index].categories) {
|
|
190
|
+
list = this.handleCategories(
|
|
191
|
+
this.updatedDocument[this.index].categories
|
|
192
|
+
);
|
|
193
|
+
} else if (this.categories) {
|
|
194
|
+
const filtered = this.categories.filter(
|
|
195
|
+
(category) => category.project === this.selectedDocument.project
|
|
196
|
+
);
|
|
197
|
+
list = this.handleCategories(filtered);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
return list;
|
|
201
|
+
},
|
|
202
|
+
handleCategories(categories) {
|
|
203
|
+
return categories.map((category) => {
|
|
204
|
+
return {
|
|
205
|
+
id: category.id,
|
|
206
|
+
name: this.categoryName(category.id),
|
|
207
|
+
confidence: this.categoryConfidence(category.confidence),
|
|
208
|
+
};
|
|
209
|
+
});
|
|
210
|
+
},
|
|
211
|
+
checkIfDropdownIsDisabled() {
|
|
212
|
+
if (
|
|
213
|
+
this.projectHasSingleCategory ||
|
|
214
|
+
this.documentCannotBeEdited(this.selectedDocument) ||
|
|
215
|
+
(this.documentHasCorrectAnnotations && !this.splitMode)
|
|
216
|
+
) {
|
|
217
|
+
this.dropdownIsDisabled = true;
|
|
218
|
+
} else {
|
|
219
|
+
this.dropdownIsDisabled = false;
|
|
220
|
+
}
|
|
221
|
+
},
|
|
222
|
+
// The current category name will change
|
|
223
|
+
// depending on if we are on edit mode or not
|
|
224
|
+
handleOptionInDropdownDisabled(category) {
|
|
225
|
+
if (!this.splitMode)
|
|
226
|
+
return category.id === this.selectedDocument.category;
|
|
227
|
+
|
|
228
|
+
return category.id === this.updatedDocument[this.index].category;
|
|
229
|
+
},
|
|
230
|
+
handleChangeCategory(category) {
|
|
231
|
+
// handling the category change will be different based on
|
|
232
|
+
// the dropdown being on the topbar or the Rename and Categorize view
|
|
233
|
+
const updatedCategory = {
|
|
234
|
+
category: category.id,
|
|
235
|
+
};
|
|
236
|
+
|
|
237
|
+
if (!this.splitMode) {
|
|
238
|
+
this.$store.dispatch("document/startRecalculatingAnnotations");
|
|
239
|
+
|
|
240
|
+
this.$store
|
|
241
|
+
.dispatch("document/updateDocument", updatedCategory)
|
|
242
|
+
.catch((error) => {
|
|
243
|
+
this.$store.dispatch("document/createErrorMessage", {
|
|
244
|
+
error,
|
|
245
|
+
serverErrorMessage: this.$t("server_error"),
|
|
246
|
+
defaultErrorMessage: this.$t("edit_error"),
|
|
247
|
+
});
|
|
248
|
+
})
|
|
249
|
+
.finally(() => {
|
|
250
|
+
this.$store.dispatch("document/endRecalculatingAnnotations");
|
|
251
|
+
});
|
|
252
|
+
|
|
253
|
+
return;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
// Send the category ID to the Rename and Categorize view
|
|
257
|
+
// to update the new document category
|
|
258
|
+
this.$emit("category-change", this.page, category.id);
|
|
259
|
+
},
|
|
260
|
+
setTooltipText() {
|
|
261
|
+
// Text set from innerHTML vs 'label' due to html tag in locales file string
|
|
262
|
+
let tooltipText;
|
|
263
|
+
let tooltipDelay = 0;
|
|
264
|
+
|
|
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
|
+
}
|
|
273
|
+
|
|
274
|
+
this.tooltipCloseDelay = tooltipDelay;
|
|
275
|
+
this.$refs.tooltipContent.innerHTML = tooltipText;
|
|
276
|
+
},
|
|
277
|
+
},
|
|
278
|
+
};
|
|
279
|
+
</script>
|
|
280
|
+
|
|
281
|
+
<style scoped lang="scss" src="../assets/scss/document_category.scss"></style>
|