@eturnity/eturnity_reusable_components 8.16.9-EPDM-11600.8 → 8.16.9-EPDM-14690.5

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.
@@ -17,8 +17,8 @@
17
17
  />
18
18
  </ChartControlsWrapper>
19
19
  <GraphSection :height="height" :width="width">
20
- <YAxis :width="yAxisWidth">
21
- <YAxisTitleWrapper v-if="yAxisTitle">
20
+ <YAxis :height="height" :width="yAxisWidth">
21
+ <YAxisTitleWrapper v-if="yAxisTitle" :height="yAxisHeight">
22
22
  {{ yAxisTitle }}
23
23
  </YAxisTitleWrapper>
24
24
  <YAxisRow
@@ -30,15 +30,15 @@
30
30
  )
31
31
  "
32
32
  >
33
- <YAxisLabel>{{ label }}</YAxisLabel>
33
+ <YAxisLabel>{{ getYAxisLabel(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
- :is-scrollable="isScrollable"
41
40
  :height="height"
41
+ :is-scrollable="isScrollable"
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"
67
68
  :bar-width="barWidth"
68
69
  class="bar-group"
69
70
  :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"
75
76
  class="bar-segment"
76
77
  :gradient-from="getSegmentGradient(index, segment).from"
77
78
  :gradient-to="getSegmentGradient(index, segment).to"
78
79
  :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" />
99
+ <slot :item="tooltipData" name="tooltip"></slot>
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,7 +128,11 @@
128
128
  :gradient-to="segment.gradientTo"
129
129
  />
130
130
  <TooltipText>
131
- {{ handleValueFormatter(segment.value) }}
131
+ {{
132
+ fieldMode === 'absolute' && showPercentageOnTooltip
133
+ ? `${segment.valuePercentage}%`
134
+ : handleValueFormatter(segment.value)
135
+ }}
132
136
  </TooltipText>
133
137
  </TooltipRow>
134
138
  </template>
@@ -159,6 +163,7 @@
159
163
  :data="data"
160
164
  :field-mode="fieldMode"
161
165
  :is-chart-controls-shown-in-bottom="isChartControlsShown('bottom')"
166
+ :is-inputs-disabled="isLoading"
162
167
  :is-scrollable="isScrollable"
163
168
  :series="series"
164
169
  :y-axis-width="yAxisWidth"
@@ -171,12 +176,13 @@
171
176
  </template>
172
177
 
173
178
  <script setup>
174
- import { useSlots, computed } from 'vue'
179
+ import { useSlots, computed, ref } from 'vue'
175
180
 
176
181
  import ChartControls from './ChartControls'
177
182
  import BottomFields from './BottomFields'
178
183
  import SelectionBox from './SelectionBox'
179
184
  import Spinner from '../spinner'
185
+ import { numberToString } from '../../helpers/numberConverter'
180
186
 
181
187
  import {
182
188
  useTooltip,
@@ -246,10 +252,6 @@
246
252
  type: String,
247
253
  default: '',
248
254
  },
249
- valueFormatter: {
250
- type: Function,
251
- default: null,
252
- },
253
255
  isLegendShown: {
254
256
  type: Boolean,
255
257
  default: false,
@@ -296,6 +298,10 @@
296
298
  type: Boolean,
297
299
  default: false,
298
300
  },
301
+ showPercentageOnTooltip: {
302
+ type: Boolean,
303
+ default: false,
304
+ },
299
305
  })
300
306
 
301
307
  const generateChartId = () =>
@@ -378,8 +384,40 @@
378
384
  }
379
385
 
380
386
  const handleValueFormatter = (value) => {
381
- return props.valueFormatter
382
- ? props.valueFormatter(Math.round(value))
383
- : 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
+ })
384
422
  }
385
423
  </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;
20
21
  font-size: 12px;
21
22
  font-weight: 500;
22
23
  color: ${(props) => props.theme.semanticColors.teal[600]};
23
24
  display: flex;
