@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.
@@ -1,40 +1,109 @@
1
1
  <template>
2
- <div class="psui-el-slider">
3
- <div v-if="label" class="psui-el-slider-label">
4
- <span>{{label}}</span>
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
- <div :class="{'psui-flex psui-items-center': !label && !bubble }">
7
- <div
8
- v-if="bubble"
9
- class="psui-relative psui-bg-gray-40 psui-text-gray-20 psui-rounded-md psui-text-white psui-font-bold psui-w-10 psui-text-center range-value"
10
- :style="{ left: `${positionBubble}px` }"
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
- {{ value }}
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
- <input
15
- type="range"
16
- :min="min"
17
- :max="max"
18
- :value="value"
19
- @input="$emit('update:value', Number($event.target.value))"
20
- class="slider psui-float-left"
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
- return {
62
- isMounted: false
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
- if (this.bubble && this.isMounted) {
68
- return (this.$refs.slider.offsetWidth / this.max) * this.value - 15
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 0
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
- getValueToScale(value) {
78
- return 100 * value / this.rangeDistanceMax
79
- }
80
- }
81
- }
82
- </script>
83
-
84
- <style scoped>
85
- .slider {
86
- width: 100%;
87
- -webkit-appearance: none;
88
- height: 6px;
89
- border-radius: 5px;
90
- background: #d3d3d3;
91
- outline: none;
92
- opacity: 0.7;
93
- -webkit-transition: .2s;
94
- transition: opacity .2s;
95
- }
96
-
97
- .slider:hover {
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
- .range-value{
131
- margin-bottom: 10px;
132
- padding: 2px 4px;
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
- </style>
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="`layout-${layout}`"
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 :style="`background-color:${getBackgroundColor(item.background_color)};`">
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:${getBackgroundColor(item.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="formatFunction && !item.is_disabled">
216
- {{ formatFunction(column.key, item.data[column.key], item.data, item.study_id) }}
217
- </p>
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
- <p
220
- v-else-if="item.is_disabled"
221
- class="psui-text-gray-50"
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="item.data[column.key] != 0 && column.renderType && column.renderType == 'tag_scope'"
245
- :included="item.data[column.key] != 0 ? true : false"
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="Math.floor(Math.random() * 100)"
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.$eventBus.$on('resetPolicyImpactItemSelected', (item, columnKey = 'forecast_emissions_savings') => {
440
- this.$eventBus.$emit('setPolicyItemSelected', { item, columnSelectedKey: columnKey })
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
- this.$eventBus.$off('resetPolicyImpactItemSelected')
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
- this.$eventBus.$emit('resetPolicyImpactItemSelected', item, column)
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>