@centreon/ui 25.3.2 → 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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@centreon/ui",
3
- "version": "25.3.2",
3
+ "version": "25.3.3",
4
4
  "description": "Centreon UI Components",
5
5
  "scripts": {
6
6
  "update:deps": "pnpx npm-check-updates -i --format group",
@@ -16,7 +16,10 @@
16
16
  "cypress:run:updateSnapshots": "cypress run --component --browser=chrome --env updateSnapshots=true",
17
17
  "cypress:run:coverage": "cypress run --component --browser=chrome --env codeCoverageTasksRegistered=true",
18
18
  "cypress:run": "cypress run --component --browser=chrome",
19
- "tokens:transform": "TS_NODE_PROJECT=tsconfig.node.json ts-node style-dictionary.transform.ts"
19
+ "cypress:install": "cypress install",
20
+ "cypress:cli": "./cypress/scripts/cypress-cli.sh",
21
+ "tokens:transform": "TS_NODE_PROJECT=tsconfig.node.json ts-node style-dictionary.transform.ts",
22
+ "install:arm:binaries": "pnpm i -D @swc/core-linux-arm64-gnu@1.6.6 @rspack/binding-linux-arm64-gnu@1.1.6 -w && pnpm remove @swc/core-linux-arm64-gnu @rspack/binding-linux-arm64-gnu"
20
23
  },
21
24
  "type": "module",
22
25
  "sideEffects": false,
@@ -50,71 +53,71 @@
50
53
  "test/*"
51
54
  ],
52
55
  "devDependencies": {
53
- "@cypress/react": "^8.0.2",
54
- "@cypress/webpack-dev-server": "^3.11.0",
55
- "@faker-js/faker": "^9.3.0",
56
+ "@cypress/react": "^9.0.0",
57
+ "@cypress/webpack-dev-server": "^4.0.1",
58
+ "@faker-js/faker": "^9.5.1",
56
59
  "@mdx-js/react": "^3.1.0",
57
60
  "@simonsmith/cypress-image-snapshot": "^9.1.0",
58
- "@storybook/addon-a11y": "^8.4.7",
59
- "@storybook/addon-docs": "^8.4.7",
60
- "@storybook/addon-essentials": "^8.4.7",
61
- "@storybook/addon-interactions": "^8.4.7",
62
- "@storybook/addon-themes": "^8.4.7",
63
- "@storybook/blocks": "^8.4.7",
64
- "@storybook/manager-api": "^8.4.7",
61
+ "@storybook/addon-a11y": "^8.6.3",
62
+ "@storybook/addon-docs": "^8.6.3",
63
+ "@storybook/addon-essentials": "^8.6.3",
64
+ "@storybook/addon-interactions": "^8.6.3",
65
+ "@storybook/addon-themes": "^8.6.3",
66
+ "@storybook/blocks": "^8.6.3",
67
+ "@storybook/manager-api": "^8.6.3",
65
68
  "@storybook/mdx2-csf": "^1.1.0",
66
- "@storybook/preview-api": "^8.4.7",
67
- "@storybook/react": "^8.4.7",
68
- "@storybook/react-vite": "^8.4.7",
69
- "@storybook/test": "^8.4.7",
70
- "@storybook/test-runner": "^0.20.1",
71
- "@storybook/theming": "^8.4.7",
72
- "@testing-library/cypress": "^10.0.2",
69
+ "@storybook/preview-api": "^8.6.3",
70
+ "@storybook/react": "^8.6.3",
71
+ "@storybook/react-vite": "^8.6.3",
72
+ "@storybook/test": "^8.6.3",
73
+ "@storybook/test-runner": "^0.22.0",
74
+ "@storybook/theming": "^8.6.3",
75
+ "@testing-library/cypress": "^10.0.3",
73
76
  "@testing-library/jest-dom": "^6.6.3",
74
- "@testing-library/react": "^16.1.0",
77
+ "@testing-library/react": "^16.2.0",
75
78
  "@testing-library/react-hooks": "^8.0.1",
76
79
  "@types/jest": "^29.5.14",
77
80
  "@types/mocha": "^10.0.10",
78
81
  "@types/ramda": "^0.30.2",
79
- "@types/react": "^18.3.3",
82
+ "@types/react": "^19.0.10",
80
83
  "@types/testing-library__jest-dom": "^6.0.0",
81
84
  "@vitejs/plugin-react": "^4.3.4",
82
- "@vitejs/plugin-react-swc": "^3.7.2",
83
- "chai": "^5.1.2",
84
- "cypress": "^13.16.1",
85
+ "@vitejs/plugin-react-swc": "^3.8.0",
86
+ "chai": "^5.2.0",
87
+ "cypress": "^14.1.0",
85
88
  "identity-obj-proxy": "^3.0.0",
86
89
  "jest-transform-stub": "^2.0.0",
87
90
  "mochawesome": "^7.1.3",
88
- "msw": "2.6.8",
91
+ "msw": "2.7.3",
89
92
  "msw-storybook-addon": "^2.0.4",
90
- "react": "^18.3.1",
91
- "react-dom": "^18.3.1",
93
+ "react": "^19.0.0",
94
+ "react-dom": "^19.0.0",
92
95
  "react-test-renderer": "^19.0.0",
93
- "remark-gfm": "^4.0.0",
96
+ "remark-gfm": "^4.0.1",
94
97
  "speed-measure-vite-plugin": "^1.1.0",
95
- "storybook": "^8.4.7",
98
+ "storybook": "^8.6.3",
96
99
  "storybook-addon-mock": "^5.0.0",
97
100
  "storybook-dark-mode": "^4.0.2",
98
- "style-dictionary": "^4.3.0",
101
+ "style-dictionary": "^4.3.3",
99
102
  "ts-node": "^10.9.2",
100
103
  "use-resize-observer": "^9.1.0",
101
- "vite": "^6.0.3",
102
- "vite-plugin-istanbul": "^6.0.2",
104
+ "vite": "^6.2.0",
105
+ "vite-plugin-istanbul": "^7.0.0",
103
106
  "vite-plugin-svgr": "^4.3.0",
104
107
  "vite-plugin-turbosnap": "^1.0.3"
105
108
  },
