@centreon/ui 25.3.1 → 25.3.3

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.
Files changed (41) hide show
  1. package/package.json +49 -46
  2. package/public/mockServiceWorker.js +1 -1
  3. package/src/Button/Save/index.tsx +17 -35
  4. package/src/Button/Save/useSave.tsx +89 -0
  5. package/src/Form/Inputs/LoadingSkeleton.tsx +1 -1
  6. package/src/Form/Inputs/Radio.tsx +7 -5
  7. package/src/Form/Inputs/Switch.tsx +4 -2
  8. package/src/Graph/BarChart/BarChart.cypress.spec.tsx +2 -2
  9. package/src/Graph/BarChart/BarChart.stories.tsx +39 -0
  10. package/src/Graph/BarChart/BarStack.tsx +8 -2
  11. package/src/Graph/BarChart/ResponsiveBarChart.tsx +10 -8
  12. package/src/Graph/Chart/BasicComponents/Lines/StackedLines/index.tsx +41 -24
  13. package/src/Graph/Chart/BasicComponents/Lines/index.tsx +22 -37
  14. package/src/Graph/Chart/Chart.cypress.spec.tsx +104 -31
  15. package/src/Graph/Chart/Chart.stories.tsx +24 -2
  16. package/src/Graph/Chart/Chart.tsx +23 -18
  17. package/src/Graph/Chart/index.tsx +2 -0
  18. package/src/Graph/Chart/models.ts +4 -3
  19. package/src/Graph/SingleBar/ThresholdLine.tsx +2 -2
  20. package/src/Graph/Tree/Tree.stories.tsx +4 -1
  21. package/src/Graph/common/Axes/index.tsx +1 -1
  22. package/src/Graph/common/BaseChart/AdditionalLine.tsx +37 -0
  23. package/src/Graph/common/BaseChart/BaseChart.tsx +5 -1
  24. package/src/Graph/common/BaseChart/Header/index.tsx +5 -7
  25. package/src/Graph/common/BaseChart/Header/useHeaderStyles.ts +5 -1
  26. package/src/Graph/common/BaseChart/useComputeBaseChartDimensions.ts +9 -2
  27. package/src/Graph/common/Thresholds/ThresholdLine.tsx +2 -2
  28. package/src/Graph/common/models.ts +7 -0
  29. package/src/Graph/common/timeSeries/index.ts +1 -1
  30. package/src/Graph/common/utils.ts +22 -1
  31. package/src/Graph/mockedData/lastDayWithNullValues.json +6 -40
  32. package/src/Graph/mockedData/pingService.json +3 -3
  33. package/src/InputField/Select/index.tsx +11 -9
  34. package/src/Listing/Listing.cypress.spec.tsx +9 -11
  35. package/src/RichTextEditor/RichTextEditor.tsx +1 -1
  36. package/src/api/useMutationQuery/useMutationQuery.cypress.spec.tsx +0 -18
  37. package/src/components/Button/Button.tsx +19 -15
  38. package/src/components/CollapsibleItem/CollapsibleItem.cypress.spec.tsx +8 -8
  39. package/src/components/CopyCommand/CopyCommand.cypress.spec.tsx +11 -10
  40. package/src/Button/Save/Content.tsx +0 -34
  41. package/src/Button/Save/StartIcon.tsx +0 -24
