@policystudio/policy-studio-ui-vue 1.1.44 → 1.1.47
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/.storybook/PolicyStudio.js +0 -1
- package/.storybook/eventBus.js +3 -0
- package/dist/css/psui_styles.css +524 -28
- package/package.json +1 -1
- package/src/assets/scss/components/PsSlider.scss +152 -6
- package/src/assets/scss/components/PsSwitch.scss +62 -64
- package/src/assets/scss/components/PsTableResults.scss +256 -18
- package/src/components/controls/PsCheckboxSimple.vue +5 -1
- package/src/components/controls/PsDraggable.vue +1 -0
- package/src/components/controls/PsSlider.vue +204 -84
- package/src/components/table-results/PsTableResults.vue +83 -30
- package/src/components/table-results/PsTableResultsHeadFlexible.vue +117 -0
- package/src/components/tooltip/PsTooltip.vue +6 -1
- package/src/contents/ComparisonData.js +378 -0
- package/src/contents/FlexibleData.js +502 -0
- package/src/contents/ResultsData.js +531 -0
- package/src/index.js +9 -1
- package/src/stories/Slider.stories.js +50 -15
- package/src/stories/TableResults.stories.js +684 -1438
|
@@ -1,40 +1,109 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
<div
|
|
3
|
+
class="psui-el-slider"
|
|
4
|
+
:class="`layout-${layout}`"
|
|
5
|
+
>
|
|
6
|
+
<div
|
|
7
|
+
v-if="label"
|
|
8
|
+
class="psui-el-slider-label"
|
|
9
|
+
>
|
|
10
|
+
<span>{{ label }}</span>
|
|
5
11
|
</div>
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
12
|
+
|
|
13
|
+
<div
|
|
14
|
+
class="psui-el-slider-wrapper"
|
|
15
|
+
:class="{ 'psui-flex psui-items-center' : !label && !bubble }"
|
|
16
|
+
>
|
|
17
|
+
<div class="psui-el-slider-wrapper-input">
|
|
18
|
+
<div
|
|
19
|
+
v-if="bubble"
|
|
20
|
+
class="psui-el-slider-range-value"
|
|
21
|
+
:style="{ left: positionBubble }"
|
|
22
|
+
>
|
|
23
|
+
{{ sliderValue }}
|
|
24
|
+
</div>
|
|
25
|
+
|
|
26
|
+
<div
|
|
27
|
+
class="slider-bar"
|
|
28
|
+
:style="{ width: progressWidth }"
|
|
29
|
+
></div>
|
|
30
|
+
|
|
31
|
+
<div
|
|
32
|
+
v-for="(barStyle, index) in bgBarStyles"
|
|
33
|
+
:key="index"
|
|
34
|
+
class="slider-bar-bg"
|
|
35
|
+
:style="bgBarStyles[index]"
|
|
36
|
+
></div>
|
|
37
|
+
|
|
38
|
+
<div
|
|
39
|
+
v-for="(bar, index) in barStyles"
|
|
40
|
+
:key="index"
|
|
41
|
+
class="slider-bar-dynamic"
|
|
42
|
+
:style="barStyles[index]"
|
|
43
|
+
></div>
|
|
44
|
+
|
|
45
|
+
<input
|
|
46
|
+
ref="slider"
|
|
47
|
+
type="range"
|
|
48
|
+
:min="min"
|
|
49
|
+
:max="max"
|
|
50
|
+
:step="step"
|
|
51
|
+
class="psui-el-slider-input psui-float-left"
|
|
52
|
+
v-model="sliderValue"
|
|
53
|
+
@input="updateSlider($event)"
|
|
54
|
+
/>
|
|
55
|
+
</div>
|
|
56
|
+
|
|
57
|
+
<div
|
|
58
|
+
v-if="dividers"
|
|
59
|
+
class="psui-el-slider-grid"
|
|
11
60
|
>
|
|
12
|
-
|
|
61
|
+
<div
|
|
62
|
+
v-for="(grid, index) in gridData"
|
|
63
|
+
:key="index"
|
|
64
|
+
class="line"
|
|
65
|
+
:style="{ left: `${grid}%` }"
|
|
66
|
+
></div>
|
|
67
|
+
|
|
68
|
+
<span class="info info-min">{{ min }}</span>
|
|
69
|
+
<span class="info info-max">{{ max }}</span>
|
|
13
70
|
</div>
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
ref="slider"
|
|
22
|
-
/>
|
|
23
|
-
<span v-if="!label && !bubble" class="psui-bg-gray-20 psui-font-bold psui-text-gray-50 psui-px-2 psui-py-px psui-rounded-sm psui-float-left psui-ml-2">{{ value }}</span>
|
|
71
|
+
|
|
72
|
+
<span
|
|
73
|
+
v-if="!label && !bubble"
|
|
74
|
+
class="psui-el-slider-bubble"
|
|
75
|
+
>
|
|
76
|
+
{{ sliderValue }}
|
|
77
|
+
</span>
|
|
24
78
|
</div>
|
|
25
79
|
</div>
|
|
26
80
|
</template>
|
|
27
81
|
|
|
28
82
|
<script>
|
|
83
|
+
export const sliderLayout = ['default', 'rich']
|
|
84
|
+
|
|
29
85
|
export default {
|
|
30
86
|
name: 'PsSlider',
|
|
31
87
|
props: {
|
|
88
|
+
layout: {
|
|
89
|
+
type: String,
|
|
90
|
+
default: 'default',
|
|
91
|
+
validator: (value) => {
|
|
92
|
+
return sliderLayout.indexOf(value) !== -1
|
|
93
|
+
}
|
|
94
|
+
},
|
|
32
95
|
min: {
|
|
33
96
|
type: Number,
|
|
34
97
|
default: 0,
|
|
35
98
|
},
|
|
36
99
|
max: {
|
|
37
100
|
type: Number,
|
|
101
|
+
default: 100,
|
|
102
|
+
required: true,
|
|
103
|
+
},
|
|
104
|
+
maxValue: {
|
|
105
|
+
type: Number,
|
|
106
|
+
default: 100,
|
|
38
107
|
required: true,
|
|
39
108
|
},
|
|
40
109
|
label: {
|
|
@@ -42,6 +111,7 @@ export default {
|
|
|
42
111
|
},
|
|
43
112
|
value: {
|
|
44
113
|
type: [Number, String],
|
|
114
|
+
default: 0,
|
|
45
115
|
},
|
|
46
116
|
baseValue: {
|
|
47
117
|
type: [Number, Boolean]
|
|
@@ -55,81 +125,131 @@ export default {
|
|
|
55
125
|
},
|
|
56
126
|
bubble: {
|
|
57
127
|
type: Boolean
|
|
128
|
+
},
|
|
129
|
+
dividers: {
|
|
130
|
+
type: Boolean,
|
|
131
|
+
default: false
|
|
132
|
+
},
|
|
133
|
+
modelValue: {
|
|
134
|
+
type: Number,
|
|
135
|
+
default: 50,
|
|
136
|
+
},
|
|
137
|
+
gridData: {
|
|
138
|
+
type: Array,
|
|
139
|
+
default() {
|
|
140
|
+
return [0, 30, 55, 80, 100]
|
|
141
|
+
}
|
|
142
|
+
},
|
|
143
|
+
sliderColors: {
|
|
144
|
+
type: Array,
|
|
145
|
+
default() {
|
|
146
|
+
return [
|
|
147
|
+
{ start: 140, end: 170, bgColor: '#FF906D' },
|
|
148
|
+
{ start: 170, end: 200, bgColor: '#D65C5A' },
|
|
149
|
+
]
|
|
150
|
+
}
|
|
151
|
+
},
|
|
152
|
+
bgColors: {
|
|
153
|
+
type: Array,
|
|
154
|
+
default() {
|
|
155
|
+
return [
|
|
156
|
+
{ start: 0, end: 170, bgColor: '#D6DDE5' },
|
|
157
|
+
{ start: 170, end: 200, bgColor: '#A2ACB7' },
|
|
158
|
+
]
|
|
159
|
+
}
|
|
58
160
|
}
|
|
59
161
|
},
|
|
60
|
-
data: () => {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
162
|
+
data: () => ({
|
|
163
|
+
isMounted: false,
|
|
164
|
+
sliderWidth: 0,
|
|
165
|
+
sliderValue: 0,
|
|
166
|
+
progress: 0,
|
|
167
|
+
barStyles: [],
|
|
168
|
+
bgBarStyles: []
|
|
169
|
+
}),
|
|
65
170
|
computed: {
|
|
66
171
|
positionBubble() {
|
|
67
|
-
|
|
68
|
-
|
|
172
|
+
const val = this.sliderValue
|
|
173
|
+
const width = this.sliderWidth - 24
|
|
174
|
+
const percent = (val - this.min) / (this.max - this.min)
|
|
175
|
+
const offset = -2
|
|
176
|
+
const position = width * percent + offset
|
|
177
|
+
|
|
178
|
+
return `${position}px`
|
|
179
|
+
},
|
|
180
|
+
progressWidth() {
|
|
181
|
+
if (this.sliderValue > this.maxValue) {
|
|
182
|
+
return '100%'
|
|
69
183
|
}
|
|
70
|
-
return
|
|
71
|
-
}
|
|
184
|
+
return ((this.sliderValue - this.min) / (this.max - this.min)) * 100 + '%'
|
|
185
|
+
},
|
|
186
|
+
},
|
|
187
|
+
watch: {
|
|
188
|
+
sliderValue(newValue) {
|
|
189
|
+
this.updateProgress()
|
|
190
|
+
this.$emit('input', newValue)
|
|
191
|
+
this.updateBarStyles()
|
|
192
|
+
},
|
|
193
|
+
value(newValue) {
|
|
194
|
+
this.sliderValue = newValue
|
|
195
|
+
},
|
|
196
|
+
sliderColors: {
|
|
197
|
+
immediate: true,
|
|
198
|
+
handler() {
|
|
199
|
+
this.updateBarStyles()
|
|
200
|
+
},
|
|
201
|
+
},
|
|
202
|
+
},
|
|
203
|
+
created() {
|
|
204
|
+
window.addEventListener('resize', this.resizeHandler)
|
|
205
|
+
},
|
|
206
|
+
destroyed() {
|
|
207
|
+
window.removeEventListener('resize', this.resizeHandler)
|
|
72
208
|
},
|
|
73
209
|
mounted() {
|
|
74
210
|
this.isMounted = true
|
|
211
|
+
this.updateProgress()
|
|
212
|
+
this.updateBarStyles()
|
|
75
213
|
},
|
|
76
214
|
methods: {
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
opacity: 1;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
.slider::-webkit-slider-thumb {
|
|
102
|
-
border: none;
|
|
103
|
-
-webkit-appearance: none;
|
|
104
|
-
appearance: none;
|
|
105
|
-
width: 20px;
|
|
106
|
-
height: 20px;
|
|
107
|
-
border-radius: 50%;
|
|
108
|
-
background: #64B5CE;
|
|
109
|
-
cursor: pointer;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
.slider::-moz-range-thumb {
|
|
113
|
-
border: none;
|
|
114
|
-
width: 20px;
|
|
115
|
-
height: 20px;
|
|
116
|
-
border-radius: 50%;
|
|
117
|
-
background: #64B5CE;
|
|
118
|
-
cursor: pointer;
|
|
119
|
-
}
|
|
120
|
-
.slider::-webkit-slider-progress, .slider::-moz-range-progress {
|
|
121
|
-
border-top-left-radius: 5px;
|
|
122
|
-
border-bottom-left-radius: 5px;
|
|
123
|
-
-webkit-appearance: none;
|
|
124
|
-
box-shadow: none;
|
|
125
|
-
border: none;
|
|
126
|
-
background: #64B5CE;
|
|
127
|
-
height: 6px;
|
|
128
|
-
}
|
|
215
|
+
updateProgress() {
|
|
216
|
+
this.progress = Math.round(
|
|
217
|
+
((this.sliderValue - this.min) / (this.max - this.min)) * 100
|
|
218
|
+
)
|
|
219
|
+
},
|
|
220
|
+
updateSlider(event) {
|
|
221
|
+
this.sliderValue = Math.min(event.target.value, this.maxValue)
|
|
222
|
+
},
|
|
223
|
+
updateBarStyles() {
|
|
224
|
+
this.barStyles = this.sliderColors.map((bar) => this.getBarStyle(bar))
|
|
225
|
+
this.bgBarStyles = this.bgColors.map((bar) => this.getBarStyle(bar, false))
|
|
226
|
+
},
|
|
227
|
+
resizeHandler() {
|
|
228
|
+
this.sliderWidth = this.$refs.slider.clientWidth
|
|
229
|
+
},
|
|
230
|
+
getBarStyle(bar, normalizeByProgress = true) {
|
|
231
|
+
const start = (bar.start / this.max) * 100
|
|
232
|
+
const end = (bar.end / this.max) * 100
|
|
233
|
+
const progress = parseFloat(this.progressWidth)
|
|
234
|
+
let barWidth = end - start
|
|
235
|
+
let barLeft = start
|
|
129
236
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
237
|
+
if (normalizeByProgress) {
|
|
238
|
+
if (progress < start) {
|
|
239
|
+
barWidth = 0
|
|
240
|
+
} else if (progress < end) {
|
|
241
|
+
barWidth = progress - start
|
|
242
|
+
}
|
|
243
|
+
}
|
|
133
244
|
|
|
245
|
+
return {
|
|
246
|
+
left: `${barLeft}%`,
|
|
247
|
+
backgroundColor: bar.bgColor,
|
|
248
|
+
width: `${barWidth}%`
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
},
|
|
252
|
+
|
|
134
253
|
}
|
|
135
|
-
</
|
|
254
|
+
</script>
|
|
255
|
+
<style> /* Please, use the file src/assets/scss/components/PsSlider.scss */ </style>
|
|
@@ -1,17 +1,20 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div
|
|
3
|
+
ref="tableWrapper"
|
|
3
4
|
class="psui-el-table-results-wrapper"
|
|
5
|
+
:class="`table-${layout}`"
|
|
4
6
|
:style="{ maxHeight: tableMaxHeight }"
|
|
5
7
|
>
|
|
6
8
|
<table
|
|
7
9
|
ref="table"
|
|
8
10
|
class="psui-el-table-results"
|
|
9
|
-
:class="
|
|
11
|
+
:class="[
|
|
12
|
+
`layout-${layout}`,
|
|
13
|
+
{ 'is-sticky': isSticky }
|
|
14
|
+
]"
|
|
10
15
|
>
|
|
11
16
|
<slot name="header"></slot>
|
|
12
17
|
|
|
13
|
-
<!-- <slot name="body"></slot> -->
|
|
14
|
-
|
|
15
18
|
<tbody>
|
|
16
19
|
<tr
|
|
17
20
|
v-for="(item, index) in getRows"
|
|
@@ -32,7 +35,10 @@
|
|
|
32
35
|
@mouseenter="onRowHover(index)"
|
|
33
36
|
@mouseleave="onRowHover(false)"
|
|
34
37
|
>
|
|
35
|
-
<td
|
|
38
|
+
<td
|
|
39
|
+
:style="item.background_color ? `background-color: ${getBackgroundColor(item.background_color)};` : ''"
|
|
40
|
+
class="psui-transition"
|
|
41
|
+
>
|
|
36
42
|
<div class="psui-flex psui-justify-between psui-relative">
|
|
37
43
|
<div
|
|
38
44
|
class="psui-flex psui-items-center actions psui-space-x-3"
|
|
@@ -171,14 +177,17 @@
|
|
|
171
177
|
|
|
172
178
|
<template v-for="(columnGroup, indexColumn) of columnGroups">
|
|
173
179
|
<td
|
|
174
|
-
:style="`background-color
|
|
180
|
+
:style="item.background_color ? `background-color: ${getBackgroundColor(item.background_color)};` : ''"
|
|
175
181
|
v-for="column of columnGroup.columns"
|
|
182
|
+
class="psui-transition"
|
|
176
183
|
:key="indexColumn + '-' + columnGroup.key + '-' + column.key"
|
|
177
184
|
:data-test-id="column.key"
|
|
185
|
+
:class="`column-${column.key}`"
|
|
178
186
|
>
|
|
179
187
|
<div
|
|
180
188
|
v-if="layout != 'comparison'"
|
|
181
189
|
class="psui-space-x-2 psui-show-childrens-on-hover"
|
|
190
|
+
:class="column.isCenteredContent ? 'psui-justify-center' : 'psui-justify-end'"
|
|
182
191
|
>
|
|
183
192
|
<PsTooltip v-if="isSelectedRow(column,item)">
|
|
184
193
|
<template v-slot:trigger>
|
|
@@ -212,48 +221,62 @@
|
|
|
212
221
|
</template>
|
|
213
222
|
</PsTooltip>
|
|
214
223
|
|
|
215
|
-
<p v-if="
|
|
216
|
-
|
|
217
|
-
|
|
224
|
+
<p v-if="!column.isSwitch">
|
|
225
|
+
<template v-if="column.hasScoreHelper">
|
|
226
|
+
<PsTooltip
|
|
227
|
+
layout="blue"
|
|
228
|
+
>
|
|
229
|
+
<template v-slot:trigger>
|
|
230
|
+
{{ getItemContent(column, item) }}
|
|
231
|
+
</template>
|
|
232
|
+
<template v-slot:content>
|
|
233
|
+
<p class="psui-text-xsmall psui-font-bold">{{ column.hasScoreHelper.title }}</p>
|
|
234
|
+
{{ column.hasScoreHelper.description }}
|
|
235
|
+
</template>
|
|
236
|
+
</PsTooltip>
|
|
237
|
+
</template>
|
|
218
238
|
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
>
|
|
223
|
-
--
|
|
224
|
-
</p>
|
|
225
|
-
<p v-else>
|
|
226
|
-
{{ item.data[column.key] }}
|
|
239
|
+
<template v-else>
|
|
240
|
+
{{ getItemContent(column, item) }}
|
|
241
|
+
</template>
|
|
227
242
|
</p>
|
|
228
243
|
|
|
229
244
|
<PsProgressBar
|
|
230
|
-
v-if="column.isChart && formatFunction"
|
|
245
|
+
v-if="column.isChart && formatFunction && item.data[column.key] != null"
|
|
231
246
|
:value="formatFunction(column.key, item.data[column.key], item.data) == '--' ? 0 : item.data[column.key]"
|
|
232
247
|
:force-break-even="item.is_disabled || formatFunction(column.key, item.data[column.key], item.data) === '--' ? true : false"
|
|
233
248
|
/>
|
|
234
249
|
|
|
235
250
|
<PsProgressBar
|
|
236
|
-
v-else-if="column.isChart"
|
|
251
|
+
v-else-if="column.isChart && item.data[column.key] != null"
|
|
237
252
|
:value="item.data[column.key] == '--' ? 0 : item.data[column.key]"
|
|
238
253
|
:force-break-even="item.is_disabled || item.data[column.key] === '--' ? true : false"
|
|
239
254
|
/>
|
|
255
|
+
|
|
256
|
+
<PsSwitch
|
|
257
|
+
v-if="column.isSwitch && item.data[column.key] != null"
|
|
258
|
+
:value="item.data[column.key]"
|
|
259
|
+
size="small"
|
|
260
|
+
/>
|
|
240
261
|
</div>
|
|
262
|
+
|
|
263
|
+
<!-- only comparison layout -->
|
|
241
264
|
<div v-else>
|
|
242
265
|
<div class="psui-py-4 psui-px-6">
|
|
243
266
|
<PsTagScope
|
|
244
|
-
v-if="
|
|
245
|
-
:included="item.data[column.key]
|
|
267
|
+
v-if="column.renderType && column.renderType == 'tag_scope'"
|
|
268
|
+
:included="item.data[column.key] == true"
|
|
246
269
|
/>
|
|
247
270
|
|
|
248
271
|
<PsBarChart
|
|
249
272
|
v-else-if="item.data[column.key] != 0 && column.renderType && column.renderType == 'bar_chart'"
|
|
250
273
|
:show-number="item.data[column.key] != 0 ? true : false"
|
|
251
|
-
:total="item.data[column.key]"
|
|
252
|
-
:fill-width="
|
|
274
|
+
:total="formatFunction ? formatFunction(column.key, item.data[column.key], item.data) == '--' ? 0 : formatFunction(column.key, item.data[column.key], item.data) : item.data[column.key]"
|
|
275
|
+
:fill-width="getPsBarChartWidth(column.key, item.data[column.key])"
|
|
253
276
|
/>
|
|
254
277
|
|
|
255
278
|
<p v-else-if="item.data[column.key] != 0">
|
|
256
|
-
{{ item.data[column.key] }}
|
|
279
|
+
{{ formatFunction(column.key, item.data[column.key], item.data) }}
|
|
257
280
|
</p>
|
|
258
281
|
</div>
|
|
259
282
|
</div>
|
|
@@ -268,15 +291,17 @@
|
|
|
268
291
|
</template>
|
|
269
292
|
|
|
270
293
|
<script>
|
|
294
|
+
import { eventBus } from '../../../.storybook/eventBus'
|
|
271
295
|
import PsRichTooltip from '../tooltip/PsRichTooltip.vue'
|
|
272
296
|
import PsIcon from '../ui/PsIcon.vue'
|
|
273
297
|
import PsProgressBar from '../badges-and-tags/PsProgressBar.vue'
|
|
274
298
|
import PsTagScope from '../badges-and-tags/PsTagScope.vue'
|
|
275
299
|
import PsBarChart from '../data-graphics/PsBarChart.vue'
|
|
276
300
|
import PsTooltip from '../tooltip/PsTooltip.vue'
|
|
301
|
+
import PsSwitch from '../controls/PsSwitch.vue'
|
|
277
302
|
import tailwindConfig from '../../../tailwind.config'
|
|
278
303
|
|
|
279
|
-
export const tableLayout = ['results', 'comparison']
|
|
304
|
+
export const tableLayout = ['results', 'comparison', 'flexible']
|
|
280
305
|
|
|
281
306
|
export default {
|
|
282
307
|
name: 'PsTableResults',
|
|
@@ -286,7 +311,7 @@ export default {
|
|
|
286
311
|
PsRichTooltip,
|
|
287
312
|
PsTagScope,
|
|
288
313
|
PsBarChart,
|
|
289
|
-
PsTooltip
|
|
314
|
+
PsTooltip, PsSwitch
|
|
290
315
|
},
|
|
291
316
|
props: {
|
|
292
317
|
/**
|
|
@@ -406,7 +431,8 @@ export default {
|
|
|
406
431
|
isHoveringRow : false,
|
|
407
432
|
selectedRow : null,
|
|
408
433
|
policyItemSelected: null,
|
|
409
|
-
columnSelectedKey : null
|
|
434
|
+
columnSelectedKey : null,
|
|
435
|
+
isSticky: false
|
|
410
436
|
}),
|
|
411
437
|
computed: {
|
|
412
438
|
getRows() {
|
|
@@ -436,13 +462,15 @@ export default {
|
|
|
436
462
|
},
|
|
437
463
|
mounted () {
|
|
438
464
|
this.setCollapsedRows()
|
|
439
|
-
this.$
|
|
440
|
-
|
|
465
|
+
this.$refs.tableWrapper.addEventListener('scroll', this.handleTableScroll)
|
|
466
|
+
eventBus.$on('resetPolicyImpactItemSelected', (item, columnKey = 'forecast_emissions_savings') => {
|
|
467
|
+
eventBus.$emit('setPolicyItemSelected', { item, columnSelectedKey: columnKey })
|
|
441
468
|
this.selectedRow = null
|
|
442
469
|
})
|
|
443
470
|
},
|
|
444
471
|
beforeDestroy() {
|
|
445
|
-
|
|
472
|
+
eventBus.$off('resetPolicyImpactItemSelected')
|
|
473
|
+
this.$refs.tableWrapper.removeEventListener('scroll', this.handleTableScroll)
|
|
446
474
|
},
|
|
447
475
|
methods: {
|
|
448
476
|
setCollapsedRows() {
|
|
@@ -519,6 +547,17 @@ export default {
|
|
|
519
547
|
getText(item) {
|
|
520
548
|
if(item?.actions?.length === 1) return item.actions[0].text
|
|
521
549
|
},
|
|
550
|
+
getItemContent(column, item) {
|
|
551
|
+
if ( column.isSwitch ) return
|
|
552
|
+
|
|
553
|
+
if (this.formatFunction && !item.is_disabled) {
|
|
554
|
+
return this.formatFunction(column.key, item.data[column.key], item.data, item.study_id)
|
|
555
|
+
} else if (item.is_disabled) {
|
|
556
|
+
return '--'
|
|
557
|
+
} else {
|
|
558
|
+
return item.data[column.key]
|
|
559
|
+
}
|
|
560
|
+
},
|
|
522
561
|
executeCallback(item, action) {
|
|
523
562
|
if(item?.actions?.length === 1) item.actions[0].callback(item)
|
|
524
563
|
else action?.callback(item)
|
|
@@ -539,7 +578,7 @@ export default {
|
|
|
539
578
|
this.$emit('policy-selected', { item: item, column: column })
|
|
540
579
|
},
|
|
541
580
|
onCloseSelectRow(item, column) {
|
|
542
|
-
|
|
581
|
+
eventBus.$emit('resetPolicyImpactItemSelected', item, column)
|
|
543
582
|
},
|
|
544
583
|
isSelectedRow(column,item) {
|
|
545
584
|
if(!item.id){
|
|
@@ -561,6 +600,20 @@ export default {
|
|
|
561
600
|
content = `<p class="psui-font-bold psui-text-gray-80 psui-text-xsmall">${item.title} buildings are <br>not allowed.</p>`
|
|
562
601
|
}
|
|
563
602
|
return content
|
|
603
|
+
},
|
|
604
|
+
|
|
605
|
+
getPsBarChartWidth(key, value) {
|
|
606
|
+
const max = Math.max(...this.getRows.map(item => item.data[key]))
|
|
607
|
+
return (value * 100) / max
|
|
608
|
+
},
|
|
609
|
+
|
|
610
|
+
handleTableScroll() {
|
|
611
|
+
const tableWrapper = this.$refs.tableWrapper
|
|
612
|
+
if (tableWrapper.scrollLeft > 0) {
|
|
613
|
+
this.isSticky = true
|
|
614
|
+
} else {
|
|
615
|
+
this.isSticky = false
|
|
616
|
+
}
|
|
564
617
|
}
|
|
565
618
|
},
|
|
566
619
|
}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<thead>
|
|
3
|
+
<tr>
|
|
4
|
+
<th
|
|
5
|
+
v-for="columnGroup of header"
|
|
6
|
+
:key="columnGroup.key"
|
|
7
|
+
:colspan="columnGroup.columns.reduce( (prev, cur) => cur.isActive ? prev + 1 : prev, 0 )"
|
|
8
|
+
>
|
|
9
|
+
<div class="psui-flex psui-space-x-1 psui-items-center psui-show-childrens-on-hover">
|
|
10
|
+
<p class="title">{{ columnGroup.title }}</p>
|
|
11
|
+
<PsIcon
|
|
12
|
+
icon="info"
|
|
13
|
+
size="18"
|
|
14
|
+
class="psui-cursor-pointer"
|
|
15
|
+
icon-classes="psui-text-blue-50 psui-opacity-0 psui-leading-none psui-transition"
|
|
16
|
+
:style="{ display: 'flex' }"
|
|
17
|
+
@click.native="$emit('click-column-group-helper', columnGroup, $event)"
|
|
18
|
+
/>
|
|
19
|
+
</div>
|
|
20
|
+
</th>
|
|
21
|
+
</tr>
|
|
22
|
+
|
|
23
|
+
<tr>
|
|
24
|
+
<template v-for="(columnGroup, columnGroupIndex) of header">
|
|
25
|
+
<th
|
|
26
|
+
v-for="column of columnGroup.columns"
|
|
27
|
+
:key="`${columnGroup.key}-${column.key}`"
|
|
28
|
+
:data-test-id="column.key"
|
|
29
|
+
>
|
|
30
|
+
<div
|
|
31
|
+
class="psui-flex psui-flex-col psui-justify-center"
|
|
32
|
+
:class="columnGroupIndex == 0 ? 'psui-items-center' : 'psui-items-end'"
|
|
33
|
+
:data-index="columnGroupIndex"
|
|
34
|
+
>
|
|
35
|
+
<div class="psui-show-childrens-on-hover absolute-childrens psui-mb-px">
|
|
36
|
+
<p class="title" v-if="column.title">{{ column.title }}</p>
|
|
37
|
+
|
|
38
|
+
<PsIcon
|
|
39
|
+
icon="info"
|
|
40
|
+
size="16"
|
|
41
|
+
class="psui-cursor-pointer helper"
|
|
42
|
+
icon-classes="psui-text-blue-50 psui-opacity-0 psui-leading-none psui-transition"
|
|
43
|
+
:style="{ display: 'flex' }"
|
|
44
|
+
@click.native="$emit('click-column-helper', column, $event)"
|
|
45
|
+
/>
|
|
46
|
+
|
|
47
|
+
<PsIcon
|
|
48
|
+
v-if="showOrder"
|
|
49
|
+
:icon="orderDirection == 'asc' ? 'arrow_downward' : 'arrow_upward'"
|
|
50
|
+
:type="orderDirection == 'asc' ? 'arrow_upward' : 'arrow_upward'"
|
|
51
|
+
size="16"
|
|
52
|
+
class="psui-cursor-pointer helper"
|
|
53
|
+
icon-classes="psui-text-blue-50 psui-opacity-0 psui-leading-none psui-transition"
|
|
54
|
+
:style="{ display: 'flex' }"
|
|
55
|
+
@click.native="$emit('click-order-column', column)"
|
|
56
|
+
/>
|
|
57
|
+
</div>
|
|
58
|
+
<p class="description" v-if="column.description">{{ column.description }}</p>
|
|
59
|
+
</div>
|
|
60
|
+
</th>
|
|
61
|
+
</template>
|
|
62
|
+
</tr>
|
|
63
|
+
</thead>
|
|
64
|
+
</template>
|
|
65
|
+
|
|
66
|
+
<script>
|
|
67
|
+
import PsIcon from '../ui/PsIcon.vue'
|
|
68
|
+
export default {
|
|
69
|
+
name: 'PsTableResultsHeadFlexible',
|
|
70
|
+
components: { PsIcon },
|
|
71
|
+
props: {
|
|
72
|
+
/**
|
|
73
|
+
* It sets the title for the first column.
|
|
74
|
+
*/
|
|
75
|
+
firstColumnTitle: {
|
|
76
|
+
type: String,
|
|
77
|
+
default: ''
|
|
78
|
+
},
|
|
79
|
+
/**
|
|
80
|
+
* It sets the description for the first column.
|
|
81
|
+
*/
|
|
82
|
+
firstColumnDescription: {
|
|
83
|
+
type: String,
|
|
84
|
+
default: ''
|
|
85
|
+
},
|
|
86
|
+
/**
|
|
87
|
+
* It sets the values which will be use to render the header.
|
|
88
|
+
*/
|
|
89
|
+
header: {
|
|
90
|
+
type: Array,
|
|
91
|
+
required: true,
|
|
92
|
+
default: () => {
|
|
93
|
+
return []
|
|
94
|
+
},
|
|
95
|
+
},
|
|
96
|
+
/**
|
|
97
|
+
* this sets whether sorting will be displayed.
|
|
98
|
+
*/
|
|
99
|
+
showOrder: {
|
|
100
|
+
type: Boolean,
|
|
101
|
+
default: false
|
|
102
|
+
}
|
|
103
|
+
},
|
|
104
|
+
computed: {
|
|
105
|
+
columnsSelectedForStudy() {
|
|
106
|
+
return this.$parent.columnsSelectedForStudy
|
|
107
|
+
},
|
|
108
|
+
orderColumn() {
|
|
109
|
+
return this.$parent.orderColumn
|
|
110
|
+
},
|
|
111
|
+
orderDirection() {
|
|
112
|
+
return this.$parent.orderDirection
|
|
113
|
+
},
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
</script>
|
|
117
|
+
<style> /* Please, use the file src/assets/scss/components/PsTableResults.scss */ </style>
|