@eturnity/eturnity_reusable_components 8.16.9-EPDM-14690.4 → 8.16.9-EPDM-11600.9

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.16.9-EPDM-14690.4",
3
+ "version": "8.16.9-EPDM-11600.9",
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.blue[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() {
@@ -131,7 +123,11 @@
131
123
  return this.type === 'error_minor'
132
124
  },
133
125
  iconName() {
134
- return this.type === 'warning' ? 'warning_triangle' : 'info'
126
+ return this.type === 'warning'
127
+ ? 'warning_triangle'
128
+ : this.isErrorMinor
129
+ ? 'erase'
130
+ : 'info'
135
131
  },
136
132
  presetStyles() {
137
133
  // the types that doesn't have explicit border anyway have it transparent
@@ -149,16 +145,12 @@
149
145
  stylesCollection.backgroundColor = theme.semanticColors.yellow[300]
150
146
  stylesCollection.iconColor = theme.semanticColors.teal[800]
151
147
  } else if (this.isErrorMinor) {
152
- stylesCollection.borderStyle = 'dashed'
153
- stylesCollection.borderColor = theme.colors.pureRed
154
- stylesCollection.iconColor = theme.colors.pureRed
155
- } else if (this.isInfoSimple) {
156
148
  stylesCollection.borderStyle = 'dashed'
157
149
  stylesCollection.borderColor = theme.colors.grey4
150
+ stylesCollection.iconColor = theme.colors.red
158
151
  } else {
159
- stylesCollection.color = theme.semanticColors.teal[800]
160
- stylesCollection.backgroundColor = theme.semanticColors.blue[300]
161
- stylesCollection.iconColor = theme.semanticColors.teal[800]
152
+ stylesCollection.borderStyle = 'dashed'
153
+ stylesCollection.borderColor = theme.colors.grey4
162
154
  }
163
155
 
164
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
  })
@@ -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:
@@ -43,23 +43,19 @@
43
43
  :color-mode="colorMode"
44
44
  :data-id="inputDataId"
45
45
  :data-qa-id="dataQaId"
46
- :disabled="disabled"
47
46
  :font-color="colorMode === 'transparent' ? 'white' : fontColor"
48
47
  :font-size="fontSize"
49
48
  :has-label-slot="hasLabelSlot"
50
49
  :has-slot="hasSlot"
51
50
  :has-unit="unitName && !!unitName.length"
52
51
  :input-height="inputHeight"
53
- :is-border-error-only="isBorderErrorOnly"
54
52
  :is-disabled="disabled"
55
53
  :is-error="isError"
56
- :is-info-border="isInfoBorder"
57
54
  :is-interactive="isInteractive"
58
55
  :min-width="minWidth"
59
56
  :no-border="noBorder"
60
57
  :placeholder="displayedPlaceholder"
61
58
  :read-only="isReadOnly"
62
- :readonly="isReadOnly"
63
59
  :show-arrow-controls="showArrowControls"
64
60
  :show-linear-unit-name="showLinearUnitName"
65
61
  :slot-size="slotSize"
@@ -83,7 +79,7 @@
83
79
  >{{ unitName }}</UnitContainer
84
80
  >
85
81
  <IconWrapper
86
- v-if="isError && !showLinearUnitName && !isBorderErrorOnly"
82
+ v-if="isError && !showLinearUnitName"
87
83
  :margin-right="showSelect ? selectWidth : 0"
88
84
  size="16px"
89
85
  >
@@ -137,9 +133,7 @@
137
133
  </ArrowButton>
138
134
  </ArrowControls>
139
135
  </InputWrapper>
140
- <ErrorMessage v-if="isError && errorMessage">{{
141
- errorMessage
142
- }}</ErrorMessage>
136
+ <ErrorMessage v-if="isError && errorMessage">{{ errorMessage }}</ErrorMessage>
143
137
  </Container>
144
138
  </template>
145
139
 
@@ -210,8 +204,6 @@
210
204
  colorMode: String,
211
205
  showArrowControls: Boolean,
212
206
  readOnly: Boolean,
213
- isBorderErrorOnly: Boolean,
214
- isInfoBorder: Boolean,
215
207
  }
216
208
 
217
209
  const Container = styled('div', inputProps)`
@@ -224,9 +216,7 @@
224
216
 
225
217
  const InputContainer = styled('input', inputProps)`
226
218
  border: ${(props) =>
227
- props.isInfoBorder
228
- ? '1px solid ' + props.theme.semanticColors.blue[500]
229
- : props.isError
219
+ props.isError
230
220
  ? '1px solid ' + props.theme.colors.red
231
221
  : props.noBorder
232
222
  ? 'none'
@@ -245,17 +235,16 @@
245
235
  showLinearUnitName,
246
236
  colorMode,
247
237
  showArrowControls,
248
- isBorderErrorOnly,
249
238
  }) =>
250
239
  showArrowControls
251
240
  ? '40px'
252
241
  : colorMode === 'transparent'
253
242
  ? '0'
254
243
  : slotSize
255
- ? isError && !showLinearUnitName && !isBorderErrorOnly
244
+ ? isError && !showLinearUnitName
256
245
  ? 'calc(' + slotSize + ' + 24px)'
257
246
  : 'calc(' + slotSize + ' + 10px)'
258
- : isError && !showLinearUnitName && !isBorderErrorOnly
247
+ : isError && !showLinearUnitName
259
248
  ? '24px'
260
249
  : '5px'};
261
250
  border-radius: ${(props) =>
@@ -667,12 +656,18 @@
667
656
  required: false,
668
657
  default: '',
669
658
  },
659
+ labelDataTestId: {
660
+ type: String,
661
+ required: false,
662
+ default: '',
663
+ },
670
664
  inputDataId: {
671
665
  type: String,
672
666
  required: false,
673
667
  default: '',
674
668
  },
675
669
  dataQaId: {
670
+ type: String,
676
671
  required: false,
677
672
  default: '',
678
673
  },
@@ -708,14 +703,6 @@
708
703
  type: Boolean,
709
704
  default: false,
710
705
  },
711
- isBorderErrorOnly: {
712
- type: Boolean,
713
- default: false,
714
- },
715
- isInfoBorder: {
716
- type: Boolean,
717
- default: false,
718
- },
719
706
  },
720
707
  data() {
721
708
  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,
@@ -1,8 +1,8 @@
1
1
  <template>
2
2
  <TitleWrap data-test-id="page_wrapper" :has-info-text="!!infoText">
3
3
  <TitleText
4
- :color="color"
5
4
  data-test-id="page_title_text"
5
+ :color="color"
6
6
  :font-size="fontSize"
7
7
  :uppercase="uppercase"
8
8
  >
@@ -10,8 +10,8 @@
10
10
  </TitleText>
11
11
  <InfoText
12
12
  v-if="!!infoText"
13
- :align-arrow="infoAlign"
14
13
  data-test-id="page_title_tooltip"
14
+ :align-arrow="infoAlign"
15
15
  :text="infoText"
16
16
  />
17
17
  </TitleWrap>
@@ -44,8 +44,9 @@
44
44
  const titleAttrs = { color: String, fontSize: String, uppercase: Boolean }
45
45
  const TitleText = styled('span', titleAttrs)`
46
46
  color: ${(props) => (props.color ? props.color : props.theme.colors.black)};
47
- font-weight: 500;
47
+ font-weight: bold;
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>