@itfin/components 1.4.11 → 1.4.13
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/_dark-theme.scss +2 -2
- package/src/assets/scss/components/_select.scss +2 -2
- package/src/components/button/Button.vue +1 -3
- package/src/components/datepicker/PeriodPicker.vue +39 -182
- package/src/components/datepicker/PeriodPickerInline.vue +187 -0
- package/src/components/datepicker/index.stories.js +4 -0
- package/src/components/filter/FilterBadge.vue +12 -7
- package/src/components/filter/FilterFacetsList.vue +7 -6
- package/src/components/filter/FilterPanel.vue +107 -13
- package/src/components/panels/PanelList.vue +2 -2
- package/src/components/table/Table2.vue +0 -2
- package/src/components/table/TableGroup.vue +7 -3
- package/src/components/table/table2.scss +9 -4
- package/src/components/view/View.vue +21 -12
- package/src/locales/en.js +1 -1
- package/src/locales/uk.js +1 -1
package/package.json
CHANGED
|
@@ -60,7 +60,7 @@ body[data-theme="dark"] {
|
|
|
60
60
|
|
|
61
61
|
.dropdown-menu {
|
|
62
62
|
--bs-dropdown-link-color: #{$dark-link-color};
|
|
63
|
-
--bs-dropdown-link-hover-
|
|
64
|
-
--bs-dropdown-link-
|
|
63
|
+
--bs-dropdown-link-hover-bg: rgba(var(--bs-primary-rgb), .15);
|
|
64
|
+
--bs-dropdown-link-active-bg: rgba(var(--bs-primary-rgb), .5);
|
|
65
65
|
}
|
|
66
66
|
}
|
|
@@ -17,7 +17,6 @@ class itfButton extends Vue {
|
|
|
17
17
|
@Prop(Boolean) large;
|
|
18
18
|
@Prop(Boolean) icon;
|
|
19
19
|
@Prop(Boolean) block;
|
|
20
|
-
@Prop(Boolean) squircle;
|
|
21
20
|
@Prop(String) loadingText;
|
|
22
21
|
@Prop(String) color;
|
|
23
22
|
@Prop(Boolean) disabled;
|
|
@@ -28,7 +27,7 @@ class itfButton extends Vue {
|
|
|
28
27
|
|
|
29
28
|
render (createElement, { data, slots, children, props }) {
|
|
30
29
|
const {
|
|
31
|
-
to, href, target, disabled, color, block, loading, labeled, secondary, primary, small, large, icon, loadingText,
|
|
30
|
+
to, href, target, disabled, color, block, loading, labeled, secondary, primary, small, large, icon, loadingText, default: defaultStyle,
|
|
32
31
|
class: classNames
|
|
33
32
|
} = props;
|
|
34
33
|
const component = to ? 'nuxt-link' : (props.href ? 'a' : 'button');
|
|
@@ -48,7 +47,6 @@ class itfButton extends Vue {
|
|
|
48
47
|
'btn-default': defaultStyle,
|
|
49
48
|
'btn-basic': !primary && !secondary && !color && !defaultStyle,
|
|
50
49
|
'btn-secondary': secondary,
|
|
51
|
-
'btn-squircle': squircle,
|
|
52
50
|
'btn-sm': small,
|
|
53
51
|
'btn-lg': large,
|
|
54
52
|
// 'px-3': small && !icon,
|
|
@@ -11,85 +11,27 @@
|
|
|
11
11
|
:placeholder="placeholder"
|
|
12
12
|
/>
|
|
13
13
|
<div style="display: none">
|
|
14
|
-
<
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
<div class="col">
|
|
22
|
-
<itf-button block @click="setYear(prevYear)">
|
|
23
|
-
{{prevYear}}
|
|
24
|
-
</itf-button>
|
|
25
|
-
</div>
|
|
26
|
-
<div class="col">
|
|
27
|
-
<itf-button color="outline-primary" block>
|
|
28
|
-
{{year}}
|
|
29
|
-
</itf-button>
|
|
30
|
-
</div>
|
|
31
|
-
<div class="col">
|
|
32
|
-
<itf-button block @click="setYear(nextYear)">
|
|
33
|
-
{{nextYear}}
|
|
34
|
-
</itf-button>
|
|
35
|
-
</div>
|
|
36
|
-
<div class="col text-end">
|
|
37
|
-
<itf-button @click="setYear(nextYear)">
|
|
38
|
-
<itf-icon name="chevron_right" />
|
|
39
|
-
</itf-button>
|
|
40
|
-
</div>
|
|
41
|
-
</div>
|
|
42
|
-
|
|
43
|
-
<itf-button block class="mb-3" :class="{'btn-whole': !isCurrentYear()}" :primary="isCurrentYear()" @click="onYearSelect(year)">
|
|
44
|
-
{{ $t('components.wholeYear') }}
|
|
45
|
-
</itf-button>
|
|
46
|
-
|
|
47
|
-
<div class="itf-periodpicker__quarters">
|
|
48
|
-
<div
|
|
49
|
-
v-for="quarter of quarters"
|
|
50
|
-
:key="quarter.Number"
|
|
51
|
-
class="itf-periodpicker__quarter"
|
|
52
|
-
:class="{ 'active': isOnlyQuarter(quarter.Number), 'active-inside': isCurrentQuarter(quarter.Number) }">
|
|
53
|
-
<div class="px-3 pt-2" @click="onQuarterSelect([quarter.Months[0], quarter.Months[2]])">
|
|
54
|
-
<small><b>QUARTER</b></small><br>
|
|
55
|
-
<span class="quarter-number">{{ quarter.Number }}</span>
|
|
56
|
-
</div>
|
|
57
|
-
|
|
58
|
-
<div class="itf-periodpicker__months">
|
|
59
|
-
<itf-button
|
|
60
|
-
class="itf-periodpicker__month px-1"
|
|
61
|
-
v-for="month of quarter.Months"
|
|
62
|
-
:key="month"
|
|
63
|
-
:primary="isCurrentMonth(month)"
|
|
64
|
-
@click="onMonthSelect(month)"
|
|
65
|
-
>
|
|
66
|
-
{{ month | formatMonth }}
|
|
67
|
-
</itf-button>
|
|
68
|
-
</div>
|
|
69
|
-
</div>
|
|
70
|
-
</div>
|
|
71
|
-
</div>
|
|
14
|
+
<itf-period-picker-inline
|
|
15
|
+
ref="dropdown"
|
|
16
|
+
class="itf-periodpicker__dropdown"
|
|
17
|
+
v-model="value"
|
|
18
|
+
:value-format="valueFormat"
|
|
19
|
+
@input="onInput"
|
|
20
|
+
/>
|
|
72
21
|
</div>
|
|
73
22
|
</div>
|
|
74
23
|
</template>
|
|
75
24
|
<script>
|
|
76
25
|
import { Vue, Component, Prop, Inject } from 'vue-property-decorator';
|
|
77
|
-
import { DateTime } from 'luxon';
|
|
78
26
|
import tippy from 'tippy.js';
|
|
79
|
-
import
|
|
80
|
-
import
|
|
27
|
+
import itfPeriodPickerInline from "./PeriodPickerInline.vue";
|
|
28
|
+
import {DateTime} from "luxon";
|
|
81
29
|
import ITFSettings from '../../ITFSettings';
|
|
82
30
|
|
|
83
31
|
export default @Component({
|
|
84
32
|
name: 'itfPeriodPicker',
|
|
85
33
|
components: {
|
|
86
|
-
|
|
87
|
-
itfButton
|
|
88
|
-
},
|
|
89
|
-
filters: {
|
|
90
|
-
formatMonth(month) {
|
|
91
|
-
return DateTime.local().set({ month }).toFormat('MMM');
|
|
92
|
-
}
|
|
34
|
+
itfPeriodPickerInline
|
|
93
35
|
}
|
|
94
36
|
})
|
|
95
37
|
class itfPeriodPicker extends Vue {
|
|
@@ -97,51 +39,12 @@ class itfPeriodPicker extends Vue {
|
|
|
97
39
|
|
|
98
40
|
@Prop({ type: Array }) value;
|
|
99
41
|
@Prop({ type: String, default: 'ISO' }) valueFormat;
|
|
100
|
-
@Prop({ type: String }) displayFormat;
|
|
101
42
|
@Prop({ type: String, default: 'bottom-start' }) placement;
|
|
102
|
-
@Prop({ type: String, default: 'days', validator: (value) => ['days', 'months', 'years'].includes(value) }) startView;
|
|
103
|
-
@Prop({ type: Boolean, default: false }) onlyCalendar;
|
|
104
43
|
@Prop({ type: String, default: '' }) placeholder;
|
|
105
|
-
|
|
106
|
-
year = null;
|
|
44
|
+
@Prop({ type: String }) displayFormat;
|
|
107
45
|
|
|
108
46
|
focused = false;
|
|
109
47
|
|
|
110
|
-
tooltip = null;
|
|
111
|
-
|
|
112
|
-
get quarters() {
|
|
113
|
-
return [
|
|
114
|
-
{ Name: `${this.$t('components.quarter')} 1`, Months: [1, 2, 3], Number: 1 },
|
|
115
|
-
{ Name: `${this.$t('components.quarter')} 2`, Months: [4, 5, 6], Number: 2 },
|
|
116
|
-
{ Name: `${this.$t('components.quarter')} 3`, Months: [7, 8, 9], Number: 3 },
|
|
117
|
-
{ Name: `${this.$t('components.quarter')} 4`, Months: [10, 11, 12], Number: 4 },
|
|
118
|
-
];
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
get dateFormat() {
|
|
122
|
-
return this.displayFormat || ITFSettings.defaultDisplayDateFormat;
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
get nextYear() {
|
|
126
|
-
return this.year + 1;
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
get prevYear() {
|
|
130
|
-
return this.year - 1;
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
setYear(year) {
|
|
134
|
-
this.year = year;
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
isInvalid() {
|
|
138
|
-
return this.itemLabel && this.itemLabel.isHasError();
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
isSuccess() {
|
|
142
|
-
return this.itemLabel && this.itemLabel.isHasSuccess();
|
|
143
|
-
}
|
|
144
|
-
|
|
145
48
|
mounted() {
|
|
146
49
|
const context = this.$el.closest('.itf-append-context') || document.body;
|
|
147
50
|
this.tooltip = tippy(this.$refs.input, {
|
|
@@ -149,30 +52,17 @@ class itfPeriodPicker extends Vue {
|
|
|
149
52
|
interactiveDebounce: 75,
|
|
150
53
|
animation: 'scale',
|
|
151
54
|
arrow: true,
|
|
152
|
-
content: this.$refs.dropdown,
|
|
55
|
+
content: this.$refs.dropdown.$el,
|
|
153
56
|
allowHTML: true,
|
|
154
57
|
trigger: 'click',
|
|
155
58
|
interactive: true,
|
|
156
59
|
placement: this.placement,
|
|
157
60
|
appendTo: context,
|
|
158
61
|
});
|
|
159
|
-
this.year = (this.value && this.value[0]) ? this.valueAsLuxon[0].year : DateTime.local().year;
|
|
160
62
|
}
|
|
161
63
|
|
|
162
|
-
get
|
|
163
|
-
|
|
164
|
-
return null;
|
|
165
|
-
}
|
|
166
|
-
if (this.valueFormat === 'ISO') {
|
|
167
|
-
return [
|
|
168
|
-
DateTime.fromISO(this.value[0]),
|
|
169
|
-
DateTime.fromISO(this.value[1]),
|
|
170
|
-
];
|
|
171
|
-
}
|
|
172
|
-
return [
|
|
173
|
-
DateTime.fromFormat(this.value[0], this.valueFormat),
|
|
174
|
-
DateTime.fromFormat(this.value[1], this.valueFormat),
|
|
175
|
-
];
|
|
64
|
+
get dateFormat() {
|
|
65
|
+
return this.displayFormat || ITFSettings.defaultDisplayDateFormat;
|
|
176
66
|
}
|
|
177
67
|
|
|
178
68
|
get displayText() {
|
|
@@ -183,12 +73,29 @@ class itfPeriodPicker extends Vue {
|
|
|
183
73
|
if (!this.valueAsLuxon || this.valueAsLuxon.length < 2) {
|
|
184
74
|
return [];
|
|
185
75
|
}
|
|
76
|
+
console.info(this.valueAsLuxon);
|
|
186
77
|
return [
|
|
187
78
|
this.valueAsLuxon[0].toFormat(this.dateFormat),
|
|
188
79
|
this.valueAsLuxon[1].toFormat(this.dateFormat)
|
|
189
80
|
];
|
|
190
81
|
}
|
|
191
82
|
|
|
83
|
+
get valueAsLuxon() {
|
|
84
|
+
if (!this.value || this.value.length < 2) {
|
|
85
|
+
return null;
|
|
86
|
+
}
|
|
87
|
+
if (this.valueFormat === 'ISO') {
|
|
88
|
+
return [
|
|
89
|
+
DateTime.fromISO(this.value[0]),
|
|
90
|
+
DateTime.fromISO(this.value[1]),
|
|
91
|
+
];
|
|
92
|
+
}
|
|
93
|
+
return [
|
|
94
|
+
DateTime.fromFormat(this.value[0], this.valueFormat),
|
|
95
|
+
DateTime.fromFormat(this.value[1], this.valueFormat),
|
|
96
|
+
];
|
|
97
|
+
}
|
|
98
|
+
|
|
192
99
|
onFocus() {
|
|
193
100
|
this.focused = true;
|
|
194
101
|
}
|
|
@@ -197,71 +104,21 @@ class itfPeriodPicker extends Vue {
|
|
|
197
104
|
this.focused = false;
|
|
198
105
|
}
|
|
199
106
|
|
|
200
|
-
|
|
201
|
-
this
|
|
202
|
-
this.tooltip.hide();
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
isCurrentMonth(month) {
|
|
206
|
-
if (!this.valueAsLuxon) {
|
|
207
|
-
return false;
|
|
208
|
-
}
|
|
209
|
-
return Number(this.valueAsLuxon[0].toFormat('M')) === month && Number(this.valueAsLuxon[1].toFormat('M')) === month;
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
isOnlyQuarter(quarter) {
|
|
213
|
-
if (!this.valueAsLuxon) {
|
|
214
|
-
return false;
|
|
215
|
-
}
|
|
216
|
-
return this.isCurrentQuarter(quarter) && this.valueAsLuxon[0].month !== this.valueAsLuxon[1].month;
|
|
107
|
+
isInvalid() {
|
|
108
|
+
return this.itemLabel && this.itemLabel.isHasError();
|
|
217
109
|
}
|
|
218
110
|
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
return false;
|
|
222
|
-
}
|
|
223
|
-
return this.valueAsLuxon[0].quarter === quarter && this.valueAsLuxon[1].quarter === quarter;
|
|
111
|
+
isSuccess() {
|
|
112
|
+
return this.itemLabel && this.itemLabel.isHasSuccess();
|
|
224
113
|
}
|
|
225
114
|
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
return false;
|
|
229
|
-
}
|
|
230
|
-
return this.valueAsLuxon[0].hasSame(this.valueAsLuxon[0].startOf('year'), 'day')
|
|
231
|
-
&& this.valueAsLuxon[1].hasSame(this.valueAsLuxon[0].endOf('year'), 'day');
|
|
115
|
+
selectInlineDate(date) {
|
|
116
|
+
this.$emit('input', date);
|
|
232
117
|
}
|
|
233
118
|
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
this.$emit('input', []);
|
|
237
|
-
return;
|
|
238
|
-
}
|
|
239
|
-
this.$emit('input', [
|
|
240
|
-
(this.valueFormat === 'ISO') ? start.toISO() : start.toFormat(this.valueFormat),
|
|
241
|
-
(this.valueFormat === 'ISO') ? end.toISO() : end.toFormat(this.valueFormat),
|
|
242
|
-
]);
|
|
119
|
+
onInput(val) {
|
|
120
|
+
this.$emit('input', val);
|
|
243
121
|
this.tooltip.hide();
|
|
244
122
|
}
|
|
245
|
-
|
|
246
|
-
onYearSelect(year) {
|
|
247
|
-
this.updateValue(
|
|
248
|
-
DateTime.local().set({ year }).startOf('year'),
|
|
249
|
-
DateTime.local().set({ year }).endOf('year'),
|
|
250
|
-
);
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
onMonthSelect(month) {
|
|
254
|
-
this.updateValue(
|
|
255
|
-
DateTime.local().set({ month, year: this.year }).startOf('month'),
|
|
256
|
-
DateTime.local().set({ month, year: this.year }).endOf('month'),
|
|
257
|
-
);
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
onQuarterSelect([startMonth, endMonth]) {
|
|
261
|
-
this.updateValue(
|
|
262
|
-
DateTime.local().set({ month: startMonth, year: this.year }).startOf('quarter'),
|
|
263
|
-
DateTime.local().set({ month: endMonth, year: this.year }).endOf('quarter'),
|
|
264
|
-
);
|
|
265
|
-
}
|
|
266
123
|
}
|
|
267
124
|
</script>
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div>
|
|
3
|
+
<div class="row mb-3">
|
|
4
|
+
<div class="col">
|
|
5
|
+
<itf-button icon @click="setYear(prevYear)">
|
|
6
|
+
<itf-icon name="chevron_left" />
|
|
7
|
+
</itf-button>
|
|
8
|
+
</div>
|
|
9
|
+
<div class="col">
|
|
10
|
+
<itf-button block @click="setYear(prevYear)">
|
|
11
|
+
{{prevYear}}
|
|
12
|
+
</itf-button>
|
|
13
|
+
</div>
|
|
14
|
+
<div class="col">
|
|
15
|
+
<itf-button color="outline-primary" block>
|
|
16
|
+
{{year}}
|
|
17
|
+
</itf-button>
|
|
18
|
+
</div>
|
|
19
|
+
<div class="col">
|
|
20
|
+
<itf-button block @click="setYear(nextYear)">
|
|
21
|
+
{{nextYear}}
|
|
22
|
+
</itf-button>
|
|
23
|
+
</div>
|
|
24
|
+
<div class="col text-end">
|
|
25
|
+
<itf-button icon @click="setYear(nextYear)">
|
|
26
|
+
<itf-icon name="chevron_right" />
|
|
27
|
+
</itf-button>
|
|
28
|
+
</div>
|
|
29
|
+
</div>
|
|
30
|
+
|
|
31
|
+
<itf-button block class="mb-3" :class="{'btn-whole': !isCurrentYear()}" :primary="isCurrentYear()" @click="onYearSelect(year)">
|
|
32
|
+
{{ $t('components.wholeYear') }}
|
|
33
|
+
</itf-button>
|
|
34
|
+
|
|
35
|
+
<div class="itf-periodpicker__quarters">
|
|
36
|
+
<div
|
|
37
|
+
v-for="quarter of quarters"
|
|
38
|
+
:key="quarter.Number"
|
|
39
|
+
class="itf-periodpicker__quarter"
|
|
40
|
+
:class="{ 'active': isOnlyQuarter(quarter.Number), 'active-inside': isCurrentQuarter(quarter.Number) }">
|
|
41
|
+
<div class="px-3 pt-2" @click="onQuarterSelect([quarter.Months[0], quarter.Months[2]])">
|
|
42
|
+
<small><b>{{ $t('components.quarter') }}</b></small><br>
|
|
43
|
+
<span class="quarter-number">{{ quarter.Number }}</span>
|
|
44
|
+
</div>
|
|
45
|
+
|
|
46
|
+
<div class="itf-periodpicker__months">
|
|
47
|
+
<itf-button
|
|
48
|
+
class="itf-periodpicker__month px-1"
|
|
49
|
+
v-for="month of quarter.Months"
|
|
50
|
+
:key="month"
|
|
51
|
+
:primary="isCurrentMonth(month)"
|
|
52
|
+
@click="onMonthSelect(month)"
|
|
53
|
+
>
|
|
54
|
+
{{ month | formatMonth }}
|
|
55
|
+
</itf-button>
|
|
56
|
+
</div>
|
|
57
|
+
</div>
|
|
58
|
+
</div>
|
|
59
|
+
</div>
|
|
60
|
+
</template>
|
|
61
|
+
<script>
|
|
62
|
+
import { Vue, Component, Prop } from 'vue-property-decorator';
|
|
63
|
+
import { DateTime } from 'luxon';
|
|
64
|
+
import itfIcon from '../icon/Icon';
|
|
65
|
+
import itfButton from '../button/Button';
|
|
66
|
+
|
|
67
|
+
export default @Component({
|
|
68
|
+
name: 'itfPeriodPickerInline',
|
|
69
|
+
components: {
|
|
70
|
+
itfIcon,
|
|
71
|
+
itfButton
|
|
72
|
+
},
|
|
73
|
+
filters: {
|
|
74
|
+
formatMonth(month) {
|
|
75
|
+
return DateTime.local().set({ month }).toFormat('MMM');
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
})
|
|
79
|
+
class itfPeriodPickerInline extends Vue {
|
|
80
|
+
@Prop({ type: Array }) value;
|
|
81
|
+
@Prop({ type: String, default: 'ISO' }) valueFormat;
|
|
82
|
+
|
|
83
|
+
year = null;
|
|
84
|
+
|
|
85
|
+
get quarters() {
|
|
86
|
+
return [
|
|
87
|
+
{ Name: `${this.$t('components.quarter')} 1`, Months: [1, 2, 3], Number: 1 },
|
|
88
|
+
{ Name: `${this.$t('components.quarter')} 2`, Months: [4, 5, 6], Number: 2 },
|
|
89
|
+
{ Name: `${this.$t('components.quarter')} 3`, Months: [7, 8, 9], Number: 3 },
|
|
90
|
+
{ Name: `${this.$t('components.quarter')} 4`, Months: [10, 11, 12], Number: 4 },
|
|
91
|
+
];
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
get nextYear() {
|
|
95
|
+
return this.year + 1;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
get prevYear() {
|
|
99
|
+
return this.year - 1;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
setYear(year) {
|
|
103
|
+
this.year = year;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
mounted() {
|
|
107
|
+
this.year = (this.value && this.value[0]) ? this.valueAsLuxon[0].year : DateTime.local().year;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
get valueAsLuxon() {
|
|
111
|
+
if (!this.value || this.value.length < 2) {
|
|
112
|
+
return null;
|
|
113
|
+
}
|
|
114
|
+
if (this.valueFormat === 'ISO') {
|
|
115
|
+
return [
|
|
116
|
+
DateTime.fromISO(this.value[0]),
|
|
117
|
+
DateTime.fromISO(this.value[1]),
|
|
118
|
+
];
|
|
119
|
+
}
|
|
120
|
+
return [
|
|
121
|
+
DateTime.fromFormat(this.value[0], this.valueFormat),
|
|
122
|
+
DateTime.fromFormat(this.value[1], this.valueFormat),
|
|
123
|
+
];
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
isCurrentMonth(month) {
|
|
127
|
+
if (!this.valueAsLuxon) {
|
|
128
|
+
return false;
|
|
129
|
+
}
|
|
130
|
+
return Number(this.valueAsLuxon[0].toFormat('M')) === month && Number(this.valueAsLuxon[1].toFormat('M')) === month;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
isOnlyQuarter(quarter) {
|
|
134
|
+
if (!this.valueAsLuxon) {
|
|
135
|
+
return false;
|
|
136
|
+
}
|
|
137
|
+
return this.isCurrentQuarter(quarter) && this.valueAsLuxon[0].month !== this.valueAsLuxon[1].month;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
isCurrentQuarter(quarter) {
|
|
141
|
+
if (!this.valueAsLuxon) {
|
|
142
|
+
return false;
|
|
143
|
+
}
|
|
144
|
+
return this.valueAsLuxon[0].quarter === quarter && this.valueAsLuxon[1].quarter === quarter;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
isCurrentYear() {
|
|
148
|
+
if (!this.valueAsLuxon) {
|
|
149
|
+
return false;
|
|
150
|
+
}
|
|
151
|
+
return this.valueAsLuxon[0].hasSame(this.valueAsLuxon[0].startOf('year'), 'day')
|
|
152
|
+
&& this.valueAsLuxon[1].hasSame(this.valueAsLuxon[0].endOf('year'), 'day');
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
updateValue(start, end) {
|
|
156
|
+
if (!start) {
|
|
157
|
+
this.$emit('input', []);
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
this.$emit('input', [
|
|
161
|
+
(this.valueFormat === 'ISO') ? start.toISO() : start.toFormat(this.valueFormat),
|
|
162
|
+
(this.valueFormat === 'ISO') ? end.toISO() : end.toFormat(this.valueFormat),
|
|
163
|
+
]);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
onYearSelect(year) {
|
|
167
|
+
this.updateValue(
|
|
168
|
+
DateTime.local().set({ year }).startOf('year'),
|
|
169
|
+
DateTime.local().set({ year }).endOf('year'),
|
|
170
|
+
);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
onMonthSelect(month) {
|
|
174
|
+
this.updateValue(
|
|
175
|
+
DateTime.local().set({ month, year: this.year }).startOf('month'),
|
|
176
|
+
DateTime.local().set({ month, year: this.year }).endOf('month'),
|
|
177
|
+
);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
onQuarterSelect([startMonth, endMonth]) {
|
|
181
|
+
this.updateValue(
|
|
182
|
+
DateTime.local().set({ month: startMonth, year: this.year }).startOf('quarter'),
|
|
183
|
+
DateTime.local().set({ month: endMonth, year: this.year }).endOf('quarter'),
|
|
184
|
+
);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
</script>
|
|
@@ -2,6 +2,7 @@ import { storiesOf } from '@storybook/vue';
|
|
|
2
2
|
import itfDatePicker from './DatePicker.vue';
|
|
3
3
|
import itfMonthPicker from './MonthPicker.vue';
|
|
4
4
|
import itfPeriodPicker from './PeriodPicker';
|
|
5
|
+
import itfPeriodPickerInline from './PeriodPickerInline';
|
|
5
6
|
import itfDatePickerInline from './DatePickerInline.vue';
|
|
6
7
|
import itfDateRangePicker from './DateRangePicker.vue';
|
|
7
8
|
import itfDateRangePickerInline from './DateRangePickerInline.vue';
|
|
@@ -13,6 +14,7 @@ storiesOf('Common', module)
|
|
|
13
14
|
itfApp,
|
|
14
15
|
itfDatePicker,
|
|
15
16
|
itfPeriodPicker,
|
|
17
|
+
itfPeriodPickerInline,
|
|
16
18
|
itfMonthPicker,
|
|
17
19
|
itfDateRangePicker,
|
|
18
20
|
itfDatePickerInline,
|
|
@@ -86,6 +88,8 @@ storiesOf('Common', module)
|
|
|
86
88
|
<h2>Period</h2>
|
|
87
89
|
|
|
88
90
|
<itf-period-picker :value="dateRange" v-model.lazy="dateRange"></itf-period-picker>
|
|
91
|
+
|
|
92
|
+
<itf-period-picker-inline :value="dateRange" v-model.lazy="dateRange"></itf-period-picker-inline>
|
|
89
93
|
</itf-app>
|
|
90
94
|
</div>`,
|
|
91
95
|
}));
|
|
@@ -29,9 +29,8 @@
|
|
|
29
29
|
@input="onFilterChange({ value: $event })"
|
|
30
30
|
/>
|
|
31
31
|
</template>
|
|
32
|
-
<template v-else-if="type === '
|
|
33
|
-
<itf-period-picker
|
|
34
|
-
style="margin: -.5rem"
|
|
32
|
+
<template v-else-if="type === 'timeframe'">
|
|
33
|
+
<itf-period-picker-inline
|
|
35
34
|
:value="value.value"
|
|
36
35
|
value-format="yyyy-MM-dd"
|
|
37
36
|
@input="onFilterChange({ value: $event })"
|
|
@@ -69,6 +68,7 @@
|
|
|
69
68
|
<style lang="scss">
|
|
70
69
|
:root {
|
|
71
70
|
--filter-badge__default-color: #475266;
|
|
71
|
+
--filter-badge__icon-color: #A7AFBB;
|
|
72
72
|
--filter-badge__default-border-color: #0000001A;
|
|
73
73
|
--filter-badge__default-bg-color: transparent;
|
|
74
74
|
--filter-badge__default-bg-color-hover: #1A4A970D;
|
|
@@ -83,6 +83,10 @@
|
|
|
83
83
|
--filter-badge__padding-y: .5rem;
|
|
84
84
|
--filter-badge__padding-x: .75rem;
|
|
85
85
|
}
|
|
86
|
+
body[data-theme="dark"] {
|
|
87
|
+
--filter-badge__default-border-color: #FFFFFF1A;
|
|
88
|
+
--filter-badge__selected-color: #efd877;
|
|
89
|
+
}
|
|
86
90
|
.filter-pill {
|
|
87
91
|
align-items: center;
|
|
88
92
|
font-size: 14px;
|
|
@@ -95,6 +99,7 @@
|
|
|
95
99
|
|
|
96
100
|
.icon {
|
|
97
101
|
margin: -2px;
|
|
102
|
+
color: var(--filter-badge__icon-color);
|
|
98
103
|
}
|
|
99
104
|
&:hover {
|
|
100
105
|
background-color: var(--filter-badge__default-bg-color-hover);
|
|
@@ -112,7 +117,7 @@
|
|
|
112
117
|
}
|
|
113
118
|
}
|
|
114
119
|
.filter-pill__label {
|
|
115
|
-
color: var(--filter-badge__default-color);
|
|
120
|
+
//color: var(--filter-badge__default-color);
|
|
116
121
|
padding: var(--filter-badge__padding-y) 0 var(--filter-badge__padding-y) var(--filter-badge__padding-x);
|
|
117
122
|
max-width: 330px;
|
|
118
123
|
text-overflow: ellipsis;
|
|
@@ -137,7 +142,7 @@
|
|
|
137
142
|
padding: 0 calc(var(--filter-badge__padding-x) / 2) 0 calc(var(--filter-badge__padding-x) / 4);
|
|
138
143
|
|
|
139
144
|
svg {
|
|
140
|
-
color: var(--filter-badge__default-color);
|
|
145
|
+
//color: var(--filter-badge__default-color);
|
|
141
146
|
}
|
|
142
147
|
&.filter-pill__icon-invalid svg {
|
|
143
148
|
color: var(--filter-badge__invalid-color);
|
|
@@ -154,7 +159,7 @@ import itfButton from '../button/Button';
|
|
|
154
159
|
import itfDropdown from '../dropdown/Dropdown.vue';
|
|
155
160
|
import itfDatePickerInline from '../datepicker/DatePickerInline.vue';
|
|
156
161
|
import itfDateRangePickerInline from '../datepicker/DateRangePickerInline.vue';
|
|
157
|
-
import
|
|
162
|
+
import itfPeriodPickerInline from '../datepicker/PeriodPickerInline.vue'
|
|
158
163
|
import itfTextField from '../text-field/TextField.vue';
|
|
159
164
|
import FilterFacetsList from './FilterFacetsList';
|
|
160
165
|
import FilterAmountRange from './FilterAmountRange.vue';
|
|
@@ -166,7 +171,7 @@ export default @Component({
|
|
|
166
171
|
itfDropdown,
|
|
167
172
|
itfDatePickerInline,
|
|
168
173
|
itfDateRangePickerInline,
|
|
169
|
-
|
|
174
|
+
itfPeriodPickerInline,
|
|
170
175
|
itfTextField,
|
|
171
176
|
FilterFacetsList,
|
|
172
177
|
FilterAmountRange
|
|
@@ -23,9 +23,9 @@
|
|
|
23
23
|
<div v-for="(val, n) of mappedValues" :key="n" class="dropdown-item px-2" :class="{'active': val.isSelected}" @click="onFilterClick(val)">
|
|
24
24
|
<span class="facet-name text-dark d-flex align-items-center">
|
|
25
25
|
<itf-checkbox ungrouped :value="val.isSelected" class="m-0" />
|
|
26
|
-
<div class="w-100 text-truncate">{{ val.label }}</div>
|
|
26
|
+
<div class="w-100 text-truncate">{{ val.label }} <span v-if="val.description" class="small"><br/>{{ val.description }}</span></div>
|
|
27
27
|
</span>
|
|
28
|
-
<span v-if="val.count" class="facet-stat
|
|
28
|
+
<span v-if="val.count" class="facet-stat">
|
|
29
29
|
{{ val.count }}
|
|
30
30
|
<span class="facet-bar"><span :style="{'--bar-width': `${getPercent(val)}%`}" class="facet-bar-progress" /></span>
|
|
31
31
|
</span>
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
justify-content: space-between;
|
|
61
61
|
position: relative;
|
|
62
62
|
box-sizing: border-box;
|
|
63
|
-
height: 1.75rem;
|
|
63
|
+
min-height: 1.75rem;
|
|
64
64
|
width: 100%;
|
|
65
65
|
font-size: 0.875rem;
|
|
66
66
|
line-height: 1.25rem;
|
|
@@ -76,16 +76,17 @@
|
|
|
76
76
|
margin: 1px 0;
|
|
77
77
|
&.active {
|
|
78
78
|
.facet-bar-progress {
|
|
79
|
-
background-color: var(--bs-
|
|
79
|
+
background-color: var(--bs-primary);
|
|
80
80
|
}
|
|
81
81
|
}
|
|
82
82
|
.facet-name {
|
|
83
83
|
min-width: 0;
|
|
84
84
|
text-align: left;
|
|
85
|
+
line-height: 100%;
|
|
85
86
|
white-space: nowrap;
|
|
86
87
|
|
|
87
88
|
.itf-checkbox {
|
|
88
|
-
min-height:
|
|
89
|
+
min-height: 1.25rem;
|
|
89
90
|
}
|
|
90
91
|
}
|
|
91
92
|
.facet-stat {
|
|
@@ -104,7 +105,7 @@
|
|
|
104
105
|
width: var(--bar-width);
|
|
105
106
|
min-width: 5px;
|
|
106
107
|
height: 10px;
|
|
107
|
-
background-color: rgba(var(--bs-
|
|
108
|
+
background-color: rgba(var(--bs-primary-rgb), 50%);
|
|
108
109
|
transition: width 0.3s ease 0s;
|
|
109
110
|
}
|
|
110
111
|
}
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
prepend-icon="search"
|
|
12
12
|
:delay-input="250"
|
|
13
13
|
clearable
|
|
14
|
-
:value="
|
|
14
|
+
:value="filterValueQuery"
|
|
15
15
|
@input="(e) => onFilterChange({ type: 'text', name: 'query' }, { value: e })"
|
|
16
16
|
/>
|
|
17
17
|
</div>
|
|
@@ -27,20 +27,29 @@
|
|
|
27
27
|
<slot name="after-filter-btn"></slot>
|
|
28
28
|
</div>
|
|
29
29
|
</div>
|
|
30
|
-
<div class="d-flex align-items-
|
|
31
|
-
<div v-
|
|
30
|
+
<div class="d-flex align-items-start justify-content-between w-100">
|
|
31
|
+
<div v-show="showFilters && showFilter" class="gap-2 filters-row" ref="container" :class="{'expanded': isFilterExpanded}">
|
|
32
32
|
<filter-badge
|
|
33
33
|
v-for="(facet, n) in visibleFilters"
|
|
34
34
|
:key="n"
|
|
35
|
+
class="itf-filter-panel__badge"
|
|
36
|
+
:ref="'item-' + n"
|
|
35
37
|
v-model="filter[facet.name]"
|
|
36
38
|
:is-default="filter[facet.name].isDefault"
|
|
37
39
|
:text="filter[facet.name].label"
|
|
38
40
|
:type="facet.type"
|
|
39
41
|
:icon="facet.icon"
|
|
40
42
|
:options="facet.options"
|
|
43
|
+
:class="{ hidden: !visibleItems.has(n) && !isFilterExpanded }"
|
|
41
44
|
@change="onFilterChange(facet, $event)"
|
|
42
45
|
/>
|
|
43
46
|
</div>
|
|
47
|
+
<div v-if="showFilters && showFilter && (visibleItems.size < visibleFilters.length || (isFilterExpanded && visibleItems.size === visibleFilters.length))">
|
|
48
|
+
<itf-button icon default small class="itf-filter-panel__filters" @click="toggleExpandFilter">
|
|
49
|
+
<itf-icon v-if="isFilterExpanded" name="minus" />
|
|
50
|
+
<itf-icon v-else name="plus" />
|
|
51
|
+
</itf-button>
|
|
52
|
+
</div>
|
|
44
53
|
<slot name="after-filters"></slot>
|
|
45
54
|
</div>
|
|
46
55
|
<div v-if="loading">
|
|
@@ -51,6 +60,18 @@
|
|
|
51
60
|
</template>
|
|
52
61
|
<style lang="scss">
|
|
53
62
|
.itf-filter-panel {
|
|
63
|
+
&__badge {
|
|
64
|
+
transition: opacity 0.3s ease-in-out;
|
|
65
|
+
|
|
66
|
+
&.hidden {
|
|
67
|
+
opacity: 0;
|
|
68
|
+
pointer-events: none;
|
|
69
|
+
visibility: hidden;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
&__filters {
|
|
73
|
+
outline: 1px solid var(--filter-badge__default-border-color);
|
|
74
|
+
}
|
|
54
75
|
.itf-text-field:not(.is-valid):not(.is-invalid) .itf-icon {
|
|
55
76
|
color: #8E97A5;
|
|
56
77
|
}
|
|
@@ -69,11 +90,21 @@
|
|
|
69
90
|
}
|
|
70
91
|
|
|
71
92
|
.filters-row {
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
93
|
+
display: flex;
|
|
94
|
+
overflow: hidden;
|
|
95
|
+
width: 100%;
|
|
96
|
+
padding: 2px;
|
|
97
|
+
margin: -2px;
|
|
98
|
+
flex-wrap: nowrap;
|
|
99
|
+
|
|
100
|
+
&.expanded {
|
|
101
|
+
flex-wrap: wrap;
|
|
102
|
+
|
|
103
|
+
.itf-filter-panel__badge.hidden {
|
|
104
|
+
opacity: 1;
|
|
105
|
+
visibility: visible;
|
|
106
|
+
pointer-events: all;
|
|
107
|
+
}
|
|
77
108
|
}
|
|
78
109
|
}
|
|
79
110
|
}
|
|
@@ -115,12 +146,63 @@ class FilterPanel extends Vue {
|
|
|
115
146
|
@Prop({ type: String, default: function() { return this.$t('components.filter.search'); } }) searchPlaceholder;
|
|
116
147
|
|
|
117
148
|
filter = {};
|
|
118
|
-
filterValue =
|
|
149
|
+
filterValue = null;
|
|
119
150
|
filters = [];
|
|
120
151
|
loading = false;
|
|
121
152
|
showFilters = true;
|
|
153
|
+
isFilterExpanded = false;
|
|
154
|
+
observer = null;
|
|
155
|
+
|
|
156
|
+
periodFilters = ['period', 'timeframe'];
|
|
157
|
+
visibleItems = new Set();
|
|
158
|
+
|
|
159
|
+
toggleExpandFilter() {
|
|
160
|
+
this.isFilterExpanded = !this.isFilterExpanded;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
beforeDestroy() {
|
|
164
|
+
if (this.observer) {
|
|
165
|
+
this.observer.disconnect();
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
initObserver() {
|
|
170
|
+
if (this.observer) {
|
|
171
|
+
this.observer.disconnect();
|
|
172
|
+
}
|
|
173
|
+
if (!this.$refs.container) {
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
this.observer = new IntersectionObserver(
|
|
177
|
+
(entries) => {
|
|
178
|
+
entries.forEach(entry => {
|
|
179
|
+
const index = parseInt(entry.target.dataset.index);
|
|
180
|
+
if (entry.isIntersecting) {
|
|
181
|
+
this.visibleItems.add(index); // Додаємо, якщо елемент у полі зору
|
|
182
|
+
} else {
|
|
183
|
+
this.visibleItems.delete(index); // Видаляємо, якщо вийшов за межі
|
|
184
|
+
}
|
|
185
|
+
this.$forceUpdate(); // Оновлюємо Vue, бо Set не є реактивним
|
|
186
|
+
});
|
|
187
|
+
},
|
|
188
|
+
{ root: this.$refs.container, threshold: 1.0 }
|
|
189
|
+
);
|
|
190
|
+
|
|
191
|
+
// Спостерігаємо за кожним елементом
|
|
192
|
+
this.$nextTick(() => {
|
|
193
|
+
for (const index in this.visibleFilters) {
|
|
194
|
+
const item = this.$refs[`item-${index}`][0];
|
|
195
|
+
if (item) {
|
|
196
|
+
item.$el.dataset.index = index; // Зберігаємо індекс у dataset
|
|
197
|
+
this.observer.observe(item.$el);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
});
|
|
201
|
+
}
|
|
122
202
|
|
|
123
|
-
|
|
203
|
+
get filterValueQuery() {
|
|
204
|
+
return this.filterValue?.query ?? '';
|
|
205
|
+
}
|
|
124
206
|
|
|
125
207
|
get visibleFilters() {
|
|
126
208
|
if (this.mini) {
|
|
@@ -194,13 +276,25 @@ class FilterPanel extends Vue {
|
|
|
194
276
|
if (this.search) {
|
|
195
277
|
filterValue.query = payload.query;
|
|
196
278
|
}
|
|
197
|
-
const prevFilter = JSON.stringify(this.
|
|
198
|
-
const newFilter = JSON.stringify(
|
|
199
|
-
if (prevFilter !== newFilter) {
|
|
279
|
+
const prevFilter = JSON.stringify(this.getVisibleFilters(this.filterValue));//.concat(JSON.stringify(this.filterValue));
|
|
280
|
+
const newFilter = JSON.stringify(this.getVisibleFilters(filterValue));//.concat(JSON.stringify(filterValue));
|
|
281
|
+
if (prevFilter !== newFilter || !this.filterValue) {
|
|
200
282
|
this.filter = filter;
|
|
201
283
|
this.filterValue = filterValue;
|
|
202
284
|
this.$emit('input', this.filterValue);
|
|
285
|
+
this.initObserver();
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
getVisibleFilters(filter) {
|
|
290
|
+
const result = [];
|
|
291
|
+
const facets = Object.values(this.filter);
|
|
292
|
+
for (const facet of facets) {
|
|
293
|
+
if (!facet.isDefault && !facet.hidden) {
|
|
294
|
+
result.push(filter[facet.name]);
|
|
295
|
+
}
|
|
203
296
|
}
|
|
297
|
+
return result.filter(Boolean);
|
|
204
298
|
}
|
|
205
299
|
|
|
206
300
|
setFilter(field, value) {
|
|
@@ -159,8 +159,8 @@ $double-an-time: $an-time * 2;
|
|
|
159
159
|
</style>
|
|
160
160
|
<script lang="ts">
|
|
161
161
|
import { Vue, Component, Prop } from 'vue-property-decorator';
|
|
162
|
-
import Panel from './Panel
|
|
163
|
-
import {hashToStack, stackToHash} from "
|
|
162
|
+
import Panel from './Panel';
|
|
163
|
+
import {hashToStack, stackToHash} from "./helpers";
|
|
164
164
|
|
|
165
165
|
interface VisualOptions {
|
|
166
166
|
title: string;
|
|
@@ -88,7 +88,6 @@ import itfTableGroup from './TableGroup.vue';
|
|
|
88
88
|
import itfTableHeader from './TableHeader.vue';
|
|
89
89
|
import itfNoticePopout from '../popover/NoticePopout.vue';
|
|
90
90
|
import './table2.scss';
|
|
91
|
-
import itfTableBody from '@itfin/components/src/components/table/TableBody.vue';
|
|
92
91
|
|
|
93
92
|
export default @Component({
|
|
94
93
|
name: 'itfTable2',
|
|
@@ -96,7 +95,6 @@ export default @Component({
|
|
|
96
95
|
return { tableEl: this }; // do not use Provide from vue-property-decorator
|
|
97
96
|
},
|
|
98
97
|
components: {
|
|
99
|
-
itfTableBody,
|
|
100
98
|
itfCheckboxGroup,
|
|
101
99
|
itfTableHeader,
|
|
102
100
|
itfButton,
|
|
@@ -95,11 +95,11 @@
|
|
|
95
95
|
|
|
96
96
|
<!-- Лінія додати нову -->
|
|
97
97
|
<div v-if="isShowTable && addNewRows"
|
|
98
|
-
class="table-row-template d-flex align-items-stretch">
|
|
98
|
+
class="table-row-template table-row-template__new-row d-flex align-items-stretch">
|
|
99
99
|
<div class="shadow-area"></div>
|
|
100
100
|
<a href="" @click.prevent="$emit('new', title)" data-test="table-add-new-item"
|
|
101
101
|
class="d-flex align-items-center flex-grow-1 table-add-new-item text-decoration-none">
|
|
102
|
-
<span class="d-sticky d-flex align-items-center py-1">
|
|
102
|
+
<span class="d-sticky d-flex align-items-center py-1 px-2 small">
|
|
103
103
|
<itf-icon name="plus"/>
|
|
104
104
|
<span>{{ newLabel }}</span>
|
|
105
105
|
</span>
|
|
@@ -268,7 +268,11 @@
|
|
|
268
268
|
min-height: var(--table-small-row-size);
|
|
269
269
|
}
|
|
270
270
|
|
|
271
|
+
.table-row-template.table-row-template__new-row {
|
|
272
|
+
min-height: 2rem;
|
|
273
|
+
}
|
|
271
274
|
.table-add-new-item {
|
|
275
|
+
background-color: var(--itf-table-header-bg);
|
|
272
276
|
border-right:var(--itf-table-border-base-width) solid var(--itf-table-border-base-color);
|
|
273
277
|
border-left:var(--itf-table-border-base-width) solid var(--itf-table-border-base-color);
|
|
274
278
|
border-bottom: var(--itf-table-border-base-width) solid var(--itf-table-border-base-color);
|
|
@@ -277,7 +281,7 @@
|
|
|
277
281
|
border-bottom-right-radius: var(--itf-table-table-border-radius);
|
|
278
282
|
|
|
279
283
|
& > span {
|
|
280
|
-
left: var(--shadow-area-width);
|
|
284
|
+
left: calc(var(--shadow-area-width) + 4px);
|
|
281
285
|
position: sticky;
|
|
282
286
|
padding-left: var(--shadow-area-width);
|
|
283
287
|
//border-left: var(--itf-table-border-base-width) solid var(--itf-table-border-base-color);
|
|
@@ -23,6 +23,8 @@
|
|
|
23
23
|
--itf-table-summary-text: var(--bs-tertiary-color);
|
|
24
24
|
--itf-table-table-border-radius: 1rem;
|
|
25
25
|
--itf-table-header-height: 2.25rem;
|
|
26
|
+
--itf-table-divider-bg: #F7F8FA;
|
|
27
|
+
--itf-table-divider-border: rgba(238, 238, 238, 1);
|
|
26
28
|
|
|
27
29
|
--group-title-height: 40px;
|
|
28
30
|
--table-row-height: none;
|
|
@@ -43,6 +45,9 @@ body[data-theme="dark"] {
|
|
|
43
45
|
--itf-table-selected-bg: #011534;
|
|
44
46
|
--itf-table-active-bg: #022e72;
|
|
45
47
|
--itf-table-summary-text: #82909d80;
|
|
48
|
+
--itf-table-border-base-color: var(--itf-table-header-bg);
|
|
49
|
+
--itf-table-divider-bg: #0f0f0f;
|
|
50
|
+
--itf-table-divider-border: rgb(100, 100, 100, .1);
|
|
46
51
|
}
|
|
47
52
|
.itf-table2 {
|
|
48
53
|
font-size: var(--itf-table-content-font-size, var(--itf-table-font-size));
|
|
@@ -60,7 +65,7 @@ body[data-theme="dark"] {
|
|
|
60
65
|
height: 100%;
|
|
61
66
|
}
|
|
62
67
|
.scroller {
|
|
63
|
-
margin-bottom: .5rem;
|
|
68
|
+
//margin-bottom: .5rem;
|
|
64
69
|
}
|
|
65
70
|
.scrollable-x {
|
|
66
71
|
overflow-x: scroll;
|
|
@@ -435,11 +440,11 @@ body[data-theme="dark"] {
|
|
|
435
440
|
}
|
|
436
441
|
|
|
437
442
|
&__row-divider {
|
|
438
|
-
background-color:
|
|
443
|
+
background-color: var(--itf-table-divider-bg);
|
|
439
444
|
height: 5px;
|
|
440
445
|
padding: 0;
|
|
441
|
-
border-top: 1px solid
|
|
442
|
-
border-bottom: 1px solid
|
|
446
|
+
border-top: 1px solid var(--itf-table-divider-border);
|
|
447
|
+
border-bottom: 1px solid var(--itf-table-divider-border);
|
|
443
448
|
}
|
|
444
449
|
//&:hover, &.permanent-editable-border {
|
|
445
450
|
// .table-view-item-value.editable {
|
|
@@ -42,12 +42,11 @@
|
|
|
42
42
|
</itf-dropdown>
|
|
43
43
|
|
|
44
44
|
<itf-segmented-control
|
|
45
|
-
v-if="tabs.length
|
|
45
|
+
v-if="tabs.length"
|
|
46
46
|
class="small"
|
|
47
|
-
|
|
47
|
+
v-model="currentTab"
|
|
48
48
|
item-key="value"
|
|
49
49
|
:items="tabs"
|
|
50
|
-
@input="updateTabs"
|
|
51
50
|
>
|
|
52
51
|
<template #item="{ item }">
|
|
53
52
|
<div class="d-flex align-items-center">
|
|
@@ -119,7 +118,7 @@
|
|
|
119
118
|
|
|
120
119
|
</template>
|
|
121
120
|
<script>
|
|
122
|
-
import {Vue, ModelSync, Component, Prop, Inject
|
|
121
|
+
import { Vue, ModelSync, Component, Prop, Inject } from 'vue-property-decorator';
|
|
123
122
|
import loading from '../../directives/loading';
|
|
124
123
|
import itfTable from '../table/Table2.vue';
|
|
125
124
|
import itfFilterPanel from '../filter/FilterPanel.vue';
|
|
@@ -127,13 +126,14 @@ import itfPagination from '../pagination/Pagination2.vue';
|
|
|
127
126
|
import itfTableBody from "../table/TableBody.vue";
|
|
128
127
|
import itfIcon from "../icon/Icon.vue";
|
|
129
128
|
import itfDropdown from "../dropdown/Dropdown.vue";
|
|
130
|
-
import itfSegmentedControl from '
|
|
129
|
+
import itfSegmentedControl from '../segmented-control/SegmentedControl.vue';
|
|
131
130
|
|
|
132
131
|
export default @Component({
|
|
133
132
|
name: 'itfView',
|
|
134
133
|
components: {
|
|
135
134
|
itfSegmentedControl,
|
|
136
|
-
itfDropdown,
|
|
135
|
+
itfDropdown,
|
|
136
|
+
itfIcon,
|
|
137
137
|
itfPagination,
|
|
138
138
|
itfFilterPanel,
|
|
139
139
|
itfTableBody,
|
|
@@ -149,7 +149,10 @@ class itfView extends Vue {
|
|
|
149
149
|
|
|
150
150
|
@Prop({ type: Boolean }) loading;
|
|
151
151
|
@Prop({ type: Array }) filters;
|
|
152
|
+
// @Prop({ type: Object, required: true }) schema;
|
|
152
153
|
@Prop({ type: Object }) schema;
|
|
154
|
+
// @Prop({ default: 20 }) size;
|
|
155
|
+
// @Prop({ default: 1 }) page;
|
|
153
156
|
@Prop(String) defaultSorting;
|
|
154
157
|
@Prop(String) endpoint;
|
|
155
158
|
@Prop(String) filtersEndpoint;
|
|
@@ -194,6 +197,10 @@ class itfView extends Vue {
|
|
|
194
197
|
return this.tab;
|
|
195
198
|
}
|
|
196
199
|
|
|
200
|
+
set currentTab(val) {
|
|
201
|
+
this.$emit('update:tab', val);
|
|
202
|
+
}
|
|
203
|
+
|
|
197
204
|
get tabs() {
|
|
198
205
|
const views = [];
|
|
199
206
|
if (this.listViewEnabled) {
|
|
@@ -212,6 +219,7 @@ class itfView extends Vue {
|
|
|
212
219
|
}
|
|
213
220
|
|
|
214
221
|
get tableSchema() {
|
|
222
|
+
// return this.tableColumns || this.schema;
|
|
215
223
|
if (this.tableColumns) {
|
|
216
224
|
return {
|
|
217
225
|
properties: this.tableColumns
|
|
@@ -224,12 +232,13 @@ class itfView extends Vue {
|
|
|
224
232
|
}
|
|
225
233
|
|
|
226
234
|
created() {
|
|
227
|
-
const defaultSize = localStorage.getItem('sizePerPage') ?? 20;
|
|
228
|
-
|
|
229
|
-
const { page, size, sorting } = this.panel.getPayload() ?? {};
|
|
230
|
-
this.page = page ?? 1;
|
|
231
|
-
this.size = size ?? defaultSize;
|
|
232
|
-
this.sorting = sorting ?? this.defaultSorting;
|
|
235
|
+
// const defaultSize = localStorage.getItem('sizePerPage') ?? 20;
|
|
236
|
+
//
|
|
237
|
+
// const { page, size, sorting } = this.panel.getPayload() ?? {};
|
|
238
|
+
// this.page = page ?? 1;
|
|
239
|
+
// this.size = size ?? defaultSize;
|
|
240
|
+
// this.sorting = sorting ?? this.defaultSorting;
|
|
241
|
+
this.sorting = this.defaultSorting;
|
|
233
242
|
}
|
|
234
243
|
|
|
235
244
|
mounted() {
|
package/src/locales/en.js
CHANGED
package/src/locales/uk.js
CHANGED