@eturnity/eturnity_reusable_components 7.4.4-EPDM-9677.0 → 7.4.4-EPDM-7260.2
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 +3 -3
- package/src/App.vue +69 -74
- package/src/assets/svgIcons/consumption_tariffs.svg +43 -0
- package/src/assets/svgIcons/electricity_tariff.svg +3 -0
- package/src/assets/svgIcons/handle.svg +5 -0
- package/src/assets/svgIcons/summer.svg +3 -0
- package/src/components/infoText/index.vue +1 -1
- package/src/components/inputs/radioButton/index.vue +5 -2
- package/src/components/inputs/select/index.vue +37 -10
- package/src/components/rangeSlider/Slider.vue +541 -0
- package/src/components/rangeSlider/index.vue +488 -0
- package/src/components/rangeSlider/utils/dom.js +49 -0
- package/src/components/rangeSlider/utils/fns.js +26 -0
- package/src/components/selectedOptions/index.vue +145 -0
- package/src/components/threeDots/index.vue +36 -22
- package/src/main.js +5 -5
@@ -0,0 +1,488 @@
|
|
1
|
+
<template>
|
2
|
+
<RangeSliderContainer>
|
3
|
+
<Labels v-if="topLabels && topLabels.length > 0">
|
4
|
+
<Label v-for="label in topLabels" :key="label">
|
5
|
+
{{ label }}
|
6
|
+
</Label>
|
7
|
+
</Labels>
|
8
|
+
|
9
|
+
<BarContainer v-if="leftLabels && leftLabels.length > 0">
|
10
|
+
<BarWrapper v-for="(label, index) in leftLabels" :key="index">
|
11
|
+
<VerticalLabel>{{ label.name }}</VerticalLabel>
|
12
|
+
<BarSlider>
|
13
|
+
<Bar
|
14
|
+
@contextmenu="
|
15
|
+
onBarRightClick({ event: $event, label, type: 'add' })
|
16
|
+
"
|
17
|
+
>
|
18
|
+
<SliderWrapper>
|
19
|
+
<Slider
|
20
|
+
v-for="(bar, index) in label.selectedTariffs"
|
21
|
+
:key="index"
|
22
|
+
:active="!disabled"
|
23
|
+
:draggable="!disabled"
|
24
|
+
:resizable="!disabled"
|
25
|
+
:color="
|
26
|
+
hasOverlap && OverlapId === label.id ? '#ff5656' : bar.color
|
27
|
+
"
|
28
|
+
:minWidth="minWidth"
|
29
|
+
:min="bar.min"
|
30
|
+
:max="bar.max"
|
31
|
+
:z="index"
|
32
|
+
:step="step"
|
33
|
+
:stepCount="stepCount"
|
34
|
+
:subStepCount="subStepCount"
|
35
|
+
@dragStop="
|
36
|
+
onChange(
|
37
|
+
'drag',
|
38
|
+
{
|
39
|
+
itemId: bar.id,
|
40
|
+
parentId: bar.parentId,
|
41
|
+
entityId: label.id,
|
42
|
+
...$event
|
43
|
+
},
|
44
|
+
label.id,
|
45
|
+
label.selectedTariffs
|
46
|
+
)
|
47
|
+
"
|
48
|
+
@resizeStop="
|
49
|
+
onChange(
|
50
|
+
'resize',
|
51
|
+
{
|
52
|
+
itemId: bar.id,
|
53
|
+
entityId: label.id,
|
54
|
+
...$event
|
55
|
+
},
|
56
|
+
label.id,
|
57
|
+
label.selectedTariffs
|
58
|
+
)
|
59
|
+
"
|
60
|
+
@contextmenu.native.stop="
|
61
|
+
onBarRightClick({
|
62
|
+
event: $event,
|
63
|
+
label,
|
64
|
+
type: 'delete',
|
65
|
+
bar
|
66
|
+
})
|
67
|
+
"
|
68
|
+
@activated="onActivateBar({ item: bar })"
|
69
|
+
@deactivated="onDeactivateBar()"
|
70
|
+
>
|
71
|
+
<template #mr>
|
72
|
+
<HandleIcon name="handle" size="50px" cursor="pointer" />
|
73
|
+
</template>
|
74
|
+
<template #ml>
|
75
|
+
<HandleIcon name="handle" size="50px" cursor="pointer" />
|
76
|
+
</template>
|
77
|
+
</Slider>
|
78
|
+
</SliderWrapper>
|
79
|
+
</Bar>
|
80
|
+
<Ruler>
|
81
|
+
<RulerRule v-for="n in stepCount" :key="n"></RulerRule>
|
82
|
+
</Ruler>
|
83
|
+
<SubRuler>
|
84
|
+
<RulerSubRule v-for="n in subStepCount" :key="n"></RulerSubRule>
|
85
|
+
</SubRuler>
|
86
|
+
<ErrorMessage
|
87
|
+
v-if="!canOverlap && hasOverlap && OverlapId === label.id"
|
88
|
+
>
|
89
|
+
*{{ $gettext('overlap_error_message') }}
|
90
|
+
</ErrorMessage>
|
91
|
+
</BarSlider>
|
92
|
+
</BarWrapper>
|
93
|
+
</BarContainer>
|
94
|
+
<bar-options-container
|
95
|
+
v-if="showBarOptions"
|
96
|
+
:top="barOptionsPosition.y"
|
97
|
+
:left="barOptionsPosition.x"
|
98
|
+
ref="barDropdown"
|
99
|
+
>
|
100
|
+
<bar-item-container
|
101
|
+
v-for="item in barOptionsList"
|
102
|
+
:key="item.id"
|
103
|
+
@click="onBarTariffClick({ item })"
|
104
|
+
>
|
105
|
+
<icon
|
106
|
+
:name="barOptionsType === 'add' ? 'add_icon' : 'delete'"
|
107
|
+
size="14px"
|
108
|
+
/>
|
109
|
+
<bar-item-text>{{ item.name }}</bar-item-text>
|
110
|
+
</bar-item-container>
|
111
|
+
</bar-options-container>
|
112
|
+
</RangeSliderContainer>
|
113
|
+
</template>
|
114
|
+
|
115
|
+
<script>
|
116
|
+
import styled from 'vue-styled-components'
|
117
|
+
|
118
|
+
import SliderComponent from './Slider'
|
119
|
+
import Icon from '../icon'
|
120
|
+
|
121
|
+
const wrapperAttrs = { width: String, height: String }
|
122
|
+
const SliderWrapper = styled('div', wrapperAttrs)`
|
123
|
+
position: relative;
|
124
|
+
display: flex;
|
125
|
+
height: ${(props) => props.height || '24px'};
|
126
|
+
width: ${(props) => props.width || '100%'};
|
127
|
+
`
|
128
|
+
|
129
|
+
const sliderAttrs = { color: String }
|
130
|
+
const Slider = styled(SliderComponent, sliderAttrs)`
|
131
|
+
cursor: pointer;
|
132
|
+
opacity: 0.7;
|
133
|
+
display: flex;
|
134
|
+
justify-content: space-between;
|
135
|
+
align-items: center;
|
136
|
+
border: unset !important;
|
137
|
+
background-color: ${(props) => props.color};
|
138
|
+
`
|
139
|
+
|
140
|
+
const ErrorMessage = styled.p`
|
141
|
+
color: ${(props) => props.theme.colors.red};
|
142
|
+
font-style: italic;
|
143
|
+
font-size: 13px;
|
144
|
+
margin-top: 5px;
|
145
|
+
`
|
146
|
+
|
147
|
+
const Bar = styled.div`
|
148
|
+
display: flex;
|
149
|
+
margin-bottom: -30px;
|
150
|
+
margin-left: 1px;
|
151
|
+
background-color: #f6faff;
|
152
|
+
width: 100%;
|
153
|
+
background-color: ${(props) => props.theme.colors.gray1};
|
154
|
+
`
|
155
|
+
|
156
|
+
const Ruler = styled.div`
|
157
|
+
margin: 10px 0px -5px 0px;
|
158
|
+
display: flex;
|
159
|
+
overflow: hidden;
|
160
|
+
`
|
161
|
+
|
162
|
+
const RulerRule = styled.div`
|
163
|
+
border-left: solid 1px ${(props) => props.theme.colors.grey2};
|
164
|
+
border-bottom: solid 1px ${(props) => props.theme.colors.grey2};
|
165
|
+
display: flex;
|
166
|
+
flex-grow: 1;
|
167
|
+
flex-shrink: 1;
|
168
|
+
padding: 10px 0px;
|
169
|
+
|
170
|
+
&:last-child {
|
171
|
+
border-right: solid 1px ${(props) => props.theme.colors.grey2};
|
172
|
+
}
|
173
|
+
`
|
174
|
+
|
175
|
+
const SubRuler = styled.div`
|
176
|
+
margin: -7px 0px -5px 0px;
|
177
|
+
display: flex;
|
178
|
+
`
|
179
|
+
|
180
|
+
const RulerSubRule = styled.div`
|
181
|
+
border-left: solid 1px ${(props) => props.theme.colors.grey2};
|
182
|
+
border-bottom: solid 1px ${(props) => props.theme.colors.grey2};
|
183
|
+
display: flex;
|
184
|
+
flex-grow: 1;
|
185
|
+
flex-shrink: 1;
|
186
|
+
padding: 3px 0px;
|
187
|
+
|
188
|
+
&:last-child {
|
189
|
+
border-right: solid 1px ${(props) => props.theme.colors.grey2};
|
190
|
+
}
|
191
|
+
|
192
|
+
&:nth-child(odd) {
|
193
|
+
margin-top: -5px;
|
194
|
+
padding: 5px 0px;
|
195
|
+
}
|
196
|
+
`
|
197
|
+
|
198
|
+
const BarSlider = styled.div`
|
199
|
+
width: 100%;
|
200
|
+
`
|
201
|
+
|
202
|
+
const BarContainer = styled.div`
|
203
|
+
display: flex;
|
204
|
+
flex-direction: column;
|
205
|
+
`
|
206
|
+
|
207
|
+
const BarWrapper = styled.div`
|
208
|
+
display: flex;
|
209
|
+
flex-direction: row;
|
210
|
+
margin: 20px 0px;
|
211
|
+
align-items: center;
|
212
|
+
`
|
213
|
+
|
214
|
+
const RangeSliderContainer = styled.div`
|
215
|
+
display: flex;
|
216
|
+
position: relative;
|
217
|
+
padding: 20px 10px;
|
218
|
+
flex-direction: column;
|
219
|
+
user-select: none;
|
220
|
+
width: 100%;
|
221
|
+
`
|
222
|
+
|
223
|
+
const Labels = styled.div`
|
224
|
+
display: flex;
|
225
|
+
justify-content: space-between;
|
226
|
+
padding: 0px;
|
227
|
+
margin: 10px -100px 0px 100px;
|
228
|
+
width: calc(100% - 100px);
|
229
|
+
`
|
230
|
+
|
231
|
+
const Label = styled.div`
|
232
|
+
font-size: 80%;
|
233
|
+
display: flex;
|
234
|
+
width: 1px;
|
235
|
+
justify-content: center;
|
236
|
+
`
|
237
|
+
|
238
|
+
const VerticalLabel = styled.div`
|
239
|
+
text-align: left;
|
240
|
+
min-width: 100px;
|
241
|
+
font-size: 13px;
|
242
|
+
`
|
243
|
+
|
244
|
+
const HandleIcon = styled(Icon)`
|
245
|
+
width: auto;
|
246
|
+
min-width: 0;
|
247
|
+
margin: -12px;
|
248
|
+
`
|
249
|
+
|
250
|
+
const BarOptionAttrs = { top: Number, left: Number }
|
251
|
+
const BarOptionsContainer = styled('div', BarOptionAttrs)`
|
252
|
+
display: grid;
|
253
|
+
position: fixed;
|
254
|
+
z-index: 9999;
|
255
|
+
border-radius: 4px;
|
256
|
+
background-color: ${(props) => props.theme.colors.white};
|
257
|
+
padding: 6px 10px;
|
258
|
+
border: 1px solid ${(props) => props.theme.colors.grey4};
|
259
|
+
top: ${(props) => props.top + 'px'};
|
260
|
+
left: ${(props) => props.left + 'px'};
|
261
|
+
`
|
262
|
+
|
263
|
+
const BarItemContainer = styled.div`
|
264
|
+
display: grid;
|
265
|
+
grid-template-columns: auto 1fr;
|
266
|
+
grid-gap: 12px;
|
267
|
+
align-items: center;
|
268
|
+
cursor: pointer;
|
269
|
+
padding: 6px 10px;
|
270
|
+
border-radius: 4px;
|
271
|
+
|
272
|
+
&:hover {
|
273
|
+
background-color: ${(props) => props.theme.colors.lightGray};
|
274
|
+
}
|
275
|
+
`
|
276
|
+
|
277
|
+
const BarItemText = styled.div`
|
278
|
+
font-size: 13px;
|
279
|
+
`
|
280
|
+
|
281
|
+
export default {
|
282
|
+
name: 'RangeSlider',
|
283
|
+
props: {
|
284
|
+
tariffItems: { type: Array, default: () => [] },
|
285
|
+
labels: { type: Array, default: () => [] },
|
286
|
+
rangeMargin: { type: Number, default: 1 },
|
287
|
+
step: { type: Number, default: 1 },
|
288
|
+
minWidth: { type: Number, default: 1 },
|
289
|
+
canOverlap: { type: Boolean, default: true },
|
290
|
+
disabled: { type: Boolean, default: false }
|
291
|
+
},
|
292
|
+
components: {
|
293
|
+
Bar,
|
294
|
+
Label,
|
295
|
+
Labels,
|
296
|
+
Ruler,
|
297
|
+
Slider,
|
298
|
+
SubRuler,
|
299
|
+
BarSlider,
|
300
|
+
RulerRule,
|
301
|
+
HandleIcon,
|
302
|
+
BarWrapper,
|
303
|
+
ErrorMessage,
|
304
|
+
RulerSubRule,
|
305
|
+
BarContainer,
|
306
|
+
SliderWrapper,
|
307
|
+
VerticalLabel,
|
308
|
+
RangeSliderContainer,
|
309
|
+
BarOptionsContainer,
|
310
|
+
BarItemContainer,
|
311
|
+
BarItemText,
|
312
|
+
Icon
|
313
|
+
},
|
314
|
+
data() {
|
315
|
+
return {
|
316
|
+
showBarOptions: false,
|
317
|
+
barOptionsPosition: { x: 0, y: 0 },
|
318
|
+
barOptionsList: [],
|
319
|
+
barOptionsType: null, // can be "add" or "delete"
|
320
|
+
activeLabel: null,
|
321
|
+
activeItem: null,
|
322
|
+
OverlapId: null,
|
323
|
+
hasOverlap: false
|
324
|
+
}
|
325
|
+
},
|
326
|
+
computed: {
|
327
|
+
maximum() {
|
328
|
+
if (!this.labels.length) return
|
329
|
+
|
330
|
+
return this.topLabels.at(-1)
|
331
|
+
},
|
332
|
+
minimum() {
|
333
|
+
if (!this.labels.length) return
|
334
|
+
|
335
|
+
return this.topLabels[0]
|
336
|
+
},
|
337
|
+
topLabels() {
|
338
|
+
if (!this.labels.length) return
|
339
|
+
const labels = this.labels.find((label) => label.placement === 'top')
|
340
|
+
|
341
|
+
return labels ? labels.value : []
|
342
|
+
},
|
343
|
+
leftLabels() {
|
344
|
+
if (!this.labels.length) return
|
345
|
+
const labels = this.labels.find((label) => label.placement === 'left')
|
346
|
+
return labels ? labels.value : []
|
347
|
+
},
|
348
|
+
stepCount() {
|
349
|
+
let labels = this.topLabels || []
|
350
|
+
|
351
|
+
if (labels.length) {
|
352
|
+
return labels.length - 1
|
353
|
+
}
|
354
|
+
|
355
|
+
return Math.floor((this.maximum - this.minimum) / this.step)
|
356
|
+
},
|
357
|
+
subStepCount() {
|
358
|
+
let labels = this.topLabels || []
|
359
|
+
|
360
|
+
if (labels.length && this.step) {
|
361
|
+
return (this.maximum - this.minimum) / this.step
|
362
|
+
}
|
363
|
+
|
364
|
+
return 0
|
365
|
+
}
|
366
|
+
},
|
367
|
+
methods: {
|
368
|
+
onChange(type, value, entityId, tariffs) {
|
369
|
+
this.$emit(type, value)
|
370
|
+
|
371
|
+
this.hasOverlap = this.checkOverlap(value, tariffs)
|
372
|
+
this.OverlapId = this.hasOverlap ? entityId : null
|
373
|
+
},
|
374
|
+
checkOverlap(value, tariffs) {
|
375
|
+
// Check if the tariffs overlap
|
376
|
+
const { itemId, min, max } = value
|
377
|
+
|
378
|
+
return tariffs.some((tariff) => {
|
379
|
+
if (tariff.id === itemId) return false
|
380
|
+
|
381
|
+
return (
|
382
|
+
(min > tariff.min && min < tariff.max) ||
|
383
|
+
(max > tariff.min && max < tariff.max) ||
|
384
|
+
(min < tariff.min && max > tariff.max)
|
385
|
+
)
|
386
|
+
})
|
387
|
+
},
|
388
|
+
barOptionLabel(value) {
|
389
|
+
if (this.barOptionsType === 'add')
|
390
|
+
return `${this.$gettext('Add')} ${value}`
|
391
|
+
|
392
|
+
return `${this.$gettext('Remove')} ${value}`
|
393
|
+
},
|
394
|
+
onActivateBar({ item }) {
|
395
|
+
this.activeItem = item
|
396
|
+
document.addEventListener('keydown', this.onKeyDownDelete)
|
397
|
+
},
|
398
|
+
onDeactivateBar() {
|
399
|
+
this.activeItem = null
|
400
|
+
document.removeEventListener('keydown', this.onKeyDownDelete)
|
401
|
+
},
|
402
|
+
onKeyDownDelete(event) {
|
403
|
+
// Check if the pressed key is the Delete or Backspace key
|
404
|
+
if (
|
405
|
+
(event.key === 'Delete' || event.key === 'Backspace') &&
|
406
|
+
this.activeItem
|
407
|
+
) {
|
408
|
+
this.$emit('on-bar-tariff-click', {
|
409
|
+
type: 'delete',
|
410
|
+
item: this.activeItem,
|
411
|
+
label: this.activeLabel
|
412
|
+
})
|
413
|
+
this.activeItem = null
|
414
|
+
}
|
415
|
+
},
|
416
|
+
onBarTariffClick({ item }) {
|
417
|
+
this.$emit('on-bar-tariff-click', {
|
418
|
+
type: this.barOptionsType,
|
419
|
+
item,
|
420
|
+
label: this.activeLabel
|
421
|
+
})
|
422
|
+
this.showBarOptions = false
|
423
|
+
},
|
424
|
+
setBarOptions(bar) {
|
425
|
+
this.barOptionsList = []
|
426
|
+
|
427
|
+
if (this.barOptionsType === 'add') {
|
428
|
+
this.tariffItems.forEach((item) => {
|
429
|
+
if (item.name && item.name.length) {
|
430
|
+
this.barOptionsList.push(item)
|
431
|
+
}
|
432
|
+
})
|
433
|
+
} else {
|
434
|
+
// add based on the index in the chart.
|
435
|
+
this.barOptionsList.push({
|
436
|
+
name: bar.name,
|
437
|
+
id: bar.id,
|
438
|
+
index: bar.index
|
439
|
+
})
|
440
|
+
}
|
441
|
+
},
|
442
|
+
onBarRightClick({ event, label, type, bar }) {
|
443
|
+
// type can be "add", "delete"
|
444
|
+
// if "add", show all tariffItems for the group
|
445
|
+
// if "delete", only show the delete with the tariff name
|
446
|
+
event.preventDefault()
|
447
|
+
this.activeLabel = label
|
448
|
+
this.barOptionsType = type
|
449
|
+
// need to pass the index to setBarOptions in case it's 'add'
|
450
|
+
this.setBarOptions(bar)
|
451
|
+
if (this.barOptionsList.length) {
|
452
|
+
this.showBarOptions = true
|
453
|
+
this.barOptionsPosition = { x: event.clientX, y: event.clientY }
|
454
|
+
document.addEventListener('click', this.handleOutsideClick)
|
455
|
+
} else {
|
456
|
+
this.showBarOptions = false
|
457
|
+
}
|
458
|
+
},
|
459
|
+
handleOutsideClick(event) {
|
460
|
+
// Check if the click occurred outside the dropdown
|
461
|
+
if (
|
462
|
+
this.$refs.barDropdown &&
|
463
|
+
!this.$refs.barDropdown.$el.contains(event.target)
|
464
|
+
) {
|
465
|
+
// Hide the dropdown
|
466
|
+
this.showBarOptions = false
|
467
|
+
// Remove the global click event listener
|
468
|
+
document.removeEventListener('click', this.handleOutsideClick)
|
469
|
+
}
|
470
|
+
}
|
471
|
+
},
|
472
|
+
beforeDestroy() {
|
473
|
+
// Remove the global click event listener to prevent memory leaks
|
474
|
+
document.removeEventListener('click', this.handleOutsideClick)
|
475
|
+
document.removeEventListener('keydown', this.onKeyDownDelete)
|
476
|
+
},
|
477
|
+
mounted() {
|
478
|
+
// TODO: remove
|
479
|
+
// this.tariffItems.forEach((item) => {
|
480
|
+
// item.tariff_time_mfr.forEach((tariff) => {
|
481
|
+
// tariff.time_to = '12:00:00'
|
482
|
+
// tariff.time_up_to = '12:00:00'
|
483
|
+
// })
|
484
|
+
// })
|
485
|
+
console.log('mounted tariffItems', this.tariffItems)
|
486
|
+
}
|
487
|
+
}
|
488
|
+
</script>
|
@@ -0,0 +1,49 @@
|
|
1
|
+
import { isFunction } from './fns'
|
2
|
+
|
3
|
+
export function matchesSelectorToParentElements (el, selector, baseNode) {
|
4
|
+
let node = el
|
5
|
+
|
6
|
+
const matchesSelectorFunc = [
|
7
|
+
'matches',
|
8
|
+
'webkitMatchesSelector',
|
9
|
+
'mozMatchesSelector',
|
10
|
+
'msMatchesSelector',
|
11
|
+
'oMatchesSelector'
|
12
|
+
].find(func => isFunction(node[func]))
|
13
|
+
|
14
|
+
if (!isFunction(node[matchesSelectorFunc])) return false
|
15
|
+
|
16
|
+
do {
|
17
|
+
if (node[matchesSelectorFunc](selector)) return true
|
18
|
+
if (node === baseNode) return false
|
19
|
+
node = node.parentNode
|
20
|
+
} while (node)
|
21
|
+
|
22
|
+
return false
|
23
|
+
}
|
24
|
+
|
25
|
+
export function addEvent (el, event, handler) {
|
26
|
+
if (!el) {
|
27
|
+
return
|
28
|
+
}
|
29
|
+
if (el.attachEvent) {
|
30
|
+
el.attachEvent('on' + event, handler)
|
31
|
+
} else if (el.addEventListener) {
|
32
|
+
el.addEventListener(event, handler, true)
|
33
|
+
} else {
|
34
|
+
el['on' + event] = handler
|
35
|
+
}
|
36
|
+
}
|
37
|
+
|
38
|
+
export function removeEvent (el, event, handler) {
|
39
|
+
if (!el) {
|
40
|
+
return
|
41
|
+
}
|
42
|
+
if (el.detachEvent) {
|
43
|
+
el.detachEvent('on' + event, handler)
|
44
|
+
} else if (el.removeEventListener) {
|
45
|
+
el.removeEventListener(event, handler, true)
|
46
|
+
} else {
|
47
|
+
el['on' + event] = null
|
48
|
+
}
|
49
|
+
}
|
@@ -0,0 +1,26 @@
|
|
1
|
+
export function isFunction(func) {
|
2
|
+
return (
|
3
|
+
typeof func === 'function' ||
|
4
|
+
Object.prototype.toString.call(func) === '[object Function]'
|
5
|
+
)
|
6
|
+
}
|
7
|
+
|
8
|
+
export function snapToGrid(grid, pendingX) {
|
9
|
+
return Math.round(pendingX / grid) * grid
|
10
|
+
}
|
11
|
+
|
12
|
+
export function computeWidth(left, right) {
|
13
|
+
return right - left
|
14
|
+
}
|
15
|
+
|
16
|
+
export function restrictToBounds(value, min, max) {
|
17
|
+
if (min !== null && value < min) {
|
18
|
+
return min
|
19
|
+
}
|
20
|
+
|
21
|
+
if (max !== null && max < value) {
|
22
|
+
return max
|
23
|
+
}
|
24
|
+
|
25
|
+
return value
|
26
|
+
}
|
@@ -0,0 +1,145 @@
|
|
1
|
+
<template>
|
2
|
+
<page-container>
|
3
|
+
<box-container>
|
4
|
+
<selected-container
|
5
|
+
>{{ numberSelected }} {{ $gettext('selected') }}</selected-container
|
6
|
+
>
|
7
|
+
<list-container v-if="optionsList.length">
|
8
|
+
<list-item
|
9
|
+
v-for="item in optionsList"
|
10
|
+
:key="item.type"
|
11
|
+
:hoverColor="item.hoverColor"
|
12
|
+
@click="$emit('on-' + item.type)"
|
13
|
+
>
|
14
|
+
{{ item.name }}
|
15
|
+
</list-item>
|
16
|
+
</list-container>
|
17
|
+
<empty-text v-if="!optionsList.length">
|
18
|
+
{{ $gettext('no_batch_actions_available') }}
|
19
|
+
</empty-text>
|
20
|
+
<icon-container @click="$emit('on-close')">
|
21
|
+
<icon
|
22
|
+
name="close_for_modals,_tool_tips"
|
23
|
+
color="white"
|
24
|
+
size="14px"
|
25
|
+
cursor="pointer"
|
26
|
+
/>
|
27
|
+
</icon-container>
|
28
|
+
</box-container>
|
29
|
+
</page-container>
|
30
|
+
</template>
|
31
|
+
|
32
|
+
<script>
|
33
|
+
// import SelectedOptions from "@eturnity/eturnity_reusable_components/src/components/selectedOptions"
|
34
|
+
// optionsList = [
|
35
|
+
// {
|
36
|
+
// type: 'export',
|
37
|
+
// name: 'Export'
|
38
|
+
// },
|
39
|
+
// {
|
40
|
+
// type: 'delete',
|
41
|
+
// name: 'Delete',
|
42
|
+
// hoverColor: 'red' // default is green
|
43
|
+
// }
|
44
|
+
// ]
|
45
|
+
// @on-${type}="function" should $emit the callback for the 'type' in the optionsList
|
46
|
+
// <selected-options
|
47
|
+
// :numberSelected="numberSelected"
|
48
|
+
// :optionsList="optionsList"
|
49
|
+
// @on-close="onCloseFunction()"
|
50
|
+
// @on-export="function()" @on-delete="function()"
|
51
|
+
// />
|
52
|
+
import styled from 'vue-styled-components'
|
53
|
+
import Icon from '../icon'
|
54
|
+
|
55
|
+
const PageContainer = styled.div`
|
56
|
+
position: fixed;
|
57
|
+
bottom: 30px;
|
58
|
+
left: 50%;
|
59
|
+
transform: translateX(-50%);
|
60
|
+
`
|
61
|
+
|
62
|
+
const SelectedContainer = styled.div`
|
63
|
+
display: grid;
|
64
|
+
align-items: center;
|
65
|
+
height: 100%;
|
66
|
+
padding-right: 20px;
|
67
|
+
border-right: 1px solid rgba(255, 255, 255, 0.2);
|
68
|
+
`
|
69
|
+
|
70
|
+
const BoxContainer = styled.div`
|
71
|
+
display: flex;
|
72
|
+
align-items: center;
|
73
|
+
background-color: ${(props) => props.theme.colors.black};
|
74
|
+
opacity: 90%;
|
75
|
+
color: ${(props) => props.theme.colors.white};
|
76
|
+
border-radius: 4px;
|
77
|
+
padding: 8px 10px 8px 20px;
|
78
|
+
font-size: 14px;
|
79
|
+
height: 40px;
|
80
|
+
`
|
81
|
+
|
82
|
+
const ListContainer = styled.div`
|
83
|
+
padding: 0 20px;
|
84
|
+
display: flex;
|
85
|
+
gap: 20px;
|
86
|
+
color: ${(props) => props.theme.colors.white};
|
87
|
+
`
|
88
|
+
|
89
|
+
const ListAttrs = {
|
90
|
+
hoverColor: String
|
91
|
+
}
|
92
|
+
const ListItem = styled('div', ListAttrs)`
|
93
|
+
cursor: pointer;
|
94
|
+
&:hover {
|
95
|
+
color: ${(props) =>
|
96
|
+
props.hoverColor
|
97
|
+
? props.theme.colors[props.hoverColor]
|
98
|
+
: props.theme.colors.green};
|
99
|
+
}
|
100
|
+
`
|
101
|
+
|
102
|
+
const IconContainer = styled.div`
|
103
|
+
display: grid;
|
104
|
+
align-items: center;
|
105
|
+
justify-items: center;
|
106
|
+
height: 30px;
|
107
|
+
width: 30px;
|
108
|
+
cursor: pointer;
|
109
|
+
margin-left: 20px;
|
110
|
+
|
111
|
+
&:hover {
|
112
|
+
background: rgba(255, 255, 255, 0.1);
|
113
|
+
border-radius: 4px;
|
114
|
+
}
|
115
|
+
`
|
116
|
+
|
117
|
+
const EmptyText = styled.div`
|
118
|
+
color: ${(props) => props.theme.colors.white};
|
119
|
+
font-size: 13px;
|
120
|
+
padding-left: 16px;
|
121
|
+
`
|
122
|
+
|
123
|
+
export default {
|
124
|
+
name: 'selected-options',
|
125
|
+
components: {
|
126
|
+
PageContainer,
|
127
|
+
BoxContainer,
|
128
|
+
SelectedContainer,
|
129
|
+
ListContainer,
|
130
|
+
ListItem,
|
131
|
+
Icon,
|
132
|
+
IconContainer,
|
133
|
+
EmptyText
|
134
|
+
},
|
135
|
+
props: {
|
136
|
+
optionsList: {
|
137
|
+
required: true
|
138
|
+
},
|
139
|
+
numberSelected: {
|
140
|
+
required: true,
|
141
|
+
default: 0
|
142
|
+
}
|
143
|
+
}
|
144
|
+
}
|
145
|
+
</script>
|