@centreon/ui 24.4.1-MON-25027-refactor-access-rights.2 → 24.4.1-MON-32982-migrate-playlists-front-code.4

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 (40) hide show
  1. package/package.json +1 -6
  2. package/public/mockServiceWorker.js +2 -2
  3. package/src/FallbackPage/FallbackPage.tsx +3 -3
  4. package/src/InputField/Select/Autocomplete/Connected/index.tsx +3 -12
  5. package/src/Listing/Cell/DataCell.tsx +15 -1
  6. package/src/Module/LicensedModule/LicenseCheck/index.tsx +25 -10
  7. package/src/Module/LicensedModule/index.tsx +7 -1
  8. package/src/Module/Module.cypress.spec.tsx +129 -0
  9. package/src/Module/index.tsx +2 -4
  10. package/src/components/Form/index.ts +0 -1
  11. package/src/components/List/Item/ListItem.styles.ts +0 -6
  12. package/src/components/List/Item/ListItem.tsx +1 -3
  13. package/src/components/List/Item/Text.tsx +3 -5
  14. package/src/components/Form/AccessRightsV2/AccessRights.cypress.spec.tsx +0 -346
  15. package/src/components/Form/AccessRightsV2/AccessRights.stories.tsx +0 -119
  16. package/src/components/Form/AccessRightsV2/AccessRights.styles.ts +0 -10
  17. package/src/components/Form/AccessRightsV2/AccessRights.tsx +0 -56
  18. package/src/components/Form/AccessRightsV2/Actions/Actions.styles.ts +0 -14
  19. package/src/components/Form/AccessRightsV2/Actions/Actions.tsx +0 -60
  20. package/src/components/Form/AccessRightsV2/Actions/useActions.ts +0 -70
  21. package/src/components/Form/AccessRightsV2/List/Item.tsx +0 -90
  22. package/src/components/Form/AccessRightsV2/List/List.styles.tsx +0 -45
  23. package/src/components/Form/AccessRightsV2/List/List.tsx +0 -52
  24. package/src/components/Form/AccessRightsV2/List/ListItemSkeleton.tsx +0 -18
  25. package/src/components/Form/AccessRightsV2/List/ListSkeleton.tsx +0 -22
  26. package/src/components/Form/AccessRightsV2/List/RemoveAccessRight.tsx +0 -38
  27. package/src/components/Form/AccessRightsV2/List/StateChip.tsx +0 -28
  28. package/src/components/Form/AccessRightsV2/List/useItem.ts +0 -64
  29. package/src/components/Form/AccessRightsV2/Provider.tsx +0 -13
  30. package/src/components/Form/AccessRightsV2/ShareInput/ContactSwitch.tsx +0 -42
  31. package/src/components/Form/AccessRightsV2/ShareInput/ShareInput.styles.ts +0 -9
  32. package/src/components/Form/AccessRightsV2/ShareInput/ShareInput.tsx +0 -77
  33. package/src/components/Form/AccessRightsV2/ShareInput/useShareInput.tsx +0 -109
  34. package/src/components/Form/AccessRightsV2/Stats/Stats.tsx +0 -36
  35. package/src/components/Form/AccessRightsV2/atoms.ts +0 -97
  36. package/src/components/Form/AccessRightsV2/common/RoleSelectField.styles.tsx +0 -7
  37. package/src/components/Form/AccessRightsV2/common/RoleSelectField.tsx +0 -45
  38. package/src/components/Form/AccessRightsV2/models.ts +0 -54
  39. package/src/components/Form/AccessRightsV2/storiesData.ts +0 -221
  40. package/src/components/Form/AccessRightsV2/useAccessRightsInitValues.ts +0 -42
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@centreon/ui",
3
- "version": "24.4.1-MON-25027-refactor-access-rights.2",
3
+ "version": "24.4.1-MON-32982-migrate-playlists-front-code.4",
4
4
  "description": "Centreon UI Components",
