@scality/core-ui 0.168.0 → 0.169.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/.github/workflows/github-pages.yml +5 -3
- package/.storybook/preview.js +1 -0
- package/dist/components/barchartv2/Barchart.component.d.ts.map +1 -1
- package/dist/components/barchartv2/Barchart.component.js +6 -5
- package/dist/components/barchartv2/ChartTooltip.d.ts +9 -13
- package/dist/components/barchartv2/ChartTooltip.d.ts.map +1 -1
- package/dist/components/barchartv2/ChartTooltip.js +14 -4
- package/dist/components/barchartv2/utils.d.ts +9 -2
- package/dist/components/barchartv2/utils.d.ts.map +1 -1
- package/dist/components/barchartv2/utils.js +12 -16
- package/dist/components/buttonv2/Buttonv2.component.d.ts.map +1 -1
- package/dist/components/buttonv2/Buttonv2.component.js +27 -6
- package/dist/components/date/FormattedDateTime.d.ts +15 -1
- package/dist/components/date/FormattedDateTime.d.ts.map +1 -1
- package/dist/components/date/FormattedDateTime.js +25 -0
- package/dist/components/linetimeseriechart/linetimeseriechart.component.d.ts.map +1 -1
- package/dist/components/linetimeseriechart/linetimeseriechart.component.js +30 -32
- package/dist/components/linetimeseriechart/utils.d.ts +16 -0
- package/dist/components/linetimeseriechart/utils.d.ts.map +1 -0
- package/dist/components/linetimeseriechart/utils.js +28 -0
- package/dist/style/theme.d.ts +2 -2
- package/dist/style/theme.d.ts.map +1 -1
- package/dist/style/theme.js +26 -0
- package/package.json +5 -4
- package/src/lib/components/barchartv2/Barchart.component.test.tsx +1 -1
- package/src/lib/components/barchartv2/Barchart.component.tsx +14 -6
- package/src/lib/components/barchartv2/ChartTooltip.test.tsx +119 -0
- package/src/lib/components/barchartv2/ChartTooltip.tsx +49 -19
- package/src/lib/components/barchartv2/utils.test.ts +29 -44
- package/src/lib/components/barchartv2/utils.ts +22 -29
- package/src/lib/components/buttonv2/Buttonv2.component.tsx +27 -6
- package/src/lib/components/date/FormattedDateTime.tsx +30 -1
- package/src/lib/components/linetimeseriechart/linetimeseriechart.component.tsx +61 -57
- package/src/lib/components/linetimeseriechart/linetimeseriechart.test.tsx +58 -55
- package/src/lib/components/linetimeseriechart/utils.test.ts +87 -0
- package/src/lib/components/linetimeseriechart/utils.ts +43 -0
- package/src/lib/style/theme.ts +26 -0
- package/stories/BarChart/barchart.stories.tsx +1 -1
- package/stories/color.mdx +12 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"theme.d.ts","sourceRoot":"","sources":["../../src/lib/style/theme.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,OAAO,YAAY,CAAC;AACjC,eAAO,MAAM,IAAI,YAAY,CAAC;AAC9B,eAAO,MAAM,SAAS,YAAY,CAAC;AACnC,eAAO,MAAM,IAAI,YAAY,CAAC;AAC9B,eAAO,MAAM,IAAI,YAAY,CAAC;AAC9B,eAAO,MAAM,UAAU,YAAY,CAAC;AACpC,eAAO,MAAM,OAAO,YAAY,CAAC;AACjC,eAAO,MAAM,SAAS,YAAY,CAAC;AACnC,eAAO,MAAM,YAAY,YAAY,CAAC;AACtC,eAAO,MAAM,YAAY,YAAY,CAAC;AACtC,eAAO,MAAM,MAAM,YAAY,CAAC;AAChC,eAAO,MAAM,KAAK,YAAY,CAAC;AAC/B,eAAO,MAAM,KAAK,YAAY,CAAC;AAC/B,eAAO,MAAM,KAAK,YAAY,CAAC;AAC/B,eAAO,MAAM,UAAU,YAAY,CAAC;AACpC,eAAO,MAAM,WAAW,YAAY,CAAC;AACrC,eAAO,MAAM,UAAU,YAAY,CAAC;AACpC,eAAO,MAAM,QAAQ,YAAY,CAAC;AAClC,eAAO,MAAM,IAAI,YAAY,CAAC;AAC9B,eAAO,MAAM,SAAS,YAAY,CAAC;AACnC,eAAO,MAAM,WAAW,YAAY,CAAC;AACrC,eAAO,MAAM,YAAY,YAAY,CAAC;AACtC,eAAO,MAAM,WAAW,YAAY,CAAC;AACrC,eAAO,MAAM,UAAU,YAAY,CAAC;AACpC,eAAO,MAAM,QAAQ,YAAY,CAAC;AAClC,eAAO,MAAM,IAAI,YAAY,CAAC;AAC9B,eAAO,MAAM,SAAS,YAAY,CAAC;AACnC,eAAO,MAAM,WAAW,YAAY,CAAC;AACrC,eAAO,MAAM,YAAY,YAAY,CAAC;AAEtC,MAAM,MAAM,WAAW,GAAG;IACxB,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;IACzB,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;IACzB,cAAc,EAAE,MAAM,CAAC;IACvB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;IACzB,gBAAgB,EAAE,MAAM,CAAC;IACzB,gBAAgB,EAAE,MAAM,CAAC;IACzB,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,eAAO,MAAM,0BAA0B,
|
|
1
|
+
{"version":3,"file":"theme.d.ts","sourceRoot":"","sources":["../../src/lib/style/theme.ts"],"names":[],"mappings":"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"}
|
package/dist/style/theme.js
CHANGED
|
@@ -33,6 +33,7 @@ export const coreUIAvailableThemesNames = [
|
|
|
33
33
|
'darkRebrand',
|
|
34
34
|
'artescaLight',
|
|
35
35
|
'ring9dark',
|
|
36
|
+
'G-Dark'
|
|
36
37
|
];
|
|
37
38
|
export const coreUIAvailableThemes = {
|
|
38
39
|
darkRebrand: {
|
|
@@ -110,6 +111,31 @@ export const coreUIAvailableThemes = {
|
|
|
110
111
|
textReverse: '#000000',
|
|
111
112
|
textLink: '#71AEFF',
|
|
112
113
|
},
|
|
114
|
+
'G-Dark': {
|
|
115
|
+
statusHealthy: '#0AADA6',
|
|
116
|
+
statusHealthyRGB: '10,173,166',
|
|
117
|
+
statusWarning: '#F8F32B',
|
|
118
|
+
statusWarningRGB: '248,243,43',
|
|
119
|
+
statusCritical: '#E84855',
|
|
120
|
+
statusCriticalRGB: '232,72,85',
|
|
121
|
+
selectedActive: '#037AFF',
|
|
122
|
+
highlight: '#1A3C75',
|
|
123
|
+
border: '#4A4A4A',
|
|
124
|
+
buttonPrimary: 'linear-gradient(130deg, #9355E7 0%, #2E4AA3 100%)',
|
|
125
|
+
buttonSecondary: 'linear-gradient(130deg, #595A78 0%, #44455F 100%)',
|
|
126
|
+
buttonDelete: '#3D0808',
|
|
127
|
+
infoPrimary: '#8E8EAC',
|
|
128
|
+
infoSecondary: '#333366',
|
|
129
|
+
backgroundLevel1: '#121219',
|
|
130
|
+
backgroundLevel2: '#323245',
|
|
131
|
+
backgroundLevel3: '#232331',
|
|
132
|
+
backgroundLevel4: '#1B1B27',
|
|
133
|
+
textPrimary: '#EAEAEA',
|
|
134
|
+
textSecondary: '#B5B5B5',
|
|
135
|
+
textTertiary: '#DFDFDF',
|
|
136
|
+
textReverse: '#000000',
|
|
137
|
+
textLink: '#71AEFF',
|
|
138
|
+
},
|
|
113
139
|
};
|
|
114
140
|
/**
|
|
115
141
|
* @deprecated
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@scality/core-ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.169.0",
|
|
4
4
|
"description": "Scality common React component library",
|
|
5
5
|
"author": "Scality Engineering",
|
|
6
6
|
"license": "SEE LICENSE IN LICENSE",
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"test": "jest",
|
|
23
23
|
"storybook": "storybook dev -p 3000",
|
|
24
24
|
"build-storybook": "storybook build",
|
|
25
|
-
"storybook:deploy": "storybook-
|
|
25
|
+
"storybook:deploy": "npm run build-storybook && gh-pages -d storybook-static -u \"github-actions-bot <support+actions@github.com>\""
|
|
26
26
|
},
|
|
27
27
|
"keywords": [],
|
|
28
28
|
"browserslist": [
|
|
@@ -67,6 +67,7 @@
|
|
|
67
67
|
"eslint": "^8.15.0",
|
|
68
68
|
"eslint-config-react-app": "^7.0.1",
|
|
69
69
|
"eslint-plugin-storybook": "^0.10.1",
|
|
70
|
+
"gh-pages": "^6.3.0",
|
|
70
71
|
"husky": "^3.0.5",
|
|
71
72
|
"jest": "^30.0.5",
|
|
72
73
|
"jest-canvas-mock": "^2.3.1",
|
|
@@ -84,7 +85,7 @@
|
|
|
84
85
|
},
|
|
85
86
|
"dependencies": {
|
|
86
87
|
"@floating-ui/dom": "^1.6.3",
|
|
87
|
-
"@floating-ui/react": "^0.
|
|
88
|
+
"@floating-ui/react": "^0.27.15",
|
|
88
89
|
"@fortawesome/fontawesome-free": "^5.10.2",
|
|
89
90
|
"@fortawesome/fontawesome-svg-core": "^1.2.35",
|
|
90
91
|
"@fortawesome/free-regular-svg-icons": "^5.15.3",
|
|
@@ -96,7 +97,7 @@
|
|
|
96
97
|
"polished": "3.4.1",
|
|
97
98
|
"pretty-bytes": "^5.6.0",
|
|
98
99
|
"react-dropzone": "^14.2.3",
|
|
99
|
-
"react-hook-form": "^7.
|
|
100
|
+
"react-hook-form": "^7.62.0",
|
|
100
101
|
"react-query": "^3.34.0",
|
|
101
102
|
"react-router": "7.8.1",
|
|
102
103
|
"react-router-dom": "7.8.1",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { render, screen, waitFor } from '@testing-library/react';
|
|
2
2
|
import { getWrapper } from '../../testUtils';
|
|
3
|
-
import { Barchart, CustomTick
|
|
3
|
+
import { Barchart, CustomTick } from './Barchart.component';
|
|
4
4
|
import { ChartLegendWrapper } from '../chartlegend/ChartLegendWrapper';
|
|
5
5
|
import React from 'react';
|
|
6
6
|
|
|
@@ -14,13 +14,14 @@ import styled, { useTheme } from 'styled-components';
|
|
|
14
14
|
import { spacing, Stack, Wrap } from '../../spacing';
|
|
15
15
|
import { chartColors, ChartColors, fontSize } from '../../style/theme';
|
|
16
16
|
import { Box } from '../box/Box';
|
|
17
|
+
import { useChartLegend } from '../chartlegend/ChartLegendWrapper';
|
|
17
18
|
import { ConstrainedText } from '../constrainedtext/Constrainedtext.component';
|
|
19
|
+
import { FormattedDateTime } from '../date/FormattedDateTime';
|
|
18
20
|
import { IconHelp } from '../iconhelper/IconHelper';
|
|
19
21
|
import { Loader } from '../loader/Loader.component';
|
|
20
22
|
import { Text } from '../text/Text.component';
|
|
21
|
-
import {
|
|
22
|
-
import {
|
|
23
|
-
import { FormattedDateTime } from '../date/FormattedDateTime';
|
|
23
|
+
import { ChartTooltip } from './ChartTooltip';
|
|
24
|
+
import { UnitRange, useChartData } from './utils';
|
|
24
25
|
|
|
25
26
|
const CHART_CONSTANTS = {
|
|
26
27
|
TICK_WIDTH_OFFSET: 5,
|
|
@@ -344,6 +345,7 @@ export const Barchart = <T extends BarchartBars>(props: BarchartProps<T>) => {
|
|
|
344
345
|
fill={chartColors[fill] || fill}
|
|
345
346
|
minPointSize={stacked ? 0 : CHART_CONSTANTS.MIN_POINT_SIZE}
|
|
346
347
|
stackId={stackId}
|
|
348
|
+
isAnimationActive={false}
|
|
347
349
|
onMouseOver={() => setHoveredValue(dataKey)}
|
|
348
350
|
onMouseLeave={() => setHoveredValue(undefined)}
|
|
349
351
|
/>
|
|
@@ -390,9 +392,15 @@ export const Barchart = <T extends BarchartBars>(props: BarchartProps<T>) => {
|
|
|
390
392
|
/>
|
|
391
393
|
|
|
392
394
|
<Tooltip
|
|
393
|
-
content={(props: TooltipContentProps<number, string>) =>
|
|
394
|
-
|
|
395
|
-
|
|
395
|
+
content={(props: TooltipContentProps<number, string>) => (
|
|
396
|
+
<ChartTooltip
|
|
397
|
+
type={type}
|
|
398
|
+
colorSet={colorSet}
|
|
399
|
+
tooltipProps={props}
|
|
400
|
+
hoveredValue={hoveredValue}
|
|
401
|
+
tooltip={tooltip}
|
|
402
|
+
/>
|
|
403
|
+
)}
|
|
396
404
|
cursor={false}
|
|
397
405
|
/>
|
|
398
406
|
</BarChart>
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { render, screen } from '@testing-library/react';
|
|
3
|
+
import { ChartTooltip } from './ChartTooltip';
|
|
4
|
+
|
|
5
|
+
const ONE_DAY_IN_MILLISECONDS = 24 * 60 * 60 * 1000;
|
|
6
|
+
const ONE_HOUR_IN_MILLISECONDS = 60 * 60 * 1000;
|
|
7
|
+
const SUCCESS_VALUE = 39;
|
|
8
|
+
const FAILED_VALUE = 13;
|
|
9
|
+
const testTooltipProps = {
|
|
10
|
+
payload: [
|
|
11
|
+
{ name: 'Success', value: SUCCESS_VALUE },
|
|
12
|
+
{ name: 'Failed', value: FAILED_VALUE },
|
|
13
|
+
],
|
|
14
|
+
label: 'Test',
|
|
15
|
+
coordinate: { x: 10, y: 10 },
|
|
16
|
+
active: true,
|
|
17
|
+
accessibilityLayer: false,
|
|
18
|
+
};
|
|
19
|
+
const testTooltip = () => <div>Test Tooltip</div>;
|
|
20
|
+
const date = new Date('2024-07-01T00:00:00').getTime();
|
|
21
|
+
|
|
22
|
+
describe('ChartTooltip', () => {
|
|
23
|
+
const selectors = {
|
|
24
|
+
tooltip: () => screen.queryByText(/Test Tooltip/),
|
|
25
|
+
category: () => screen.queryByText(/Test/),
|
|
26
|
+
success: () => screen.queryByText(/Success/),
|
|
27
|
+
successValue: () => screen.queryByText(SUCCESS_VALUE),
|
|
28
|
+
failed: () => screen.queryByText(/Failed/),
|
|
29
|
+
failedValue: () => screen.queryByText(FAILED_VALUE),
|
|
30
|
+
date: () => screen.queryByText(/Monday, 1 July 2024/),
|
|
31
|
+
time: () => screen.queryByText(/00:00/),
|
|
32
|
+
};
|
|
33
|
+
it('should render the ChartTooltip component', () => {
|
|
34
|
+
render(
|
|
35
|
+
<ChartTooltip
|
|
36
|
+
type={{ type: 'category' }}
|
|
37
|
+
tooltipProps={testTooltipProps}
|
|
38
|
+
hoveredValue="Success"
|
|
39
|
+
tooltip={undefined}
|
|
40
|
+
/>,
|
|
41
|
+
);
|
|
42
|
+
expect(selectors.category()).toBeInTheDocument();
|
|
43
|
+
expect(selectors.success()).toBeInTheDocument();
|
|
44
|
+
expect(selectors.successValue()).toBeInTheDocument();
|
|
45
|
+
expect(selectors.failed()).toBeInTheDocument();
|
|
46
|
+
expect(selectors.failedValue()).toBeInTheDocument();
|
|
47
|
+
});
|
|
48
|
+
it('should render tooltip when tooltip is provided', () => {
|
|
49
|
+
render(
|
|
50
|
+
<ChartTooltip
|
|
51
|
+
type={{ type: 'category' }}
|
|
52
|
+
tooltipProps={testTooltipProps}
|
|
53
|
+
hoveredValue="Success"
|
|
54
|
+
tooltip={testTooltip}
|
|
55
|
+
/>,
|
|
56
|
+
);
|
|
57
|
+
expect(selectors.tooltip()).toBeInTheDocument();
|
|
58
|
+
});
|
|
59
|
+
it('should not render tooltip when tooltipProps is not active', () => {
|
|
60
|
+
render(
|
|
61
|
+
<ChartTooltip
|
|
62
|
+
type={{ type: 'category' }}
|
|
63
|
+
tooltipProps={{ ...testTooltipProps, active: false }}
|
|
64
|
+
hoveredValue="Success"
|
|
65
|
+
tooltip={testTooltip}
|
|
66
|
+
/>,
|
|
67
|
+
);
|
|
68
|
+
expect(selectors.tooltip()).not.toBeInTheDocument();
|
|
69
|
+
});
|
|
70
|
+
it('should render time tooltip when type is time', () => {
|
|
71
|
+
// timestamp for Mon Jul 01 2024 00:00:00 GMT+0000 (Coordinated Universal Time)
|
|
72
|
+
const label = date;
|
|
73
|
+
render(
|
|
74
|
+
<ChartTooltip
|
|
75
|
+
type={{
|
|
76
|
+
type: 'time',
|
|
77
|
+
timeRange: {
|
|
78
|
+
startDate: new Date(),
|
|
79
|
+
endDate: new Date(),
|
|
80
|
+
interval: ONE_DAY_IN_MILLISECONDS,
|
|
81
|
+
},
|
|
82
|
+
}}
|
|
83
|
+
tooltipProps={{ ...testTooltipProps, label }}
|
|
84
|
+
hoveredValue="Success"
|
|
85
|
+
/>,
|
|
86
|
+
);
|
|
87
|
+
|
|
88
|
+
expect(selectors.success()).toBeInTheDocument();
|
|
89
|
+
expect(selectors.successValue()).toBeInTheDocument();
|
|
90
|
+
expect(selectors.failed()).toBeInTheDocument();
|
|
91
|
+
expect(selectors.failedValue()).toBeInTheDocument();
|
|
92
|
+
|
|
93
|
+
expect(selectors.date()).toBeInTheDocument();
|
|
94
|
+
expect(selectors.time()).not.toBeInTheDocument();
|
|
95
|
+
});
|
|
96
|
+
it('should render time tooltip when type is time and interval is one hour', () => {
|
|
97
|
+
const label = date;
|
|
98
|
+
render(
|
|
99
|
+
<ChartTooltip
|
|
100
|
+
type={{
|
|
101
|
+
type: 'time',
|
|
102
|
+
timeRange: {
|
|
103
|
+
startDate: new Date(),
|
|
104
|
+
endDate: new Date(),
|
|
105
|
+
interval: ONE_HOUR_IN_MILLISECONDS,
|
|
106
|
+
},
|
|
107
|
+
}}
|
|
108
|
+
tooltipProps={{ ...testTooltipProps, label }}
|
|
109
|
+
hoveredValue="Success"
|
|
110
|
+
/>,
|
|
111
|
+
);
|
|
112
|
+
expect(selectors.success()).toBeInTheDocument();
|
|
113
|
+
expect(selectors.successValue()).toBeInTheDocument();
|
|
114
|
+
expect(selectors.failed()).toBeInTheDocument();
|
|
115
|
+
expect(selectors.failedValue()).toBeInTheDocument();
|
|
116
|
+
expect(selectors.date()).toBeInTheDocument();
|
|
117
|
+
expect(selectors.time()).toBeInTheDocument();
|
|
118
|
+
});
|
|
119
|
+
});
|
|
@@ -1,10 +1,17 @@
|
|
|
1
1
|
import styled from 'styled-components';
|
|
2
2
|
import { spacing, Stack, Wrap } from '../../spacing';
|
|
3
3
|
import { Text } from '../text/Text.component';
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
BarchartBars,
|
|
6
|
+
BarchartTooltipFn,
|
|
7
|
+
CategoryType,
|
|
8
|
+
TimeType,
|
|
9
|
+
} from './Barchart.component';
|
|
5
10
|
import { fontSize, fontWeight } from '../../style/theme';
|
|
6
11
|
import { LegendShape } from '../chartlegend/ChartLegend';
|
|
7
12
|
import { FormattedDateTime } from '../date/FormattedDateTime';
|
|
13
|
+
import { TooltipContentProps } from 'recharts';
|
|
14
|
+
import { getCurrentPoint } from './utils';
|
|
8
15
|
|
|
9
16
|
export const ChartTooltipContainer = styled.div`
|
|
10
17
|
background-color: ${({ theme }) => theme.backgroundLevel1};
|
|
@@ -30,24 +37,45 @@ export const ChartTooltipItem = styled.div<{ isHovered: boolean }>`
|
|
|
30
37
|
|
|
31
38
|
export const ChartTooltip = <T extends BarchartBars>({
|
|
32
39
|
type,
|
|
33
|
-
|
|
40
|
+
tooltipProps,
|
|
34
41
|
colorSet,
|
|
42
|
+
hoveredValue,
|
|
43
|
+
tooltip,
|
|
35
44
|
}: {
|
|
36
|
-
type:
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
colorSet: Record<string, string>;
|
|
45
|
+
type: TimeType | CategoryType;
|
|
46
|
+
tooltipProps: TooltipContentProps<number, string>;
|
|
47
|
+
colorSet?: Record<string, string>;
|
|
48
|
+
hoveredValue: string | undefined;
|
|
49
|
+
tooltip?: BarchartTooltipFn<T>;
|
|
42
50
|
}) => {
|
|
51
|
+
const { active } = tooltipProps;
|
|
52
|
+
|
|
53
|
+
if (!active) {
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const currentPoint = getCurrentPoint(tooltipProps, hoveredValue);
|
|
58
|
+
if (tooltip) {
|
|
59
|
+
return tooltip(currentPoint);
|
|
60
|
+
}
|
|
61
|
+
|
|
43
62
|
return (
|
|
44
63
|
<ChartTooltipContainer>
|
|
45
64
|
<Text isEmphazed>
|
|
46
|
-
{type === 'time' ? (
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
65
|
+
{type.type === 'time' ? (
|
|
66
|
+
<>
|
|
67
|
+
<FormattedDateTime
|
|
68
|
+
format="long-date"
|
|
69
|
+
value={new Date(currentPoint.category)}
|
|
70
|
+
/>{' '}
|
|
71
|
+
{type.type === 'time' &&
|
|
72
|
+
type.timeRange.interval < 24 * 60 * 60 * 1000 && (
|
|
73
|
+
<FormattedDateTime
|
|
74
|
+
format="time"
|
|
75
|
+
value={new Date(currentPoint.category)}
|
|
76
|
+
/>
|
|
77
|
+
)}
|
|
78
|
+
</>
|
|
51
79
|
) : (
|
|
52
80
|
currentPoint.category
|
|
53
81
|
)}
|
|
@@ -55,13 +83,15 @@ export const ChartTooltip = <T extends BarchartBars>({
|
|
|
55
83
|
<Stack direction="vertical" gap="r8" style={{ width: '100%' }}>
|
|
56
84
|
{currentPoint.values.map((value) => {
|
|
57
85
|
return (
|
|
58
|
-
<Wrap key={value.label}>
|
|
86
|
+
<Wrap key={value.label} gap={spacing.r32}>
|
|
59
87
|
<ChartTooltipItem isHovered={value.isHovered}>
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
88
|
+
{colorSet && (
|
|
89
|
+
<LegendShape
|
|
90
|
+
color={colorSet[value.label as keyof typeof colorSet]}
|
|
91
|
+
shape="rectangle"
|
|
92
|
+
chartColors={colorSet}
|
|
93
|
+
/>
|
|
94
|
+
)}
|
|
65
95
|
{value.label}
|
|
66
96
|
</ChartTooltipItem>
|
|
67
97
|
<ChartTooltipItem isHovered={value.isHovered}>
|
|
@@ -4,9 +4,9 @@ import {
|
|
|
4
4
|
computeUnitLabelAndRoundReferenceValue,
|
|
5
5
|
filterChartDataAndBarsByLegendSelection,
|
|
6
6
|
formatPrometheusDataToRechartsDataAndBars,
|
|
7
|
+
getCurrentPoint,
|
|
7
8
|
getMaxBarValue,
|
|
8
9
|
getRoundReferenceValue,
|
|
9
|
-
renderTooltipContent,
|
|
10
10
|
sortStackedBars,
|
|
11
11
|
transformCategoryData,
|
|
12
12
|
transformTimeData,
|
|
@@ -770,53 +770,38 @@ describe('sortStackedBars', () => {
|
|
|
770
770
|
});
|
|
771
771
|
});
|
|
772
772
|
|
|
773
|
-
describe('
|
|
774
|
-
it('should return
|
|
775
|
-
const
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
active: true,
|
|
801
|
-
payload: [
|
|
802
|
-
{ name: 'Success', value: 10 },
|
|
803
|
-
{ name: 'Failed', value: 20 },
|
|
804
|
-
],
|
|
805
|
-
label: 'Test',
|
|
806
|
-
coordinate: { x: 0, y: 0 },
|
|
807
|
-
accessibilityLayer: false,
|
|
808
|
-
};
|
|
809
|
-
renderTooltipContent(props, tooltip, 'Success');
|
|
810
|
-
expect(tooltip).toHaveBeenCalledWith({
|
|
773
|
+
describe('getCurrentPoint', () => {
|
|
774
|
+
it('should return the current point', () => {
|
|
775
|
+
const result = getCurrentPoint(
|
|
776
|
+
{
|
|
777
|
+
payload: [{ name: 'Success', value: 10 }],
|
|
778
|
+
label: 'Test',
|
|
779
|
+
coordinate: { x: 10, y: 10 },
|
|
780
|
+
active: true,
|
|
781
|
+
accessibilityLayer: false,
|
|
782
|
+
},
|
|
783
|
+
'Success',
|
|
784
|
+
);
|
|
785
|
+
expect(result).toEqual({
|
|
786
|
+
category: 'Test',
|
|
787
|
+
values: [{ label: 'Success', value: 10, isHovered: true }],
|
|
788
|
+
});
|
|
789
|
+
const result2 = getCurrentPoint(
|
|
790
|
+
{
|
|
791
|
+
payload: [{ name: 'Success', value: 10 }],
|
|
792
|
+
label: 'Test',
|
|
793
|
+
coordinate: { x: 10, y: 10 },
|
|
794
|
+
active: true,
|
|
795
|
+
accessibilityLayer: false,
|
|
796
|
+
},
|
|
797
|
+
'Failed',
|
|
798
|
+
);
|
|
799
|
+
expect(result2).toEqual({
|
|
811
800
|
category: 'Test',
|
|
812
|
-
values: [
|
|
813
|
-
{ label: 'Success', value: 10, isHovered: true },
|
|
814
|
-
{ label: 'Failed', value: 20, isHovered: false },
|
|
815
|
-
],
|
|
801
|
+
values: [{ label: 'Success', value: 10, isHovered: false }],
|
|
816
802
|
});
|
|
817
803
|
});
|
|
818
804
|
});
|
|
819
|
-
|
|
820
805
|
describe('filterChartDataAndBarsByLegendSelection', () => {
|
|
821
806
|
const mockChartData = [
|
|
822
807
|
{ category: 'Jan', Success: 10, Failed: 5, Warning: 3, Pending: 2 },
|
|
@@ -428,35 +428,6 @@ export const sortStackedBars = (
|
|
|
428
428
|
return barAverages.map(({ average, ...bar }) => bar);
|
|
429
429
|
};
|
|
430
430
|
|
|
431
|
-
export const renderTooltipContent = <T extends BarchartBars>(
|
|
432
|
-
props: TooltipContentProps<number, string>,
|
|
433
|
-
tooltip: BarchartTooltipFn<T> | undefined,
|
|
434
|
-
hoveredValue: string | undefined,
|
|
435
|
-
) => {
|
|
436
|
-
const { active, payload, label } = props;
|
|
437
|
-
|
|
438
|
-
if (!active || !tooltip) {
|
|
439
|
-
return null;
|
|
440
|
-
}
|
|
441
|
-
|
|
442
|
-
const tooltipValues: {
|
|
443
|
-
label: T[number]['label'];
|
|
444
|
-
value: number;
|
|
445
|
-
isHovered: boolean;
|
|
446
|
-
}[] = payload.map((item) => ({
|
|
447
|
-
label: item.name,
|
|
448
|
-
value: item.value,
|
|
449
|
-
isHovered: item.name === hoveredValue,
|
|
450
|
-
}));
|
|
451
|
-
|
|
452
|
-
const currentPoint = {
|
|
453
|
-
category: label as string | number,
|
|
454
|
-
values: tooltipValues,
|
|
455
|
-
};
|
|
456
|
-
|
|
457
|
-
return tooltip(currentPoint);
|
|
458
|
-
};
|
|
459
|
-
|
|
460
431
|
/**
|
|
461
432
|
* Filters both chart data and recharts bars to only include selected resources from legend
|
|
462
433
|
* @param data - Array of chart data objects with category and resource values
|
|
@@ -538,3 +509,25 @@ export const useChartData = <T extends BarchartBars>(
|
|
|
538
509
|
rechartsData,
|
|
539
510
|
};
|
|
540
511
|
};
|
|
512
|
+
|
|
513
|
+
export const getCurrentPoint = <T extends BarchartBars>(
|
|
514
|
+
props: TooltipContentProps<number, string>,
|
|
515
|
+
hoveredValue: string | undefined,
|
|
516
|
+
) => {
|
|
517
|
+
const { payload, label } = props;
|
|
518
|
+
|
|
519
|
+
const tooltipValues: {
|
|
520
|
+
label: T[number]['label'];
|
|
521
|
+
value: number;
|
|
522
|
+
isHovered: boolean;
|
|
523
|
+
}[] = payload.map((item) => ({
|
|
524
|
+
label: item.name,
|
|
525
|
+
value: item.value,
|
|
526
|
+
isHovered: item.name === hoveredValue,
|
|
527
|
+
}));
|
|
528
|
+
|
|
529
|
+
return {
|
|
530
|
+
category: label as string | number,
|
|
531
|
+
values: tooltipValues,
|
|
532
|
+
};
|
|
533
|
+
};
|
|
@@ -51,8 +51,10 @@ export const ButtonStyled = styled.button<Props>`
|
|
|
51
51
|
switch (props.variant) {
|
|
52
52
|
case 'primary':
|
|
53
53
|
return css`
|
|
54
|
-
background
|
|
55
|
-
|
|
54
|
+
background: ${brand.buttonPrimary};
|
|
55
|
+
background-clip: padding-box, border-box;
|
|
56
|
+
border: ${spacing.r1} solid transparent;
|
|
57
|
+
border-color: ${brand.buttonPrimary};
|
|
56
58
|
color: ${brand.textPrimary};
|
|
57
59
|
&:hover:enabled {
|
|
58
60
|
cursor: pointer;
|
|
@@ -73,8 +75,10 @@ export const ButtonStyled = styled.button<Props>`
|
|
|
73
75
|
|
|
74
76
|
case 'secondary':
|
|
75
77
|
return css`
|
|
76
|
-
background
|
|
77
|
-
|
|
78
|
+
background: ${brand.buttonSecondary};
|
|
79
|
+
background-clip: padding-box, border-box;
|
|
80
|
+
border: ${spacing.r1} solid transparent;
|
|
81
|
+
border-color: ${brand.buttonSecondary};
|
|
78
82
|
color: ${brand.textPrimary};
|
|
79
83
|
&:hover:enabled {
|
|
80
84
|
cursor: pointer;
|
|
@@ -88,7 +92,8 @@ export const ButtonStyled = styled.button<Props>`
|
|
|
88
92
|
&:active:enabled {
|
|
89
93
|
cursor: pointer;
|
|
90
94
|
color: ${brand.textPrimary};
|
|
91
|
-
border: ${spacing.r1} solid
|
|
95
|
+
border: ${spacing.r1} solid transparent;
|
|
96
|
+
border-color: ${brand.buttonSecondary};
|
|
92
97
|
}
|
|
93
98
|
`;
|
|
94
99
|
|
|
@@ -112,13 +117,18 @@ export const ButtonStyled = styled.button<Props>`
|
|
|
112
117
|
|
|
113
118
|
case 'outline':
|
|
114
119
|
return css`
|
|
115
|
-
border: ${spacing.r1} solid
|
|
120
|
+
border: ${spacing.r1} solid transparent;
|
|
121
|
+
border-color: ${brand.buttonSecondary};
|
|
116
122
|
background-color: transparent;
|
|
117
123
|
color: ${brand.textPrimary};
|
|
118
124
|
&:hover:enabled {
|
|
119
125
|
cursor: pointer;
|
|
120
126
|
border-color: ${brand.infoPrimary};
|
|
121
127
|
color: ${brand.textPrimary};
|
|
128
|
+
|
|
129
|
+
&::before {
|
|
130
|
+
background-image: ${brand.buttonPrimary};
|
|
131
|
+
}
|
|
122
132
|
}
|
|
123
133
|
&:focus-visible:enabled {
|
|
124
134
|
${FocusVisibleStyle}
|
|
@@ -129,6 +139,17 @@ export const ButtonStyled = styled.button<Props>`
|
|
|
129
139
|
border: ${spacing.r1} solid ${brand.infoSecondary};
|
|
130
140
|
color: ${brand.textPrimary};
|
|
131
141
|
}
|
|
142
|
+
&::before {
|
|
143
|
+
content: '';
|
|
144
|
+
position: absolute;
|
|
145
|
+
inset: 0;
|
|
146
|
+
padding: ${spacing.r1};
|
|
147
|
+
background-image: ${brand.buttonSecondary};
|
|
148
|
+
border-radius: inherit;
|
|
149
|
+
mask: linear-gradient(white, white) content-box, linear-gradient(white, white);
|
|
150
|
+
mask-composite: exclude;
|
|
151
|
+
pointer-events: none;
|
|
152
|
+
}
|
|
132
153
|
`;
|
|
133
154
|
|
|
134
155
|
default:
|
|
@@ -8,6 +8,16 @@ export const LONG_DATE_FORMATER = Intl.DateTimeFormat('en-GB', {
|
|
|
8
8
|
day: 'numeric',
|
|
9
9
|
});
|
|
10
10
|
|
|
11
|
+
/**
|
|
12
|
+
* @description Long date formatter, without weekday.
|
|
13
|
+
* @example 01 September 2025
|
|
14
|
+
*/
|
|
15
|
+
export const LONG_DATE_FORMATER_WITHOUT_WEEKDAY = Intl.DateTimeFormat('en-GB', {
|
|
16
|
+
year: 'numeric',
|
|
17
|
+
month: 'long',
|
|
18
|
+
day: '2-digit',
|
|
19
|
+
});
|
|
20
|
+
|
|
11
21
|
export const DATE_FORMATER = Intl.DateTimeFormat('fr-CA', {
|
|
12
22
|
year: 'numeric',
|
|
13
23
|
month: '2-digit',
|
|
@@ -46,6 +56,10 @@ export const DAY_MONTH_ABBREVIATED_HOUR_MINUTE_SECOND = Intl.DateTimeFormat(
|
|
|
46
56
|
},
|
|
47
57
|
);
|
|
48
58
|
|
|
59
|
+
/**
|
|
60
|
+
* @description Day month abbreviated hour minute formatter, without second.
|
|
61
|
+
* @example 15 Sept 14:30
|
|
62
|
+
*/
|
|
49
63
|
export const DAY_MONTH_ABBREVIATED_HOUR_MINUTE = Intl.DateTimeFormat('en-GB', {
|
|
50
64
|
day: 'numeric',
|
|
51
65
|
month: 'short',
|
|
@@ -64,6 +78,15 @@ export const YEAR_MONTH_DAY_FORMATTER = Intl.DateTimeFormat('en-CA', {
|
|
|
64
78
|
day: '2-digit',
|
|
65
79
|
});
|
|
66
80
|
|
|
81
|
+
/**
|
|
82
|
+
* @description Month day formatter, without year. Used for short term date ranges.
|
|
83
|
+
* @example 01-15
|
|
84
|
+
*/
|
|
85
|
+
export const MONTH_DAY_FORMATTER = Intl.DateTimeFormat('en-CA', {
|
|
86
|
+
month: '2-digit',
|
|
87
|
+
day: '2-digit',
|
|
88
|
+
});
|
|
89
|
+
|
|
67
90
|
type FormattedDateTimeProps = {
|
|
68
91
|
format:
|
|
69
92
|
| 'date'
|
|
@@ -75,8 +98,10 @@ type FormattedDateTimeProps = {
|
|
|
75
98
|
| 'day-month-abbreviated-hour-minute'
|
|
76
99
|
| 'day-month-abbreviated-hour-minute-second'
|
|
77
100
|
| 'long-date'
|
|
101
|
+
| 'long-date-without-weekday'
|
|
78
102
|
| 'chart-date'
|
|
79
|
-
| 'year-month-day'
|
|
103
|
+
| 'year-month-day'
|
|
104
|
+
| 'month-day';
|
|
80
105
|
|
|
81
106
|
value: Date;
|
|
82
107
|
};
|
|
@@ -207,10 +232,14 @@ export const FormattedDateTime = ({
|
|
|
207
232
|
);
|
|
208
233
|
case 'long-date':
|
|
209
234
|
return <>{LONG_DATE_FORMATER.format(value)}</>;
|
|
235
|
+
case 'long-date-without-weekday':
|
|
236
|
+
return <>{LONG_DATE_FORMATER_WITHOUT_WEEKDAY.format(value)}</>;
|
|
210
237
|
case 'chart-date':
|
|
211
238
|
return <>{DAY_MONTH_FORMATER.format(value).replace(/[ ,]/g, '')}</>;
|
|
212
239
|
case 'year-month-day':
|
|
213
240
|
return <>{YEAR_MONTH_DAY_FORMATTER.format(value)}</>;
|
|
241
|
+
case 'month-day':
|
|
242
|
+
return <>{MONTH_DAY_FORMATTER.format(value)}</>;
|
|
214
243
|
default:
|
|
215
244
|
return <></>;
|
|
216
245
|
}
|