106
109
  "peerDependencies": {
107
- "@centreon/ui-context": "file:../ui-context"
110
+ "@centreon/ui-context": "link:../ui-context"
108
111
  },
109
112
  "dependencies": {
110
- "@lexical/html": "^0.21.0",
111
- "@lexical/link": "^0.21.0",
112
- "@lexical/list": "^0.21.0",
113
- "@lexical/react": "^0.21.0",
114
- "@lexical/rich-text": "^0.21.0",
115
- "@lexical/selection": "^0.21.0",
116
- "@lexical/utils": "^0.21.0",
117
- "@mui/material": "^6.2.0",
113
+ "@lexical/html": "^0.27.0",
114
+ "@lexical/link": "^0.27.0",
115
+ "@lexical/list": "^0.27.0",
116
+ "@lexical/react": "^0.27.0",
117
+ "@lexical/rich-text": "^0.27.0",
118
+ "@lexical/selection": "^0.27.0",
119
+ "@lexical/utils": "^0.27.0",
120
+ "@mui/material": "^6.4.6",
118
121
  "@react-spring/web": "^9.7.5",
119
122
  "@visx/clip-path": "^3.12.0",
120
123
  "@visx/curve": "^3.12.0",
@@ -133,18 +136,18 @@
133
136
  "anylogger": "^1.0.11",
134
137
  "d3-array": "3.2.4",
135
138
  "dayjs": "^1.11.13",
136
- "highlight.js": "^11.10.0",
137
- "html-react-parser": "^5.2.0",
139
+ "highlight.js": "^11.11.1",
140
+ "html-react-parser": "^5.2.2",
138
141
  "humanize-duration": "^3.32.1",
139
- "lexical": "^0.21.0",
140
- "notistack": "^3.0.1",
142
+ "lexical": "^0.27.0",
143
+ "notistack": "^3.0.2",
141
144
  "numeral": "^2.0.6",
142
145
  "ramda": "0.30.1",
143
146
  "react-grid-layout": "^1.5.0",
144
147
  "react-resizable": "^3.0.5",
145
148
  "react-router": "7",
146
149
  "react-transition-group": "^4.4.5",
147
- "sanitize-html": "^2.13.1",
150
+ "sanitize-html": "^2.14.0",
148
151
  "ulog": "^2.0.0-beta.19"
149
152
  },