@@ -19,13 +19,11 @@ const Header = ({ title, header }: Props): JSX.Element => {
19
19
  Component: (
20
20
  <div className={classes.header}>
21
21
  <div />
22
- <div>
23
- {displayTitle && (
24
- <Typography align="center" variant="body1">
25
- {title}
26
- </Typography>
27
- )}
28
- </div>
22
+ {displayTitle && (
23
+ <Typography align="center" variant="body1" className={classes.title}>
24
+ {title}
25
+ </Typography>
26
+ )}
29
27
  {header?.extraComponent}
30
28
  </div>
31
29
  ),
@@ -3,7 +3,11 @@ import { makeStyles } from 'tss-react/mui';
3
3
  export const ussHeaderChartStyles = makeStyles()({
4
4
  header: {
5
5
  display: 'grid',
6
- gridTemplateColumns: '0.4fr 1fr 0.4fr',
6
+ gridTemplateColumns: 'auto 1fr auto',
7
7
  width: '100%'
8
+ },
9
+ title: {
10
+ whiteSpace: 'pre-wrap',
11
+ lineHeight: '1.2'
8
12
  }
9
13
  });
@@ -21,6 +21,7 @@ interface UseComputeBaseChartDimensionsState {
21
21
  graphHeight: number;
22
22
  graphWidth: number;
23
23
  legendRef: MutableRefObject<HTMLDivElement | null>;
24
+ titleRef: MutableRefObject<HTMLDivElement | null>;
24
25
  }
25
26
 
26
27
  export const useComputeBaseChartDimensions = ({
@@ -33,6 +34,7 @@ export const useComputeBaseChartDimensions = ({
33
34
  maxAxisCharacters
34
35
  }: UseComputeBaseChartDimensionsProps): UseComputeBaseChartDimensionsState => {
35
36
  const legendRef = useRef<HTMLDivElement | null>(null);
37
+ const titleRef = useRef<HTMLDivElement | null>(null);
36
38
 
37
39
  const currentLegendHeight =
38
40
  legendHeight ?? (legendRef.current?.getBoundingClientRect().height || 0);
@@ -57,12 +59,17 @@ export const useComputeBaseChartDimensions = ({
57
59
  : 0;
58
60
  const graphHeight =
59
61
  (height || 0) > 0
60
- ? (height || 0) - margin.top - 5 - legendBoundingHeight
62
+ ? (height || 0) -
63
+ margin.top -
64
+ legendBoundingHeight -
65
+ (titleRef.current?.getBoundingClientRect().height || 0) -
66
+ 5
61
67
  : 0;
62
68
 
63
69
  return {
64
70
  graphHeight,
65
71
  graphWidth,
66
- legendRef
72
+ legendRef,
73
+ titleRef
67
74
  };
68
75
  };
@@ -45,11 +45,11 @@ export const ThresholdLine = ({
45
45
  x1: 0,
46
46
  x2: width,
47
47
  y1: scaledValue,
48
- y2: scaledValue
48
+ y2: scaledValue + 1
49
49
  }
50
50
  : {
51
51
  x1: scaledValue,
52
- x2: scaledValue,
52
+ x2: scaledValue + 1,
53
53
  y1: 0,
54
54
  y2: width
55
55
  };
@@ -16,3 +16,10 @@ export interface Thresholds {
16
16
  enabled: boolean;
17
17
  warning: Array<Threshold>;
18
18
  }
19
+
20
+ export interface AdditionalLineProps {
21
+ yValue: number;
22
+ text?: string;
23
+ color: string;
24
+ unit: string;
25
+ }
@@ -581,7 +581,7 @@ const formatMetricValue = ({
581
581
 
582
582
  const formattedMetricValue = numeral(Math.abs(value))
583
583
  .format(`0.[00]${formatSuffix}`)
584
- .replace(/iB/g, unit);
584
+ .replace(/(iB|B)/g, unit);
585
585
 
586
586
  if (lt(value, 0)) {
587
587
  return `-${formattedMetricValue}`;
@@ -12,11 +12,14 @@ import {
12
12
  length,
13
13
  lt,
14
14
  lte,
15
- pluck
15
+ pluck,
16
+ type
16
17
  } from 'ramda';
17
18
 
18
19
  import { Theme, darken, getLuminance, lighten } from '@mui/material';
19
20
 
21
+ import { BarStyle } from '../BarChart/models';
22
+ import { LineStyle } from '../Chart/models';
20
23
  import { Threshold, Thresholds } from './models';
21
24
  import { formatMetricValue } from './timeSeries';
22
25
  import { Line, TimeValue } from './timeSeries/models';
@@ -182,6 +185,24 @@ export const commonTickLabelProps = {
182
185
  textAnchor: 'middle'
183
186
  };
184
187
 
188
+ interface GetStyleProps {
189
+ metricId?: number;
190
+ style:
191
+ | LineStyle
192
+ | BarStyle
193
+ | Array<LineStyle & { metricId: number }>
194
+ | Array<BarStyle & { metricId: number }>;
195
+ }
196
+
197
+ export const getStyle = ({
198
+ style,
199
+ metricId
200
+ }: GetStyleProps): BarStyle | LineStyle => {
201
+ return equals(type(style), 'Array')
202
+ ? style.find((metricStyle) => equals(metricId, metricStyle.metricId))
203
+ : style;
204
+ };
205
+
185
206
  interface GetFormattedAxisValuesProps {
186
207
  thresholdUnit?: string;
187
208
  axisUnit: string;
@@ -329,20 +329,7 @@
329
329
  0.32339333333,
330
330
  null
331
331
  ],
332
- "prints": [
333
- [
334
- "Last:0.32"
335
- ],
336
- [
337
- "Min:0.03"
338
- ],
339
- [
340
- "Max:0.97"
341
- ],
342
- [
343
- "Average:0.51"
344
- ]
345
- ],
332
+ "prints": [["Last:0.32"], ["Min:0.03"], ["Max:0.97"], ["Average:0.51"]],
346
333
  "last_value": 0.32,
347
334
  "minimum_value": 0.03,
348
335
  "maximum_value": 0.97,
@@ -667,18 +654,10 @@
667
654
  null
668
655
  ],
669
656
  "prints": [
670
- [
671
- "Last:87.27"
672
- ],
673
- [
674
- "Min:70.31"
675
- ],
676
- [
677
- "Max:88.03"
678
- ],
679
- [
680
- "Average:78.07"
681
- ]
657
+ ["Last:87.27"],
658
+ ["Min:70.31"],
659
+ ["Max:88.03"],
660
+ ["Average:78.07"]
682
661
  ],
683
662
  "last_value": 87.27,
684
663
  "minimum_value": 70.31,
@@ -1003,20 +982,7 @@
1003
982
  null,
1004
983
  null
1005
984
  ],
1006
- "prints": [
1007
- [
1008
- "Last:0.65"
1009
- ],
1010
- [
1011
- "Min:0.03"
1012
- ],
1013
- [
1014
- "Max:0.98"
1015
- ],
1016
- [
1017
- "Average:0.50"
1018
- ]
1019
- ],
985
+ "prints": [["Last:0.65"], ["Min:0.03"], ["Max:0.98"], ["Average:0.50"]],
1020
986
  "last_value": 0.65,
1021
987
  "minimum_value": 0.03,
1022
988
  "maximum_value": 0.98,
@@ -62,7 +62,7 @@
62
62
  "ds_filled": true,
63
63
  "ds_invert": false,
64
64
  "ds_legend": null,
65
- "ds_stack": false,
65
+ "ds_stack": true,
66
66
  "ds_order": 1,
67
67
  "ds_transparency": 80.0,
68
68
  "ds_color_line_mode": 0
@@ -99,7 +99,7 @@
99
99
  "ds_filled": true,
100
100
  "ds_invert": false,
101
101
  "ds_legend": null,
102
- "ds_stack": false,
102
+ "ds_stack": true,
103
103
  "ds_order": 1,
104
104
  "ds_transparency": 80.0,
105
105
  "ds_color_line_mode": 0
@@ -144,7 +144,7 @@
144
144
  "ds_filled": false,
145
145
  "ds_invert": false,
146
146
  "ds_legend": null,
147
- "ds_stack": false,
147
+ "ds_stack": true,
148
148
  "ds_order": 2,
149
149
  "ds_transparency": 80.0,
150
150
  "ds_color_line_mode": 0
@@ -97,15 +97,17 @@ const SelectField = ({
97
97
  <Select
98
98
  displayEmpty
99
99
  fullWidth={fullWidth}
100
- inputProps={{
101
- 'aria-label': ariaLabel,
102
- className: cx(classes.input, {
103
- [classes.noLabelInput]: !label && !compact,
104
- [classes.compact]: compact
105
- }),
106
- 'data-testid': dataTestId,
107
- id: getNormalizedId(dataTestId || ''),
108
- ...inputProps
100
+ slotProps={{
101
+ input: {
102
+ 'aria-label': ariaLabel,
103
+ className: cx(classes.input, {
104
+ [classes.noLabelInput]: !label && !compact,
105
+ [classes.compact]: compact
106
+ }),
107
+ 'data-testid': dataTestId,
108
+ id: getNormalizedId(dataTestId || ''),
109
+ ...inputProps
110
+ }
109
111
  }}
110
112
  label={label}
111
113
  renderValue={(id): string => {
@@ -237,35 +237,33 @@ describe('Listing', () => {
237
237
  it('selects displayed rows when a row is selected and another row is selected with the shift key', () => {
238
238
  mountListingForSubItems({ canCheckSubItems: true, isSmallListing: true });
239
239
 
240
- cy.findByLabelText('Expand 0').click();
240
+ cy.findByLabelText('Expand 2').click();
241
241
 
242
- cy.findByLabelText('Collapse 0').should('be.visible');
242
+ cy.findByLabelText('Collapse 2').should('be.visible');
243
243
 
244
- cy.findAllByLabelText('Select row 0').eq(0).click();
244
+ cy.findAllByLabelText('Select row 2').eq(0).click();
245
245
  cy.get('body').type('{shift}', { release: false });
246
246
  cy.findByLabelText('Select row 50').eq(0).click();
247
247
 
248
- cy.findAllByLabelText('Select row 0').eq(0).should('be.checked');
249
- cy.findAllByLabelText('Select row 0').eq(1).should('be.checked');
248
+ cy.findAllByLabelText('Select row 2').eq(0).should('be.checked');
250
249
  cy.findByLabelText('Select row 10').should('be.checked');
251
250
  cy.findByLabelText('Select row 20').should('be.checked');
252
251
  cy.findByLabelText('Select row 30').should('be.checked');
253
252
  cy.findByLabelText('Select row 40').should('be.checked');
254
- cy.findByLabelText('Select row 50').should('be.checked');
255
253
 
256
- cy.findByLabelText('Collapse 0').click();
254
+ cy.findByLabelText('Collapse 2').click();
257
255
  });
258
256
 
259
257
  it('selects displayed rows when the corresponding checkbox is clicked', () => {
260
258
  mountListingForSubItems({ canCheckSubItems: true, isSmallListing: true });
261
259
 
262
- cy.findByLabelText('Expand 0').click();
260
+ cy.findByLabelText('Expand 2').click();
263
261
 
264
- cy.findByLabelText('Collapse 0').should('be.visible');
262
+ cy.findByLabelText('Collapse 2').should('be.visible');
265
263
 
266
264
  cy.findAllByLabelText('Select all').eq(0).click();
267
265
 
268
- cy.findAllByLabelText('Select row 0').eq(0).should('be.checked');
266
+ cy.findAllByLabelText('Select row 2').eq(0).should('be.checked');
269
267
  tenElements.forEach((_, index) => {
270
268
  if (index === 0) {
271
269
  cy.findAllByLabelText('Select row 0').eq(1).should('be.checked');
@@ -277,7 +275,7 @@ describe('Listing', () => {
277
275
  cy.findByLabelText('Select row 1').should('be.checked');
278
276
  cy.findByLabelText('Select row 2').should('be.checked');
279
277
 
280
- cy.findByLabelText('Collapse 0').click();
278
+ cy.findByLabelText('Collapse 2').click();
281
279
  });
282
280
  });
283
281
 
@@ -2,7 +2,7 @@ import { $generateHtmlFromNodes } from '@lexical/html';
2
2
  import { AutoLinkNode, LinkNode } from '@lexical/link';
3
3
  import { ListItemNode, ListNode } from '@lexical/list';
4
4
  import { LexicalComposer } from '@lexical/react/LexicalComposer';
5
- import LexicalErrorBoundary from '@lexical/react/LexicalErrorBoundary';
5
+ import { LexicalErrorBoundary } from '@lexical/react/LexicalErrorBoundary';
6
6
  import { HistoryPlugin } from '@lexical/react/LexicalHistoryPlugin';
7
7
  import { LinkPlugin } from '@lexical/react/LexicalLinkPlugin';
8
8
  import { ListPlugin } from '@lexical/react/LexicalListPlugin';
@@ -2,17 +2,12 @@ import useMutationQuery, { Method } from '.';
2
2
  import SnackbarProvider from '../../Snackbar/SnackbarProvider';
3
3
  import TestQueryProvider from '../TestQueryProvider';
4
4
 
5
- // biome-ignore lint/suspicious/noImplicitAnyLet: <explanation>
6
- let spyMutation;
7
-
8
5
  const TestComponent = (props) => {
9
6
  const mutation = useMutationQuery({
10
7
  ...props,
11
8
  getEndpoint: () => '/endpoint'
12
9
  });
13
10
 
14
- spyMutation = mutation;
15
-
16
11
  return (
17
12
  <button
18
13
  type="button"
@@ -46,8 +41,6 @@ const initialize = ({ mutationProps, isError = false }) => {
46
41
  </TestQueryProvider>
47
42
  </SnackbarProvider>
48
43
  )
49
- }).then(() => {
50
- cy.spy(spyMutation, 'mutateAsync').as('mutateAsync');
51
44
  });
52
45
  };
53
46
 
@@ -67,13 +60,6 @@ describe('useMutationQuery', () => {
67
60
  expect(request.body).to.deep.equal({ a: 'a', b: 2, c: ['arr', 'ay'] });
68
61
  expect(request.headers.get('content-type')).to.equal('application/json');
69
62
  });
70
- cy.get('@mutateAsync').should('be.calledWith', {
71
- payload: {
72
- a: 'a',
73
- b: 2,
74
- c: ['arr', 'ay']
75
- }
76
- });
77
63
  });
78
64
 
79
65
  it("shows an error from the API via the Snackbar and inside the browser's console when posting data to an endpoint", () => {
@@ -87,8 +73,6 @@ describe('useMutationQuery', () => {
87
73
 
88
74
  cy.get('button').click();
89
75
 
90
- cy.get('@mutateAsync').should('be.called');
91
-
92
76
  cy.contains('custom error message').should('be.visible');
93
77
  });
94
78
 
@@ -104,8 +88,6 @@ describe('useMutationQuery', () => {
104
88
 
105
89
  cy.get('button').click();
106
90
 
107
- cy.get('@mutateAsync').should('be.called');
108
-
109
91
  cy.contains('custom error message').should('not.exist');
110
92
  });
111
93
  });
@@ -1,6 +1,9 @@
1
1
  import { ReactElement, ReactNode, useMemo } from 'react';
2
2
 
3
- import { Button as MuiButton } from '@mui/material';
3
+ import {
4
+ Button as MuiButton,
5
+ ButtonProps as MuiButtonProps
6
+ } from '@mui/material';
4
7
 
5
8
  import { AriaLabelingAttributes } from '../../@types/aria-attributes';
6
9
  import { DataTestAttributes } from '../../@types/data-attributes';
@@ -16,20 +19,21 @@ const muiVariantMap: Record<
16
19
  secondary: 'outlined'
17
20
  };
18
21
 
19
- export type ButtonProps = {
20
- children: ReactNode;
21
- className?: string;
22
- disabled?: boolean;
23
- icon?: string | ReactNode;
24
- iconVariant?: 'none' | 'start' | 'end';
25
- isDanger?: boolean;
26
- onClick?: (e) => void;
27
- ref?: React.Ref<HTMLButtonElement>;
28
- size?: 'small' | 'medium' | 'large';
29
- type?: 'button' | 'submit' | 'reset';
30
- variant?: 'primary' | 'secondary' | 'ghost';
31
- } & AriaLabelingAttributes &
32
- DataTestAttributes;
22
+ export type ButtonProps = AriaLabelingAttributes &
23
+ DataTestAttributes &
24
+ Omit<MuiButtonProps, 'variant'> & {
25
+ children: ReactNode;
26
+ className?: string;
27
+ disabled?: boolean;
28
+ icon?: string | ReactNode;
29
+ iconVariant?: 'none' | 'start' | 'end';
30
+ isDanger?: boolean;
31
+ onClick?: (e) => void;
32
+ ref?: React.Ref<HTMLButtonElement>;
33
+ size?: 'small' | 'medium' | 'large';
34
+ type?: 'button' | 'submit' | 'reset';
35
+ variant?: 'primary' | 'secondary' | 'ghost';
36
+ };
33
37
 
34
38
  const Button = ({
35
39
  children,
@@ -16,7 +16,7 @@ describe('CollapsibleItem', () => {
16
16
 
17
17
  cy.contains(title).should('be.visible');
18
18
  cy.contains('Content').should('not.be.visible');
19
- cy.get('div[aria-expanded="false"]').should('exist');
19
+ cy.get('button[aria-expanded="false"]').should('exist');
20
20
 
21
21
  cy.makeSnapshot();
22
22
  });
@@ -26,7 +26,7 @@ describe('CollapsibleItem', () => {
26
26
 
27
27
  cy.contains(title).should('be.visible');
28
28
  cy.contains('Content').should('be.visible');
29
- cy.get('div[aria-expanded="true"]').should('exist');
29
+ cy.get('button[aria-expanded="true"]').should('exist');
30
30
 
31
31
  cy.makeSnapshot();
32
32
  });
@@ -35,7 +35,7 @@ describe('CollapsibleItem', () => {
35
35
  initialize({ title: customizedTitle });
36
36
 
37
37
  cy.contains('Customized title').should('be.visible');
38
- cy.get('div[aria-expanded="false"]').should('exist');
38
+ cy.get('button[aria-expanded="false"]').should('exist');
39
39
 
40
40
  cy.makeSnapshot();
41
41
  });
@@ -44,7 +44,7 @@ describe('CollapsibleItem', () => {
44
44
  initialize({ compact: true, title });
45
45
 
46
46
  cy.contains(title).should('be.visible');
47
- cy.get('div[aria-expanded="false"]').should('exist');
47
+ cy.get('button[aria-expanded="false"]').should('exist');
48
48
  cy.get('div[data-compact="true"]').should('exist');
49
49
 
50
50
  cy.makeSnapshot();
@@ -54,11 +54,11 @@ describe('CollapsibleItem', () => {
54
54
  initialize({ compact: true, title });
55
55
 
56
56
  cy.contains(title).should('be.visible');
57
- cy.get('div[aria-expanded="false"]').should('exist');
57
+ cy.get('button[aria-expanded="false"]').should('exist');
58
58
 
59
- cy.get('div[aria-expanded="false"]').click();
59
+ cy.get('button[aria-expanded="false"]').click();
60
60
 
61
- cy.get('div[aria-expanded="true"]').should('exist');
61
+ cy.get('button[aria-expanded="true"]').should('exist');
62
62
  cy.contains('Content').should('be.visible');
63
63
 
64
64
  cy.makeSnapshot();
@@ -68,7 +68,7 @@ describe('CollapsibleItem', () => {
68
68
  initialize({ compact: true, title: customizedTitle });
69
69
 
70
70
  cy.contains('Customized title').should('be.visible');
71
- cy.get('div[aria-expanded="false"]').should('exist');
71
+ cy.get('button[aria-expanded="false"]').should('exist');
72
72
  cy.get('div[data-compact="true"]').should('exist');
73
73
 
74
74
  cy.makeSnapshot();
@@ -1,5 +1,4 @@
1
1
  import { ThemeMode, userAtom } from '@centreon/ui-context';
2
- import { mount } from 'cypress/react18';
3
2
  import { Provider, createStore } from 'jotai';
4
3
  import SnackbarProvider from '../../Snackbar/SnackbarProvider';
5
4
  import ThemeProvider from '../../ThemeProvider';
@@ -8,15 +7,17 @@ import CopyCommand, { CopyCommandProps } from './CopyCommand';
8
7
  const initialize = (props: CopyCommandProps & { theme?: ThemeMode }): void => {
9
8
  const store = createStore();
10
9
  store.set(userAtom, { themeMode: props.theme || ThemeMode.light });
11
- mount(
12
- <Provider store={store}>
13
- <ThemeProvider>
14
- <SnackbarProvider>
15
- <CopyCommand {...props} />
16
- </SnackbarProvider>
17
- </ThemeProvider>
18
- </Provider>
19
- );
10
+ cy.mount({
11
+ Component: (
12
+ <Provider store={store}>
13
+ <ThemeProvider>
14
+ <SnackbarProvider>
15
+ <CopyCommand {...props} />
16
+ </SnackbarProvider>
17
+ </ThemeProvider>
18
+ </Provider>
19
+ )
20
+ });
20
21
  };
21
22
 
22
23
  describe('CopyCommand', () => {
@@ -1,34 +0,0 @@
1
- import { useTranslation } from 'react-i18next';
2
-
3
- import CheckIcon from '@mui/icons-material/Check';
4
- import SaveIcon from '@mui/icons-material/Save';
5
-
6
- interface Props {
7
- labelLoading: string;
8
- labelSave: string;
9
- labelSucceeded: string;
10
- loading: boolean;
11
- succeeded: boolean;
12
- }
13
-
14
- const Content = ({
15
- succeeded,
16
- labelSucceeded,
17
- labelSave,
18
- loading,
19
- labelLoading
20
- }: Props): JSX.Element | string | null => {
21
- const { t } = useTranslation();
22
-
23
- if (loading) {
24
- return t(labelLoading);
25
- }
26
-
27
- if (succeeded) {
28
- return labelSucceeded ? t(labelSucceeded) : <CheckIcon />;
29
- }
30
-
31
- return labelSave ? t(labelSave) : <SaveIcon />;
32
- };
33
-
34
- export default Content;
@@ -1,24 +0,0 @@
1
- import { T, always, cond, not, pipe, propEq } from 'ramda';
2
-
3
- import CheckIcon from '@mui/icons-material/Check';
4
- import SaveIcon from '@mui/icons-material/Save';
5
-
6
- interface StartIconConfigProps {
7
- hasLabel: boolean;
8
- loading: boolean;
9
- succeeded: boolean;
10
- }
11
-
12
- interface Props {
13
- startIconConfig: StartIconConfigProps;
14
- }
15
-
16
- const StartIcon = ({ startIconConfig }: Props): JSX.Element | null =>
17
- cond<Array<StartIconConfigProps>, JSX.Element | null>([
18
- [pipe(propEq(true, 'hasLabel'), not), always(null)],
19
- [propEq(true, 'succeeded'), always(<CheckIcon />)],
20
- [propEq(true, 'loading'), always(<SaveIcon />)],
21
- [T, always(<SaveIcon />)]
22
- ])(startIconConfig);
23
-
24
- export default StartIcon;