@itfin/components 1.3.33 → 1.3.35
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 +2 -1
- package/src/ITFSettings.js +8 -0
- package/src/assets/fonts/bootstrap-icons.woff +0 -0
- package/src/assets/fonts/bootstrap-icons.woff2 +0 -0
- package/src/assets/scss/components/select/_selected.scss +1 -1
- package/src/assets/scss/icons.scss +2085 -0
- package/src/assets/scss/main.scss +1 -0
- package/src/components/avatar/index.stories.js +0 -1
- package/src/components/button/1.html +30 -0
- package/src/components/button/NativeButton.js +116 -0
- package/src/components/button/index.stories.js +10 -6
- package/src/components/checkbox/Checkbox.vue +5 -1
- package/src/components/datepicker/DatePickerInline.vue +10 -3
- package/src/components/datepicker/DateRangePickerInline.vue +10 -3
- package/src/components/dropdown/Dropdown.vue +5 -4
- package/src/components/dropdown/DropdownMenu.vue +7 -0
- package/src/components/filter/FilterBadge.vue +36 -19
- package/src/components/filter/FilterControl.vue +105 -0
- package/src/components/filter/constants.js +7 -6
- package/src/components/filter/index.stories.js +31 -3
- package/src/components/select/Select.vue +9 -2
- package/src/components/sortable/sortable-shopify.js +1 -1
- package/src/components/table/Table2.vue +108 -33
- package/src/components/table/TableBody.vue +58 -36
- package/src/components/table/TableGroup.vue +166 -114
- package/src/components/table/TableHeader.vue +153 -36
- package/src/components/table/index.stories.js +152 -4
- package/src/components/table/sticky.js +439 -0
- package/src/components/text-field/TextField.vue +1 -0
|
@@ -1,34 +1,38 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
|
|
3
|
-
<div class="scrollable scrollable-x big-scrollbar">
|
|
4
|
-
<
|
|
5
|
-
<
|
|
6
|
-
<
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
3
|
+
<div class="scrollable scrollable-x big-scrollbar" :class="{'permanent-checkboxes': selectedIds.length}">
|
|
4
|
+
<itf-checkbox-group v-model="selectedIds">
|
|
5
|
+
<template v-for="(group, index) in groups">
|
|
6
|
+
<div class="table-view-body">
|
|
7
|
+
<itf-table-group
|
|
8
|
+
:key="index"
|
|
9
|
+
:id-property="idProperty"
|
|
10
|
+
:columns="columns"
|
|
11
|
+
@update:columns="onColumnsUpdate"
|
|
12
|
+
:rows="group.rows"
|
|
13
|
+
:title="group.name"
|
|
14
|
+
:selected-ids.sync="selectedIds"
|
|
15
|
+
:add-new-rows="addNewRows"
|
|
16
|
+
:column-sorting="columnSorting"
|
|
17
|
+
:column-resizing="columnResizing"
|
|
18
|
+
:show-grouping="showGrouping"
|
|
19
|
+
:show-summary="showSummary"
|
|
20
|
+
:show-add-column="showAddColumn"
|
|
21
|
+
:show-header="!noHeader"
|
|
22
|
+
:schema="schema"
|
|
23
|
+
@new="$emit('new', $event)"
|
|
24
|
+
@add-column="$emit('add-column', $event)"
|
|
25
|
+
>
|
|
26
|
+
<template v-for="(_, name) in $slots" #[name]="slotData">
|
|
27
|
+
<slot :name="name" v-bind="slotData || {}" />
|
|
28
|
+
</template>
|
|
29
|
+
<template v-for="(_, name) in $scopedSlots" #[name]="slotData">
|
|
30
|
+
<slot :name="name" v-bind="slotData || {}" />
|
|
31
|
+
</template>
|
|
32
|
+
</itf-table-group>
|
|
33
|
+
</div>
|
|
34
|
+
</template>
|
|
35
|
+
</itf-checkbox-group>
|
|
32
36
|
</div>
|
|
33
37
|
|
|
34
38
|
</template>
|
|
@@ -65,7 +69,8 @@
|
|
|
65
69
|
}
|
|
66
70
|
</style>
|
|
67
71
|
<script>
|
|
68
|
-
import { Vue, Component, Prop,
|
|
72
|
+
import { Vue, Component, Prop, Watch } from 'vue-property-decorator';
|
|
73
|
+
import itfCheckboxGroup from '../checkbox/CheckboxGroup.vue';
|
|
69
74
|
import itfButton from '../button/Button.vue';
|
|
70
75
|
import itfIcon from '../icon/Icon.vue';
|
|
71
76
|
import itfTableGroup from './TableGroup.vue';
|
|
@@ -73,7 +78,11 @@ import itfTableHeader from './TableHeader.vue';
|
|
|
73
78
|
|
|
74
79
|
export default @Component({
|
|
75
80
|
name: 'itfTable2',
|
|
81
|
+
provide() {
|
|
82
|
+
return { tableEl: this }; // do not use Provide from vue-property-decorator
|
|
83
|
+
},
|
|
76
84
|
components: {
|
|
85
|
+
itfCheckboxGroup,
|
|
77
86
|
itfTableHeader,
|
|
78
87
|
itfButton,
|
|
79
88
|
itfIcon,
|
|
@@ -81,16 +90,72 @@ export default @Component({
|
|
|
81
90
|
}
|
|
82
91
|
})
|
|
83
92
|
class itfTable2 extends Vue {
|
|
84
|
-
@Prop({ required: true, type: Array }) columns;
|
|
93
|
+
// @Prop({ required: true, type: Array }) columns;
|
|
85
94
|
@Prop({ required: true, type: Array }) rows;
|
|
86
|
-
@Prop({ type: Number, default: 40 }) rowHeight;
|
|
87
95
|
@Prop({ type: String, default: null }) groupBy;
|
|
96
|
+
@Prop({ type: String, default: 'Id' }) idProperty;
|
|
97
|
+
@Prop({ type: String, default: null }) stateName; // save state to storage
|
|
98
|
+
@Prop({ type: Object, default: () => ({}) }) schema;
|
|
88
99
|
@Prop(Boolean) addNewRows;
|
|
89
100
|
@Prop(Boolean) columnSorting;
|
|
90
101
|
@Prop(Boolean) columnResizing;
|
|
91
102
|
@Prop(Boolean) showAddColumn;
|
|
92
103
|
@Prop(Boolean) showGrouping;
|
|
93
104
|
@Prop(Boolean) showSummary;
|
|
105
|
+
@Prop(Boolean) noHeader;
|
|
106
|
+
|
|
107
|
+
state = {
|
|
108
|
+
selectedIds: [],
|
|
109
|
+
columns: []
|
|
110
|
+
};
|
|
111
|
+
selectedIds = [];
|
|
112
|
+
|
|
113
|
+
getTableState() {
|
|
114
|
+
const list = this.schema?.properties || [];
|
|
115
|
+
let state = this.stateName ? JSON.parse(localStorage.getItem(this.stateKey) || 'null') : null;
|
|
116
|
+
if (!state) {
|
|
117
|
+
state = {
|
|
118
|
+
selectedIds: [],
|
|
119
|
+
columns: [...list]
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
state.selectedIds = [];
|
|
123
|
+
for (const column of list) {
|
|
124
|
+
const stateColumn = state.columns.find(i => i.property === column.property);
|
|
125
|
+
if (stateColumn) {
|
|
126
|
+
Object.assign(stateColumn, column);
|
|
127
|
+
} else {
|
|
128
|
+
state.columns.push(column);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
for (const column of state.columns) {
|
|
132
|
+
const originColumn = list.find(i => i.property === column.property);
|
|
133
|
+
if (!originColumn) {
|
|
134
|
+
state.columns = state.columns.filter(i => i.property !== column.property);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
return state;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
get stateKey() {
|
|
141
|
+
return this.stateName ? `itf-table-${this.stateName}` : null;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
saveTableState() {
|
|
145
|
+
if (!this.stateName) {
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
localStorage.setItem(this.stateKey, JSON.stringify(this.state));
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
mounted() {
|
|
152
|
+
this.state = this.getTableState();
|
|
153
|
+
this.selectedIds = this.state.selectedIds;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
get columns() {
|
|
157
|
+
return this.state?.columns || [];
|
|
158
|
+
}
|
|
94
159
|
|
|
95
160
|
get groups() {
|
|
96
161
|
const { groupBy, rows } = this;
|
|
@@ -108,8 +173,18 @@ class itfTable2 extends Vue {
|
|
|
108
173
|
return Object.entries(groups).map(([name, rows]) => ({ name, rows }));
|
|
109
174
|
}
|
|
110
175
|
|
|
176
|
+
@Watch('selectedIds')
|
|
177
|
+
onSelectedIdsUpdate(selectedIds) {
|
|
178
|
+
this.state.selectedIds = selectedIds;
|
|
179
|
+
this.saveTableState();
|
|
180
|
+
}
|
|
181
|
+
|
|
111
182
|
onColumnsUpdate(columns) {
|
|
112
|
-
|
|
183
|
+
const pinned = [...columns.filter(i => i.pinned)];
|
|
184
|
+
const unpinned = [...columns.filter(i => !i.pinned)];
|
|
185
|
+
this.state.columns = [...pinned, ...unpinned].map((item, key) => ({ ...item, index: key }));
|
|
186
|
+
this.$emit('update:columns', this.state.columns);
|
|
187
|
+
this.saveTableState();
|
|
113
188
|
}
|
|
114
189
|
}
|
|
115
190
|
</script>
|
|
@@ -1,15 +1,10 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
|
|
3
|
-
<
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
key-field="Id"
|
|
9
|
-
v-slot="{ item }"
|
|
10
|
-
direction="vertical"
|
|
11
|
-
>
|
|
12
|
-
<div group="items" data-test="table-item" class="table-view-item grouped draggable-item">
|
|
3
|
+
<div class="scroller">
|
|
4
|
+
<div
|
|
5
|
+
v-for="(item, n) in rows"
|
|
6
|
+
:key="n"
|
|
7
|
+
group="items" data-test="table-item" class="table-view-item grouped draggable-item">
|
|
13
8
|
<div class="table-row-template">
|
|
14
9
|
<div accept-group="items" class="table-view-body-space"></div>
|
|
15
10
|
<div class="shadow-area">
|
|
@@ -24,17 +19,10 @@
|
|
|
24
19
|
</div>
|
|
25
20
|
<div class="indicator sticky">
|
|
26
21
|
<div class="fill on-rest table-view-row-count">
|
|
27
|
-
<span>{{ item
|
|
22
|
+
<!-- <span>{{ item[idProperty] }}</span>-->
|
|
28
23
|
</div>
|
|
29
24
|
<div class="fill on-hover">
|
|
30
|
-
<
|
|
31
|
-
<i class="ic-expand"></i>
|
|
32
|
-
</a>
|
|
33
|
-
<div class="">
|
|
34
|
-
<a data-test="table-row-generator" href="">
|
|
35
|
-
<i class="ic-plus"></i>
|
|
36
|
-
</a>
|
|
37
|
-
</div>
|
|
25
|
+
<itf-checkbox :value="item[idProperty]" />
|
|
38
26
|
</div>
|
|
39
27
|
</div>
|
|
40
28
|
<div accept-group="items" class="table-item-inner">
|
|
@@ -44,12 +32,18 @@
|
|
|
44
32
|
:data-column="n"
|
|
45
33
|
:style="`width: ${column.width}px; left: ${column.left}px;`"
|
|
46
34
|
:class="{'sticky': column.pinned, 'last-sticky-column': n === lastPinnedIndex, 'flex-grow-1': column.grow}"
|
|
47
|
-
class="table-view-item-value d-flex h-100 align-items-stretch
|
|
35
|
+
class="table-view-item-value d-flex h-100 align-items-stretch">
|
|
48
36
|
<slot :name="`column.${column.name}`" :item="item" :column="column">
|
|
49
|
-
<template v-if="
|
|
50
|
-
<
|
|
37
|
+
<template v-if="column.editable">
|
|
38
|
+
<slot :name="`edit.${column.type}`" :value="getValue(item, column)" :item="item" :column="column">
|
|
39
|
+
<div class="px-1 py-1 w-100"><itf-text-field :value="getValue(item, column)" /></div>
|
|
40
|
+
</slot>
|
|
41
|
+
</template>
|
|
42
|
+
<template v-else>
|
|
43
|
+
<slot :name="`format.${column.type}`" :value="getValue(item, column)" :item="item" :column="column">
|
|
44
|
+
<div class="px-2 w-100">{{getValue(item, column)}}</div>
|
|
45
|
+
</slot>
|
|
51
46
|
</template>
|
|
52
|
-
<div v-else v-text="item.Name" />
|
|
53
47
|
</slot>
|
|
54
48
|
</div>
|
|
55
49
|
</template>
|
|
@@ -61,7 +55,7 @@
|
|
|
61
55
|
</div>
|
|
62
56
|
</div>
|
|
63
57
|
</div>
|
|
64
|
-
</
|
|
58
|
+
</div>
|
|
65
59
|
</template>
|
|
66
60
|
<style lang="scss">
|
|
67
61
|
.table-row-template {
|
|
@@ -70,7 +64,6 @@
|
|
|
70
64
|
align-items: stretch;
|
|
71
65
|
}
|
|
72
66
|
.table-item-inner {
|
|
73
|
-
height: 100%;
|
|
74
67
|
flex-grow: 1;
|
|
75
68
|
position: relative;
|
|
76
69
|
display: flex;
|
|
@@ -83,7 +76,6 @@
|
|
|
83
76
|
border-right: 1px solid var(--bs-border-color);
|
|
84
77
|
border-bottom: 1px solid var(--bs-border-color);
|
|
85
78
|
align-items: stretch;
|
|
86
|
-
height: 100%;
|
|
87
79
|
display: flex;
|
|
88
80
|
position: relative;
|
|
89
81
|
line-height: var(--itf-table-line-height);
|
|
@@ -108,7 +100,7 @@
|
|
|
108
100
|
}
|
|
109
101
|
}
|
|
110
102
|
&:hover {
|
|
111
|
-
background-color: var(--
|
|
103
|
+
background-color: var(--bs-tertiary-bg);
|
|
112
104
|
}
|
|
113
105
|
|
|
114
106
|
&.sticky {
|
|
@@ -119,20 +111,19 @@
|
|
|
119
111
|
}
|
|
120
112
|
|
|
121
113
|
.table-item-inner .extra {
|
|
122
|
-
height: 100%;
|
|
123
114
|
flex-grow: 1;
|
|
124
115
|
border-color: var(--bs-border-color);
|
|
125
116
|
}
|
|
126
117
|
|
|
127
118
|
.indicator {
|
|
128
|
-
height: 100%;
|
|
119
|
+
//height: 100%;
|
|
129
120
|
left: var(--shadow-area-width);
|
|
130
121
|
width: var(--indicator-area-width);
|
|
131
122
|
z-index: 4;
|
|
132
123
|
position: -webkit-sticky;
|
|
133
124
|
position: sticky;
|
|
134
125
|
background-color: var(--bs-body-bg);
|
|
135
|
-
border-right: 1px solid var(--bs-border-color);
|
|
126
|
+
//border-right: 1px solid var(--bs-border-color);
|
|
136
127
|
border-bottom: 1px solid var(--bs-border-color);
|
|
137
128
|
display: flex;
|
|
138
129
|
align-items: center;
|
|
@@ -140,6 +131,31 @@
|
|
|
140
131
|
min-width: var(--itf-table-min-width);
|
|
141
132
|
}
|
|
142
133
|
|
|
134
|
+
.table-row-template, .table-view-header-value {
|
|
135
|
+
.form-check {
|
|
136
|
+
padding: 0;
|
|
137
|
+
margin-bottom: 0;
|
|
138
|
+
|
|
139
|
+
.form-check-input {
|
|
140
|
+
margin-left: 0;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
.table-row-template {
|
|
145
|
+
.on-hover {
|
|
146
|
+
display: none;
|
|
147
|
+
}
|
|
148
|
+
&:hover, .permanent-checkboxes & {
|
|
149
|
+
.on-rest {
|
|
150
|
+
display: none;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
.on-hover {
|
|
154
|
+
display: block;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
143
159
|
.table-item-inner .boundary {
|
|
144
160
|
z-index: 3;
|
|
145
161
|
position: absolute;
|
|
@@ -172,7 +188,7 @@
|
|
|
172
188
|
bottom: 0;
|
|
173
189
|
}
|
|
174
190
|
.table-small-row .table-view-item {
|
|
175
|
-
height: var(--table-row-height);
|
|
191
|
+
// height: var(--table-row-height);
|
|
176
192
|
}
|
|
177
193
|
.resize-observer {
|
|
178
194
|
position: absolute;
|
|
@@ -191,27 +207,33 @@
|
|
|
191
207
|
</style>
|
|
192
208
|
<script>
|
|
193
209
|
import { Vue, Component, Prop } from 'vue-property-decorator';
|
|
210
|
+
import get from 'lodash/get';
|
|
194
211
|
import { RecycleScroller } from 'vue-virtual-scroller'
|
|
195
|
-
import
|
|
196
|
-
import
|
|
212
|
+
import itfCheckbox from '../checkbox/Checkbox.vue';
|
|
213
|
+
import itfTextField from '../text-field/TextField.vue';
|
|
197
214
|
import { INLINE_TYPES } from '../customize/constants';
|
|
198
215
|
import 'vue-virtual-scroller/dist/vue-virtual-scroller.css';
|
|
199
216
|
|
|
200
217
|
export default @Component({
|
|
201
218
|
name: 'itfTableBody',
|
|
202
219
|
components: {
|
|
203
|
-
|
|
204
|
-
|
|
220
|
+
itfCheckbox,
|
|
221
|
+
itfTextField,
|
|
222
|
+
RecycleScroller
|
|
205
223
|
}
|
|
206
224
|
})
|
|
207
225
|
class itfTableBody extends Vue {
|
|
208
226
|
@Prop() columns;
|
|
209
227
|
@Prop() rows;
|
|
228
|
+
@Prop() idProperty;
|
|
210
229
|
@Prop(Boolean) showAddColumn;
|
|
211
|
-
@Prop({ type: Number, default: 40 }) rowHeight;
|
|
212
230
|
|
|
213
231
|
editTypes = {};
|
|
214
232
|
|
|
233
|
+
getValue(item, column) {
|
|
234
|
+
return get(item, column.property);
|
|
235
|
+
}
|
|
236
|
+
|
|
215
237
|
get visibleAttributes() {
|
|
216
238
|
return this.columns;
|
|
217
239
|
}
|