150
153
  "jest-junit": {
@@ -8,7 +8,7 @@
8
8
  * - Please do NOT serve this file on production.
9
9
  */
10
10
 
11
- const PACKAGE_VERSION = '2.6.8'
11
+ const PACKAGE_VERSION = '2.7.3'
12
12
  const INTEGRITY_CHECKSUM = '00729d72e3b82faf54ca8b9621dbb96f'
13
13
  const IS_MOCKED_RESPONSE = Symbol('isMockedResponse')
14
14
  const activeClientIds = new Set()
@@ -1,13 +1,11 @@
1
- import { any, isEmpty, isNil, not, or, pipe } from 'ramda';
2
1
  import { makeStyles } from 'tss-react/mui';
3
2
 
4
- import { LoadingButton, LoadingButtonProps } from '@mui/lab';
5
3
  import { Theme, Tooltip } from '@mui/material';
6
4
 
7
5
  import { getNormalizedId } from '../../utils';
8
6
 
9
- import Content from './Content';
10
- import StartIcon from './StartIcon';
7
+ import { Button, ButtonProps } from '../../components';
8
+ import { useSave } from './useSave';
11
9
 
12
10
  const useStyles = makeStyles()((theme: Theme) => ({
13
11
  loadingButton: {
@@ -15,7 +13,7 @@ const useStyles = makeStyles()((theme: Theme) => ({
15
13
  }
16
14
  }));
17
15
 
18
- interface Props {
16
+ export interface Props {
19
17
  className?: string;
20
18
  labelLoading?: string;
21
19
  labelSave?: string;
@@ -28,15 +26,6 @@ interface Props {
28
26
  tooltipLabel?: string;
29
27
  }
30
28
 
31
- interface StartIconConfigProps {
32
- hasLabel: boolean;
33
- loading: boolean;
34
- succeeded: boolean;
35
- }
36
-
37
- const isNilOrEmpty = (value): boolean => or(isNil(value), isEmpty(value));
38
- const hasValue = any(pipe(isNilOrEmpty, not));
39
-
40
29
  const SaveButton = ({
41
30
  succeeded = false,
42
31
  loading = false,
@@ -48,20 +37,22 @@ const SaveButton = ({
48
37
  className,
49
38
  startIcon = true,
50
39
  ...rest
51
- }: Props & LoadingButtonProps): JSX.Element => {
40
+ }: Props & Omit<ButtonProps, 'children'>): JSX.Element => {
52
41
  const { classes, cx } = useStyles();
53
- const hasLabel = hasValue([labelLoading, labelSave, labelSucceeded]);
54
42
 
55
- const startIconConfig = {
56
- hasLabel,
43
+ const { content, startIconToDisplay, hasLabel } = useSave({
44
+ labelLoading,
45
+ labelSave,
46
+ labelSucceeded,
57
47
  loading,
58
- succeeded
59
- } as StartIconConfigProps;
48
+ succeeded,
49
+ startIcon
50
+ });
60
51
 
61
52
  return (
62
53
  <Tooltip placement="bottom" title={tooltipLabel}>
63
54
  <div>
64
- <LoadingButton
55
+ <Button
65
56
  aria-label="save button"
66
57
  className={cx(
67
58
  {
@@ -69,26 +60,17 @@ const SaveButton = ({
69
60
  },
70
61
  className
71
62
  )}
72
- color="primary"
73
63
  data-testid={labelSave}
74
64
  id={getNormalizedId(labelSave)}
75
65
  loading={loading}
76
- loadingPosition={labelLoading ? 'start' : 'center'}
66
+ loadingPosition={labelLoading ? 'start' : undefined}
77
67
  size={size}
78
- startIcon={
79
- startIcon && <StartIcon startIconConfig={startIconConfig} />
80
- }
81
- variant="contained"
68
+ startIcon={startIconToDisplay}
69
+ variant="primary"
82
70
  {...rest}
83
71
  >
84
- {Content({
85
- labelLoading,
86
- labelSave,
87
- labelSucceeded,
88
- loading,
89
- succeeded
90
- })}
91
- </LoadingButton>
72
+ {content}
73
+ </Button>
92
74
  </div>
93
75
  </Tooltip>
94
76
  );
@@ -0,0 +1,89 @@
1
+ import CheckIcon from '@mui/icons-material/Check';
2
+ import SaveIcon from '@mui/icons-material/Save';
3
+ import {
4
+ T,
5
+ always,
6
+ any,
7
+ cond,
8
+ isEmpty,
9
+ isNil,
10
+ not,
11
+ or,
12
+ pipe,
13
+ propEq
14
+ } from 'ramda';
15
+ import { useMemo } from 'react';
16
+ import { useTranslation } from 'react-i18next';
17
+ import { Props } from '.';
18
+
19
+ interface StartIconConfigProps {
20
+ hasLabel: boolean;
21
+ loading: boolean;
22
+ succeeded: boolean;
23
+ enabled: boolean;
24
+ }
25
+
26
+ const isNilOrEmpty = (value): boolean => or(isNil(value), isEmpty(value));
27
+ const hasValue = any(pipe(isNilOrEmpty, not));
28
+
29
+ interface UseSaveState {
30
+ content: string | JSX.Element;
31
+ startIconToDisplay: null | JSX.Element;
32
+ hasLabel: boolean;
33
+ }
34
+
35
+ export const useSave = ({
36
+ labelLoading,
37
+ labelSave,
38
+ labelSucceeded,
39
+ loading,
40
+ succeeded,
41
+ startIcon
42
+ }: Pick<
43
+ Props,
44
+ | 'startIcon'
45
+ | 'succeeded'
46
+ | 'loading'
47
+ | 'labelSave'
48
+ | 'labelSucceeded'
49
+ | 'labelLoading'
50
+ >): UseSaveState => {
51
+ const { t } = useTranslation();
52
+
53
+ const hasLabel = hasValue([labelLoading, labelSave, labelSucceeded]);
54
+
55
+ const startIconConfig = {
56
+ hasLabel,
57
+ loading,
58
+ succeeded,
59
+ enabled: startIcon
60
+ } as StartIconConfigProps;
61
+
62
+ const content = useMemo(() => {
63
+ if (loading) {
64
+ return t(labelLoading || 'loading');
65
+ }
66
+
67
+ if (succeeded) {
68
+ return labelSucceeded ? t(labelSucceeded) : <CheckIcon />;
69
+ }
70
+
71
+ return labelSave ? t(labelSave) : <SaveIcon />;
72
+ }, [labelLoading, labelSucceeded, labelSave, loading, succeeded]);
73
+
74
+ const startIconToDisplay = useMemo(() => {
75
+ return cond<Array<StartIconConfigProps>, JSX.Element | null>([
76
+ [propEq(true, 'enabled'), always(null)],
77
+ [pipe(propEq(true, 'hasLabel'), not), always(null)],
78
+ [propEq(true, 'succeeded'), always(<CheckIcon />)],
79
+ [propEq(true, 'loading'), always(<SaveIcon />)],
80
+ [T, always(<SaveIcon />)]
81
+ ])(startIconConfig);
82
+ }, [startIconConfig]);
83
+
84
+ return {
85
+ content,
86
+ startIconToDisplay,
87
+ hasLabel
88
+ };
89
+ };
@@ -1,6 +1,6 @@
1
1
  import { always, cond, equals } from 'ramda';
2
2
 
3
- import { LoadingSkeleton } from '../..';
3
+ import LoadingSkeleton from '../../LoadingSkeleton';
4
4
 
5
5
  import { InputProps, InputType } from './models';
6
6
 
@@ -80,11 +80,13 @@ const Radio = ({
80
80
  data-testid={`${dataTestId} ${optionLabel}`}
81
81
  disabled={disabled}
82
82
  id={getNormalizedId(`${dataTestId}${optionLabel}`)}
83
- inputProps={{
84
- 'aria-label':
85
- (equals(type(optionLabel), 'String') &&
86
- t(optionLabel as string)) ||
87
- ''
83
+ slotProps={{
84
+ input: {
85
+ 'aria-label':
86
+ (equals(type(optionLabel), 'String') &&
87
+ t(optionLabel as string)) ||
88
+ ''
89
+ }
88
90
  }}
89
91
  />
90
92
  }
@@ -58,8 +58,10 @@ const Switch = ({
58
58
  data-testid={dataTestId}
59
59
  disabled={disabled}
60
60
  id={getNormalizedId(dataTestId || '')}
61
- inputProps={{
62
- 'aria-label': t(label) || ''
61
+ slotProps={{
62
+ input: {
63
+ 'aria-label': t(label) || ''
64
+ }
63
65
  }}
64
66
  onChange={changeSwitchValue}
65
67
  />
@@ -758,8 +758,8 @@ describe('Lines and bars', () => {
758
758
  cy.get('path[data-metric="3"]').should('be.visible');
759
759
 
760
760
  cy.contains('some text').should('be.visible');
761
- cy.findByTestId('pink-3').should('be.visible');
762
- cy.findByTestId('red-0.15').should('be.visible');
761
+ cy.findByTestId('pink-3').should('exist');
762
+ cy.findByTestId('red-0.15').should('exist');
763
763
 
764
764
  cy.makeSnapshot();
765
765
  });
@@ -63,7 +63,7 @@ export const ThresholdLine = ({
63
63
  strokeDasharray="6, 6"
64
64
  strokeWidth={2}
65
65
  x1={scaledValue}
66
- x2={scaledValue}
66
+ x2={scaledValue + 1}
67
67
  y1={
68
68
  isSmall
69
69
  ? groupMargin - lineMargin + 6
@@ -80,7 +80,7 @@ export const ThresholdLine = ({
80
80
  stroke="transparent"
81
81
  strokeWidth={5}
82
82
  x1={scaledValue}
83
- x2={scaledValue}
83
+ x2={scaledValue + 1}
84
84
  y1={
85
85
  isSmall
86
86
  ? groupMargin - lineMargin + 5
@@ -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
  };
@@ -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;