@eturnity/eturnity_reusable_components 8.22.23 → 8.26.0
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/dist/main.es12.js +2 -2
- package/dist/main.es13.js +3 -3
- package/dist/main.es14.js +2 -2
- package/dist/main.es15.js +21 -213
- package/dist/main.es16.js +1051 -19
- package/dist/main.es17.js +215 -1044
- package/dist/main.es18.js +69 -197
- package/dist/main.es19.js +2 -99
- package/dist/main.es20.js +541 -2
- package/dist/main.es21.js +188 -530
- package/dist/main.es22.js +209 -192
- package/dist/main.es24.js +2 -2
- package/dist/main.es5.js +2 -2
- package/dist/main.es6.js +4 -4
- package/dist/main.es9.js +1 -1
- package/package.json +1 -1
- package/src/assets/tests/__mocks__/svgMock.js +5 -1
- package/src/components/filterComponent/viewFilter.vue +97 -1
- package/src/components/rangeSlider/RangeSlider.spec.js +178 -0
- package/src/components/rangeSlider/RangeSlider.stories.js +159 -0
- package/src/components/rangeSlider/index.vue +15 -20
- package/src/components/tabsHeader/index.vue +1 -0
@@ -0,0 +1,178 @@
|
|
1
|
+
// Mock SVG components
|
2
|
+
const SvgMock = {
|
3
|
+
name: 'SvgMock',
|
4
|
+
template: '<div class="mock-svg"></div>',
|
5
|
+
}
|
6
|
+
|
7
|
+
// Mock Slider component
|
8
|
+
const Slider = {
|
9
|
+
name: 'Slider',
|
10
|
+
template: '<div class="mock-slider"></div>',
|
11
|
+
props: [
|
12
|
+
'color',
|
13
|
+
'draggable',
|
14
|
+
'max',
|
15
|
+
'min',
|
16
|
+
'minWidth',
|
17
|
+
'resizable',
|
18
|
+
'step',
|
19
|
+
'stepCount',
|
20
|
+
'subStepCount',
|
21
|
+
'z',
|
22
|
+
],
|
23
|
+
emits: ['drag-stop', 'resize-stop', 'activated', 'deactivated'],
|
24
|
+
}
|
25
|
+
|
26
|
+
jest.mock('../../assets/svgIcons/handle.svg', () => SvgMock)
|
27
|
+
jest.mock('../../assets/svgIcons/add_icon.svg', () => SvgMock)
|
28
|
+
jest.mock('./Slider', () => Slider)
|
29
|
+
|
30
|
+
import { mount } from '@vue/test-utils'
|
31
|
+
import RangeSlider from './index.vue'
|
32
|
+
|
33
|
+
const baseProps = {
|
34
|
+
dataLocation: 'test',
|
35
|
+
tariffItems: [
|
36
|
+
{ id: 1, name: 'Tariff A', color: '#4CAF50' },
|
37
|
+
{ id: 2, name: 'Tariff B', color: '#2196F3' },
|
38
|
+
],
|
39
|
+
labels: [
|
40
|
+
{
|
41
|
+
placement: 'top',
|
42
|
+
value: ['00:00', '12:00', '24:00'],
|
43
|
+
},
|
44
|
+
{
|
45
|
+
placement: 'left',
|
46
|
+
value: [
|
47
|
+
{
|
48
|
+
id: 1,
|
49
|
+
name: 'Group 1',
|
50
|
+
selectedTariffs: [
|
51
|
+
{
|
52
|
+
id: 1,
|
53
|
+
name: 'Tariff A',
|
54
|
+
min: 0,
|
55
|
+
max: 12,
|
56
|
+
color: '#4CAF50',
|
57
|
+
parentId: 1,
|
58
|
+
},
|
59
|
+
],
|
60
|
+
},
|
61
|
+
],
|
62
|
+
},
|
63
|
+
],
|
64
|
+
rangeMargin: 1,
|
65
|
+
step: 1,
|
66
|
+
minWidth: 1,
|
67
|
+
canOverlap: true,
|
68
|
+
disabled: false,
|
69
|
+
}
|
70
|
+
|
71
|
+
describe('RangeSlider', () => {
|
72
|
+
it('renders top and left labels', () => {
|
73
|
+
const wrapper = mount(RangeSlider, { props: baseProps })
|
74
|
+
expect(wrapper.text()).toContain('00:00')
|
75
|
+
expect(wrapper.text()).toContain('Group 1')
|
76
|
+
})
|
77
|
+
|
78
|
+
it('renders sliders for selected tariffs', () => {
|
79
|
+
const wrapper = mount(RangeSlider, { props: baseProps })
|
80
|
+
// Should render one slider for Tariff A
|
81
|
+
expect(wrapper.findAll('[data-id^="slider_bar_item_"]').length).toBe(1)
|
82
|
+
})
|
83
|
+
|
84
|
+
it('emits onChange when slider is dragged or resized', async () => {
|
85
|
+
const wrapper = mount(RangeSlider, { props: baseProps })
|
86
|
+
// Simulate drag-stop event on Slider
|
87
|
+
await wrapper
|
88
|
+
.findComponent({ name: 'Slider' })
|
89
|
+
.vm.$emit('drag-stop', { min: 2, max: 10 })
|
90
|
+
expect(wrapper.emitted().drag).toBeTruthy()
|
91
|
+
})
|
92
|
+
|
93
|
+
it('shows error message when overlap is detected and canOverlap is false', async () => {
|
94
|
+
const overlappingLabels = [
|
95
|
+
baseProps.labels[0],
|
96
|
+
{
|
97
|
+
placement: 'left',
|
98
|
+
value: [
|
99
|
+
{
|
100
|
+
id: 1,
|
101
|
+
name: 'Group 1',
|
102
|
+
selectedTariffs: [
|
103
|
+
{
|
104
|
+
id: 1,
|
105
|
+
name: 'Tariff A',
|
106
|
+
min: 0,
|
107
|
+
max: 12,
|
108
|
+
color: '#4CAF50',
|
109
|
+
parentId: 1,
|
110
|
+
},
|
111
|
+
{
|
112
|
+
id: 2,
|
113
|
+
name: 'Tariff B',
|
114
|
+
min: 10,
|
115
|
+
max: 20,
|
116
|
+
color: '#2196F3',
|
117
|
+
parentId: 1,
|
118
|
+
},
|
119
|
+
],
|
120
|
+
},
|
121
|
+
],
|
122
|
+
},
|
123
|
+
]
|
124
|
+
|
125
|
+
// First mount with non-overlapping labels
|
126
|
+
const wrapper = mount(RangeSlider, {
|
127
|
+
props: {
|
128
|
+
...baseProps,
|
129
|
+
canOverlap: false,
|
130
|
+
labels: baseProps.labels, // Start with non-overlapping labels
|
131
|
+
},
|
132
|
+
global: {
|
133
|
+
mocks: {
|
134
|
+
$gettext: (msg) => msg,
|
135
|
+
},
|
136
|
+
},
|
137
|
+
})
|
138
|
+
|
139
|
+
// Wait for initial mount
|
140
|
+
await wrapper.vm.$nextTick()
|
141
|
+
|
142
|
+
// Now update with overlapping labels
|
143
|
+
await wrapper.setProps({ labels: overlappingLabels })
|
144
|
+
|
145
|
+
// Wait for all updates to complete
|
146
|
+
await wrapper.vm.$nextTick()
|
147
|
+
await new Promise((resolve) => setTimeout(resolve, 0))
|
148
|
+
|
149
|
+
// Verify the overlap state
|
150
|
+
expect(wrapper.vm.hasOverlap).toBe(true)
|
151
|
+
expect(wrapper.vm.OverlapId).toContain(1)
|
152
|
+
|
153
|
+
// Check for error message
|
154
|
+
expect(wrapper.text()).toContain('overlap_error_message')
|
155
|
+
})
|
156
|
+
|
157
|
+
it('does not allow interaction when disabled', async () => {
|
158
|
+
const wrapper = mount(RangeSlider, {
|
159
|
+
props: { ...baseProps, disabled: true },
|
160
|
+
})
|
161
|
+
// Try to click on a bar
|
162
|
+
await wrapper.find('[data-id^="slider_bar_"]').trigger('click')
|
163
|
+
// Should not emit any events
|
164
|
+
expect(wrapper.emitted()['on-bar-tariff-click']).toBeFalsy()
|
165
|
+
})
|
166
|
+
|
167
|
+
it('emits on-bar-tariff-click when a bar is clicked', async () => {
|
168
|
+
const wrapper = mount(RangeSlider, { props: baseProps })
|
169
|
+
await wrapper.find('[data-id^="slider_bar_item_"]').trigger('click')
|
170
|
+
expect(wrapper.emitted()['on-bar-tariff-click']).toBeTruthy()
|
171
|
+
})
|
172
|
+
|
173
|
+
it('renders nothing if labels are empty', () => {
|
174
|
+
const wrapper = mount(RangeSlider, { props: { ...baseProps, labels: [] } })
|
175
|
+
expect(wrapper.html()).toContain('<div') // Should still render container
|
176
|
+
expect(wrapper.text()).not.toContain('00:00')
|
177
|
+
})
|
178
|
+
})
|
@@ -0,0 +1,159 @@
|
|
1
|
+
import RangeSlider from './index.vue'
|
2
|
+
|
3
|
+
export default {
|
4
|
+
title: 'Components/RangeSlider',
|
5
|
+
component: RangeSlider,
|
6
|
+
argTypes: {
|
7
|
+
dataLocation: { control: 'text' },
|
8
|
+
tariffItems: { control: 'array' },
|
9
|
+
labels: { control: 'array' },
|
10
|
+
rangeMargin: { control: 'number' },
|
11
|
+
step: { control: 'number' },
|
12
|
+
minWidth: { control: 'number' },
|
13
|
+
canOverlap: { control: 'boolean' },
|
14
|
+
disabled: { control: 'boolean' },
|
15
|
+
onChange: { action: 'changed' },
|
16
|
+
onBarTariffClick: { action: 'barTariffClicked' },
|
17
|
+
activate: { action: 'activated' },
|
18
|
+
deactivate: { action: 'deactivated' },
|
19
|
+
hasOverlap: { action: 'overlapDetected' },
|
20
|
+
},
|
21
|
+
}
|
22
|
+
|
23
|
+
const Template = (args) => ({
|
24
|
+
components: { RangeSlider },
|
25
|
+
setup() {
|
26
|
+
return { args }
|
27
|
+
},
|
28
|
+
template: '<RangeSlider v-bind="args" />',
|
29
|
+
})
|
30
|
+
|
31
|
+
export const Default = Template.bind({})
|
32
|
+
Default.args = {
|
33
|
+
dataLocation: 'default',
|
34
|
+
tariffItems: [
|
35
|
+
{ id: 1, name: 'Tariff A', color: '#4CAF50' },
|
36
|
+
{ id: 2, name: 'Tariff B', color: '#2196F3' },
|
37
|
+
{ id: 3, name: 'Tariff C', color: '#FFC107' },
|
38
|
+
],
|
39
|
+
labels: [
|
40
|
+
{
|
41
|
+
placement: 'top',
|
42
|
+
value: ['00:00', '04:00', '08:00', '12:00', '16:00', '20:00', '24:00'],
|
43
|
+
},
|
44
|
+
{
|
45
|
+
placement: 'left',
|
46
|
+
value: [
|
47
|
+
{
|
48
|
+
id: 1,
|
49
|
+
name: 'Group 1',
|
50
|
+
selectedTariffs: [
|
51
|
+
{
|
52
|
+
id: 1,
|
53
|
+
name: 'Tariff A',
|
54
|
+
min: 0,
|
55
|
+
max: 8,
|
56
|
+
color: '#4CAF50',
|
57
|
+
parentId: 1,
|
58
|
+
},
|
59
|
+
],
|
60
|
+
},
|
61
|
+
{
|
62
|
+
id: 2,
|
63
|
+
name: 'Group 2',
|
64
|
+
selectedTariffs: [
|
65
|
+
{
|
66
|
+
id: 2,
|
67
|
+
name: 'Tariff B',
|
68
|
+
min: 8,
|
69
|
+
max: 16,
|
70
|
+
color: '#2196F3',
|
71
|
+
parentId: 2,
|
72
|
+
},
|
73
|
+
],
|
74
|
+
},
|
75
|
+
],
|
76
|
+
},
|
77
|
+
],
|
78
|
+
rangeMargin: 1,
|
79
|
+
step: 1,
|
80
|
+
minWidth: 1,
|
81
|
+
canOverlap: true,
|
82
|
+
disabled: false,
|
83
|
+
}
|
84
|
+
|
85
|
+
export const WithOverlap = Template.bind({})
|
86
|
+
WithOverlap.args = {
|
87
|
+
...Default.args,
|
88
|
+
labels: [
|
89
|
+
{
|
90
|
+
placement: 'top',
|
91
|
+
value: ['00:00', '04:00', '08:00', '12:00', '16:00', '20:00', '24:00'],
|
92
|
+
},
|
93
|
+
{
|
94
|
+
placement: 'left',
|
95
|
+
value: [
|
96
|
+
{
|
97
|
+
id: 1,
|
98
|
+
name: 'Group 1',
|
99
|
+
selectedTariffs: [
|
100
|
+
{
|
101
|
+
id: 1,
|
102
|
+
name: 'Tariff A',
|
103
|
+
min: 0,
|
104
|
+
max: 8,
|
105
|
+
color: '#4CAF50',
|
106
|
+
parentId: 1,
|
107
|
+
},
|
108
|
+
{
|
109
|
+
id: 2,
|
110
|
+
name: 'Tariff B',
|
111
|
+
min: 6,
|
112
|
+
max: 14,
|
113
|
+
color: '#2196F3',
|
114
|
+
parentId: 1,
|
115
|
+
},
|
116
|
+
],
|
117
|
+
},
|
118
|
+
],
|
119
|
+
},
|
120
|
+
],
|
121
|
+
canOverlap: false,
|
122
|
+
}
|
123
|
+
|
124
|
+
export const Disabled = Template.bind({})
|
125
|
+
Disabled.args = {
|
126
|
+
...Default.args,
|
127
|
+
disabled: true,
|
128
|
+
}
|
129
|
+
|
130
|
+
export const CustomSteps = Template.bind({})
|
131
|
+
CustomSteps.args = {
|
132
|
+
...Default.args,
|
133
|
+
step: 2,
|
134
|
+
labels: [
|
135
|
+
{
|
136
|
+
placement: 'top',
|
137
|
+
value: ['00:00', '06:00', '12:00', '18:00', '24:00'],
|
138
|
+
},
|
139
|
+
{
|
140
|
+
placement: 'left',
|
141
|
+
value: [
|
142
|
+
{
|
143
|
+
id: 1,
|
144
|
+
name: 'Group 1',
|
145
|
+
selectedTariffs: [
|
146
|
+
{
|
147
|
+
id: 1,
|
148
|
+
name: 'Tariff A',
|
149
|
+
min: 0,
|
150
|
+
max: 12,
|
151
|
+
color: '#4CAF50',
|
152
|
+
parentId: 1,
|
153
|
+
},
|
154
|
+
],
|
155
|
+
},
|
156
|
+
],
|
157
|
+
},
|
158
|
+
],
|
159
|
+
}
|
@@ -322,42 +322,37 @@
|
|
322
322
|
},
|
323
323
|
computed: {
|
324
324
|
maximum() {
|
325
|
-
if (!this.labels
|
326
|
-
|
327
|
-
return
|
325
|
+
if (!this.labels?.length) return 0
|
326
|
+
const labels = this.topLabels
|
327
|
+
return labels?.length ? labels[labels.length - 1] : 0
|
328
328
|
},
|
329
329
|
minimum() {
|
330
|
-
if (!this.labels
|
331
|
-
|
332
|
-
return
|
330
|
+
if (!this.labels?.length) return 0
|
331
|
+
const labels = this.topLabels
|
332
|
+
return labels?.length ? labels[0] : 0
|
333
333
|
},
|
334
334
|
topLabels() {
|
335
|
-
if (!this.labels
|
335
|
+
if (!this.labels?.length) return []
|
336
336
|
const labels = this.labels.find((label) => label.placement === 'top')
|
337
|
-
|
338
|
-
return labels ? labels.value : []
|
337
|
+
return labels?.value || []
|
339
338
|
},
|
340
339
|
leftLabels() {
|
341
|
-
if (!this.labels
|
340
|
+
if (!this.labels?.length) return []
|
342
341
|
const labels = this.labels.find((label) => label.placement === 'left')
|
343
|
-
return labels
|
342
|
+
return labels?.value || []
|
344
343
|
},
|
345
344
|
stepCount() {
|
346
|
-
|
347
|
-
|
345
|
+
const labels = this.topLabels || []
|
348
346
|
if (labels.length) {
|
349
347
|
return labels.length - 1
|
350
348
|
}
|
351
|
-
|
352
|
-
return Math.floor((this.maximum - this.minimum) / this.step)
|
349
|
+
return Math.floor((this.maximum - this.minimum) / this.step) || 0
|
353
350
|
},
|
354
351
|
subStepCount() {
|
355
|
-
|
356
|
-
|
352
|
+
const labels = this.topLabels || []
|
357
353
|
if (labels.length && this.step) {
|
358
|
-
return (this.maximum - this.minimum) / this.step
|
354
|
+
return Math.floor((this.maximum - this.minimum) / this.step) || 0
|
359
355
|
}
|
360
|
-
|
361
356
|
return 0
|
362
357
|
},
|
363
358
|
},
|
@@ -395,7 +390,7 @@
|
|
395
390
|
}
|
396
391
|
},
|
397
392
|
},
|
398
|
-
|
393
|
+
beforeUnmount() {
|
399
394
|
// Remove the global click event listener to prevent memory leaks
|
400
395
|
document.removeEventListener('click', this.handleOutsideClick)
|
401
396
|
document.removeEventListener('keydown', this.onKeyDownDelete)
|