@konfuzio/document-validation-ui 0.1.6-pre-release-2 → 0.1.7-pre-release-1

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.6-pre-release-2",
3
+ "version": "0.1.7-pre-release-1",
4
4
  "repository": "git://github.com:konfuzio-ai/document-validation-ui.git",
5
5
  "main": "dist/app.js",
6
6
  "scripts": {
@@ -17,7 +17,7 @@
17
17
 
18
18
  .dashboard-document {
19
19
  height: 100%;
20
- overflow: visible;
20
+ overflow: auto;
21
21
  position: relative;
22
22
  flex: 1;
23
23
  background-image: radial-gradient(#bfc1c9 0.8px, #ededed 0.1px);
@@ -5,10 +5,6 @@
5
5
  flex: 1;
6
6
  background-color: $background;
7
7
 
8
- &.split-overview-component {
9
- min-width: 600px;
10
- }
11
-
12
8
  .pages-section {
13
9
  width: 100%;
14
10
  overflow-y: scroll;
@@ -19,59 +15,55 @@
19
15
  justify-content: space-between;
20
16
 
21
17
  .document-grid {
22
- padding: 42px;
23
- display: grid;
24
- grid-template-columns: repeat(auto-fill, minmax(138px, 138px));
25
- justify-items: center;
26
- gap: 20px;
18
+ padding: 32px;
19
+ display: flex;
20
+ flex-wrap: wrap;
21
+ row-gap: 16px;
27
22
 
28
23
  .image-section {
29
24
  cursor: grab;
30
- width: 138px;
31
- height: 138px;
32
25
  display: flex;
33
26
  align-items: center;
27
+ flex-direction: column;
34
28
 
35
- .img-container {
36
- cursor: pointer;
37
-
38
- .img-thumbnail {
39
- border: $component-border;
40
- border-radius: 2px;
41
- }
29
+ .top-section {
30
+ display: flex;
31
+ flex-direction: row;
32
+ justify-content: space-between;
33
+ }
34
+ .bottom-section {
35
+ text-align: center;
36
+ }
42
37
 
43
- &.selected {
44
- .img-thumbnail {
45
- border-color: $text-color;
46
- filter: contrast(0.7);
47
- }
48
- }
38
+ .page-number {
39
+ margin-top: 8px;
40
+ color: $text-lighter;
41
+ font-size: 12px;
42
+ line-height: 12px;
43
+ font-weight: 400;
44
+ align-self: center;
45
+ padding-right: 60px;
49
46
  }
50
47
 
51
48
  .splitting-lines {
52
49
  cursor: pointer;
53
50
  position: relative;
54
- height: 130px;
55
51
  display: flex;
56
52
  align-items: center;
57
- padding-bottom: 20px;
53
+ justify-content: center;
54
+ width: 54px;
58
55
 
59
56
  .lines {
60
57
  display: flex;
61
- margin-left: 6px;
62
- padding-right: 19px;
63
- width: 25px;
64
58
  align-items: center;
65
59
  justify-content: center;
66
60
  }
67
61
 
68
62
  .scissors-icon {
69
63
  display: none;
70
- transform: rotate(-90deg);
64
+ transform: translate(10%) rotate(-90deg);
71
65
  position: absolute;
72
66
  z-index: 999;
73
- top: 42px;
74
- left: 3.3px;
75
67
  }
76
68
 
77
69
  &:hover {
@@ -99,69 +91,8 @@
99
91
  .splitting-lines {
100
92
  display: none;
101
93
  }
102
- }
103
-
104
- .image-container {
105
- width: fit-content;
106
- display: flex;
107
- flex-direction: column;
108
-
109
- .thumbnail {
110
- position: relative;
111
- display: flex;
112
- flex-direction: column;
113
- justify-content: center;
114
- align-items: center;
115
- height: 130px;
116
- width: 138px;
117
-
118
- &:hover {
119
- .icon-container {
120
- display: flex;
121
- }
122
- }
123
-
124
- .icon-container {
125
- position: absolute;
126
- width: auto;
127
- display: flex;
128
- flex-direction: column;
129
- align-items: center;
130
- gap: 6px;
131
- display: none;
132
-
133
- .action-icon {
134
- border-radius: 60px;
135
- background-color: $text-color;
136
- width: 32px;
137
- height: 32px;
138
- color: $white;
139
- display: flex;
140
- align-items: center;
141
- justify-content: center;
142
- cursor: pointer;
143
-
144
- svg {
145
- height: 21px;
146
- }
147
- }
148
- }
149
- }
150
-
151
94
  .page-number {
152
- color: $text-lighter;
153
- font-size: 12px;
154
- line-height: 12px;
155
- font-weight: 400;
156
- align-self: center;
157
- padding-bottom: 10px;
158
- }
159
-
160
- &.split-overview {
161
- img {
162
- height: 30px !important;
163
- width: 30px !important;
164
- }
95
+ padding-right: 0px;
165
96
  }
166
97
  }
167
98
  }
@@ -307,6 +238,7 @@
307
238
 
308
239
  &.split-overview-component {
309
240
  background-color: $background;
241
+ min-width: 600px;
310
242
 
311
243
  .split-overview-section {
312
244
  padding-left: 30px;
@@ -317,6 +249,10 @@
317
249
 
318
250
  .split-overview {
319
251
  margin-top: 20px;
252
+ img {
253
+ height: 30px !important;
254
+ width: 30px !important;
255
+ }
320
256
 
321
257
  .back-section {
322
258
  display: flex;
@@ -384,33 +320,6 @@
384
320
  }
385
321
  }
386
322
  }
387
-
388
- .icon-container {
389
- position: absolute;
390
- display: none;
391
-
392
- .action-icon {
393
- border-radius: 60px;
394
- background-color: $text-color;
395
- width: 28px;
396
- height: 28px;
397
- color: $white;
398
- display: flex;
399
- align-items: center;
400
- justify-content: center;
401
- cursor: pointer;
402
-
403
- svg {
404
- height: 21px;
405
- }
406
- }
407
- }
408
-
409
- &:hover {
410
- .icon-container {
411
- display: flex;
412
- }
413
- }
414
323
  }
415
324
  }
416
325
 
@@ -83,6 +83,14 @@
83
83
  background: $low-opacity-white;
84
84
  border-radius: 4px;
85
85
  }
86
+ &.zoom-disabled {
87
+ opacity: 30%;
88
+
89
+ &:hover {
90
+ cursor: not-allowed !important;
91
+ background: inherit;
92
+ }
93
+ }
86
94
  }
87
95
  }
88
96
  }
@@ -0,0 +1,53 @@
1
+ @import "./imports.scss";
2
+
3
+ .edit-page-thumbnail {
4
+ width: 80px;
5
+ display: flex;
6
+ flex-direction: column;
7
+ position: relative;
8
+ padding: 6px;
9
+
10
+ .action-checkbox {
11
+ cursor: pointer;
12
+ position: absolute;
13
+ left: 0;
14
+ top: 0;
15
+ z-index: 999;
16
+ }
17
+
18
+ .page-thumbnail {
19
+ display: flex;
20
+ flex-direction: column;
21
+ justify-content: center;
22
+ align-items: center;
23
+ border: $component-border;
24
+ border-radius: 2px;
25
+ cursor: pointer;
26
+ position: relative;
27
+
28
+ &.visible {
29
+ border: 1px solid $text-color;
30
+ }
31
+
32
+ &.selected {
33
+ border: 2px solid $primary;
34
+ }
35
+
36
+ .action-icon {
37
+ position: absolute;
38
+ background-color: $text-color;
39
+ left: 0;
40
+ bottom: 0;
41
+ width: 22px;
42
+ height: 22px;
43
+ color: $white;
44
+ display: flex;
45
+ align-items: center;
46
+ justify-content: center;
47
+
48
+ svg {
49
+ height: 16px;
50
+ }
51
+ }
52
+ }
53
+ }
@@ -275,6 +275,9 @@ body {
275
275
  }
276
276
 
277
277
  .b-checkbox.checkbox {
278
+ .check {
279
+ background-color: $white;
280
+ }
278
281
  &:hover input[type="checkbox"]:not(:disabled) + .check {
279
282
  border-color: $primary !important;
280
283
  }
@@ -6,7 +6,7 @@
6
6
  scroll-behavior: smooth;
7
7
 
8
8
  .scrolling-page {
9
- margin: 8px 0;
9
+ padding: 8px 0;
10
10
  }
11
11
 
12
12
  .loading-page {
@@ -1,5 +1,11 @@
1
1
  <template>
2
- <div class="multi-ann-table-overlay">
2
+ <div
3
+ class="multi-ann-table-overlay"
4
+ :style="{
5
+ left: `${left}px`,
6
+ width: `${width === 0 ? '100%' : `${width}px`}`,
7
+ }"
8
+ >
3
9
  <b-table
4
10
  ref="table"
5
11
  class="multi-ann-set-table dark-header header-32"
@@ -94,6 +100,18 @@ export default {
94
100
  AnnotationRow,
95
101
  DraggableIcon,
96
102
  },
103
+ props: {
104
+ left: {
105
+ type: Number,
106
+ required: false,
107
+ default: 0,
108
+ },
109
+ width: {
110
+ type: Number,
111
+ required: false,
112
+ default: 0,
113
+ },
114
+ },
97
115
  data() {
98
116
  return {
99
117
  rows: [],
@@ -5,3 +5,4 @@ export { default as DocumentLabel } from "./DocumentLabel";
5
5
  export { default as AnnotationDetails } from "./AnnotationDetails";
6
6
  export { default as ChooseLabelSetModal } from "./ChooseLabelSetModal";
7
7
  export { default as AnnotationRow } from "./AnnotationRow";
8
+ export { default as MultiAnnotationTableOverlay } from "./MultiAnnotationTableOverlay";
@@ -87,10 +87,7 @@ export default {
87
87
  };
88
88
  },
89
89
  computed: {
90
- ...mapGetters("category", {
91
- categoryName: "categoryName",
92
- projectHasSingleCategory: "projectHasSingleCategory",
93
- }),
90
+ ...mapGetters("category", ["categoryName", "projectHasSingleCategory"]),
94
91
  ...mapGetters("document", [
95
92
  "documentCannotBeEdited",
96
93
  "documentHasCorrectAnnotations",
@@ -112,17 +109,8 @@ export default {
112
109
  },
113
110
  },
114
111
  watch: {
115
- categories(newValue) {
116
- newValue.map((category) => {
117
- if (category.project === this.selectedDocument.project) {
118
- const found = this.currentProjectCategories.find(
119
- (cat) => cat.id === category.id
120
- );
121
- if (found) return;
122
-
123
- this.currentProjectCategories.push(category);
124
- }
125
- });
112
+ categories() {
113
+ this.handleCategories();
126
114
  },
127
115
  annotations() {
128
116
  this.checkIfDropdownIsDisabled();
@@ -131,31 +119,29 @@ export default {
131
119
  },
132
120
  mounted() {
133
121
  if (this.categories) {
134
- this.categories.map((category) => {
135
- if (category.project === this.selectedDocument.project) {
136
- const found = this.currentProjectCategories.find(
137
- (cat) => cat.id === category.id
138
- );
139
- if (found) return;
140
-
141
- this.currentProjectCategories.push(category);
142
- }
143
- });
122
+ this.handleCategories();
144
123
  }
145
124
 
146
125
  if (this.projectHasSingleCategory()) {
147
126
  this.tooltipIsShown = true;
148
127
  }
149
-
150
- this.$nextTick(() => {
151
- this.setTooltipText();
152
- this.checkIfDropdownIsDisabled();
153
- });
154
128
  },
155
129
  updated() {
156
130
  this.setTooltipText();
131
+ this.checkIfDropdownIsDisabled();
157
132
  },
158
133
  methods: {
134
+ handleCategories() {
135
+ this.categories.map((category) => {
136
+ if (category.project === this.selectedDocument.project) {
137
+ const found = this.currentProjectCategories.find(
138
+ (cat) => cat.id === category.id
139
+ );
140
+ if (found) return;
141
+ this.currentProjectCategories.push(category);
142
+ }
143
+ });
144
+ },
159
145
  checkIfDropdownIsDisabled() {
160
146
  if (
161
147
  this.projectHasSingleCategory() ||
@@ -218,7 +204,7 @@ export default {
218
204
  tooltipText = this.$t("approved_annotations");
219
205
  } else if (this.projectHasSingleCategory()) {
220
206
  tooltipText = this.$t("single_category_in_project");
221
- this.tooltipCloseDelay = 5000;
207
+ tooltipDelay = 5000;
222
208
  }
223
209
 
224
210
  this.tooltipCloseDelay = tooltipDelay;
@@ -7,6 +7,12 @@
7
7
  <DocumentAnnotations v-if="!editMode" ref="annotations" />
8
8
  <DocumentEdit v-else ref="editView" />
9
9
 
10
+ <MultiAnnotationTableOverlay
11
+ v-if="showAnnSetTable"
12
+ :left="documentContainerLeftPadding"
13
+ :width="documentContainerWidth"
14
+ />
15
+
10
16
  <transition name="slide-fade">
11
17
  <div
12
18
  v-if="showActionError"
@@ -43,7 +49,10 @@ import { mapGetters, mapState } from "vuex";
43
49
  import { DocumentTopBar } from "./DocumentTopBar";
44
50
  import { ScrollingDocument } from "./DocumentPage";
45
51
  import { DocumentThumbnails } from "./DocumentThumbnails";
46
- import { DocumentAnnotations } from "./DocumentAnnotations";
52
+ import {
53
+ DocumentAnnotations,
54
+ MultiAnnotationTableOverlay,
55
+ } from "./DocumentAnnotations";
47
56
  import { DocumentEdit } from "./DocumentEdit";
48
57
  import ErrorMessage from "./ErrorMessage";
49
58
  import NotOptimizedViewportModal from "../components/DocumentModals/NotOptimizedViewportModal";
@@ -66,11 +75,14 @@ export default {
66
75
  NotOptimizedViewportModal,
67
76
  DocumentErrorModal,
68
77
  SplittingSuggestionsModal,
78
+ MultiAnnotationTableOverlay,
69
79
  },
70
80
  data() {
71
81
  return {
72
82
  resizeObserver: null,
73
83
  unwatchSelectedDocument: null,
84
+ documentContainerLeftPadding: 0,
85
+ documentContainerWidth: 0,
74
86
  };
75
87
  },
76
88
  computed: {
@@ -80,6 +92,7 @@ export default {
80
92
  "optimalResolution",
81
93
  "pageWidthScale",
82
94
  "currentPage",
95
+ "showAnnSetTable",
83
96
  ]),
84
97
  ...mapState("document", [
85
98
  "showActionError",
@@ -125,6 +138,10 @@ export default {
125
138
  return elementsWidth;
126
139
  },
127
140
  onDocumentResize() {
141
+ this.documentContainerLeftPadding =
142
+ this.$refs.scrollingDocument.$el.getBoundingClientRect().left;
143
+ this.documentContainerWidth =
144
+ this.$refs.scrollingDocument.$el.offsetWidth;
128
145
  this.$store.dispatch(
129
146
  "display/updateOptimalResolution",
130
147
  this.$el.offsetWidth
@@ -4,7 +4,6 @@
4
4
  <EditPages
5
5
  :splitting-lines="splittingLines"
6
6
  :split-suggestions-enabled="splitSuggestionsEnabled"
7
- @change-page="changePage"
8
7
  @handle-splitting-lines="handleSplittingLines"
9
8
  @check-move="checkMove"
10
9
  @handle-drag-end="handleDragEnd"
@@ -0,0 +1,116 @@
1
+ <template>
2
+ <div
3
+ class="edit-page-thumbnail"
4
+ :tabindex="index"
5
+ @mouseenter="isHover = true"
6
+ @mouseleave="isHover = false"
7
+ >
8
+ <div
9
+ :class="[
10
+ 'page-thumbnail',
11
+ isVisible && 'visible',
12
+ checkboxValue && 'selected',
13
+ ]"
14
+ :style="{
15
+ transform: `rotate(${rotation}deg)`,
16
+ }"
17
+ @click="selectPage()"
18
+ >
19
+ <ServerImage :image-url="`${page.thumbnail_url}?${page.updated_at}`">
20
+ <b-skeleton width="80px" height="80px" />
21
+ </ServerImage>
22
+
23
+ <div v-if="isVisible" class="action-icon">
24
+ <EyeIcon />
25
+ </div>
26
+ </div>
27
+ <b-checkbox
28
+ v-show="isHover || checkboxValue"
29
+ v-model="checkboxValue"
30
+ class="action-checkbox"
31
+ @input="checkboxInput"
32
+ />
33
+ </div>
34
+ </template>
35
+
36
+ <script>
37
+ import { mapGetters, mapState } from "vuex";
38
+ import ServerImage from "../../assets/images/ServerImage";
39
+ import EyeIcon from "../../assets/images/EyeIcon";
40
+
41
+ export default {
42
+ name: "EditPageThumbnail",
43
+ components: {
44
+ ServerImage,
45
+ EyeIcon,
46
+ },
47
+ props: {
48
+ page: {
49
+ required: true,
50
+ type: Object,
51
+ default: null,
52
+ },
53
+ index: {
54
+ required: true,
55
+ type: Number,
56
+ default: 0,
57
+ },
58
+ rotation: {
59
+ required: false,
60
+ type: Number,
61
+ default: 0,
62
+ },
63
+ },
64
+ data() {
65
+ return {
66
+ isHover: false,
67
+ checkboxValue: false,
68
+ };
69
+ },
70
+ computed: {
71
+ ...mapState("display", ["currentPage"]),
72
+ ...mapState("edit", ["selectedPages"]),
73
+ ...mapGetters("edit", ["isPageSelected"]),
74
+ isVisible() {
75
+ return this.currentPage === this.page.number;
76
+ },
77
+ isSelected() {
78
+ return this.isPageSelected(this.page.id) !== undefined;
79
+ },
80
+ },
81
+ watch: {
82
+ isSelected() {
83
+ this.checkboxValue = this.isSelected;
84
+ },
85
+ },
86
+ mounted() {
87
+ this.checkboxValue = this.isSelected;
88
+ },
89
+ methods: {
90
+ selectPage(value = !this.isSelected) {
91
+ this.changePage();
92
+ this.$store.dispatch(
93
+ value ? "edit/selectPage" : "edit/unselectPage",
94
+ this.page
95
+ );
96
+ },
97
+ checkboxInput(value) {
98
+ this.selectPage(value);
99
+ },
100
+ changePage() {
101
+ if (!this.isVisible) {
102
+ this.$store.dispatch(
103
+ "display/updateCurrentPage",
104
+ parseInt(this.page.number, 10)
105
+ );
106
+ }
107
+ },
108
+ },
109
+ };
110
+ </script>
111
+
112
+ <style
113
+ scoped
114
+ lang="scss"
115
+ src="../../assets/scss/edit_page_thumbnail.scss"
116
+ ></style>