5
5
  "scripts": {
6
6
  "eslint": "eslint ./src --ext .js,.jsx,.ts,.tsx --max-warnings 0",
@@ -85,8 +85,6 @@
85
85
  "identity-obj-proxy": "^3.0.0",
86
86
  "jest-transform-stub": "^2.0.0",
87
87
  "mochawesome": "^7.1.3",
88
- "msw": "1.3.2",
89
- "msw-storybook-addon": "^1.10.0",
90
88
  "puppeteer": "^13.7.0",
91
89
  "react": "^18.2.0",
92
90
  "react-dom": "^18.2.0",
@@ -159,8 +157,5 @@
159
157
  "jest-junit": {
160
158
  "suiteName": "jest tests",
161
159
  "output": "./junit.xml"
162
- },
163
- "msw": {
164
- "workerDirectory": "public"
165
160
  }
166
161
  }
@@ -2,7 +2,7 @@
2
2
  /* tslint:disable */
3
3
 
4
4
  /**
5
- * Mock Service Worker (1.3.2).
5
+ * Mock Service Worker (1.2.1).
6
6
  * @see https://github.com/mswjs/msw
7
7
  * - Please do NOT modify this file.
8
8
  * - Please do NOT serve this file on production.
@@ -300,4 +300,4 @@ function sleep(timeMs) {
300
300
  async function respondWithMock(response) {
301
301
  await sleep(response.delay)
302
302
  return new Response(response.body, response)
303
- }
303
+ }
@@ -17,7 +17,7 @@ const useStyles = makeStyles()((theme) => ({
17
17
  logo: {
18
18
  alignSelf: 'flex-end',
19
19
  height: theme.spacing(11),
20
- width: '22rem'
20
+ width: '239px'
21
21
  },
22
22
  message: {
23
23
  color: theme.palette.text.primary
@@ -66,9 +66,9 @@ export const FallbackPage: FC<FallbackPageProps> = typedMemo(
66
66
 
67
67
  return (
68
68
  <div className={classes.notAuthorizedContainer}>
69
- <section className={classes.logo}>
69
+ <div className={classes.logo}>
70
70
  <CentreonLogo />
71
- </section>
71
+ </div>
72
72
  <section className={classes.messageBlock}>
73
73
  <header>
74
74
  <Typography color="primary" fontWeight="bold" variant="h3">
@@ -33,7 +33,6 @@ import useFetchQuery from '../../../../api/useFetchQuery';
33
33
  export interface ConnectedAutoCompleteFieldProps<TData> {
34
34
  allowUniqOption?: boolean;
35
35
  baseEndpoint?: string;
36
- changeIdValue: (item: TData) => number | string;
37
36
  conditionField?: keyof SelectEntry;
38
37
  field: string;
39
38
  getEndpoint: ({ search, page }) => string;
@@ -63,7 +62,6 @@ const ConnectedAutocompleteField = (
63
62
  queryKey,
64
63
  allowUniqOption,
65
64
  baseEndpoint,
66
- changeIdValue,
67
65
  ...props
68
66
  }: ConnectedAutoCompleteFieldProps<TData> &
69
67
  Omit<AutocompleteFieldProps, 'options'>): JSX.Element => {
@@ -240,24 +238,17 @@ const ConnectedAutocompleteField = (
240
238
 
241
239
  const moreOptions = page > 1 ? options : [];
242
240
 
243
- const formattedList = changeIdValue
244
- ? newOptions.result.map((item) => ({
245
- ...item,
246
- id: changeIdValue(item)
247
- }))
248
- : newOptions.result;
249
-
250
241
  if (!isEmpty(labelKey) && !isNil(labelKey)) {
251
- const list = formattedList.map((item) =>
242
+ const list = newOptions.result.map((item) =>
252
243
  renameKey({ key: labelKey, newKey: 'name', object: item })
253
244
  );
254
245
  setOptions(moreOptions.concat(list as Array<TData>));
255
246
 
256
247
  return;
257
248
  }
258
- setOptions(moreOptions.concat(formattedList));
249
+ setOptions(moreOptions.concat(newOptions.result));
259
250
 
260
- setOptions(moreOptions.concat(formattedList as Array<TData>));
251
+ setOptions(moreOptions.concat(newOptions.result as Array<TData>));
261
252
 
262
253
  const total = prop('total', newOptions.meta) || 1;
263
254
  const limit = prop('limit', newOptions.meta) || 1;
@@ -107,7 +107,21 @@ const DataCell = ({
107
107
  const isCellHidden = getHiddenCondition?.(isRowSelected);
108
108
 
109
109
  if (isCellHidden) {
110
- return null;
110
+ return (
111
+ <Cell
112
+ className={classes.cell}
113
+ isRowHighlighted={isRowHighlighted}
114
+ listingVariant={listingVariant}
115
+ onClick={(e): void => {
116
+ if (!clickable) {
117
+ return;
118
+ }
119
+ e.preventDefault();
120
+ e.stopPropagation();
121
+ }}
122
+ {...commonCellProps}
123
+ />
124
+ );
111
125
  }
112
126
 
113
127
  return (
@@ -1,10 +1,7 @@
1
- import * as React from 'react';
2
-
3
- import { isNil } from 'ramda';
4
1
  import { useTranslation } from 'react-i18next';
5
2
 
6
3
  import { FallbackPage } from '../../../FallbackPage/FallbackPage';
7
- import { PageSkeleton, useFetchQuery } from '../../..';
4
+ import { MenuSkeleton, PageSkeleton, useFetchQuery } from '../../..';
8
5
  import { getModuleLicenseCheckEndpoint } from '../api';
9
6
 
10
7
  import { licenseDecoder } from './decoder';
@@ -17,17 +14,27 @@ import {
17
14
 
18
15
  export interface LicenseCheckProps {
19
16
  children: React.ReactElement;
17
+ isFederatedComponent?: boolean;
20
18
  moduleName: string;
21
19
  }
22
20
 
23
21
  interface ContentProps {
24
22
  children: React.ReactElement;
23
+ isFederatedComponent?: boolean;
25
24
  isValid: boolean;
26
25
  }
27
26
 
28
- const Content = ({ children, isValid }: ContentProps): JSX.Element => {
27
+ const Content = ({
28
+ children,
29
+ isValid,
30
+ isFederatedComponent
31
+ }: ContentProps): JSX.Element | null => {
29
32
  const { t } = useTranslation();
30
33
 
34
+ if (isFederatedComponent && !isValid) {
35
+ return null;
36
+ }
37
+
31
38
  return isValid ? (
32
39
  children
33
40
  ) : (
@@ -41,9 +48,10 @@ const Content = ({ children, isValid }: ContentProps): JSX.Element => {
41
48
 
42
49
  const LicenseCheck = ({
43
50
  children,
44
- moduleName
51
+ moduleName,
52
+ isFederatedComponent
45
53
  }: LicenseCheckProps): JSX.Element | null => {
46
- const { isError, data } = useFetchQuery<License>({
54
+ const { isError, data, isLoading } = useFetchQuery<License>({
47
55
  decoder: licenseDecoder,
48
56
  getEndpoint: () => getModuleLicenseCheckEndpoint(moduleName),
49
57
  getQueryKey: () => ['license', moduleName]
@@ -55,10 +63,17 @@ const LicenseCheck = ({
55
63
 
56
64
  const isValid = data?.success;
57
65
 
58
- return isNil(isValid) ? (
59
- <PageSkeleton />
66
+ const skeleton = isFederatedComponent ? <MenuSkeleton /> : <PageSkeleton />;
67
+
68
+ return isLoading ? (
69
+ skeleton
60
70
  ) : (
61
- <Content isValid={isValid as boolean}>{children}</Content>
71
+ <Content
72
+ isFederatedComponent={isFederatedComponent}
73
+ isValid={isValid as boolean}
74
+ >
75
+ {children}
76
+ </Content>
62
77
  );
63
78
  };
64
79
 
@@ -7,11 +7,17 @@ type Props = ModuleProps & LicenseCheckProps;
7
7
  const LicensedModule = ({
8
8
  moduleName,
9
9
  children,
10
+ isFederatedComponent,
10
11
  ...props
11
12
  }: Props): JSX.Element => {
12
13
  return (
13
14
  <Module {...props}>
14
- <LicenseCheck moduleName={moduleName}>{children}</LicenseCheck>
15
+ <LicenseCheck
16
+ isFederatedComponent={isFederatedComponent}
17
+ moduleName={moduleName}
18
+ >
19
+ {children}
20
+ </LicenseCheck>
15
21
  </Module>
16
22
  );
17
23
  };
@@ -0,0 +1,129 @@
1
+ import { createStore } from 'jotai';
2
+
3
+ import { Method } from '..';
4
+
5
+ import LicensedModule from './LicensedModule';
6
+
7
+ import Module from '.';
8
+
9
+ const initializeModule = (): void => {
10
+ cy.mount({
11
+ Component: (
12
+ <Module seedName="seed" store={createStore()}>
13
+ <p>Module</p>
14
+ </Module>
15
+ )
16
+ });
17
+ };
18
+
19
+ const initializeModuleWithValidLicense = (
20
+ isFederatedComponent = false
21
+ ): void => {
22
+ cy.interceptAPIRequest({
23
+ alias: 'getValidLicense',
24
+ method: Method.GET,
25
+ path: './api/internal.php?object=centreon_license_manager&action=licenseValid&productName=valid',
26
+ response: {
27
+ success: true
28
+ }
29
+ });
30
+
31
+ cy.mount({
32
+ Component: (
33
+ <div style={{ height: '100vh' }}>
34
+ <LicensedModule
35
+ isFederatedComponent={isFederatedComponent}
36
+ moduleName="valid"
37
+ seedName="seed"
38
+ store={createStore()}
39
+ >
40
+ <p>Module</p>
41
+ </LicensedModule>
42
+ </div>
43
+ )
44
+ });
45
+ };
46
+
47
+ const initializeModuleWithInvalidLicense = (
48
+ isFederatedComponent = false
49
+ ): void => {
50
+ cy.interceptAPIRequest({
51
+ alias: 'getInvalidLicense',
52
+ method: Method.GET,
53
+ path: './api/internal.php?object=centreon_license_manager&action=licenseValid&productName=invalid',
54
+ response: {
55
+ success: false
56
+ }
57
+ });
58
+
59
+ cy.mount({
60
+ Component: (
61
+ <div style={{ height: '100vh' }}>
62
+ <LicensedModule
63
+ isFederatedComponent={isFederatedComponent}
64
+ moduleName="invalid"
65
+ seedName="seed"
66
+ store={createStore()}
67
+ >
68
+ <p>Module</p>
69
+ </LicensedModule>
70
+ </div>
71
+ )
72
+ });
73
+ };
74
+
75
+ describe('Module', () => {
76
+ beforeEach(() => {
77
+ initializeModule();
78
+ });
79
+
80
+ it('displays the content of the module', () => {
81
+ cy.contains('Module').should('be.visible');
82
+
83
+ cy.makeSnapshot();
84
+ });
85
+ });
86
+
87
+ describe('Valid license module', () => {
88
+ it('displays the content of the page when the license is valid license', () => {
89
+ initializeModuleWithValidLicense();
90
+ cy.waitForRequest('@getValidLicense');
91
+
92
+ cy.contains('Module').should('be.visible');
93
+
94
+ cy.makeSnapshot();
95
+ });
96
+
97
+ it('displays the content of the component when the license is valid license', () => {
98
+ initializeModuleWithValidLicense(true);
99
+
100
+ cy.contains('Module').should('be.visible');
101
+
102
+ cy.makeSnapshot();
103
+ });
104
+ });
105
+
106
+ describe('Invalid license module', () => {
107
+ it('displays the content of the page when the license is invalid license', () => {
108
+ initializeModuleWithInvalidLicense();
109
+ cy.waitForRequest('@getInvalidLicense');
110
+
111
+ cy.contains('Module').should('not.exist');
112
+
113
+ cy.contains('Oops').should('be.visible');
114
+ cy.contains('License invalid or expired').should('be.visible');
115
+ cy.contains('Please contact your administrator.').should('be.visible');
116
+ cy.get('img[alt="License invalid or expired !"]').should('be.visible');
117
+ cy.get('img[alt="Centreon Logo"]').should('be.visible');
118
+
119
+ cy.makeSnapshot();
120
+ });
121
+
122
+ it('displays the content of the module when the license is invalid license', () => {
123
+ initializeModuleWithInvalidLicense(true);
124
+
125
+ cy.contains('Module').should('not.exist');
126
+
127
+ cy.makeSnapshot();
128
+ });
129
+ });
@@ -1,5 +1,3 @@
1
- import * as React from 'react';
2
-
3
1
  import { Provider as JotaiProvider, createStore } from 'jotai';
4
2
 
5
3
  import { createGenerateClassName, StylesProvider } from '@mui/styles';
@@ -9,7 +7,7 @@ import SnackbarProvider from '../Snackbar/SnackbarProvider';
9
7
 
10
8
  export interface ModuleProps {
11
9
  children: React.ReactElement;
12
- maxSnackbars: number;
10
+ maxSnackbars?: number;
13
11
  seedName: string;
14
12
  store: ReturnType<typeof createStore>;
15
13
  }
@@ -17,7 +15,7 @@ export interface ModuleProps {
17
15
  const Module = ({
18
16
  children,
19
17
  seedName,
20
- maxSnackbars,
18
+ maxSnackbars = 3,
21
19
  store
22
20
  }: ModuleProps): JSX.Element => {
23
21
  const generateClassName = createGenerateClassName({
@@ -1,4 +1,3 @@
1
1
  export * from './Form.models';
2
2
  export * from './Dashboard';
3
3
  export * from './AccessRights';
4
- export { default as AccessRightsV2 } from './AccessRightsV2/AccessRights';
@@ -23,12 +23,6 @@ export const useStyles = makeStyles()((theme) => ({
23
23
  paddingBottom: theme.spacing(1),
24
24
  paddingTop: theme.spacing(1)
25
25
  },
26
- secondary: {
27
- alignItems: 'center',
28
- display: 'flex',
29
- flexDirection: 'row',
30
- gap: theme.spacing(1)
31
- },
32
26
  text: {
33
27
  '&, &.MuiListItemText-root': {
34
28
  '& .MuiListItemText-primary': {
@@ -22,9 +22,7 @@ export const ListItem = forwardRef(
22
22
  disableGutters
23
23
  className={cx(classes.listItem, className)}
24
24
  ref={ref}
25
- secondaryAction={
26
- action && <div className={classes.secondary}>{action}</div>
27
- }
25
+ secondaryAction={action}
28
26
  {...attr}
29
27
  >
30
28
  {children}
@@ -5,21 +5,19 @@ import { ListItemText as MuiListItemText } from '@mui/material';
5
5
  import { useStyles } from './ListItem.styles';
6
6
 
7
7
  type TextProps = {
8
- className?: string;
9
8
  primaryText: ReactNode;
10
9
  secondaryText?: ReactNode;
11
10
  };
12
11
 
13
12
  export const Text = ({
14
13
  primaryText,
15
- secondaryText,
16
- className
14
+ secondaryText
17
15
  }: TextProps): ReactElement => {
18
- const { classes, cx } = useStyles();
16
+ const { classes } = useStyles();
19
17
 
20
18
  return (
21
19
  <MuiListItemText
22
- className={cx(classes.text, className)}
20
+ className={classes.text}
23
21
  primary={primaryText}
24
22
  secondary={secondaryText}
25
23
  />