24
- align-items: flex-start;
25
+ align-items: center;
25
26
  `
26
27
 
27
28
  export const TotalRow = styled(LabelRow)``
28
29
 
29
30
  export const FieldsContainer = styled.div`
30
31
  flex: 1;
31
- overflow-x: auto;
32
32
  scrollbar-width: none;
33
33
 
34
34
  &::-webkit-scrollbar {
@@ -59,8 +59,22 @@ export const InputGroup = styled('div', {
59
59
  barWidth: Number,
60
60
  isScrollable: Boolean,
61
61
  })`
62
- ${(props) => (props.isScrollable ? 'min-width' : 'width')}:${(props) =>
63
- props.barWidth}px;
62
+ ${(props) => (props.isScrollable ? 'min-width' : 'width')}: 70px;
64
63
  display: flex;
65
64
  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;
66
80
  `
@@ -16,9 +16,12 @@ 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 })`
19
+ export const YAxis = styled('div', { width: String, height: String })`
20
20
  width: ${(props) => props.width};
21
+ display: flex;
22
+ flex-direction: column;
21
23
  position: relative;
24
+ height: ${(props) => props.height};
22
25
  `
23
26
 
24
27
  export const YAxisRow = styled('div', { percentage: Number })`
@@ -54,19 +57,18 @@ export const YAxisLine = styled('div', { yAxisWidth: String })`
54
57
  transform: translateY(-50%);
55
58
  `
56
59
 
57
- export const YAxisTitleWrapper = styled('div')`
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;
58
66
  font-size: 12px;
59
- font-weight: 500;
60
- color: ${(props) => props.theme.semanticColors.grey[700]};
61
- white-space: nowrap;
62
- height: 0;
63
- width: 0;
67
+ color: ${(props) => props.theme.semanticColors.teal[600]};
64
68
  display: flex;
65
- align-items: flex-start;
66
- justify-content: center;
67
- position: absolute;
68
- top: 50%;
69
- transform: rotate(-90deg);
69
+ align-items: center;
70
+ white-space: nowrap;
71
+ font-family: ${(props) => props.theme.fonts.mainFont};
70
72
  `
71
73
 
72
74
  export const ScrollContainer = styled('div', {
@@ -125,6 +127,7 @@ export const BarWrapper = styled.div`
125
127
  height: 100%;
126
128
  width: 100%;
127
129
  position: relative;
130
+ overflow: hidden;
128
131
  `
129
132
 
130
133
  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,7 +73,12 @@
73
73
  type: {
74
74
  required: false,
75
75
  type: String,
76
- default: 'info',
76
+ default: 'info_simple',
77
+ validator(value) {
78
+ return ['info_simple', 'warning', 'error_minor', 'info'].includes(
79
+ value
80
+ )
81
+ },
77
82
  },
78
83
  minWidth: {
79
84
  required: false,
@@ -112,8 +117,11 @@
112
117
  },
113
118
  },
114
119
  computed: {
115
- isInfo() {
120
+ isInfoSimple() {
116
121
  // this property is used for tests
122
+ return this.type === 'info_simple'
123
+ },
124
+ isInfo() {
117
125
  return this.type === 'info'
118
126
  },
119
127
  isWarning() {
@@ -123,11 +131,7 @@
123
131
  return this.type === 'error_minor'
124
132
  },
125
133
  iconName() {
126
- return this.type === 'warning'
127
- ? 'warning_triangle'
128
- : this.isErrorMinor
129
- ? 'erase'
130
- : 'info'
134
+ return this.type === 'warning' ? 'warning_triangle' : 'info'
131
135
  },
132
136
  presetStyles() {
133
137
  // the types that doesn't have explicit border anyway have it transparent
@@ -146,11 +150,15 @@
146
150
  stylesCollection.iconColor = theme.semanticColors.teal[800]
147
151
  } else if (this.isErrorMinor) {
148
152
  stylesCollection.borderStyle = 'dashed'
149
- stylesCollection.borderColor = theme.colors.grey4
150
- stylesCollection.iconColor = theme.colors.red
151
- } else {
153
+ stylesCollection.borderColor = theme.colors.pureRed
154
+ stylesCollection.iconColor = theme.colors.pureRed
155
+ } else if (this.isInfoSimple) {
152
156
  stylesCollection.borderStyle = 'dashed'
153
157
  stylesCollection.borderColor = theme.colors.grey4
158
+ } else {
159
+ stylesCollection.color = theme.semanticColors.teal[800]
160
+ stylesCollection.backgroundColor = theme.semanticColors.blue[300]
161
+ stylesCollection.iconColor = theme.semanticColors.teal[800]
154
162
  }
155
163
 
156
164
  return stylesCollection
@@ -45,19 +45,19 @@ describe('RCInfoCard.vue', () => {
45
45
  },
46
46
  })
47
47
 
48
- expect(wrapper.vm.isInfo).toBe(true)
48
+ expect(wrapper.vm.isInfoSimple).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.isInfo).toBe(false)
54
+ expect(wrapper.vm.isInfoSimple).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.isInfo).toBe(false)
60
+ expect(wrapper.vm.isInfoSimple).toBe(false)
61
61
  expect(wrapper.vm.isWarning).toBe(false)
