@eturnity/eturnity_reusable_components 8.19.8-EPDM-14690.4 → 8.19.8-EPDM-15590.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eturnity/eturnity_reusable_components",
3
- "version": "8.19.8-EPDM-14690.4",
3
+ "version": "8.19.8-EPDM-15590.0",
4
4
  "files": [
5
5
  "dist",
6
6
  "src"
package/src/App.vue CHANGED
@@ -1,19 +1,17 @@
1
1
  <template>
2
2
  <ThemeProvider :style="{ height: '100%' }" :theme="theme">
3
3
  <RouterView />
4
- <ProTag />
5
4
  </ThemeProvider>
6
5
  </template>
7
6
 
8
7
  <script>
9
8
  import { ThemeProvider } from 'vue3-styled-components'
10
9
  import theme from '@/assets/theme.js'
11
- import ProTag from '@/components/tag/proTag'
10
+
12
11
  export default {
13
12
  name: 'App',
14
13
  components: {
15
14
  ThemeProvider,
16
- ProTag,
17
15
  },
18
16
  setup() {
19
17
  return {
@@ -416,30 +416,6 @@ const theme = (() => {
416
416
  },
417
417
  },
418
418
  },
419
- protag: {
420
- main: {
421
- default: {
422
- backgroundColor: semanticColors.yellow[300],
423
- textColor: semanticColors.teal[800],
424
- borderColor: 'transparent',
425
- },
426
- hover: {
427
- backgroundColor: semanticColors.yellow[300],
428
- textColor: semanticColors.teal[800],
429
- borderColor: '',
430
- },
431
- active: {
432
- backgroundColor: semanticColors.yellow[300],
433
- textColor: semanticColors.teal[800],
434
- borderColor: '',
435
- },
436
- disabled: {
437
- backgroundColor: semanticColors.yellow[300],
438
- textColor: semanticColors.teal[400],
439
- borderColor: '',
440
- },
441
- },
442
- },
443
419
  filter: {
444
420
  main: {
445
421
  default: {
@@ -614,55 +590,6 @@ const theme = (() => {
614
590
  },
615
591
  },
616
592
  },
617
- tertiary: {
618
- // type
619
- main: {
620
- // variant: this is the default variant
621
- default: {
622
- backgroundColor: 'transparent',
623
- textColor: semanticColors.purple[50],
624
- borderColor: semanticColors.teal[500],
625
- },
626
- hover: {
627
- backgroundColor: semanticColors.teal[600],
628
- textColor: semanticColors.purple[50],
629
- borderColor: semanticColors.teal[400],
630
- },
631
- active: {
632
- backgroundColor: semanticColors.teal[700],
633
- textColor: semanticColors.purple[50],
634
- borderColor: semanticColors.teal[300],
635
- },
636
- disabled: {
637
- textColor: semanticColors.grey[600],
638
- backgroundColor: semanticColors.grey[500],
639
- borderColor: semanticColors.grey[800],
640
- },
641
- },
642
- cancel: {
643
- // variant
644
- default: {
645
- backgroundColor: semanticColors.teal[200],
646
- textColor: semanticColors.red[400],
647
- borderColor: semanticColors.teal[500],
648
- },
649
- hover: {
650
- backgroundColor: semanticColors.red[700],
651
- textColor: semanticColors.red[700],
652
- borderColor: semanticColors.teal[400],
653
- },
654
- active: {
655
- backgroundColor: semanticColors.red[600],
656
- textColor: semanticColors.red[200],
657
- borderColor: semanticColors.teal[300],
658
- },
659
- disabled: {
660
- textColor: semanticColors.grey[600],
661
- backgroundColor: semanticColors.grey[500],
662
- borderColor: semanticColors.grey[800],
663
- },
664
- },
665
- },
666
593
  ghost: {
667
594
  // type
668
595
  main: {
@@ -753,11 +680,6 @@ const theme = (() => {
753
680
  fontSize: '14px',
754
681
  iconWidth: '26px',
755
682
  },
756
- tiny: {
757
- padding: '2px 5px',
758
- fontSize: '10px',
759
- iconWidth: '18px',
760
- },
761
683
  },
762
684
  },
763
685
  }
@@ -1,14 +1,14 @@
1
1
  <template>
2
2
  <Container :is-chart-controls-shown-in-bottom="isChartControlsShownInBottom">
3
3
  <LabelsColumn :width="yAxisWidth">
4
- <LabelRow v-for="series in seriesData" :key="series.name">
4
+ <LabelRow v-for="series in props.series" :key="series.name">
5
5
  {{ series.name }}
6
6
  </LabelRow>
7
- <TotalRow v-if="seriesData.length && fieldMode === 'percentage'">
8
- {{ $gettext ? `${$gettext('Total')} (%)` : 'Total (%)' }}
7
+ <TotalRow v-if="props.series.length && fieldMode === 'percentage'">
8
+ {{ $gettext ? $gettext('Total (%)') : 'Total (%)' }}
9
9
  </TotalRow>
10
- <TotalRow v-if="seriesData.length">
11
- {{ $gettext ? `${$gettext('Total')} (kWh)` : 'Total (kWh)' }}
10
+ <TotalRow v-if="props.series.length">
11
+ {{ $gettext ? $gettext('Total (kWh)') : 'Total (kWh)' }}
12
12
  </TotalRow>
13
13
  </LabelsColumn>
14
14
 
@@ -18,36 +18,27 @@
18
18
  >
19
19
  <FieldsWrapper>
20
20
  <!-- For stacked bar chart -->
21
- <template v-if="seriesData.length">
21
+ <template v-if="props.series.length">
22
22
  <InputRow
23
- v-for="series in seriesData"
23
+ v-for="series in props.series"
24
24
  :key="series.name"
25
25
  :data-series-name="series.name"
26
26
  >
27
27
  <InputGroup
28
28
  v-for="(item, index) in props.data"
29
- :key="index"
30
29
  :bar-width="barWidth"
31
30
  :is-scrollable="isScrollable"
31
+ :key="index"
32
32
  >
33
33
  <InputNumber
34
34
  :allow-negative="false"
35
- :disabled="isInputsDisabled"
36
35
  input-height="36px"
37
- :is-disabled-styled-only="true"
38
- :is-info-border="
39
- fieldMode === 'percentage'
40
- ? calculatePercentageTotal(item.label) !== 100
41
- : false
42
- "
36
+ :number-precision="0"
43
37
  :min-decimals="0"
44
- :number-precision="fieldMode === 'percentage' ? 2 : 0"
45
38
  text-align="center"
46
39
  :unit-name="fieldMode === 'percentage' ? '%' : ''"
47
40
  :value="getDisplayValue(series.data, item.label)"
48
- @input-blur="
49
- handleInputBlur($event, series.name, item.label, series.data)
50
- "
41
+ @input-blur="handleInputBlur($event, series.name, item.label)"
51
42
  @input-focus="handleInputFocus(series.name, item.label)"
52
43
  />
53
44
  </InputGroup>
@@ -56,18 +47,16 @@
56
47
  <TotalInputRow v-if="fieldMode === 'percentage'">
57
48
  <InputGroup
58
49
  v-for="(item, index) in props.data"
59
- :key="index"
60
50
  :bar-width="barWidth"
61
51
  :is-scrollable="isScrollable"
52
+ :key="index"
62
53
  >
63
54
  <InputNumber
64
55
  :allow-negative="false"
65
- :disabled="isInputsDisabled"
66
56
  input-height="36px"
67
- :is-disabled-styled-only="true"
68
57
  :is-read-only="true"
58
+ :number-precision="0"
69
59
  :min-decimals="0"
70
- :number-precision="fieldMode === 'percentage' ? 2 : 0"
71
60
  text-align="center"
72
61
  :unit-name="fieldMode === 'percentage' ? '%' : ''"
73
62
  :value="calculatePercentageTotal(item.label)"
@@ -78,23 +67,17 @@
78
67
  <TotalInputRow>
79
68
  <InputGroup
80
69
  v-for="(item, index) in props.data"
81
- :key="index"
82
70
  :bar-width="barWidth"
83
71
  :is-scrollable="isScrollable"
72
+ :key="index"
84
73
  >
85
74
  <InputNumber
86
75
  input-height="36px"
87
- :is-border-error-only="true"
88
- :is-info-border="
89
- fieldMode === 'percentage'
90
- ? calculatePercentageTotal(item.label) !== 100
91
- : false
92
- "
93
76
  :is-read-only="true"
77
+ :number-precision="2"
94
78
  :min-decimals="0"
95
- :number-precision="0"
96
79
  text-align="center"
97
- :value="calculateTotalValue(item.label)"
80
+ :value="calculateTotal(item.label)"
98
81
  />
99
82
  </InputGroup>
100
83
  </TotalInputRow>
@@ -105,20 +88,17 @@
105
88
  <InputRow>
106
89
  <InputGroup
107
90
  v-for="(item, index) in props.data"
108
- :key="index"
109
91
  :bar-width="barWidth"
110
92
  :is-scrollable="isScrollable"
93
+ :key="index"
111
94
  >
112
95
  <InputNumber
113
- :allow-negative="false"
114
- :disabled="isInputsDisabled"
115
96
  input-height="36px"
116
- :is-disabled-styled-only="true"
117
97
  :min-decimals="0"
118
- :number-precision="0"
98
+ :number-precision="2"
119
99
  text-align="center"
120
100
  :value="item.value"
121
- @input-blur="handleInputBlur($event, null, item.label, null)"
101
+ @input-blur="handleInputBlur($event, null, item.label)"
122
102
  @input-focus="handleInputFocus(null, item.label)"
123
103
  />
124
104
  </InputGroup>
@@ -127,22 +107,11 @@
127
107
  </FieldsWrapper>
128
108
  </FieldsContainer>
129
109
  </Container>
130
- <InfoCardContainer
131
- v-if="hasAnySegmentNotTotatTo100Percent && fieldMode === 'percentage'"
132
- :yAxisWidth="yAxisWidth"
133
- >
134
- <InfoCard align-items="center" type="info">
135
- <InfoCardBody>
136
- {{ percentageErrorMessage }}
137
- </InfoCardBody>
138
- </InfoCard>
139
- </InfoCardContainer>
140
110
  </template>
141
111
 
142
112
  <script setup>
143
- import { ref, computed, watchEffect } from 'vue'
113
+ import { ref } from 'vue'
144
114
  import InputNumber from '../inputs/inputNumber'
145
- import InfoCard from '../infoCard'
146
115
 
147
116
  import {
148
117
  Container,
@@ -154,8 +123,6 @@
154
123
  InputRow,
155
124
  TotalInputRow,
156
125
  InputGroup,
157
- InfoCardContainer,
158
- InfoCardBody,
159
126
  } from './styles/bottomFields'
160
127
 
161
128
  const props = defineProps({
@@ -192,51 +159,6 @@
192
159
  default: 'absolute',
193
160
  validator: (value) => ['absolute', 'percentage'].includes(value),
194
161
  },
195
- isInputsDisabled: {
196
- type: Boolean,
197
- default: false,
198
- },
199
- percentageErrorMessage: {
200
- type: String,
201
- default: '',
202
- },
203
- })
204
-
205
- const seriesData = ref([])
206
-
207
- watchEffect(() => {
208
- let isNewSetOfSeries = false
209
- const seriesDataCopy = [...seriesData.value]
210
- if (
211
- !seriesDataCopy.length ||
212
- !props.series.length ||
213
- seriesDataCopy.length !== props.series.length ||
214
- !seriesDataCopy.some((item) => {
215
- return props.series.map((s) => s.name).includes(item.name)
216
- })
217
- ) {
218
- isNewSetOfSeries = true
219
- }
220
- const currentSeriesData = !isNewSetOfSeries ? seriesDataCopy : []
221
- const newSeriesData = []
222
-
223
- props.series.forEach((item, itemIndex) => {
224
- const data = item.data.map((d, dIndex) => ({
225
- label: d.label,
226
- value: d.value,
227
- percentage: d.percentage,
228
- originalValue: currentSeriesData.length
229
- ? currentSeriesData[itemIndex].data[dIndex].originalValue
230
- : d.value,
231
- }))
232
-
233
- newSeriesData.push({
234
- name: item.name,
235
- data,
236
- })
237
- })
238
-
239
- seriesData.value = [...newSeriesData]
240
162
  })
241
163
 
242
164
  const emit = defineEmits([
@@ -253,13 +175,11 @@
253
175
  emit('input-focus', { seriesName, label })
254
176
  }
255
177
 
256
- const calculateTotalValue = (label) => {
257
- const total = seriesData.value.reduce((sum, series) => {
178
+ const calculateTotal = (label) => {
179
+ return props.series.reduce((sum, series) => {
258
180
  const value = series.data.find((d) => d.label === label)?.value || 0
259
181
  return sum + value
260
182
  }, 0)
261
-
262
- return Math.round(total)
263
183
  }
264
184
 
265
185
  const syncScroll = (scrollLeft) => {
@@ -270,38 +190,34 @@
270
190
  container.scrollLeft = scrollLeft
271
191
  }
272
192
  }
273
-
274
- const getDisplayValue = (data, label, shouldRound = true) => {
193
+ const getDisplayValue = (seriesData, label) => {
275
194
  if (props.fieldMode === 'absolute') {
276
- return data.find((d) => d.label === label)?.value
195
+ return seriesData.find((d) => d.label === label)?.value || ''
277
196
  }
278
197
 
279
- return data.find((d) => d.label === label)?.percentage
198
+ const value = seriesData.find((d) => d.label === label)?.value || 0
199
+ const total = calculateTotal(label)
200
+ return total ? Number(((value / total) * 100).toFixed(0)) : 0
280
201
  }
281
202
 
282
203
  const calculatePercentageTotal = (label) => {
283
- const percentageTotal = seriesData.value.reduce((sum, series) => {
284
- const percentage =
285
- series.data.find((d) => d.label === label)?.percentage || 0
204
+ return props.series.reduce((sum, series) => {
205
+ const value = series.data.find((d) => d.label === label)?.value || 0
206
+ const total = calculateTotal(label)
207
+ const percentage = total ? Number(((value / total) * 100).toFixed(0)) : 0
286
208
  return sum + percentage
287
209
  }, 0)
288
-
289
- return Math.round(percentageTotal)
290
210
  }
291
211
 
292
212
  const handleInputBlur = (_value, seriesName, label) => {
293
- if (props.isInputsDisabled) {
294
- return
295
- }
296
213
  let value = Number(_value)
297
214
 
298
- const payload = seriesName
299
- ? {
300
- seriesName,
301
- label,
302
- value,
303
- }
304
- : { label, value }
215
+ if (props.fieldMode === 'percentage') {
216
+ const total = calculateTotal(label)
217
+ value = (value / 100) * total
218
+ }
219
+
220
+ const payload = seriesName ? { seriesName, label, value } : { label, value }
305
221
  emit('input-blur', payload)
306
222
  focusedInput.value = null
307
223
 
@@ -327,12 +243,6 @@
327
243
  }
328
244
  }
329
245
 
330
- const hasAnySegmentNotTotatTo100Percent = computed(() => {
331
- return props.data.some((d) => {
332
- return calculatePercentageTotal(d.label) !== 100
333
- })
334
- })
335
-
336
246
  const handleFieldsScroll = (event) => {
337
247
  emit('sync-scroll', event.target.scrollLeft)
338
248
  }
@@ -84,7 +84,7 @@ export function useAxisCalculations(props, maxValue) {
84
84
  })
85
85
 
86
86
  const yAxisWidth = computed(() => {
87
- return !!props.yAxisTitle || props.isBottomFieldsShown ? '80px' : '60px'
87
+ return !!props.yAxisTitle || props.isBottomFieldsShown ? '70px' : '60px'
88
88
  })
89
89
 
90
90
  const isChartControlsShown = (position) => {
@@ -66,7 +66,7 @@ export function useChartData(props, paddedMaxValue) {
66
66
  let accumulated = 0
67
67
  return {
68
68
  label: item.label,
69
- segments: [...props.series].map((series, index) => {
69
+ segments: [...props.series].reverse().map((series, index) => {
70
70
  const value =
71
71
  series.data.find((d) => d.label === item.label)?.value || 0
72
72
  accumulated += value
@@ -16,21 +16,7 @@ export function useTooltip(chartId, normalizedData) {
16
16
  if (!showTooltipContent.value) {
17
17
  showTooltipContent.value = true
18
18
  }
19
- if (isObjectEqual(item, tooltipData.value)) {
20
- return
21
- }
22
-
23
- const totalValue = item.segments.reduce((acc, segment) => {
24
- return acc + segment.value
25
- }, 0)
26
-
27
- const segments = item.segments.map((segment) => {
28
- let valuePercentage = (segment.value / totalValue) * 100
29
- segment.valuePercentage = Math.round(valuePercentage)
30
-
31
- return segment
32
- })
33
- item.segments = segments
19
+ if (isObjectEqual(item, tooltipData.value)) return
34
20
 
35
21
  tooltipData.value = { ...item }
36
22
 
@@ -55,27 +41,16 @@ export function useTooltip(chartId, normalizedData) {
55
41
 
56
42
  isInputFocused.value = true
57
43
  const barData = normalizedData.value.find((item) => item.label === label)
58
- if (!barData) return
59
44
 
60
- const totalValue = barData.segments.reduce((acc, segment) => {
61
- return acc + segment.value
62
- }, 0)
63
- const segments = barData.segments.map((segment) => {
64
- let valuePercentage = (segment.value / totalValue) * 100
65
- segment.valuePercentage = Math.round(valuePercentage)
66
-
67
- return segment
68
- })
69
- barData.segments = segments
45
+ if (!barData) return
70
46
  focusedBarData.value = barData
71
-
72
47
  const barElement = document.querySelector(
73
48
  `.barchart-${chartId} .bar-group:nth-child(${
74
49
  normalizedData.value.indexOf(barData) + 1
75
50
  })`
76
51
  )
77
- if (!barElement) return
78
52
 
53
+ if (!barElement) return
79
54
  // Get the last bar segment, samee as hover behavior
80
55
  const targetElement = barElement.querySelector('.bar-segment:last-child')
81
56
  const rect = targetElement.getBoundingClientRect()
@@ -17,7 +17,7 @@
17
17
  />
18
18
  </ChartControlsWrapper>
19
19
  <GraphSection :height="height" :width="width">
20
- <YAxis :height="height" :width="yAxisWidth">
20
+ <YAxis :width="yAxisWidth" :height="height">
21
21
  <YAxisTitleWrapper v-if="yAxisTitle" :height="yAxisHeight">
22
22
  {{ yAxisTitle }}
23
23
  </YAxisTitleWrapper>
@@ -30,15 +30,15 @@
30
30
  )
31
31
  "
32
32
  >
33
- <YAxisLabel>{{ getYAxisLabel(label) }}</YAxisLabel>
33
+ <YAxisLabel>{{ label }}</YAxisLabel>
34
34
  <YAxisLine :y-axis-width="yAxisWidth" />
35
35
  </YAxisRow>
36
36
  </YAxis>
37
37
 
38
38
  <ScrollContainer
39
39
  :class="`chart-scroll-container-${chartId}`"
40
- :height="height"
41
40
  :is-scrollable="isScrollable"
41
+ :height="height"
42
42
  @scroll="handleChartScroll"
43
43
  >
44
44
  <ChartContent
@@ -64,19 +64,19 @@
64
64
  <BarsContainer>
65
65
  <BarGroup
66
66
  v-for="(item, index) in normalizedData"
67
- :key="index"
68
67
  :bar-width="barWidth"
69
68
  class="bar-group"
70
69
  :is-scrollable="isScrollable"
70
+ :key="index"
71
71
  >
72
72
  <BarWrapper>
73
73
  <BarSegment
74
74
  v-for="(segment, segIndex) in item.segments"
75
- :key="segIndex"
76
75
  class="bar-segment"
77
76
  :gradient-from="getSegmentGradient(index, segment).from"
78
77
  :gradient-to="getSegmentGradient(index, segment).to"
79
78
  :height="`${segment.percentage}%`"
79
+ :key="segIndex"
80
80
  :z-index="item.segments.length - segIndex"
81
81
  @mouseenter="showTooltip(item, $event, series)"
82
82
  @mouseleave="hideTooltip"
@@ -96,7 +96,7 @@
96
96
  :left="tooltipStyle.left"
97
97
  :top="tooltipStyle.top"
98
98
  >
99
- <slot :item="tooltipData" name="tooltip"></slot>
99
+ <slot :item="tooltipData" name="tooltip" />
100
100
  <TooltipTextWrapper v-if="!slots.tooltip && tooltipData">
101
101
  <template v-if="!series.length">
102
102
  <TooltipText font-weight="500">{{ tooltipData.label }}</TooltipText>
@@ -128,11 +128,7 @@
128
128
  :gradient-to="segment.gradientTo"
129
129
  />
130
130
  <TooltipText>
131
- {{
132
- fieldMode === 'absolute' && showPercentageOnTooltip
133
- ? `${segment.valuePercentage}%`
134
- : handleValueFormatter(segment.value)
135
- }}
131
+ {{ handleValueFormatter(segment.value) }}
136
132
  </TooltipText>
137
133
  </TooltipRow>
138
134
  </template>
@@ -163,9 +159,7 @@
163
159
  :data="data"
164
160
  :field-mode="fieldMode"
165
161
  :is-chart-controls-shown-in-bottom="isChartControlsShown('bottom')"
166
- :is-inputs-disabled="isLoading"
167
162
  :is-scrollable="isScrollable"
168
- :percentage-error-message="percentageErrorMessage"
169
163
  :series="series"
170
164
  :y-axis-width="yAxisWidth"
171
165
  @input-blur="handleInputBlur"
@@ -177,13 +171,12 @@
177
171
  </template>
178
172
 
179
173
  <script setup>
180
- import { useSlots, computed, ref } from 'vue'
174
+ import { useSlots, computed } from 'vue'
181
175
 
182
176
  import ChartControls from './ChartControls'
183
177
  import BottomFields from './BottomFields'
184
178
  import SelectionBox from './SelectionBox'
185
179
  import Spinner from '../spinner'
186
- import { numberToString } from '../../helpers/numberConverter'
187
180
 
188
181
  import {
189
182
  useTooltip,
@@ -253,6 +246,10 @@
253
246
  type: String,
254
247
  default: '',
255
248
  },
249
+ valueFormatter: {
250
+ type: Function,
251
+ default: null,
252
+ },
256
253
  isLegendShown: {
257
254
  type: Boolean,
258
255
  default: false,
@@ -299,14 +296,6 @@
299
296
  type: Boolean,
300
297
  default: false,
301
298
  },
302
- showPercentageOnTooltip: {
303
- type: Boolean,
304
- default: false,
305
- },
306
- percentageErrorMessage: {
307
- type: String,
308
- default: '',
309
- },
310
299
  })
311
300
 
312
301
  const generateChartId = () =>
@@ -389,40 +378,8 @@
389
378
  }
390
379
 
391
380
  const handleValueFormatter = (value) => {
392
- let formattedValue = value
393
- if (value < 1000) {
394
- formattedValue = numberToString({
395
- value: formattedValue,
396
- numberPrecision: 0,
397
- minDecimals: 0,
398
- })
399
- } else if (value < 1000000) {
400
- formattedValue = numberToString({
401
- value: Number(formattedValue / 1000),
402
- numberPrecision: 2,
403
- minDecimals: 2,
404
- })
405
- } else {
406
- formattedValue = numberToString({
407
- value: Number(formattedValue / 1000000),
408
- numberPrecision: 2,
409
- minDecimals: 2,
410
- })
411
- }
412
- if (value < 1000) {
413
- return `${formattedValue} kWh`
414
- } else if (value < 1000000) {
415
- return `${formattedValue} MWh`
416
- } else {
417
- return `${formattedValue} GWh`
418
- }
419
- }
420
-
421
- const getYAxisLabel = (label) => {
422
- return numberToString({
423
- value: label,
424
- numberPrecision: 0,
425
- minDecimals: 0,
426
- })
381
+ return props.valueFormatter
382
+ ? props.valueFormatter(Math.round(value))
383
+ : value
427
384
  }
428
385
  </script>