@itfin/components 1.3.54 → 1.3.57
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 +1 -1
- package/src/assets/scss/components/_datepicker.scss +1 -1
- package/src/components/datepicker/MonthPicker.vue +16 -1
- package/src/components/datepicker/index.stories.js +2 -0
- package/src/components/modal/Modal.vue +1 -1
- package/src/components/pagination/Pagination.vue +33 -5
- package/src/components/panels/PanelList.vue +68 -34
- package/src/components/table/Table2.vue +11 -2
- package/src/components/table/TableBody.vue +20 -14
- package/src/components/table/TableGroup.vue +14 -5
- package/src/components/table/TableHeader.vue +2 -1
- package/src/components/table/TableRows.vue +11 -7
- package/src/components/table/table2.scss +4 -2
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div class="itf-monthpicker" :class="{'with-addon addon-start': prependIcon}">
|
|
2
|
+
<div class="itf-monthpicker input-group" :class="{'with-addon addon-start': prependIcon, 'with-addon addon-end': clearable}">
|
|
3
3
|
<div class="addon" v-if="prependIcon">
|
|
4
4
|
<slot name="addon">
|
|
5
5
|
<itf-icon :name="prependIcon" />
|
|
@@ -16,6 +16,17 @@
|
|
|
16
16
|
:value="displayValue"
|
|
17
17
|
:placeholder="placeholder"
|
|
18
18
|
/>
|
|
19
|
+
<div class="addon-end" v-if="clearable && value">
|
|
20
|
+
<slot name="clear">
|
|
21
|
+
<itf-button
|
|
22
|
+
icon
|
|
23
|
+
small
|
|
24
|
+
@click="$emit('input', '')"
|
|
25
|
+
>
|
|
26
|
+
<itf-icon name="close" />
|
|
27
|
+
</itf-button>
|
|
28
|
+
</slot>
|
|
29
|
+
</div>
|
|
19
30
|
<div style="display: none">
|
|
20
31
|
<div ref="dropdown" class="itf-monthpicker__dropdown border rounded">
|
|
21
32
|
<div>
|
|
@@ -42,10 +53,12 @@ import { DateTime } from 'luxon';
|
|
|
42
53
|
import tippy from 'tippy.js';
|
|
43
54
|
import itfIcon from '../icon/Icon';
|
|
44
55
|
import itfDatePickerInline from './DatePickerInline.vue';
|
|
56
|
+
import itfButton from "../button/Button.vue";
|
|
45
57
|
|
|
46
58
|
export default @Component({
|
|
47
59
|
name: 'itfMonthPicker',
|
|
48
60
|
components: {
|
|
61
|
+
itfButton,
|
|
49
62
|
itfIcon,
|
|
50
63
|
itfDatePickerInline
|
|
51
64
|
},
|
|
@@ -64,6 +77,8 @@ class itfMonthPicker extends Vue {
|
|
|
64
77
|
@Prop({ type: String, default: '' }) prependIcon;
|
|
65
78
|
@Prop({ type: String, default: 'bottom-start' }) placement;
|
|
66
79
|
|
|
80
|
+
@Prop(Boolean) clearable;
|
|
81
|
+
|
|
67
82
|
focused = false;
|
|
68
83
|
|
|
69
84
|
tooltip = null;
|
|
@@ -73,7 +73,7 @@ class itfModal extends Vue {
|
|
|
73
73
|
|
|
74
74
|
@Watch('value')
|
|
75
75
|
onVisibleChanged(newValue, oldValue) {
|
|
76
|
-
if (!this.modalEl || this.preventEvents || (typeof oldValue === 'undefined' && !newValue)) {
|
|
76
|
+
if (!this.modalEl || (this.preventEvents && oldValue !== true) || (typeof oldValue === 'undefined' && !newValue)) {
|
|
77
77
|
return;
|
|
78
78
|
}
|
|
79
79
|
if (newValue) {
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
|
|
3
|
-
<nav aria-label="Page navigation example">
|
|
3
|
+
<nav aria-label="Page navigation example" class="d-flex">
|
|
4
4
|
<ul class="pagination itf-pagination px-3">
|
|
5
5
|
<li
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
6
|
+
v-for="(page, n) in pagesArr"
|
|
7
|
+
:key="n"
|
|
8
|
+
class="page-item"
|
|
9
|
+
:class="{'active': page.current, 'disabled': !page.active && !page.current }"
|
|
10
10
|
>
|
|
11
11
|
<a v-if="page.type === 'prev'" href="" class="page-link" aria-label="Previous" @click.prevent="onPage(page.number)">
|
|
12
12
|
<itf-icon name="chevron_left" aria-hidden="true" />
|
|
@@ -22,19 +22,41 @@
|
|
|
22
22
|
</a>
|
|
23
23
|
</li>
|
|
24
24
|
</ul>
|
|
25
|
+
|
|
26
|
+
<itf-select
|
|
27
|
+
v-if="showSize"
|
|
28
|
+
class="itf-pagination-select"
|
|
29
|
+
:options="perPageOptions"
|
|
30
|
+
:reduce="(item) => item.value"
|
|
31
|
+
:get-option-label="(item) => item.title"
|
|
32
|
+
:value="size"
|
|
33
|
+
@input="onPerPage"
|
|
34
|
+
>
|
|
35
|
+
</itf-select>
|
|
25
36
|
</nav>
|
|
26
37
|
|
|
27
38
|
</template>
|
|
39
|
+
<style lang="scss" scoped>
|
|
40
|
+
.itf-pagination-select
|
|
41
|
+
{}
|
|
42
|
+
</style>
|
|
28
43
|
<script>
|
|
29
44
|
import { Vue, Component, Model, Prop } from 'vue-property-decorator';
|
|
30
45
|
import itfIcon from '../icon/Icon.vue';
|
|
46
|
+
import itfSelect from "@itfin/components/src/components/select/Select.vue";
|
|
31
47
|
|
|
32
48
|
const MIN_PAGES_BLOCKS = 2;
|
|
33
49
|
const MAX_PAGES_BLOCKS = 6;
|
|
50
|
+
const PER_PAGE_OPTIONS = [
|
|
51
|
+
{ title: '20', value: 20 },
|
|
52
|
+
{ title: '50', value: 50 },
|
|
53
|
+
{ title: '100', value: 100 }
|
|
54
|
+
];
|
|
34
55
|
|
|
35
56
|
export default @Component({
|
|
36
57
|
name: 'itfPagination',
|
|
37
58
|
components: {
|
|
59
|
+
itfSelect,
|
|
38
60
|
itfIcon
|
|
39
61
|
}
|
|
40
62
|
})
|
|
@@ -45,11 +67,17 @@ class itfPagination extends Vue {
|
|
|
45
67
|
@Prop({ type: [String, Number] }) pages;
|
|
46
68
|
@Prop({ type: [String, Number], default: MIN_PAGES_BLOCKS }) minBlocks;
|
|
47
69
|
@Prop({ type: [String, Number], default: MAX_PAGES_BLOCKS }) maxBlocks;
|
|
70
|
+
@Prop({type: Array, default: () => PER_PAGE_OPTIONS}) perPageOptions;
|
|
71
|
+
@Prop(Boolean) showSize;
|
|
48
72
|
|
|
49
73
|
onPage(page) {
|
|
50
74
|
this.$emit('input', page);
|
|
51
75
|
}
|
|
52
76
|
|
|
77
|
+
onPerPage(size) {
|
|
78
|
+
this.$emit('per-page', size);
|
|
79
|
+
}
|
|
80
|
+
|
|
53
81
|
get pagesArr () {
|
|
54
82
|
const pageSize = Number(this.size);
|
|
55
83
|
const totalItems = Number(this.length);
|
|
@@ -139,8 +139,9 @@ export default class PanelList extends Vue {
|
|
|
139
139
|
|
|
140
140
|
created() {
|
|
141
141
|
if (this.firstPanel) {
|
|
142
|
-
this.
|
|
142
|
+
this.internalOpenPanel(this.firstPanel.title, this.firstPanel.icon, this.firstPanel.type, this.firstPanel.payload);
|
|
143
143
|
}
|
|
144
|
+
this.parsePanelHash();
|
|
144
145
|
}
|
|
145
146
|
|
|
146
147
|
get isOpenMultiple() {
|
|
@@ -184,7 +185,7 @@ export default class PanelList extends Vue {
|
|
|
184
185
|
this.panelsStack = newStack;
|
|
185
186
|
}
|
|
186
187
|
|
|
187
|
-
|
|
188
|
+
internalOpenPanel(title: string, icon: string, type: string, payload: any, openIndex?: number) {
|
|
188
189
|
const newPanel:any = {
|
|
189
190
|
id: this.nextId++,
|
|
190
191
|
title,
|
|
@@ -203,42 +204,51 @@ export default class PanelList extends Vue {
|
|
|
203
204
|
newStack = newStack.slice(0, openIndex);
|
|
204
205
|
}
|
|
205
206
|
this.panelsStack = newStack;
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
newPanel.__events[eventName]
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
newPanel.off = (eventName, func: (event: string, ...args: any[]) => any) => {
|
|
219
|
-
if (newPanel.__events[eventName]) {
|
|
220
|
-
newPanel.__events[eventName] = newPanel.__events[eventName].filter(f => f !== func);
|
|
221
|
-
}
|
|
222
|
-
};
|
|
223
|
-
newPanel.once = (eventName, func: (event: string, ...args: any[]) => any) => {
|
|
224
|
-
const wrapper = (...args: any[]) => {
|
|
225
|
-
func(eventName, ...args);
|
|
226
|
-
newPanel.off(eventName, wrapper);
|
|
207
|
+
return new Promise(res => {
|
|
208
|
+
this.$nextTick(() => { // щоб панелі змінювались при редагуванні
|
|
209
|
+
const n = newStack.length;
|
|
210
|
+
newPanel.emit = (event, ...args) => this.emitEvent(event, ...args);
|
|
211
|
+
newPanel.open = (type, visOptions, payload) => this.openPanel(visOptions.title, visOptions.icon, type, payload, n + 1);
|
|
212
|
+
newPanel.close = () => this.closePanel(newPanel);
|
|
213
|
+
newPanel.expand = () => this.expandPanel(newPanel);
|
|
214
|
+
newPanel.on = (eventName, func: (event: string, ...args: any[]) => any) => {
|
|
215
|
+
if (!newPanel.__events[eventName]) {
|
|
216
|
+
newPanel.__events[eventName] = [];
|
|
217
|
+
}
|
|
218
|
+
newPanel.__events[eventName].push(func);
|
|
227
219
|
};
|
|
228
|
-
newPanel.
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
220
|
+
newPanel.off = (eventName, func: (event: string, ...args: any[]) => any) => {
|
|
221
|
+
if (newPanel.__events[eventName]) {
|
|
222
|
+
newPanel.__events[eventName] = newPanel.__events[eventName].filter(f => f !== func);
|
|
223
|
+
}
|
|
224
|
+
};
|
|
225
|
+
newPanel.once = (eventName, func: (event: string, ...args: any[]) => any) => {
|
|
226
|
+
const wrapper = (...args) => {
|
|
227
|
+
func(eventName, ...args);
|
|
228
|
+
newPanel.off(eventName, wrapper);
|
|
229
|
+
};
|
|
230
|
+
newPanel.on(eventName, wrapper);
|
|
231
|
+
};
|
|
232
|
+
newPanel.isMultiple = () => this.isOpenMultiple;
|
|
233
|
+
newPanel.fullsize = () => this.fullsizePanel(newPanel);
|
|
234
|
+
newPanel.getPayload = () => newPanel.payload;
|
|
235
|
+
newPanel.setPayload = (value: any) => {
|
|
236
|
+
newPanel.payload = value;
|
|
237
|
+
this.setPanelHash()
|
|
238
|
+
}
|
|
239
|
+
newStack.push(newPanel);
|
|
240
|
+
this.panelsStack = newStack;
|
|
241
|
+
this.ensureOnlyTwoOpenPanels(newPanel.id);
|
|
242
|
+
return res(newPanel);
|
|
243
|
+
})
|
|
239
244
|
});
|
|
240
245
|
}
|
|
241
246
|
|
|
247
|
+
async openPanel(title: string, icon: string, type: string, payload: any, openIndex?: number) {
|
|
248
|
+
await this.internalOpenPanel(title, icon, type, payload, openIndex);
|
|
249
|
+
this.setPanelHash()
|
|
250
|
+
}
|
|
251
|
+
|
|
242
252
|
emitEvent(event: string, ...args: any[]) {
|
|
243
253
|
for (const panel of this.panelsStack) {
|
|
244
254
|
if (panel.__events[event]) {
|
|
@@ -261,6 +271,7 @@ export default class PanelList extends Vue {
|
|
|
261
271
|
this.panelsStack[openPanelIndex - 1].isCollapsed = false;
|
|
262
272
|
}
|
|
263
273
|
this.ensureOnlyTwoOpenPanels(openPanel.id);
|
|
274
|
+
this.setPanelHash()
|
|
264
275
|
}
|
|
265
276
|
|
|
266
277
|
fullsizePanel(panel: IPanel) {
|
|
@@ -270,5 +281,28 @@ export default class PanelList extends Vue {
|
|
|
270
281
|
}
|
|
271
282
|
this.panelsStack = newStack;
|
|
272
283
|
}
|
|
284
|
+
|
|
285
|
+
setPanelHash() {
|
|
286
|
+
const hash = this.panelsStack.map(panel => {
|
|
287
|
+
return `${panel.type}=${JSON.stringify(panel.payload || {})}`;
|
|
288
|
+
}).join('&');
|
|
289
|
+
this.$router.push({ hash });
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
async parsePanelHash() {
|
|
293
|
+
const hash = this.$route.hash;
|
|
294
|
+
if (hash) {
|
|
295
|
+
const panels = hash.slice(1).split('&').map(item => {
|
|
296
|
+
const [type, payload] = item.split('=');
|
|
297
|
+
return {
|
|
298
|
+
type,
|
|
299
|
+
payload: JSON.parse(decodeURIComponent(payload))
|
|
300
|
+
};
|
|
301
|
+
});
|
|
302
|
+
for (const panel of panels) {
|
|
303
|
+
await this.internalOpenPanel('', '', panel.type, panel.payload);
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
}
|
|
273
307
|
}
|
|
274
308
|
</script>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
|
|
3
|
-
<div class="itf-table2 scrollable scrollable-x" :class="{'permanent-checkboxes': selectedIds.length}">
|
|
3
|
+
<div class="itf-table2 scrollable scrollable-x" :class="{'permanent-checkboxes': selectedIds.length}" :style="{ '--indicator-area-width': `${indicatorType === 'none' ? 1 : indicatorWidth}px` }">
|
|
4
4
|
<itf-checkbox-group v-model="selectedIds">
|
|
5
5
|
<template v-for="(group, index) in groups">
|
|
6
6
|
<div class="table-view-body">
|
|
@@ -30,6 +30,11 @@
|
|
|
30
30
|
:subrows-property="subrowsProperty"
|
|
31
31
|
:indicator-type="indicatorType"
|
|
32
32
|
:expanded-all="expandedAll"
|
|
33
|
+
:indicatorWidth="indicatorWidth"
|
|
34
|
+
:striped="striped"
|
|
35
|
+
:expanded-ids="expandedIds"
|
|
36
|
+
:css-property="cssProperty"
|
|
37
|
+
@update:expanded-ids="$emit('update:expanded-ids', $event)"
|
|
33
38
|
@new="$emit('new', $event)"
|
|
34
39
|
@add-column="$emit('add-column', $event)"
|
|
35
40
|
>
|
|
@@ -47,7 +52,7 @@
|
|
|
47
52
|
|
|
48
53
|
</template>
|
|
49
54
|
<script>
|
|
50
|
-
import { Vue, Component, Prop, Watch, ModelSync } from 'vue-property-decorator';
|
|
55
|
+
import { Vue, Component, Prop, Watch, ModelSync, PropSync } from 'vue-property-decorator';
|
|
51
56
|
import itfCheckboxGroup from '../checkbox/CheckboxGroup.vue';
|
|
52
57
|
import itfButton from '../button/Button.vue';
|
|
53
58
|
import itfIcon from '../icon/Icon.vue';
|
|
@@ -73,11 +78,14 @@ class itfTable2 extends Vue {
|
|
|
73
78
|
@Prop({ required: true, type: Array }) rows;
|
|
74
79
|
@Prop({ type: String, default: null }) groupBy;
|
|
75
80
|
@Prop({ type: String, default: null }) idProperty;
|
|
81
|
+
@Prop({ type: String, default: null }) cssProperty;
|
|
76
82
|
@Prop({ type: String, default: null }) subrowsProperty;
|
|
83
|
+
@Prop({ default: 45 }) indicatorWidth;
|
|
77
84
|
@Prop({ type: String, default: null, validator: (val) => ['order', 'checkbox', 'toggle', 'property'].includes(val) }) indicatorType;
|
|
78
85
|
@Prop({ type: String, default: null }) stateName; // save state to storage
|
|
79
86
|
@Prop({ type: Object, default: () => ({}) }) schema;
|
|
80
87
|
@ModelSync('value', 'input', { type: Array, default: () => ([]) }) selectedIds;
|
|
88
|
+
@Prop({ type: Array, default: () => [] }) expandedIds;
|
|
81
89
|
@Prop() currency;
|
|
82
90
|
@Prop() currencies;
|
|
83
91
|
@Prop(Boolean) addNewRows;
|
|
@@ -91,6 +99,7 @@ class itfTable2 extends Vue {
|
|
|
91
99
|
@Prop(Boolean) noSelectAll;
|
|
92
100
|
@Prop(Boolean) editable;
|
|
93
101
|
@Prop(Boolean) expandedAll;
|
|
102
|
+
@Prop(Boolean) striped;
|
|
94
103
|
|
|
95
104
|
state = {
|
|
96
105
|
selectedIds: [],
|
|
@@ -14,7 +14,10 @@
|
|
|
14
14
|
:currencies="currencies"
|
|
15
15
|
:indicatorType="indicatorType"
|
|
16
16
|
:expanded-ids="expandedIds"
|
|
17
|
+
:striped="striped"
|
|
17
18
|
:expanded-all="expandedAll"
|
|
19
|
+
:css-property="cssProperty"
|
|
20
|
+
@update:expanded-ids="$emit('update:expanded-ids', $event)"
|
|
18
21
|
@row-click="$emit('row-click', $event)"
|
|
19
22
|
@update="$emit('update', $event)"
|
|
20
23
|
@toggle="onToggle"
|
|
@@ -26,16 +29,18 @@
|
|
|
26
29
|
<slot :name="name" v-bind="slotData || {}"/>
|
|
27
30
|
</template>
|
|
28
31
|
</itf-table-rows>
|
|
29
|
-
<div v-if="!rows.length" data-test="table-no-results" class="
|
|
30
|
-
<div class="table-
|
|
31
|
-
<div
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
<div class="table-
|
|
36
|
-
|
|
32
|
+
<div v-if="!rows.length" data-test="table-no-results" class="scroller">
|
|
33
|
+
<div class="table-view-item">
|
|
34
|
+
<div class="table-row-template">
|
|
35
|
+
<div accept-group="items" class="table-view-body-space"></div>
|
|
36
|
+
<div class="shadow-area"></div>
|
|
37
|
+
<div class="indicator sticky"></div>
|
|
38
|
+
<div class="table-item-inner">
|
|
39
|
+
<div class="table-view-item-value w-100 align-items-center p-3 no-results">
|
|
40
|
+
{{$t('components.table.noResults')}}
|
|
41
|
+
</div>
|
|
42
|
+
<div class="boundary right"></div>
|
|
37
43
|
</div>
|
|
38
|
-
<div class="boundary right"></div>
|
|
39
44
|
</div>
|
|
40
45
|
</div>
|
|
41
46
|
</div>
|
|
@@ -162,7 +167,7 @@
|
|
|
162
167
|
}
|
|
163
168
|
</style>
|
|
164
169
|
<script>
|
|
165
|
-
import { Vue, Component, Prop } from 'vue-property-decorator';
|
|
170
|
+
import { Vue, Component, Prop, PropSync } from 'vue-property-decorator';
|
|
166
171
|
import itfTableRows from './TableRows.vue';
|
|
167
172
|
|
|
168
173
|
export default @Component({
|
|
@@ -180,17 +185,18 @@ class itfTableBody extends Vue {
|
|
|
180
185
|
@Prop(Boolean) noSelectAll;
|
|
181
186
|
@Prop(Boolean) editable;
|
|
182
187
|
@Prop(Boolean) expandedAll;
|
|
188
|
+
@Prop(Boolean) striped;
|
|
183
189
|
@Prop() selectedIds;
|
|
184
190
|
@Prop() currency;
|
|
185
191
|
@Prop() currencies;
|
|
192
|
+
@Prop() cssProperty;
|
|
186
193
|
@Prop({ type: String, default: null }) indicatorType;
|
|
187
|
-
|
|
188
|
-
expandedIds = [];
|
|
194
|
+
@Prop() expandedIds;
|
|
189
195
|
|
|
190
196
|
onToggle(item) {
|
|
191
|
-
this
|
|
197
|
+
this.$emit('update:expanded-ids', this.expandedIds.includes(item[this.idProperty])
|
|
192
198
|
? this.expandedIds.filter((id) => id !== item[this.idProperty])
|
|
193
|
-
: [...this.expandedIds, item[this.idProperty]];
|
|
199
|
+
: [...this.expandedIds, item[this.idProperty]]);
|
|
194
200
|
}
|
|
195
201
|
}
|
|
196
202
|
</script>
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
</span>
|
|
23
23
|
<span class="d-flex align-items-center line-overflow group-header-value"
|
|
24
24
|
data-test="group-value-group-label-value">
|
|
25
|
-
<slot name="group-title" :rows="rows" :title="
|
|
25
|
+
<slot name="group-title" :rows="rows" :title="title">{{ title }}</slot>
|
|
26
26
|
</span>
|
|
27
27
|
</a>
|
|
28
28
|
</div>
|
|
@@ -43,6 +43,7 @@
|
|
|
43
43
|
:no-column-menu="noColumnMenu"
|
|
44
44
|
:no-select-all="noSelectAll"
|
|
45
45
|
:selected-ids="selectedIds"
|
|
46
|
+
:indicatorType="indicatorType"
|
|
46
47
|
@update:selectedIds="$emit('update:selectedIds', $event)"
|
|
47
48
|
@update:columns="$emit('update:columns', $event)"
|
|
48
49
|
@add-column="$emit('add-column', $event)"
|
|
@@ -65,7 +66,12 @@
|
|
|
65
66
|
:selected-ids="selectedIds"
|
|
66
67
|
:indicatorType="indicatorType"
|
|
67
68
|
:expanded-all="expandedAll"
|
|
68
|
-
:
|
|
69
|
+
:striped="striped"
|
|
70
|
+
:show-add-column="showAddColumn"
|
|
71
|
+
:expanded-ids="expandedIds"
|
|
72
|
+
:css-property="cssProperty"
|
|
73
|
+
@update:expanded-ids="$emit('update:expanded-ids', $event)"
|
|
74
|
+
>
|
|
69
75
|
<template v-for="(_, name) in $slots" #[name]="slotData">
|
|
70
76
|
<slot :name="name" v-bind="slotData || {}"/>
|
|
71
77
|
</template>
|
|
@@ -295,7 +301,7 @@ import get from 'lodash/get';
|
|
|
295
301
|
import sortBy from 'lodash/sortBy';
|
|
296
302
|
import uniq from "lodash/uniq";
|
|
297
303
|
import { round } from "../../helpers/formatters";
|
|
298
|
-
import {Vue, Component, Prop, Watch} from 'vue-property-decorator';
|
|
304
|
+
import {Vue, Component, Prop, Watch, PropSync} from 'vue-property-decorator';
|
|
299
305
|
import itfDropdown from '../dropdown/Dropdown.vue';
|
|
300
306
|
import itfButton from '../button/Button.vue';
|
|
301
307
|
import itfIcon from '../icon/Icon.vue';
|
|
@@ -338,9 +344,13 @@ class itfTableGroup extends Vue {
|
|
|
338
344
|
@Prop(Boolean) noSelectAll;
|
|
339
345
|
@Prop(Boolean) editable;
|
|
340
346
|
@Prop(Boolean) expandedAll;
|
|
347
|
+
@Prop(Boolean) striped;
|
|
348
|
+
@Prop() indicatorWidth;
|
|
349
|
+
@Prop() cssProperty;
|
|
341
350
|
@Prop({ type: String, default: null }) indicatorType;
|
|
342
351
|
@Prop({type: String, default: function() { return this.$t('components.table.new'); } }) newLabel;
|
|
343
352
|
@Prop({type: Object, default: () => ({})}) schema;
|
|
353
|
+
@Prop() expandedIds;
|
|
344
354
|
|
|
345
355
|
isShowTable = true;
|
|
346
356
|
persistSummary = false;
|
|
@@ -348,7 +358,7 @@ class itfTableGroup extends Vue {
|
|
|
348
358
|
get visibleColumns() {
|
|
349
359
|
let list = this.columns;
|
|
350
360
|
list = sortBy(list, (column) => column.index);
|
|
351
|
-
let left =
|
|
361
|
+
let left = 12 + (this.indicatorType === 'none' ? 1 : Number(this.indicatorWidth)); // sum of first 2 cells
|
|
352
362
|
const pinned = list.filter((column) => column.pinned && column.visible !== false);
|
|
353
363
|
list = list.map((column, index) => {
|
|
354
364
|
const item = {...column};
|
|
@@ -357,7 +367,6 @@ class itfTableGroup extends Vue {
|
|
|
357
367
|
item.lastPinned = index === pinned.length - 1;
|
|
358
368
|
return item
|
|
359
369
|
});
|
|
360
|
-
console.info(list);
|
|
361
370
|
return list;
|
|
362
371
|
}
|
|
363
372
|
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
<div accept-group="items" class="table-view-body-space" v-dropzone="{ payload: 0 }"></div>
|
|
6
6
|
<div class="shadow-area"></div>
|
|
7
7
|
<div class="table-view-header-value reserved sticky">
|
|
8
|
-
<itf-checkbox v-if="visibleHeader && !noSelectAll" ungrouped value="all" v-model="selectAll" ref="selectAll" />
|
|
8
|
+
<itf-checkbox v-if="indicatorType !== 'none' && visibleHeader && !noSelectAll" ungrouped value="all" v-model="selectAll" ref="selectAll" />
|
|
9
9
|
</div>
|
|
10
10
|
|
|
11
11
|
<template v-for="(column, n) in visibleAttributes">
|
|
@@ -169,6 +169,7 @@ class itfTableHeader extends Vue {
|
|
|
169
169
|
@Prop(Boolean) noColumnMenu;
|
|
170
170
|
@Prop(Boolean) noSelectAll;
|
|
171
171
|
@Prop(Boolean) editable;
|
|
172
|
+
@Prop() indicatorType;
|
|
172
173
|
|
|
173
174
|
@Watch('selectedIds')
|
|
174
175
|
@Watch('rows')
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
group="items"
|
|
7
7
|
data-test="table-item"
|
|
8
8
|
class="table-view-item grouped draggable-item"
|
|
9
|
-
:class="{'selected': selectedIds.includes(item[idProperty])}"
|
|
9
|
+
:class="{'selected': selectedIds.includes(item[idProperty]), [cssProperty && item[cssProperty]]: !!item[cssProperty]}"
|
|
10
10
|
>
|
|
11
11
|
<div class="table-row-template">
|
|
12
12
|
<div accept-group="items" class="table-view-body-space"></div>
|
|
@@ -27,13 +27,15 @@
|
|
|
27
27
|
<a href="" @click.prevent.stop="$emit('toggle', item)" v-else-if="indicatorType === 'toggle'">
|
|
28
28
|
<template v-if="subrowsProperty && item[subrowsProperty] && item[subrowsProperty].length">
|
|
29
29
|
<template v-if="item[subrowsProperty] && item[subrowsProperty].length && !isExpanded(item)">
|
|
30
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-
|
|
31
|
-
<path d="
|
|
30
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-plus-square" viewBox="0 0 16 16">
|
|
31
|
+
<path d="M14 1a1 1 0 0 1 1 1v12a1 1 0 0 1-1 1H2a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1zM2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2z"/>
|
|
32
|
+
<path d="M8 4a.5.5 0 0 1 .5.5v3h3a.5.5 0 0 1 0 1h-3v3a.5.5 0 0 1-1 0v-3h-3a.5.5 0 0 1 0-1h3v-3A.5.5 0 0 1 8 4"/>
|
|
32
33
|
</svg>
|
|
33
34
|
</template>
|
|
34
35
|
<template v-else>
|
|
35
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-
|
|
36
|
-
<path d="
|
|
36
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-dash-square" viewBox="0 0 16 16">
|
|
37
|
+
<path d="M14 1a1 1 0 0 1 1 1v12a1 1 0 0 1-1 1H2a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1zM2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2z"/>
|
|
38
|
+
<path d="M4 8a.5.5 0 0 1 .5-.5h7a.5.5 0 0 1 0 1h-7A.5.5 0 0 1 4 8"/>
|
|
37
39
|
</svg>
|
|
38
40
|
</template>
|
|
39
41
|
</template>
|
|
@@ -100,6 +102,7 @@
|
|
|
100
102
|
:level="level + 1"
|
|
101
103
|
:expanded-ids="expandedIds"
|
|
102
104
|
:expanded-all="expandedAll"
|
|
105
|
+
:css-property="cssProperty"
|
|
103
106
|
@toggle="$emit('toggle', $event)"
|
|
104
107
|
>
|
|
105
108
|
<template v-for="(_, name) in $slots" #[name]="slotData">
|
|
@@ -149,12 +152,14 @@ class itfTableRows extends Vue {
|
|
|
149
152
|
@Prop(Boolean) noSelectAll;
|
|
150
153
|
@Prop(Boolean) editable;
|
|
151
154
|
@Prop(Boolean) expandedAll;
|
|
155
|
+
@Prop(Boolean) striped;
|
|
152
156
|
@Prop() selectedIds;
|
|
153
157
|
@Prop() expandedIds;
|
|
154
158
|
@Prop() currency;
|
|
155
159
|
@Prop() currencies;
|
|
160
|
+
@Prop() cssProperty;
|
|
156
161
|
@Prop({ type: Number, default: 0 }) level;
|
|
157
|
-
@Prop({ type: String, default: null, validator: (val) => ['order', 'checkbox', 'toggle', 'property'].includes(val) }) indicatorType;
|
|
162
|
+
@Prop({ type: String, default: null, validator: (val) => ['none', 'order', 'checkbox', 'toggle', 'property'].includes(val) }) indicatorType;
|
|
158
163
|
|
|
159
164
|
getValue(item, column) {
|
|
160
165
|
return get(item, column.property);
|
|
@@ -183,7 +188,6 @@ class itfTableRows extends Vue {
|
|
|
183
188
|
|
|
184
189
|
isExpanded(item) {
|
|
185
190
|
const isExpanded = this.expandedIds.includes(item[this.idProperty]);
|
|
186
|
-
console.info(isExpanded, this.expandedAll)
|
|
187
191
|
return this.expandedAll ? !isExpanded : isExpanded;
|
|
188
192
|
}
|
|
189
193
|
}
|
|
@@ -2,15 +2,17 @@
|
|
|
2
2
|
--itf-table-border-color: #e1e1e1;
|
|
3
3
|
--itf-table-header-bg: #f8f8f8;
|
|
4
4
|
--itf-table-selected-bg: #f0f0f0;
|
|
5
|
+
//--itf-table-border-color: #e1e1e1;
|
|
6
|
+
//--itf-table-header-bg: #f9faf5;
|
|
7
|
+
//--itf-table-selected-bg: #cbd6f4;
|
|
8
|
+
--itf-table-header-bg: #f8f8f8;
|
|
5
9
|
--itf-table-border-color: #dbddd1;
|
|
6
|
-
--itf-table-header-bg: #f9faf5;
|
|
7
10
|
--itf-table-hover-header-bg: var(--bs-tertiary-bg);
|
|
8
11
|
--itf-table-hover-bg: #f2f2f2;
|
|
9
12
|
--itf-table-bg: var(--bs-body-bg);
|
|
10
13
|
--itf-table-min-width: 45px;
|
|
11
14
|
--itf-table-input-border-color: #aaaba6;
|
|
12
15
|
--itf-table-input-focus-border-color: #0028aa;
|
|
13
|
-
--itf-table-selected-bg: #cbd6f4;
|
|
14
16
|
--itf-table-header-subtitle-color: #aeafaa;
|
|
15
17
|
--itf-table-summary-text: var(--bs-tertiary-color);
|
|
16
18
|
|