@centreon/ui 24.4.1-MON-21273-list-tokens.21 → 24.4.1-MON-32982-migrate-playlists-front-code.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@centreon/ui",
3
- "version": "24.4.1-MON-21273-list-tokens.21",
3
+ "version": "24.4.1-MON-32982-migrate-playlists-front-code.0",
4
4
  "description": "Centreon UI Components",
5
5
  "scripts": {
6
6
  "eslint": "eslint ./src --ext .js,.jsx,.ts,.tsx --max-warnings 0",
@@ -1,6 +1,7 @@
1
+ import { useTranslation } from 'react-i18next';
2
+
1
3
  import CheckIcon from '@mui/icons-material/Check';
2
4
  import SaveIcon from '@mui/icons-material/Save';
3
- import { Typography, TypographyProps } from '@mui/material';
4
5
 
5
6
  interface Props {
6
7
  labelLoading: string;
@@ -10,42 +11,24 @@ interface Props {
10
11
  succeeded: boolean;
11
12
  }
12
13
 
13
- interface WrapperLabelProps {
14
- label: string;
15
- }
16
-
17
- const WrapperLabel = ({
18
- label,
19
- ...rest
20
- }: WrapperLabelProps & TypographyProps): JSX.Element => {
21
- return <Typography {...rest}>{label}</Typography>;
22
- };
23
-
24
14
  const Content = ({
25
15
  succeeded,
26
16
  labelSucceeded,
27
17
  labelSave,
28
18
  loading,
29
- labelLoading,
30
- ...rest
31
- }: Props & TypographyProps): JSX.Element | string | null => {
19
+ labelLoading
20
+ }: Props): JSX.Element | string | null => {
21
+ const { t } = useTranslation();
22
+
32
23
  if (loading) {
33
- return <WrapperLabel label={labelLoading} {...rest} />;
24
+ return t(labelLoading);
34
25
  }
35
26
 
36
27
  if (succeeded) {
37
- return labelSucceeded ? (
38
- <WrapperLabel label={labelSucceeded} {...rest} />
39
- ) : (
40
- <CheckIcon />
41
- );
28
+ return labelSucceeded ? t(labelSucceeded) : <CheckIcon />;
42
29
  }
43
30
 
44
- return labelSave ? (
45
- <WrapperLabel label={labelSave} {...rest} />
46
- ) : (
47
- <SaveIcon />
48
- );
31
+ return labelSave ? t(labelSave) : <SaveIcon />;
49
32
  };
50
33
 
51
34
  export default Content;
@@ -1,7 +1,7 @@
1
1
  import { any, isEmpty, isNil, not, or, pipe } from 'ramda';
2
2
  import { makeStyles } from 'tss-react/mui';
3
3
 
4
- import { Theme, Tooltip, TypographyProps } from '@mui/material';
4
+ import { Theme, Tooltip } from '@mui/material';
5
5
  import { LoadingButton } from '@mui/lab';
6
6
 
7
7
  import { getNormalizedId } from '../../utils';
@@ -18,12 +18,10 @@ const useStyles = makeStyles()((theme: Theme) => ({
18
18
  interface Props extends Record<string, unknown> {
19
19
  className?: string;
20
20
  labelLoading?: string;
21
- labelProps?: TypographyProps;
22
21
  labelSave?: string;
23
22
  labelSucceeded?: string;
24
23
  loading?: boolean;
25
24
  size?: 'small' | 'medium' | 'large';
26
- startIcon?: boolean;
27
25
  succeeded?: boolean;
28
26
  tooltip?: string;
29
27
  tooltipLabel?: string;
@@ -47,8 +45,6 @@ const SaveButton = ({
47
45
  labelSave = '',
48
46
  size = 'small',
49
47
  className,
50
- startIcon = true,
51
- labelProps,
52
48
  ...rest
53
49
  }: Props): JSX.Element => {
54
50
  const { classes, cx } = useStyles();
@@ -77,9 +73,7 @@ const SaveButton = ({
77
73
  loading={loading}
78
74
  loadingPosition={labelLoading ? 'start' : 'center'}
79
75
  size={size}
80
- startIcon={
81
- startIcon && <StartIcon startIconConfig={startIconConfig} />
82
- }
76
+ startIcon={<StartIcon startIconConfig={startIconConfig} />}
83
77
  variant="contained"
84
78
  {...rest}
85
79
  >
@@ -88,8 +82,7 @@ const SaveButton = ({
88
82
  labelSave,
89
83
  labelSucceeded,
90
84
  loading,
91
- succeeded,
92
- ...labelProps
85
+ succeeded
93
86
  })}
94
87
  </LoadingButton>
95
88
  </div>
@@ -2,7 +2,7 @@ import { makeStyles } from 'tss-react/mui';
2
2
  import { T, always, cond, equals } from 'ramda';
3
3
 
4
4
  import { SvgIconComponent } from '@mui/icons-material';
5
- import Typography, { TypographyProps } from '@mui/material/Typography';
5
+ import Typography, { TypographyTypeMap } from '@mui/material/Typography';
6
6
  import { FormControlLabel, Checkbox as MuiCheckbox, Box } from '@mui/material';
7
7
 
8
8
  export type LabelPlacement = 'bottom' | 'top' | 'end' | 'start' | undefined;
@@ -56,7 +56,7 @@ interface Props {
56
56
  disabled?: boolean;
57
57
  label: string;
58
58
  labelPlacement?: LabelPlacement;
59
- labelProps?: TypographyProps;
59
+ labelProps?: TypographyTypeMap['props'];
60
60
  onChange?: (e) => void;
61
61
  }
62
62
 
@@ -2,7 +2,7 @@ import { equals, includes } from 'ramda';
2
2
  import { makeStyles } from 'tss-react/mui';
3
3
 
4
4
  import FormGroup, { FormGroupProps } from '@mui/material/FormGroup';
5
- import { TypographyProps } from '@mui/material/Typography';
5
+ import { TypographyTypeMap } from '@mui/material/Typography';
6
6
 
7
7
  import Checkbox, { LabelPlacement } from '../Checkbox';
8
8
 
@@ -13,7 +13,7 @@ interface Props {
13
13
  disabled?: boolean;
14
14
  formGroupProps?: FormGroupProps;
15
15
  labelPlacement?: LabelPlacement;
16
- labelProps?: TypographyProps;
16
+ labelProps?: TypographyTypeMap['props'];
17
17
  onChange?: (e) => void;
18
18
  options: Array<string>;
19
19
  values: Array<string>;
@@ -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">
@@ -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({
package/src/index.ts CHANGED
@@ -165,5 +165,3 @@ export { default as SimpleCustomTimePeriod } from './TimePeriods/CustomTimePerio
165
165
  export { default as DateTimePickerInput } from './TimePeriods/DateTimePickerInput';
166
166
  export * from './ParentSize';
167
167
  export { default as Subtitle } from './Typography/Subtitle';
168
- export { default as TablePagination } from './Listing/ActionBar/Pagination';
169
- export { default as PaginationActions } from './Listing/ActionBar/PaginationActions';