@centreon/ui 24.4.48 → 24.4.49
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 +36 -29
- package/public/mockServiceWorker.js +1 -1
- package/src/Button/Icon/index.tsx +1 -1
- package/src/Button/Save/StartIcon.tsx +3 -3
- package/src/Button/Save/index.tsx +9 -5
- package/src/Checkbox/Checkbox.tsx +2 -2
- package/src/Checkbox/CheckboxGroup/index.tsx +2 -2
- package/src/Dashboard/Item.tsx +1 -1
- package/src/Dashboard/Layout.tsx +2 -2
- package/src/Dialog/Confirm/index.tsx +10 -2
- package/src/Dialog/index.tsx +9 -2
- package/src/FallbackPage/FallbackPage.tsx +3 -3
- package/src/FileDropZone/index.tsx +3 -1
- package/src/Form/Form.cypress.spec.tsx +133 -0
- package/src/Form/Inputs/List/Content.tsx +62 -0
- package/src/Form/Inputs/List/List.styles.ts +29 -0
- package/src/Form/Inputs/List/List.tsx +58 -0
- package/src/Form/Inputs/List/useList.ts +81 -0
- package/src/Form/Inputs/index.tsx +3 -1
- package/src/Form/Inputs/models.ts +9 -1
- package/src/Graph/BarStack/BarStack.cypress.spec.tsx +154 -0
- package/src/Graph/BarStack/BarStack.stories.tsx +123 -0
- package/src/Graph/BarStack/BarStack.styles.ts +36 -0
- package/src/Graph/BarStack/BarStack.tsx +14 -0
- package/src/Graph/BarStack/ResponsiveBarStack.tsx +208 -0
- package/src/Graph/BarStack/index.ts +1 -0
- package/src/Graph/BarStack/models.ts +19 -0
- package/src/Graph/BarStack/useResponsiveBarStack.ts +139 -0
- package/src/Graph/Gauge/Gauge.cypress.spec.tsx +102 -0
- package/src/Graph/Gauge/Gauge.tsx +1 -1
- package/src/Graph/HeatMap/HeatMap.cypress.spec.tsx +145 -0
- package/src/Graph/HeatMap/HeatMap.stories.tsx +0 -25
- package/src/Graph/HeatMap/ResponsiveHeatMap.tsx +8 -2
- package/src/Graph/Legend/Legend.tsx +21 -0
- package/src/Graph/Legend/index.ts +1 -0
- package/src/Graph/Legend/models.ts +11 -0
- package/src/Graph/LineChart/BasicComponents/Lines/Threshold/Circle.tsx +2 -2
- package/src/Graph/LineChart/BasicComponents/Thresholds.tsx +2 -2
- package/src/Graph/LineChart/BasicComponents/useFilterLines.ts +1 -1
- package/src/Graph/LineChart/InteractiveComponents/AnchorPoint/GuidingLines.tsx +2 -2
- package/src/Graph/LineChart/InteractiveComponents/Annotations/EventAnnotations.tsx +1 -1
- package/src/Graph/LineChart/Legend/Legend.styles.ts +1 -1
- package/src/Graph/LineChart/Legend/LegendHeader.tsx +1 -1
- package/src/Graph/LineChart/Legend/useInteractiveValues.ts +2 -2
- package/src/Graph/LineChart/Legend/useLegend.ts +3 -3
- package/src/Graph/LineChart/helpers/doc.ts +16 -13
- package/src/Graph/LineChart/helpers/index.ts +1 -1
- package/src/Graph/LineChart/index.stories.tsx +4 -2
- package/src/Graph/LineChart/index.tsx +1 -1
- package/src/Graph/PieChart/PieChart.cypress.spec.tsx +169 -0
- package/src/Graph/PieChart/PieChart.stories.tsx +194 -0
- package/src/Graph/PieChart/PieChart.styles.ts +39 -0
- package/src/Graph/PieChart/PieChart.tsx +14 -0
- package/src/Graph/PieChart/ResponsivePie.tsx +251 -0
- package/src/Graph/PieChart/index.ts +1 -0
- package/src/Graph/PieChart/models.ts +19 -0
- package/src/Graph/PieChart/useResponsivePie.ts +86 -0
- package/src/Graph/SingleBar/SingleBar.cypress.spec.tsx +121 -0
- package/src/Graph/SingleBar/Thresholds.tsx +2 -2
- package/src/Graph/Text/Text.cypress.spec.tsx +101 -0
- package/src/Graph/Text/Text.stories.tsx +60 -4
- package/src/Graph/Text/Text.tsx +1 -1
- package/src/Graph/common/testUtils.ts +71 -0
- package/src/Graph/common/timeSeries/index.ts +22 -14
- package/src/Graph/common/utils.ts +19 -0
- package/src/Graph/index.ts +3 -0
- package/src/Graph/translatedLabels.ts +1 -0
- package/src/InputField/Select/Autocomplete/Connected/index.tsx +10 -7
- package/src/InputField/Select/Autocomplete/Draggable/SortableList.tsx +1 -1
- package/src/InputField/Select/Autocomplete/Draggable/SortableListContent.tsx +1 -1
- package/src/InputField/Select/Autocomplete/Draggable/index.tsx +1 -1
- package/src/InputField/Select/Autocomplete/index.tsx +121 -115
- package/src/InputField/Select/IconPopover/index.tsx +2 -2
- package/src/InputField/Select/index.tsx +1 -1
- package/src/InputField/Text/index.tsx +2 -2
- package/src/Listing/ActionBar/index.tsx +9 -8
- package/src/Listing/Cell/DataCell.styles.ts +3 -0
- package/src/Listing/Cell/DataCell.tsx +23 -5
- package/src/Listing/Header/ListingHeader.tsx +1 -1
- package/src/Listing/Listing.cypress.spec.tsx +80 -4
- package/src/Listing/Listing.styles.ts +4 -7
- package/src/Listing/index.stories.tsx +37 -3
- package/src/Listing/index.test.tsx +1 -1
- package/src/Listing/index.tsx +4 -3
- package/src/Listing/models.ts +1 -0
- package/src/Module/Module.cypress.spec.tsx +129 -0
- package/src/Module/index.tsx +2 -4
- package/src/RichTextEditor/RichTextEditor.tsx +12 -1
- package/src/SortableItems/index.tsx +2 -7
- package/src/ThemeProvider/index.tsx +24 -0
- package/src/TimePeriods/CustomTimePeriod/CompactCustomTimePeriod.styles.ts +6 -7
- package/src/TimePeriods/CustomTimePeriod/PopoverCustomTimePeriod/PickersStartEndDate.tsx +8 -3
- package/src/TimePeriods/CustomTimePeriod/PopoverCustomTimePeriod/models.ts +0 -2
- package/src/TimePeriods/DateTimePickerInput.tsx +56 -19
- package/src/TimePeriods/ResolutionTimePeriod.cypress.spec.tsx +12 -9
- package/src/TimePeriods/TimePeriods.cypress.spec.tsx +9 -33
- package/src/TimePeriods/helpers/index.ts +1 -1
- package/src/TimePeriods/index.stories.tsx +12 -4
- package/src/TimePeriods/index.tsx +2 -2
- package/src/api/QueryProvider.tsx +1 -1
- package/src/api/TestQueryProvider.tsx +1 -1
- package/src/api/useFetchQuery/index.ts +27 -23
- package/src/api/useMutationQuery/index.test.ts +4 -4
- package/src/api/useMutationQuery/index.ts +60 -25
- package/src/components/Button/Icon/IconButton.tsx +6 -2
- package/src/components/DataTable/DataListing.tsx +6 -0
- package/src/components/DataTable/DataTable.cypress.spec.tsx +193 -0
- package/src/components/DataTable/DataTable.stories.tsx +40 -0
- package/src/components/DataTable/DataTable.styles.ts +3 -0
- package/src/components/DataTable/DataTable.tsx +3 -3
- package/src/components/DataTable/Item/DataTableItem.styles.ts +7 -2
- package/src/components/DataTable/Item/DataTableItem.tsx +4 -4
- package/src/components/DataTable/index.ts +3 -1
- package/src/components/Form/AccessRights/ShareInput/ContactSwitch.tsx +3 -3
- package/src/components/Form/AccessRights/ShareInput/ShareInput.tsx +1 -0
- package/src/components/Form/Dashboard/DashboardForm.tsx +15 -12
- package/src/components/Layout/PageLayout/PageLayout.tsx +1 -1
- package/src/components/Layout/PageLayout/PageLayoutActions.tsx +1 -0
- package/src/components/Layout/PageLayout/PageLayoutBody.tsx +1 -0
- package/src/components/Layout/PageLayout/PageLayoutHeader.tsx +5 -1
- package/src/components/Layout/PageLayout/PageQuickAccess.tsx +76 -0
- package/src/components/Layout/PageLayout/index.ts +3 -1
- package/src/components/Layout/PageLayout.cypress.spec.tsx +66 -0
- package/src/components/Modal/Modal.styles.ts +1 -1
- package/src/components/Tooltip/ConfirmationTooltip/ConfirmationTooltip.stories.tsx +3 -3
- package/src/components/Tooltip/ConfirmationTooltip/ConfirmationTooltip.tsx +1 -1
- package/src/components/Tooltip/ConfirmationTooltip/models.ts +1 -1
- package/src/index.ts +2 -2
- package/src/queryParameters/url/index.ts +5 -1
- package/src/utils/index.ts +1 -1
- package/src/utils/useFullscreen/useFullscreenListener.ts +10 -7
- package/src/utils/{useLicenseExpirationWarning.cypress.spec.tsx → useLicenseExpirationWarning.test.tsx} +48 -37
- package/src/utils/useLicenseExpirationWarning.ts +18 -18
- package/src/utils/usePluralizedTranslation.ts +21 -0
- package/src/screens/dashboard/DashboardsDetail.stories.tsx +0 -108
- package/src/screens/dashboard/DashboardsOverview.stories.tsx +0 -281
- package/src/utils/useDateTimePickerAdapter.ts +0 -309
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { LegendOrdinal } from '@visx/legend';
|
|
2
|
+
import { scaleOrdinal } from '@visx/scale';
|
|
3
|
+
|
|
4
|
+
import { LegendProps } from './models';
|
|
5
|
+
|
|
6
|
+
const Legend = ({ scale, direction = 'column' }: LegendProps): JSX.Element => {
|
|
7
|
+
const legendScale = scaleOrdinal({
|
|
8
|
+
domain: scale.domain,
|
|
9
|
+
range: scale.range
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
return (
|
|
13
|
+
<LegendOrdinal
|
|
14
|
+
direction={direction}
|
|
15
|
+
labelMargin="0 16px 0 0"
|
|
16
|
+
scale={legendScale}
|
|
17
|
+
/>
|
|
18
|
+
);
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export default Legend;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as Legend } from './Legend';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Shape } from '@visx/visx';
|
|
2
2
|
import { isEmpty, isNil } from 'ramda';
|
|
3
3
|
|
|
4
|
-
import { Circle } from './models';
|
|
4
|
+
import { Circle as CircleModel } from './models';
|
|
5
5
|
import useCoordinateCircle from './useCoordinateCircle';
|
|
6
6
|
|
|
7
7
|
const Circle = ({
|
|
@@ -11,7 +11,7 @@ const Circle = ({
|
|
|
11
11
|
timeSeries,
|
|
12
12
|
getX,
|
|
13
13
|
getCountDisplayedCircles
|
|
14
|
-
}:
|
|
14
|
+
}: CircleModel): JSX.Element | null => {
|
|
15
15
|
const coordinates = useCoordinateCircle({
|
|
16
16
|
getCountDisplayedCircles,
|
|
17
17
|
getX,
|
|
@@ -2,7 +2,7 @@ import { equals, isNil } from 'ramda';
|
|
|
2
2
|
|
|
3
3
|
import { getUnits, getYScale } from '../../common/timeSeries';
|
|
4
4
|
import { Line } from '../../common/timeSeries/models';
|
|
5
|
-
import { Thresholds } from '../../common/models';
|
|
5
|
+
import { Thresholds as ThresholdsModel } from '../../common/models';
|
|
6
6
|
|
|
7
7
|
import { ThresholdLine } from './ThresholdLine';
|
|
8
8
|
|
|
@@ -13,7 +13,7 @@ interface Props {
|
|
|
13
13
|
rightScale: (value: number) => number;
|
|
14
14
|
showTooltip: (props) => void;
|
|
15
15
|
thresholdUnit?: string;
|
|
16
|
-
thresholds:
|
|
16
|
+
thresholds: ThresholdsModel;
|
|
17
17
|
width: number;
|
|
18
18
|
}
|
|
19
19
|
|
|
@@ -28,7 +28,7 @@ const useFilterLines = ({
|
|
|
28
28
|
linesGraph,
|
|
29
29
|
setLinesGraph
|
|
30
30
|
}: UseFilterLines): Result => {
|
|
31
|
-
const displayedLines = reject(propEq('display'
|
|
31
|
+
const displayedLines = reject(propEq(false, 'display'), linesGraph ?? lines);
|
|
32
32
|
const filterLines = (): Array<Line> => {
|
|
33
33
|
const lineOriginMetric = findLineOfOriginMetricThreshold(lines);
|
|
34
34
|
|
|
@@ -2,7 +2,7 @@ import { Shape } from '@visx/visx';
|
|
|
2
2
|
|
|
3
3
|
import { grey } from '@mui/material/colors';
|
|
4
4
|
|
|
5
|
-
import { GuidingLines } from './models';
|
|
5
|
+
import { GuidingLines as GuidingLinesModel } from './models';
|
|
6
6
|
import useTickGraph from './useTickGraph';
|
|
7
7
|
|
|
8
8
|
const GuidingLines = ({
|
|
@@ -10,7 +10,7 @@ const GuidingLines = ({
|
|
|
10
10
|
xScale,
|
|
11
11
|
graphHeight,
|
|
12
12
|
graphWidth
|
|
13
|
-
}:
|
|
13
|
+
}: GuidingLinesModel): JSX.Element | null => {
|
|
14
14
|
const { positionX, positionY } = useTickGraph({
|
|
15
15
|
timeSeries,
|
|
16
16
|
xScale
|
|
@@ -8,7 +8,7 @@ interface MakeStylesProps {
|
|
|
8
8
|
|
|
9
9
|
export const legendWidth = 21;
|
|
10
10
|
const legendItemHeight = 5.25;
|
|
11
|
-
const legendItemHeightCompact =
|
|
11
|
+
const legendItemHeightCompact = 2;
|
|
12
12
|
|
|
13
13
|
export const useStyles = makeStyles<MakeStylesProps>()(
|
|
14
14
|
(theme, { limitLegendRows }) => ({
|
|
@@ -5,7 +5,7 @@ import { equals, find, isNil } from 'ramda';
|
|
|
5
5
|
|
|
6
6
|
import { mousePositionAtom } from '../InteractiveComponents/interactionWithGraphAtoms';
|
|
7
7
|
import {
|
|
8
|
-
|
|
8
|
+
formatMetricValueWithUnit,
|
|
9
9
|
getLineForMetric,
|
|
10
10
|
getMetrics,
|
|
11
11
|
getTimeValue
|
|
@@ -73,7 +73,7 @@ const useInteractiveValues = ({
|
|
|
73
73
|
metric_id
|
|
74
74
|
}) as Line;
|
|
75
75
|
|
|
76
|
-
const formattedValue =
|
|
76
|
+
const formattedValue = formatMetricValueWithUnit({
|
|
77
77
|
base,
|
|
78
78
|
unit,
|
|
79
79
|
value
|
|
@@ -27,9 +27,9 @@ interface Props {
|
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
const useLegend = ({ lines, setLinesGraph }: Props): LegendActions => {
|
|
30
|
-
const displayedLines = reject(propEq('display'
|
|
30
|
+
const displayedLines = reject(propEq(false, 'display'), lines);
|
|
31
31
|
const getLineByMetric = (metric_id: number): Line =>
|
|
32
|
-
find(propEq(
|
|
32
|
+
find(propEq(metric_id, 'metric_id'), lines) as Line;
|
|
33
33
|
|
|
34
34
|
const toggleMetricLine = (metric_id): void => {
|
|
35
35
|
const data = lines.map((line) => ({
|
|
@@ -92,7 +92,7 @@ const useLegend = ({ lines, setLinesGraph }: Props): LegendActions => {
|
|
|
92
92
|
|
|
93
93
|
const newLines = lines.map((line) => ({
|
|
94
94
|
...line,
|
|
95
|
-
display: find(propEq(
|
|
95
|
+
display: find(propEq(line.metric_id, 'metric_id'), lines)?.display ?? true
|
|
96
96
|
}));
|
|
97
97
|
|
|
98
98
|
setLinesGraph(newLines);
|
|
@@ -69,21 +69,24 @@ export const getDescription = ({ sections }: Description): string => {
|
|
|
69
69
|
})}<br></details>`;
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
-
const formattedProps = props.reduce(
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
72
|
+
const formattedProps = props.reduce(
|
|
73
|
+
(accumulator, currentValue, index) => {
|
|
74
|
+
const key = Object.keys(currentValue)[0];
|
|
75
|
+
const { description, type } = currentValue[key];
|
|
76
|
+
const body = `${accumulator} ${getBodyDescription({
|
|
77
|
+
description,
|
|
78
|
+
key,
|
|
79
|
+
type
|
|
80
|
+
})}`;
|
|
80
81
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
82
|
+
if (!equals(index, props.length - 1)) {
|
|
83
|
+
return body;
|
|
84
|
+
}
|
|
84
85
|
|
|
85
|
-
|
|
86
|
-
|
|
86
|
+
return `${body}</details>`;
|
|
87
|
+
},
|
|
88
|
+
getInitialValue({ section: name, type: item?.type })
|
|
89
|
+
);
|
|
87
90
|
|
|
88
91
|
return formattedProps as string;
|
|
89
92
|
});
|
|
@@ -14,7 +14,7 @@ import { LineChartData } from '../../common/models';
|
|
|
14
14
|
export const adjustGraphData = (graphData: LineChartData): LinesData => {
|
|
15
15
|
const lines = getLineData(graphData);
|
|
16
16
|
const sortedLines = sortBy(prop('name'), lines);
|
|
17
|
-
const displayedLines = reject(propEq('display'
|
|
17
|
+
const displayedLines = reject(propEq(false, 'display'), sortedLines);
|
|
18
18
|
|
|
19
19
|
const timeSeries = getTimeSeries(graphData);
|
|
20
20
|
|
|
@@ -39,8 +39,7 @@ import { Interval, ThresholdType, TooltipData } from './models';
|
|
|
39
39
|
import WrapperLineChart from './index';
|
|
40
40
|
|
|
41
41
|
const meta: Meta<typeof WrapperLineChart> = {
|
|
42
|
-
component: WrapperLineChart
|
|
43
|
-
tags: ['autodocs']
|
|
42
|
+
component: WrapperLineChart
|
|
44
43
|
};
|
|
45
44
|
export default meta;
|
|
46
45
|
|
|
@@ -353,6 +352,9 @@ export const LineChartWithTimePeriod: Story = {
|
|
|
353
352
|
end: defaultEnd,
|
|
354
353
|
height: 500,
|
|
355
354
|
start: defaultStart
|
|
355
|
+
},
|
|
356
|
+
parameters: {
|
|
357
|
+
chromatic: { diffThreshold: 0.1 }
|
|
356
358
|
}
|
|
357
359
|
};
|
|
358
360
|
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import numeral from 'numeral';
|
|
2
|
+
|
|
3
|
+
import PieChart from './PieChart';
|
|
4
|
+
import { ArcType, PieProps } from './models';
|
|
5
|
+
|
|
6
|
+
const defaultData = [
|
|
7
|
+
{ color: '#88B922', label: 'Ok', value: 148 },
|
|
8
|
+
{ color: '#999999', label: 'Unknown', value: 13 },
|
|
9
|
+
{ color: '#F7931A', label: 'Warning', value: 16 },
|
|
10
|
+
{ color: '#FF6666', label: 'Down', value: 62 }
|
|
11
|
+
];
|
|
12
|
+
|
|
13
|
+
const dataWithNullValues = [
|
|
14
|
+
{ color: '#88B922', label: 'Ok', value: 0 },
|
|
15
|
+
{ color: '#999999', label: 'Unknown', value: 0 },
|
|
16
|
+
{ color: '#F7931A', label: 'Warning', value: 0 },
|
|
17
|
+
{ color: '#FF6666', label: 'Down', value: 0 }
|
|
18
|
+
];
|
|
19
|
+
|
|
20
|
+
const total = Math.floor(
|
|
21
|
+
defaultData.reduce((acc, { value }) => acc + value, 0)
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
const TooltipContent = ({ label, color, value }: ArcType): JSX.Element => {
|
|
25
|
+
return (
|
|
26
|
+
<div data-testid={`tooltip-${label}`} style={{ color }}>
|
|
27
|
+
{label} : {value}
|
|
28
|
+
</div>
|
|
29
|
+
);
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const initialize = ({
|
|
33
|
+
width = '500px',
|
|
34
|
+
height = '500px',
|
|
35
|
+
data = defaultData,
|
|
36
|
+
...args
|
|
37
|
+
}: Omit<PieProps, 'data'> & {
|
|
38
|
+
data?;
|
|
39
|
+
height?: string;
|
|
40
|
+
width?: string;
|
|
41
|
+
}): void => {
|
|
42
|
+
cy.mount({
|
|
43
|
+
Component: (
|
|
44
|
+
<div style={{ height, width }}>
|
|
45
|
+
<PieChart {...args} data={data} />
|
|
46
|
+
</div>
|
|
47
|
+
)
|
|
48
|
+
});
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
describe('Pie chart', () => {
|
|
52
|
+
it('renders pie chart correctly with provided data', () => {
|
|
53
|
+
initialize({});
|
|
54
|
+
|
|
55
|
+
defaultData.forEach(({ label }) => {
|
|
56
|
+
cy.findByTestId(label).should('be.visible');
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
cy.makeSnapshot();
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
it('adjusts size based on the provided width and height', () => {
|
|
63
|
+
initialize({ displayLegend: false, height: '300px', width: '300px' });
|
|
64
|
+
|
|
65
|
+
cy.findByTestId('pieChart')
|
|
66
|
+
.should('have.css', 'width', '300px')
|
|
67
|
+
.and('have.css', 'height', '300px');
|
|
68
|
+
|
|
69
|
+
cy.makeSnapshot();
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
it('renders as a donut when variant is set to "donut"', () => {
|
|
73
|
+
initialize({ variant: 'donut' });
|
|
74
|
+
cy.get('[data-variant="donut"]').should('exist');
|
|
75
|
+
|
|
76
|
+
cy.makeSnapshot();
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
it('renders as a pie when variant is set to "pie"', () => {
|
|
80
|
+
initialize({ variant: 'pie' });
|
|
81
|
+
cy.get('[data-variant="pie"]').should('exist');
|
|
82
|
+
|
|
83
|
+
cy.makeSnapshot();
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
it('displays tooltip with correct information on hover', () => {
|
|
87
|
+
initialize({ TooltipContent });
|
|
88
|
+
|
|
89
|
+
defaultData.forEach(({ label, value }) => {
|
|
90
|
+
cy.findByTestId(label).trigger('mouseover', { force: true });
|
|
91
|
+
|
|
92
|
+
cy.findByTestId(`tooltip-${label}`)
|
|
93
|
+
.should('contain', label)
|
|
94
|
+
.and('contain', numeral(value).format('0a').toUpperCase());
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
cy.makeSnapshot();
|
|
98
|
+
});
|
|
99
|
+
it('conditionally displays values on arcs based on displayValues prop', () => {
|
|
100
|
+
initialize({ displayValues: true });
|
|
101
|
+
defaultData.forEach(({ value }, index) => {
|
|
102
|
+
cy.findAllByTestId('value')
|
|
103
|
+
.eq(index)
|
|
104
|
+
.children()
|
|
105
|
+
.eq(0)
|
|
106
|
+
.should('have.text', value);
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
initialize({ displayValues: false });
|
|
110
|
+
cy.findAllByTestId('value').should('not.exist');
|
|
111
|
+
|
|
112
|
+
cy.makeSnapshot();
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
it('displays values on arcs in percentage unit when displayValues is set to true and unit to percentage', () => {
|
|
116
|
+
initialize({ displayValues: true, unit: 'percentage' });
|
|
117
|
+
defaultData.forEach(({ value }, index) => {
|
|
118
|
+
cy.findAllByTestId('value')
|
|
119
|
+
.eq(index)
|
|
120
|
+
.children()
|
|
121
|
+
.eq(0)
|
|
122
|
+
.should('have.text', `${((value * 100) / total).toFixed(1)}%`);
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
cy.makeSnapshot();
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
it('displays Legend component based on displayLegend prop', () => {
|
|
129
|
+
initialize({ displayLegend: true });
|
|
130
|
+
cy.findByTestId('Legend').should('be.visible');
|
|
131
|
+
|
|
132
|
+
initialize({ displayLegend: false });
|
|
133
|
+
cy.findByTestId('Legend').should('not.exist');
|
|
134
|
+
|
|
135
|
+
cy.makeSnapshot();
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
it('displays the title when the title is giving', () => {
|
|
139
|
+
initialize({ title: 'host' });
|
|
140
|
+
cy.findByTestId('Title').should('be.visible');
|
|
141
|
+
|
|
142
|
+
initialize({});
|
|
143
|
+
cy.findByTestId('Title').should('not.exist');
|
|
144
|
+
|
|
145
|
+
cy.makeSnapshot();
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
it('adjusts outer radius when chart dimensions are too small', () => {
|
|
149
|
+
initialize({
|
|
150
|
+
displayLegend: false,
|
|
151
|
+
height: '120px',
|
|
152
|
+
title: 'hosts',
|
|
153
|
+
variant: 'donut',
|
|
154
|
+
width: '120px'
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
cy.get('[data-variant="donut"]').should('have.css', 'width', '100px');
|
|
158
|
+
|
|
159
|
+
cy.makeSnapshot();
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
it('displays a message "No Data Available" when all values are null', () => {
|
|
163
|
+
initialize({ data: dataWithNullValues, title: 'host' });
|
|
164
|
+
|
|
165
|
+
cy.contains('No Data Available');
|
|
166
|
+
|
|
167
|
+
cy.makeSnapshot();
|
|
168
|
+
});
|
|
169
|
+
});
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
import { Meta, StoryObj } from '@storybook/react';
|
|
2
|
+
|
|
3
|
+
import { ArcType } from './models';
|
|
4
|
+
|
|
5
|
+
import { PieChart } from '.';
|
|
6
|
+
|
|
7
|
+
const data = [
|
|
8
|
+
{ color: '#88B922', label: 'Ok', value: 148 },
|
|
9
|
+
{ color: '#999999', label: 'Unknown', value: 13 },
|
|
10
|
+
{ color: '#F7931A', label: 'Warning', value: 16 },
|
|
11
|
+
{ color: '#FF6666', label: 'Down', value: 62 }
|
|
12
|
+
];
|
|
13
|
+
|
|
14
|
+
const dataWithBigNumbers = [
|
|
15
|
+
{ color: '#88B922', label: 'Ok', value: 260000 },
|
|
16
|
+
{ color: '#999999', label: 'Unknown', value: 1010900 },
|
|
17
|
+
{ color: '#F7931A', label: 'Warning', value: 63114 },
|
|
18
|
+
{ color: '#FF6666', label: 'Down', value: 122222 }
|
|
19
|
+
];
|
|
20
|
+
|
|
21
|
+
const meta: Meta<typeof PieChart> = {
|
|
22
|
+
component: PieChart
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export default meta;
|
|
26
|
+
type Story = StoryObj<typeof PieChart>;
|
|
27
|
+
|
|
28
|
+
const Template = (args): JSX.Element => {
|
|
29
|
+
return (
|
|
30
|
+
<div style={{ height: '350px', width: '350px' }}>
|
|
31
|
+
<PieChart {...args} />
|
|
32
|
+
</div>
|
|
33
|
+
);
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
export const Pie: Story = {
|
|
37
|
+
args: {
|
|
38
|
+
data,
|
|
39
|
+
title: 'hosts'
|
|
40
|
+
},
|
|
41
|
+
render: Template
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
export const Donut: Story = {
|
|
45
|
+
args: {
|
|
46
|
+
data,
|
|
47
|
+
title: 'hosts',
|
|
48
|
+
variant: 'donut'
|
|
49
|
+
},
|
|
50
|
+
render: Template
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
export const WithPencentage: Story = {
|
|
54
|
+
args: {
|
|
55
|
+
data,
|
|
56
|
+
title: 'hosts',
|
|
57
|
+
unit: 'percentage',
|
|
58
|
+
variant: 'donut'
|
|
59
|
+
},
|
|
60
|
+
render: Template
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
export const WithBigNumbers: Story = {
|
|
64
|
+
args: {
|
|
65
|
+
data: dataWithBigNumbers,
|
|
66
|
+
title: 'hosts',
|
|
67
|
+
unit: 'number',
|
|
68
|
+
variant: 'donut'
|
|
69
|
+
},
|
|
70
|
+
render: Template
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
export const WithoutLegend: Story = {
|
|
74
|
+
args: {
|
|
75
|
+
data,
|
|
76
|
+
displayLegend: false,
|
|
77
|
+
title: 'hosts',
|
|
78
|
+
variant: 'donut'
|
|
79
|
+
},
|
|
80
|
+
render: Template
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
export const DonutWithoutTitle: Story = {
|
|
84
|
+
args: {
|
|
85
|
+
data,
|
|
86
|
+
variant: 'donut'
|
|
87
|
+
},
|
|
88
|
+
render: Template
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
export const PieWithoutTitle: Story = {
|
|
92
|
+
args: {
|
|
93
|
+
data
|
|
94
|
+
},
|
|
95
|
+
render: Template
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
export const DonutWithDisplayedValues: Story = {
|
|
99
|
+
args: {
|
|
100
|
+
data,
|
|
101
|
+
displayValues: true,
|
|
102
|
+
variant: 'donut'
|
|
103
|
+
},
|
|
104
|
+
render: Template
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
export const PieWithDisplayedValues: Story = {
|
|
108
|
+
args: {
|
|
109
|
+
data,
|
|
110
|
+
displayValues: true
|
|
111
|
+
},
|
|
112
|
+
render: Template
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
const TooltipContent = ({ label, color, value }: ArcType): JSX.Element => {
|
|
116
|
+
return (
|
|
117
|
+
<div style={{ color }}>
|
|
118
|
+
{label} : {value}
|
|
119
|
+
</div>
|
|
120
|
+
);
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
export const PieWithTooltip: Story = {
|
|
124
|
+
args: {
|
|
125
|
+
TooltipContent,
|
|
126
|
+
data,
|
|
127
|
+
displayValues: true,
|
|
128
|
+
unit: 'percentage'
|
|
129
|
+
},
|
|
130
|
+
render: Template
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
export const DonutWithTooltip: Story = {
|
|
134
|
+
args: {
|
|
135
|
+
TooltipContent,
|
|
136
|
+
data,
|
|
137
|
+
displayValues: true,
|
|
138
|
+
variant: 'donut'
|
|
139
|
+
},
|
|
140
|
+
render: Template
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
const TemplateForSmallDimensions = (args): JSX.Element => {
|
|
144
|
+
return (
|
|
145
|
+
<div style={{ height: '130px', width: '130px' }}>
|
|
146
|
+
<PieChart {...args} />
|
|
147
|
+
</div>
|
|
148
|
+
);
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
export const PieWithSmallDimensions: Story = {
|
|
152
|
+
args: {
|
|
153
|
+
data,
|
|
154
|
+
displayLegend: false
|
|
155
|
+
},
|
|
156
|
+
render: TemplateForSmallDimensions
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
export const DonutWithSmallDimensions: Story = {
|
|
160
|
+
args: {
|
|
161
|
+
data,
|
|
162
|
+
displayLegend: false,
|
|
163
|
+
title: 'hosts',
|
|
164
|
+
variant: 'donut'
|
|
165
|
+
},
|
|
166
|
+
render: TemplateForSmallDimensions
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
const dataWidthOneNoZeroValue = [
|
|
170
|
+
{ color: '#88B922', label: 'Ok', value: 13 },
|
|
171
|
+
{ color: '#999999', label: 'Unknown', value: 0 },
|
|
172
|
+
{ color: '#F7931A', label: 'Warning', value: 0 },
|
|
173
|
+
{ color: '#FF6666', label: 'Down', value: 0 }
|
|
174
|
+
];
|
|
175
|
+
|
|
176
|
+
export const PieWithOneNoZeroValue: Story = {
|
|
177
|
+
args: {
|
|
178
|
+
data: dataWidthOneNoZeroValue,
|
|
179
|
+
displayLegend: false,
|
|
180
|
+
title: 'hosts',
|
|
181
|
+
variant: 'pie'
|
|
182
|
+
},
|
|
183
|
+
render: Template
|
|
184
|
+
};
|
|
185
|
+
|
|
186
|
+
export const donutWithOneNoZeroValue: Story = {
|
|
187
|
+
args: {
|
|
188
|
+
data: dataWidthOneNoZeroValue,
|
|
189
|
+
displayLegend: false,
|
|
190
|
+
title: 'hosts',
|
|
191
|
+
variant: 'donut'
|
|
192
|
+
},
|
|
193
|
+
render: Template
|
|
194
|
+
};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { lt } from 'ramda';
|
|
2
|
+
import { makeStyles } from 'tss-react/mui';
|
|
3
|
+
|
|
4
|
+
export const usePieStyles = makeStyles<{ svgSize: number }>()(
|
|
5
|
+
(theme, { svgSize }) => ({
|
|
6
|
+
container: {
|
|
7
|
+
alignItems: 'center',
|
|
8
|
+
display: 'flex',
|
|
9
|
+
gap: theme.spacing(2),
|
|
10
|
+
justifyContent: 'center'
|
|
11
|
+
},
|
|
12
|
+
pieChartTooltip: {
|
|
13
|
+
backgroundColor: theme.palette.background.paper,
|
|
14
|
+
color: theme.palette.text.primary,
|
|
15
|
+
padding: 0,
|
|
16
|
+
position: 'relative'
|
|
17
|
+
},
|
|
18
|
+
svgContainer: {
|
|
19
|
+
alignItems: 'center',
|
|
20
|
+
backgroundColor: theme.palette.background.panelGroups,
|
|
21
|
+
borderRadius: '100%',
|
|
22
|
+
display: 'flex',
|
|
23
|
+
justifyContent: 'center'
|
|
24
|
+
},
|
|
25
|
+
svgWrapper: {
|
|
26
|
+
alignItems: 'center',
|
|
27
|
+
display: 'flex',
|
|
28
|
+
flexDirection: 'column',
|
|
29
|
+
gap: theme.spacing(1),
|
|
30
|
+
justifyContent: 'center'
|
|
31
|
+
},
|
|
32
|
+
title: {
|
|
33
|
+
fontSize: lt(svgSize, 150)
|
|
34
|
+
? theme.typography.body1.fontSize
|
|
35
|
+
: theme.typography.h6.fontSize,
|
|
36
|
+
fontWeight: theme.typography.fontWeightMedium
|
|
37
|
+
}
|
|
38
|
+
})
|
|
39
|
+
);
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { ParentSize } from '../..';
|
|
2
|
+
|
|
3
|
+
import ResponsivePie from './ResponsivePie';
|
|
4
|
+
import { PieProps } from './models';
|
|
5
|
+
|
|
6
|
+
const PieChart = (props: PieProps): JSX.Element => (
|
|
7
|
+
<ParentSize>
|
|
8
|
+
{({ width, height }) => (
|
|
9
|
+
<ResponsivePie {...props} height={height} width={width} />
|
|
10
|
+
)}
|
|
11
|
+
</ParentSize>
|
|
12
|
+
);
|
|
13
|
+
|
|
14
|
+
export default PieChart;
|