@eturnity/eturnity_reusable_components 8.19.8-EPDM-14690.1 → 8.19.8-EPDM-11600.10

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.1",
3
+ "version": "8.19.8-EPDM-11600.10",
4
4
  "files": [
5
5
  "dist",
6
6
  "src"
@@ -1,4 +1,3 @@
1
- <svg fill="none" height="16" viewbox="12 12 16 16" width="16" xmlns="http://www.w3.org/2000/svg">
2
- <circle cx="20" cy="20" r="7"></circle>
3
- <path d="M24.9592 15.0408C22.2382 12.3197 17.7618 12.3197 15.0408 15.0408C12.3197 17.7618 12.3197 22.2382 15.0408 24.9592C17.7618 27.6803 22.2382 27.6803 24.9592 24.9592C27.6803 22.2382 27.6803 17.8495 24.9592 15.0408ZM23.6426 22.5016L22.4138 23.7304L19.9561 21.2727L17.4984 23.7304L16.2696 22.5016L18.7273 20.0439L16.2696 17.5862L17.4984 16.3574L19.9561 18.815L22.4138 16.3574L23.6426 17.5862L21.185 20.0439L23.6426 22.5016Z" fill="#FF5656"></path>
1
+ <svg width="22" height="21" viewBox="0 0 22 21" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path d="M18.4389 3.06113C14.3574 -1.02038 7.64263 -1.02038 3.56113 3.06113C-0.520376 7.14263 -0.520376 13.8574 3.56113 17.9389C7.64263 22.0204 14.3574 22.0204 18.4389 17.9389C22.5204 13.8574 22.5204 7.2743 18.4389 3.06113ZM16.464 14.2524L14.6207 16.0956L10.9342 12.4091L7.24765 16.0956L5.40439 14.2524L9.09091 10.5658L5.40439 6.87931L7.24765 5.03605L10.9342 8.72257L14.6207 5.03605L16.464 6.87931L12.7774 10.5658L16.464 14.2524Z" fill="#FF5656"/>
4
3
  </svg>
@@ -333,7 +333,7 @@ const theme = (() => {
333
333
  borderColor: semanticColors.grey[300],
334
334
  },
335
335
  active: {
336
- backgroundColor: semanticColors.purple[100],
336
+ backgroundColor: semanticColors.purple[50],
337
337
  textColor: semanticColors.purple[600],
338
338
  borderColor: semanticColors.grey[600],
339
339
  },
@@ -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,35 +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-info-border="
38
- fieldMode === 'percentage'
39
- ? calculatePercentageTotal(item.label) !== 100
40
- : false
41
- "
36
+ :number-precision="0"
42
37
  :min-decimals="0"
43
- :number-precision="fieldMode === 'percentage' ? 2 : 0"
44
38
  text-align="center"
45
39
  :unit-name="fieldMode === 'percentage' ? '%' : ''"
46
40
  :value="getDisplayValue(series.data, item.label)"
47
- @input-blur="
48
- handleInputBlur($event, series.name, item.label, series.data)
49
- "
41
+ @input-blur="handleInputBlur($event, series.name, item.label)"
50
42
  @input-focus="handleInputFocus(series.name, item.label)"
51
43
  />
52
44
  </InputGroup>
@@ -55,17 +47,16 @@
55
47
  <TotalInputRow v-if="fieldMode === 'percentage'">
56
48
  <InputGroup
57
49
  v-for="(item, index) in props.data"
58
- :key="index"
59
50
  :bar-width="barWidth"
60
51
  :is-scrollable="isScrollable"
52
+ :key="index"
61
53
  >
62
54
  <InputNumber
63
55
  :allow-negative="false"
64
- :disabled="isInputsDisabled"
65
56
  input-height="36px"
66
57
  :is-read-only="true"
58
+ :number-precision="0"
67
59
  :min-decimals="0"
68
- :number-precision="fieldMode === 'percentage' ? 2 : 0"
69
60
  text-align="center"
70
61
  :unit-name="fieldMode === 'percentage' ? '%' : ''"
71
62
  :value="calculatePercentageTotal(item.label)"
@@ -76,23 +67,17 @@
76
67
  <TotalInputRow>
77
68
  <InputGroup
78
69
  v-for="(item, index) in props.data"
79
- :key="index"
80
70
  :bar-width="barWidth"
81
71
  :is-scrollable="isScrollable"
72
+ :key="index"
82
73
  >
83
74
  <InputNumber
84
75
  input-height="36px"
85
- :is-border-error-only="true"
86
- :is-info-border="
87
- fieldMode === 'percentage'
88
- ? calculatePercentageTotal(item.label) !== 100
89
- : false
90
- "
91
76
  :is-read-only="true"
77
+ :number-precision="2"
92
78
  :min-decimals="0"
93
- :number-precision="0"
94
79
  text-align="center"
95
- :value="calculateTotalValue(item.label)"
80
+ :value="calculateTotal(item.label)"
96
81
  />
97
82
  </InputGroup>
98
83
  </TotalInputRow>
@@ -103,19 +88,17 @@
103
88
  <InputRow>
104
89
  <InputGroup
105
90
  v-for="(item, index) in props.data"
106
- :key="index"
107
91
  :bar-width="barWidth"
108
92
  :is-scrollable="isScrollable"
93
+ :key="index"
109
94
  >
110
95
  <InputNumber
111
- :allow-negative="false"
112
- :disabled="isInputsDisabled"
113
96
  input-height="36px"
114
97
  :min-decimals="0"
115
- :number-precision="0"
98
+ :number-precision="2"
116
99
  text-align="center"
117
100
  :value="item.value"
118
- @input-blur="handleInputBlur($event, null, item.label, null)"
101
+ @input-blur="handleInputBlur($event, null, item.label)"
119
102
  @input-focus="handleInputFocus(null, item.label)"
120
103
  />
121
104
  </InputGroup>
@@ -124,22 +107,11 @@
124
107
  </FieldsWrapper>
125
108
  </FieldsContainer>
126
109
  </Container>
127
- <InfoCardContainer
128
- v-if="hasAnySegmentNotTotatTo100Percent && fieldMode === 'percentage'"
129
- :yAxisWidth="yAxisWidth"
130
- >
131
- <InfoCard align-items="center" type="info">
132
- <InfoCardBody>
133
- {{ $gettext('load_profile_not_add_up_to_100') }}
134
- </InfoCardBody>
135
- </InfoCard>
136
- </InfoCardContainer>
137
110
  </template>
138
111
 
139
112
  <script setup>
140
- import { ref, computed, watchEffect } from 'vue'
113
+ import { ref } from 'vue'
141
114
  import InputNumber from '../inputs/inputNumber'
142
- import InfoCard from '../infoCard'
143
115
 
144
116
  import {
145
117
  Container,
@@ -151,8 +123,6 @@
151
123
  InputRow,
152
124
  TotalInputRow,
153
125
  InputGroup,
154
- InfoCardContainer,
155
- InfoCardBody,
156
126
  } from './styles/bottomFields'
157
127
 
158
128
  const props = defineProps({
@@ -189,47 +159,6 @@
189
159
  default: 'absolute',
190
160
  validator: (value) => ['absolute', 'percentage'].includes(value),
191
161
  },
192
- isInputsDisabled: {
193
- type: Boolean,
194
- default: false,
195
- },
196
- })
197
-
198
- const seriesData = ref([])
199
-
200
- watchEffect(() => {
201
- let isNewSetOfSeries = false
202
- const seriesDataCopy = [...seriesData.value]
203
- if (
204
- !seriesDataCopy.length ||
205
- !props.series.length ||
206
- seriesDataCopy.length !== props.series.length ||
207
- !seriesDataCopy.some((item) => {
208
- return props.series.map((s) => s.name).includes(item.name)
209
- })
210
- ) {
211
- isNewSetOfSeries = true
212
- }
213
- const currentSeriesData = !isNewSetOfSeries ? seriesDataCopy : []
214
- const newSeriesData = []
215
-
216
- props.series.forEach((item, itemIndex) => {
217
- const data = item.data.map((d, dIndex) => ({
218
- label: d.label,
219
- value: d.value,
220
- percentage: d.percentage,
221
- originalValue: currentSeriesData.length
222
- ? currentSeriesData[itemIndex].data[dIndex].originalValue
223
- : d.value,
224
- }))
225
-
226
- newSeriesData.push({
227
- name: item.name,
228
- data,
229
- })
230
- })
231
-
232
- seriesData.value = [...newSeriesData]
233
162
  })
234
163
 
235
164
  const emit = defineEmits([
@@ -246,13 +175,11 @@
246
175
  emit('input-focus', { seriesName, label })
247
176
  }
248
177
 
249
- const calculateTotalValue = (label) => {
250
- const total = seriesData.value.reduce((sum, series) => {
178
+ const calculateTotal = (label) => {
179
+ return props.series.reduce((sum, series) => {
251
180
  const value = series.data.find((d) => d.label === label)?.value || 0
252
181
  return sum + value
253
182
  }, 0)
254
-
255
- return Math.round(total)
256
183
  }
257
184
 
258
185
  const syncScroll = (scrollLeft) => {
@@ -263,43 +190,34 @@
263
190
  container.scrollLeft = scrollLeft
264
191
  }
265
192
  }
266
-
267
- const calculateTotalOriginalValue = (label) => {
268
- return seriesData.value.reduce((sum, series) => {
269
- const value =
270
- series.data.find((d) => d.label === label)?.originalValue || 0
271
- return sum + value
272
- }, 0)
273
- }
274
-
275
- const getDisplayValue = (data, label, shouldRound = true) => {
193
+ const getDisplayValue = (seriesData, label) => {
276
194
  if (props.fieldMode === 'absolute') {
277
- return data.find((d) => d.label === label)?.value
195
+ return seriesData.find((d) => d.label === label)?.value || ''
278
196
  }
279
197
 
280
- 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
281
201
  }
282
202
 
283
203
  const calculatePercentageTotal = (label) => {
284
- const percentageTotal = seriesData.value.reduce((sum, series) => {
285
- const percentage =
286
- 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
287
208
  return sum + percentage
288
209
  }, 0)
289
-
290
- return Math.round(percentageTotal)
291
210
  }
292
211
 
293
- const handleInputBlur = (_value, seriesName, label, currentSeriesData) => {
212
+ const handleInputBlur = (_value, seriesName, label) => {
294
213
  let value = Number(_value)
295
214
 
296
- const payload = seriesName
297
- ? {
298
- seriesName,
299
- label,
300
- value,
301
- }
302
- : { 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 }
303
221
  emit('input-blur', payload)
304
222
  focusedInput.value = null
305
223
 
@@ -325,12 +243,6 @@
325
243
  }
326
244
  }
327
245
 
328
- const hasAnySegmentNotTotatTo100Percent = computed(() => {
329
- return props.data.some((d) => {
330
- return calculatePercentageTotal(d.label) !== 100
331
- })
332
- })
333
-
334
246
  const handleFieldsScroll = (event) => {
335
247
  emit('sync-scroll', event.target.scrollLeft)
336
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,8 +17,8 @@
17
17
  />
18
18
  </ChartControlsWrapper>
19
19
  <GraphSection :height="height" :width="width">
20
- <YAxis :height="height" :width="yAxisWidth">
21
- <YAxisTitleWrapper v-if="yAxisTitle" :height="yAxisHeight">
20
+ <YAxis :width="yAxisWidth">
21
+ <YAxisTitleWrapper v-if="yAxisTitle">
22
22
  {{ yAxisTitle }}
23
23
  </YAxisTitleWrapper>
24
24
  <YAxisRow
@@ -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,7 +159,6 @@
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
163
  :series="series"
169
164
  :y-axis-width="yAxisWidth"
@@ -176,13 +171,12 @@
176
171
  </template>
177
172
 
178
173
  <script setup>
179
- import { useSlots, computed, ref } from 'vue'
174
+ import { useSlots, computed } from 'vue'
180
175
 
181
176
  import ChartControls from './ChartControls'
182
177
  import BottomFields from './BottomFields'
183
178
  import SelectionBox from './SelectionBox'
184
179
  import Spinner from '../spinner'
185
- import { numberToString } from '../../helpers/numberConverter'
186
180
 
187
181
  import {
188
182
  useTooltip,
@@ -252,6 +246,10 @@
252
246
  type: String,
253
247
  default: '',
254
248
  },
249
+ valueFormatter: {
250
+ type: Function,
251
+ default: null,
252
+ },
255
253
  isLegendShown: {
256
254
  type: Boolean,
257
255
  default: false,
@@ -298,10 +296,6 @@
298
296
  type: Boolean,
299
297
  default: false,
300
298
  },
301
- showPercentageOnTooltip: {
302
- type: Boolean,
303
- default: false,
304
- },
305
299
  })
306
300
 
307
301
  const generateChartId = () =>
@@ -384,40 +378,8 @@
384
378
  }
385
379
 
386
380
  const handleValueFormatter = (value) => {
387
- let formattedValue = value
388
- if (value < 1000) {
389
- formattedValue = numberToString({
390
- value: formattedValue,
391
- numberPrecision: 0,
392
- minDecimals: 0,
393
- })
394
- } else if (value < 1000000) {
395
- formattedValue = numberToString({
396
- value: Number(formattedValue / 1000),
397
- numberPrecision: 2,
398
- minDecimals: 2,
399
- })
400
- } else {
401
- formattedValue = numberToString({
402
- value: Number(formattedValue / 1000000),
403
- numberPrecision: 2,
404
- minDecimals: 2,
405
- })
406
- }
407
- if (value < 1000) {
408
- return `${formattedValue} kWh`
409
- } else if (value < 1000000) {
410
- return `${formattedValue} MWh`
411
- } else {
412
- return `${formattedValue} GWh`
413
- }
414
- }
415
-
416
- const getYAxisLabel = (label) => {
417
- return numberToString({
418
- value: label,
419
- numberPrecision: 0,
420
- minDecimals: 0,
421
- })
381
+ return props.valueFormatter
382
+ ? props.valueFormatter(Math.round(value))
383
+ : value
422
384
  }
423
385
  </script>
@@ -17,18 +17,18 @@ export const LabelsColumn = styled('div', { width: String })`
17
17
 
18
18
  export const LabelRow = styled.div`
19
19
  height: 32px;
20
- padding-top: 5px;
21
20
  font-size: 12px;
22
21
  font-weight: 500;
23
22
  color: ${(props) => props.theme.semanticColors.teal[600]};
24
23
  display: flex;
25
- align-items: center;
24
+ align-items: flex-start;
26
25
  `
27
26
 
28
27
  export const TotalRow = styled(LabelRow)``
29
28
 
30
29
  export const FieldsContainer = styled.div`
31
30
  flex: 1;
31
+ overflow-x: auto;
32
32
  scrollbar-width: none;
33
33
 
34
34
  &::-webkit-scrollbar {
@@ -59,22 +59,8 @@ export const InputGroup = styled('div', {
59
59
  barWidth: Number,
60
60
  isScrollable: Boolean,
61
61
  })`
62
- ${(props) => (props.isScrollable ? 'min-width' : 'width')}: 70px;
62
+ ${(props) => (props.isScrollable ? 'min-width' : 'width')}:${(props) =>
63
+ props.barWidth}px;
63
64
  display: flex;
64
65
  justify-content: center;
65
- position: relative;
66
-
67
- input[readonly] {
68
- border: 1px solid ${(props) => props.theme.colors.grey4} !important;
69
- }
70
- `
71
-
72
- export const InfoCardContainer = styled('div', { yAxisWidth: String })`
73
- margin-left: ${(props) => props.yAxisWidth};
74
- padding: 12px;
75
- margin-top: 12px;
76
- `
77
-
78
- export const InfoCardBody = styled.div`
79
- padding: 8px 0;
80
66
  `
@@ -16,12 +16,9 @@ export const GraphSection = styled('div', { width: String, height: String })`
16
16
  display: flex;
17
17
  `
18
18
 
19
- export const YAxis = styled('div', { width: String, height: String })`
19
+ export const YAxis = styled('div', { width: String })`
20
20
  width: ${(props) => props.width};
21
- display: flex;
22
- flex-direction: column;
23
21
  position: relative;
24
- height: ${(props) => props.height};
25
22
  `
26
23
 
27
24
  export const YAxisRow = styled('div', { percentage: Number })`
@@ -57,18 +54,19 @@ export const YAxisLine = styled('div', { yAxisWidth: String })`
57
54
  transform: translateY(-50%);
58
55
  `
59
56
 
60
- export const YAxisTitleWrapper = styled('div', { height: String })`
61
- position: absolute;
62
- left: -66px;
63
- top: ${(props) => props.height};
64
- transform: rotate(-90deg) translateX(50%);
65
- transform-origin: right;
57
+ export const YAxisTitleWrapper = styled('div')`
66
58
  font-size: 12px;
67
- color: ${(props) => props.theme.semanticColors.teal[600]};
68
- display: flex;
69
- align-items: center;
59
+ font-weight: 500;
60
+ color: ${(props) => props.theme.semanticColors.grey[700]};
70
61
  white-space: nowrap;
71
- font-family: ${(props) => props.theme.fonts.mainFont};
62
+ height: 0;
63
+ width: 0;
64
+ display: flex;
65
+ align-items: flex-start;
66
+ justify-content: center;
67
+ position: absolute;
68
+ top: 50%;
69
+ transform: rotate(-90deg);
72
70
  `
73
71
 
74
72
  export const ScrollContainer = styled('div', {
@@ -127,7 +125,6 @@ export const BarWrapper = styled.div`
127
125
  height: 100%;
128
126
  width: 100%;
129
127
  position: relative;
130
- overflow: hidden;
131
128
  `
132
129
 
133
130
  export const BarSegment = styled('div', {
@@ -19,7 +19,7 @@
19
19
  background: ${(props) => props.theme.colors.red};
20
20
  padding: 10px;
21
21
  width: max-content;
22
- /* max-width: 100%; */
22
+ max-width: 100%;
23
23
  min-width: min-content;
24
24
  font-size: 11px;
25
25
  font-weight: 400;
@@ -73,12 +73,7 @@
73
73
  type: {
74
74
  required: false,
75
75
  type: String,
76
- default: 'info_simple',
77
- validator(value) {
78
- return ['info_simple', 'warning', 'error_minor', 'info'].includes(
79
- value
80
- )
81
- },
76
+ default: 'info',
82
77
  },
83
78
  minWidth: {
84
79
  required: false,
@@ -117,11 +112,8 @@
117
112
  },
118
113
  },
119
114
  computed: {
120
- isInfoSimple() {
121
- // this property is used for tests
122
- return this.type === 'info_simple'
123
- },
124
115
  isInfo() {
116
+ // this property is used for tests
125
117
  return this.type === 'info'
126
118
  },
127
119
  isWarning() {
@@ -156,13 +148,9 @@
156
148
  stylesCollection.borderStyle = 'dashed'
157
149
  stylesCollection.borderColor = theme.colors.grey4
158
150
  stylesCollection.iconColor = theme.colors.red
159
- } else if (this.isInfoSimple) {
151
+ } else {
160
152
  stylesCollection.borderStyle = 'dashed'
161
153
  stylesCollection.borderColor = theme.colors.grey4
162
- } else {
163
- stylesCollection.color = theme.semanticColors.teal[800]
164
- stylesCollection.backgroundColor = theme.semanticColors.blue[300]
165
- stylesCollection.iconColor = theme.semanticColors.teal[800]
166
154
  }
167
155
 
168
156
  return stylesCollection
@@ -45,19 +45,19 @@ describe('RCInfoCard.vue', () => {
45
45
  },
46
46
  })
47
47
 
48
- expect(wrapper.vm.isInfoSimple).toBe(true)
48
+ expect(wrapper.vm.isInfo).toBe(true)
49
49
  expect(wrapper.vm.isWarning).toBe(false)
50
50
  expect(wrapper.vm.isErrorMinor).toBe(false)
51
51
 
52
52
  await wrapper.setProps({ type: 'warning' })
53
53
 
54
- expect(wrapper.vm.isInfoSimple).toBe(false)
54
+ expect(wrapper.vm.isInfo).toBe(false)
55
55
  expect(wrapper.vm.isWarning).toBe(true)
56
56
  expect(wrapper.vm.isErrorMinor).toBe(false)
57
57
 
58
58
  await wrapper.setProps({ type: 'error_minor' })
59
59
 
60
- expect(wrapper.vm.isInfoSimple).toBe(false)
60
+ expect(wrapper.vm.isInfo).toBe(false)
61
61
  expect(wrapper.vm.isWarning).toBe(false)
62
62
  expect(wrapper.vm.isErrorMinor).toBe(true)
63
63
  })
@@ -15,40 +15,37 @@
15
15
  :is-disabled="isDisabled"
16
16
  :padding="padding"
17
17
  >
18
- <template v-if="!$slots.trigger">
19
- <LabelWrapper
20
- v-if="labelText && labelAlign === 'left'"
21
- :color="iconColor || computedIconColor"
22
- :size="labelSize"
23
- >
24
- {{ labelText }}
25
- </LabelWrapper>
26
- <Dot
27
- v-if="type === 'dot'"
28
- :color="dotColor"
29
- data-test-id="infoText_dot"
30
- />
31
- <IconComponent
32
- v-else-if="!noIcon"
33
- :color="iconColor || computedIconColor"
34
- :cursor="isDisabled ? 'not-allowed' : 'pointer'"
35
- :disabled="isDisabled"
36
- :hovered-color="iconColor || computedIconColor"
37
- :name="iconName"
38
- :size="size"
39
- />
40
- <LabelWrapper
41
- v-if="labelText && labelAlign === 'right'"
42
- :color="iconColor || computedIconColor"
43
- :size="labelSize"
44
- >
45
- {{ labelText }}
46
- </LabelWrapper>
47
- </template>
48
- <slot name="trigger"></slot>
18
+ <LabelWrapper
19
+ v-if="labelText && labelAlign === 'left'"
20
+ :color="iconColor || computedIconColor"
21
+ :size="labelSize"
22
+ >
23
+ {{ labelText }}
24
+ </LabelWrapper>
25
+ <Dot
26
+ v-if="type === 'dot'"
27
+ :color="dotColor"
28
+ data-test-id="infoText_dot"
29
+ />
30
+ <IconComponent
31
+ v-else-if="!noIcon"
32
+ :color="iconColor || computedIconColor"
33
+ :cursor="isDisabled ? 'not-allowed' : 'pointer'"
34
+ :disabled="isDisabled"
35
+ :hovered-color="iconColor || computedIconColor"
36
+ :name="iconName"
37
+ :size="size"
38
+ />
39
+ <LabelWrapper
40
+ v-if="labelText && labelAlign === 'right'"
41
+ :color="iconColor || computedIconColor"
42
+ :size="labelSize"
43
+ >
44
+ {{ labelText }}
45
+ </LabelWrapper>
49
46
  </IconWrapper>
50
47
  </div>
51
- <Teleport v-if="isVisible && !!text" to="body">
48
+ <Teleport v-if="isVisible" to="body">
52
49
  <TextWrapper data-test-id="info_text_wrapper" :style="wrapperStyle">
53
50
  <TextOverlay
54
51
  ref="infoBox"
@@ -230,7 +227,7 @@
230
227
  },
231
228
  infoPosition: {
232
229
  required: false,
233
- default: null,
230
+ default: 'bottom',
234
231
  type: String,
235
232
  },
236
233
  maxWidth: {
@@ -366,9 +363,7 @@
366
363
  { position: 'left', space: spaceLeft },
367
364
  ].sort((a, b) => b.space - a.space)
368
365
 
369
- const bestPosition = props.infoPosition
370
- ? props.infoPosition
371
- : positions[0].position
366
+ const bestPosition = positions[0].position
372
367
 
373
368
  let top, left, arrowPosition
374
369
 
@@ -3,15 +3,15 @@ import InputNumber from './index.vue'
3
3
  export default {
4
4
  title: 'InputNumber',
5
5
  component: InputNumber,
6
- // argTypes: {},
7
6
  }
8
7
 
9
- const Template = (args, { argTypes }) => ({
8
+ const Template = (args) => ({
10
9
  // Components used in your story `template` are defined in the `components` object
11
10
  components: { InputNumber },
12
- // The story's `args` need to be mapped into the template through the `setup()` method
13
- props: Object.keys(argTypes),
14
- template: '<input-number v-bind="$props" />',
11
+ setup() {
12
+ return { args: args }
13
+ },
14
+ template: `<InputNumber v-bind="args" />`,
15
15
 
16
16
  // import InputNumber from "@eturnity/eturnity_reusable_components/src/components/inputs/inputNumber"
17
17
  // How to use:
@@ -30,61 +30,7 @@
30
30
  />
31
31
  </LabelWrapper>
32
32
  <InputWrapper>
33
- <InfoText
34
- v-if="!!inputInfoText"
35
- info-position="bottom"
36
- :text="inputInfoText"
37
- >
38
- <template #trigger>
39
- <InputContainer
40
- v-bind="$attrs"
41
- ref="inputField1"
42
- :align-items="alignItems"
43
- :background-color="
44
- colorMode === 'transparent' ? 'transparent' : backgroundColor
45
- "
46
- :border-color="
47
- colorMode === 'transparent' && !borderColor
48
- ? 'white'
49
- : borderColor
50
- "
51
- :color-mode="colorMode"
52
- :data-id="inputDataId"
53
- :data-qa-id="dataQaId"
54
- :disabled="disabled"
55
- :font-color="colorMode === 'transparent' ? 'white' : fontColor"
56
- :font-size="fontSize"
57
- :has-label-slot="hasLabelSlot"
58
- :has-slot="hasSlot"
59
- :has-unit="unitName && !!unitName.length"
60
- :input-height="inputHeight"
61
- :is-border-error-only="isBorderErrorOnly"
62
- :is-disabled="disabled"
63
- :is-error="isError"
64
- :is-info-border="isInfoBorder"
65
- :is-interactive="isInteractive"
66
- :min-width="minWidth"
67
- :no-border="noBorder"
68
- :placeholder="displayedPlaceholder"
69
- :read-only="isReadOnly"
70
- :readonly="isReadOnly"
71
- :show-arrow-controls="showArrowControls"
72
- :show-linear-unit-name="showLinearUnitName"
73
- :slot-size="slotSize"
74
- :text-align="textAlign"
75
- :value="formatWithCurrency(value)"
76
- @blur="onInputBlur($event)"
77
- @focus="focusInput()"
78
- @input="onInput($event)"
79
- @keydown.down="decrementValue"
80
- @keydown.up="incrementValue"
81
- @keyup.enter="onEnterPress"
82
- />
83
- </template>
84
- </InfoText>
85
-
86
33
  <InputContainer
87
- v-else
88
34
  v-bind="$attrs"
89
35
  ref="inputField1"
90
36
  :align-items="alignItems"
@@ -97,23 +43,19 @@
97
43
  :color-mode="colorMode"
98
44
  :data-id="inputDataId"
99
45
  :data-qa-id="dataQaId"
100
- :disabled="disabled"
101
46
  :font-color="colorMode === 'transparent' ? 'white' : fontColor"
102
47
  :font-size="fontSize"
103
48
  :has-label-slot="hasLabelSlot"
104
49
  :has-slot="hasSlot"
105
50
  :has-unit="unitName && !!unitName.length"
106
51
  :input-height="inputHeight"
107
- :is-border-error-only="isBorderErrorOnly"
108
52
  :is-disabled="disabled"
109
53
  :is-error="isError"
110
- :is-info-border="isInfoBorder"
111
54
  :is-interactive="isInteractive"
112
55
  :min-width="minWidth"
113
56
  :no-border="noBorder"
114
57
  :placeholder="displayedPlaceholder"
115
58
  :read-only="isReadOnly"
116
- :readonly="isReadOnly"
117
59
  :show-arrow-controls="showArrowControls"
118
60
  :show-linear-unit-name="showLinearUnitName"
119
61
  :slot-size="slotSize"
@@ -126,7 +68,6 @@
126
68
  @keydown.up="incrementValue"
127
69
  @keyup.enter="onEnterPress"
128
70
  />
129
-
130
71
  <SlotContainer v-if="hasSlot" :is-error="isError" :slot-size="slotSize">
131
72
  <slot></slot>
132
73
  </SlotContainer>
@@ -138,7 +79,7 @@
138
79
  >{{ unitName }}</UnitContainer
139
80
  >
140
81
  <IconWrapper
141
- v-if="isError && !showLinearUnitName && !isBorderErrorOnly"
82
+ v-if="isError && !showLinearUnitName"
142
83
  :margin-right="showSelect ? selectWidth : 0"
143
84
  size="16px"
144
85
  >
@@ -192,9 +133,7 @@
192
133
  </ArrowButton>
193
134
  </ArrowControls>
194
135
  </InputWrapper>
195
- <ErrorMessage v-if="isError && errorMessage">{{
196
- errorMessage
197
- }}</ErrorMessage>
136
+ <ErrorMessage v-if="isError && errorMessage">{{ errorMessage }}</ErrorMessage>
198
137
  </Container>
199
138
  </template>
200
139
 
@@ -265,8 +204,6 @@
265
204
  colorMode: String,
266
205
  showArrowControls: Boolean,
267
206
  readOnly: Boolean,
268
- isBorderErrorOnly: Boolean,
269
- isInfoBorder: Boolean,
270
207
  }
271
208
 
272
209
  const Container = styled('div', inputProps)`
@@ -279,9 +216,7 @@
279
216
 
280
217
  const InputContainer = styled('input', inputProps)`
281
218
  border: ${(props) =>
282
- props.isInfoBorder
283
- ? '1px solid ' + props.theme.semanticColors.blue[500]
284
- : props.isError
219
+ props.isError
285
220
  ? '1px solid ' + props.theme.colors.red
286
221
  : props.noBorder
287
222
  ? 'none'
@@ -300,17 +235,16 @@
300
235
  showLinearUnitName,
301
236
  colorMode,
302
237
  showArrowControls,
303
- isBorderErrorOnly,
304
238
  }) =>
305
239
  showArrowControls
306
240
  ? '40px'
307
241
  : colorMode === 'transparent'
308
242
  ? '0'
309
243
  : slotSize
310
- ? isError && !showLinearUnitName && !isBorderErrorOnly
244
+ ? isError && !showLinearUnitName
311
245
  ? 'calc(' + slotSize + ' + 24px)'
312
246
  : 'calc(' + slotSize + ' + 10px)'
313
- : isError && !showLinearUnitName && !isBorderErrorOnly
247
+ : isError && !showLinearUnitName
314
248
  ? '24px'
315
249
  : '5px'};
316
250
  border-radius: ${(props) =>
@@ -723,12 +657,18 @@
723
657
  required: false,
724
658
  default: '',
725
659
  },
660
+ labelDataTestId: {
661
+ type: String,
662
+ required: false,
663
+ default: '',
664
+ },
726
665
  inputDataId: {
727
666
  type: String,
728
667
  required: false,
729
668
  default: '',
730
669
  },
731
670
  dataQaId: {
671
+ type: String,
732
672
  required: false,
733
673
  default: '',
734
674
  },
@@ -764,18 +704,6 @@
764
704
  type: Boolean,
765
705
  default: false,
766
706
  },
767
- isBorderErrorOnly: {
768
- type: Boolean,
769
- default: false,
770
- },
771
- isInfoBorder: {
772
- type: Boolean,
773
- default: false,
774
- },
775
- inputInfoText: {
776
- type: String,
777
- default: '',
778
- },
779
707
  },
780
708
  data() {
781
709
  return {
@@ -5,7 +5,8 @@
5
5
  :has-info-text="!!infoText"
6
6
  :margin-bottom="marginBottom"
7
7
  >
8
- <span data-test-id="page_subtitle_text">
8
+ <span v-if="containsHtml" data-test-id="page_subtitle_text" v-html="text"></span>
9
+ <span v-else data-test-id="page_subtitle_text">
9
10
  {{ text }}
10
11
  </span>
11
12
  <InfoText
@@ -58,6 +59,11 @@
58
59
  required: true,
59
60
  type: String,
60
61
  },
62
+ containsHtml: {
63
+ required: false,
64
+ type: Boolean,
65
+ default: false,
66
+ },
61
67
  color: {
62
68
  required: false,
63
69
  type: String,
@@ -46,6 +46,7 @@
46
46
  color: ${(props) => (props.color ? props.color : props.theme.colors.black)};
47
47
  font-weight: 600;
48
48
  font-size: ${(props) => (props.fontSize ? props.fontSize : '20px')};
49
+ text-transform: ${(props) => (props.uppercase ? 'uppercase' : 'none')};
49
50
  `
50
51
 
51
52
  export default {
package/src/TestChart.vue DELETED
@@ -1,229 +0,0 @@
1
- <template>
2
- <div
3
- style="
4
- margin-top: 100px;
5
- margin-left: 80px;
6
- padding-bottom: 100px;
7
- display: flex;
8
- flex-direction: column;
9
- "
10
- >
11
- <!-- Simple bar chart -->
12
- <BarChart
13
- :bar-width="60"
14
- chart-controls-position="bottom"
15
- :data="monthlyData"
16
- height="400px"
17
- :is-bottom-fields-shown="true"
18
- :is-scrollable="false"
19
- :is-selection-enabled="true"
20
- :selection-size="3"
21
- :value-formatter="valueFormatter"
22
- width="700px"
23
- @selection-change="handleSelectionChange"
24
- />
25
- <br />
26
- <br />
27
-
28
- <!-- Stacked bar chart -->
29
- <BarChart
30
- :bar-width="60"
31
- :data="monthLabels"
32
- height="400px"
33
- :is-bottom-fields-shown="true"
34
- :is-legend-shown="true"
35
- :legends-item-per-row="4"
36
- :selected-split-button="selectedTimeFrame"
37
- :series="tariffZones"
38
- :show-percentage-on-tooltip="true"
39
- :split-button-options="options"
40
- :value-formatter="valueFormatter"
41
- width="700px"
42
- y-axis-title="Energy (kWh)"
43
- @input-blur="handleInputBlur"
44
- @select-split-button="handleSelectSplitButton"
45
- />
46
-
47
- <!-- Stacked bar chart -->
48
- <BarChart
49
- :bar-width="60"
50
- :data="monthLabels"
51
- field-mode="percentage"
52
- height="400px"
53
- :is-bottom-fields-shown="true"
54
- :is-legend-shown="false"
55
- :legends-item-per-row="4"
56
- :series="tariffZones"
57
- :value-formatter="valueFormatter"
58
- width="700px"
59
- @input-blur="handleInputBlur"
60
- @select-split-button="handleSelectSplitButton"
61
- >
62
- <!-- <template #tooltip="{ item, segment }">
63
- <div style="display: flex; flex-direction: column">
64
- {{ $c.log(item, segment) }}
65
- <div>{{ item.label }}</div>
66
- <div>{{ item.segments[0].value }} kWh</div>
67
- </div>
68
- </template> -->
69
- </BarChart>
70
- </div>
71
- </template>
72
-
73
- <script setup>
74
- import { ref } from 'vue'
75
- import BarChart from '@/components/barchart/index.vue'
76
-
77
- const options = [
78
- { label: 'Day', value: 'day' },
79
- { label: 'Month', value: 'month' },
80
- { label: 'Year', value: 'year' },
81
- ]
82
-
83
- const selectedTimeFrame = ref('day')
84
-
85
- const handleSelectSplitButton = (value) => {
86
- selectedTimeFrame.value = value
87
- }
88
-
89
- const monthlyData = [
90
- { label: 'Jan', value: 300 },
91
- { label: 'Feb', value: 600 },
92
- { label: 'Mar', value: 1000 },
93
- { label: 'Apr', value: 1200 },
94
- { label: 'May', value: 1400 },
95
- { label: 'Jun', value: 1810 },
96
- { label: 'Jul', value: 1400 },
97
- { label: 'Aug', value: 1200 },
98
- { label: 'Sep', value: 1000 },
99
- // { label: 'Oct', value: 800 },
100
- // { label: 'Nov', value: 600 },
101
- // { label: 'Dec', value: 400 },
102
- // { label: 'Jan', value: 300 },
103
- // { label: 'Feb', value: 600 },
104
- // { label: 'Mar', value: 1000 },
105
- // { label: 'Apr', value: 1200 },
106
- // { label: 'May', value: 1400 },
107
- // { label: 'Jun', value: 1810 },
108
- // { label: 'Jul', value: 1400 },
109
- // { label: 'Aug', value: 1200 },
110
- // { label: 'Sep', value: 1000 },
111
- // { label: 'Oct', value: 800 },
112
- // { label: 'Nov', value: 600 },
113
- // { label: 'Dec', value: 400 },
114
-
115
- // ... more months
116
- ]
117
-
118
- const monthLabels = [
119
- { label: 'Jan' },
120
- { label: 'Feb' },
121
- { label: 'Mar' },
122
- { label: 'Apr' },
123
- { label: 'May' },
124
- { label: 'Jun' },
125
- // ... more months
126
- ]
127
-
128
- const tariffZones = ref([
129
- {
130
- name: 'Tariff Zone 1',
131
- data: [
132
- { label: 'Jan', value: 200 },
133
- { label: 'Feb', value: 130 },
134
- { label: 'Mar', value: 220 },
135
- { label: 'Apr', value: 230 },
136
- { label: 'May', value: 200 },
137
- { label: 'Jun', value: 210 },
138
- // ... more months
139
- ],
140
- },
141
- {
142
- name: 'Tariff Zone 2',
143
- data: [
144
- { label: 'Jan', value: 200 },
145
- { label: 'Feb', value: 100 },
146
- { label: 'Mar', value: 270 },
147
- { label: 'Apr', value: 180 },
148
- { label: 'May', value: 300 },
149
- { label: 'Jun', value: 250 },
150
- // ... more months
151
- ],
152
- },
153
- {
154
- name: 'Tariff Zone 3',
155
- data: [
156
- { label: 'Jan', value: 200 },
157
- { label: 'Feb', value: 100 },
158
- { label: 'Mar', value: 210 },
159
- { label: 'Apr', value: 220 },
160
- { label: 'May', value: 300 },
161
- { label: 'Jun', value: 190 },
162
- // ... more months
163
- ],
164
- },
165
- {
166
- name: 'Tariff Zone 4',
167
- data: [
168
- { label: 'Jan', value: 200 },
169
- { label: 'Feb', value: 100 },
170
- { label: 'Mar', value: 210 },
171
- { label: 'Apr', value: 220 },
172
- { label: 'May', value: 300 },
173
- { label: 'Jun', value: 190 },
174
- // ... more months
175
- ],
176
- },
177
- {
178
- name: 'Tariff Zone 5',
179
- data: [
180
- { label: 'Jan', value: 200 },
181
- { label: 'Feb', value: 100 },
182
- { label: 'Mar', value: 210 },
183
- { label: 'Apr', value: 220 },
184
- { label: 'May', value: 300 },
185
- { label: 'Jun', value: 190 },
186
- // ... more months
187
- ],
188
- },
189
- {
190
- name: 'Tariff Zone 6',
191
- data: [
192
- { label: 'Jan', value: 200 },
193
- { label: 'Feb', value: 100 },
194
- { label: 'Mar', value: 210 },
195
- { label: 'Apr', value: 220 },
196
- { label: 'May', value: 300 },
197
- { label: 'Jun', value: 190 },
198
- // ... more months
199
- ],
200
- },
201
- // ... more tariff zones
202
- ])
203
-
204
- const valueFormatter = (value) => {
205
- return `${value} kWh`
206
- }
207
-
208
- const handleSelectionChange = (selectedBars) => {
209
- console.log('selectedBars', selectedBars)
210
- }
211
-
212
- const handleInputBlur = (payload) => {
213
- const newVal = [...tariffZones.value].map((zone) => {
214
- if (zone.name === payload.seriesName) {
215
- zone.data = zone.data.map((item) => {
216
- if (item.label === payload.label) {
217
- item.value = payload.value
218
- }
219
- return item
220
- })
221
- }
222
- return zone
223
- })
224
-
225
- tariffZones.value = newVal
226
- }
227
- </script>
228
-
229
- <style lang="scss" scoped></style>