62
62
  expect(wrapper.vm.isErrorMinor).toBe(true)
63
63
  })
@@ -15,37 +15,40 @@
15
15
  :is-disabled="isDisabled"
16
16
  :padding="padding"
17
17
  >
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>
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>
46
49
  </IconWrapper>
47
50
  </div>
48
- <Teleport v-if="isVisible" to="body">
51
+ <Teleport v-if="isVisible && !!text" to="body">
49
52
  <TextWrapper data-test-id="info_text_wrapper" :style="wrapperStyle">
50
53
  <TextOverlay
51
54
  ref="infoBox"
@@ -227,7 +230,7 @@
227
230
  },
228
231
  infoPosition: {
229
232
  required: false,
230
- default: 'bottom',
233
+ default: null,
231
234
  type: String,
232
235
  },
233
236
  maxWidth: {
@@ -363,7 +366,9 @@
363
366
  { position: 'left', space: spaceLeft },
364
367
  ].sort((a, b) => b.space - a.space)
365
368
 
366
- const bestPosition = positions[0].position
369
+ const bestPosition = props.infoPosition
370
+ ? props.infoPosition
371
+ : positions[0].position
367
372
 
368
373
  let top, left, arrowPosition
369
374
 
@@ -3,15 +3,15 @@ import InputNumber from './index.vue'
3
3
  export default {
4
4
  title: 'InputNumber',
5
5
  component: InputNumber,
6
+ // argTypes: {},
6
7
  }
7
8
 
8
- const Template = (args) => ({
9
+ const Template = (args, { argTypes }) => ({
9
10
  // Components used in your story `template` are defined in the `components` object
10
11
  components: { InputNumber },
11
- setup() {
12
- return { args: args }
13
- },
14
- template: `<InputNumber v-bind="args" />`,
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" />',
15
15
 
16
16
  // import InputNumber from "@eturnity/eturnity_reusable_components/src/components/inputs/inputNumber"
17
17
  // How to use:
@@ -73,20 +73,6 @@ Disabled.args = {
73
73
  showLinearUnitName: false,
74
74
  }
75
75
 
76
- export const DisabledAndPreDefined = Template.bind({})
77
- DisabledAndPreDefined.args = {
78
- placeholder: 'Enter Value',
79
- disabled: true,
80
- isPreDefined: true,
81
- value: '',
82
- inputWidth: '200px',
83
- isError: false,
84
- numberPrecision: 0,
85
- noBorder: false,
86
- textAlign: 'left',
87
- showLinearUnitName: false,
88
- }
89
-
90
76
  export const LinearUnit = Template.bind({})
91
77
  LinearUnit.args = {
92
78
  placeholder: 'Enter Value',