@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.
- package/package.json +1 -6
- package/public/mockServiceWorker.js +2 -2
- package/src/FallbackPage/FallbackPage.tsx +3 -3
- package/src/InputField/Select/Autocomplete/Connected/index.tsx +3 -12
- package/src/Listing/Cell/DataCell.tsx +15 -1
- package/src/Module/LicensedModule/LicenseCheck/index.tsx +25 -10
- package/src/Module/LicensedModule/index.tsx +7 -1
- package/src/Module/Module.cypress.spec.tsx +129 -0
- package/src/Module/index.tsx +2 -4
- package/src/components/Form/index.ts +0 -1
- package/src/components/List/Item/ListItem.styles.ts +0 -6
- package/src/components/List/Item/ListItem.tsx +1 -3
- package/src/components/List/Item/Text.tsx +3 -5
- package/src/components/Form/AccessRightsV2/AccessRights.cypress.spec.tsx +0 -346
- package/src/components/Form/AccessRightsV2/AccessRights.stories.tsx +0 -119
- package/src/components/Form/AccessRightsV2/AccessRights.styles.ts +0 -10
- package/src/components/Form/AccessRightsV2/AccessRights.tsx +0 -56
- package/src/components/Form/AccessRightsV2/Actions/Actions.styles.ts +0 -14
- package/src/components/Form/AccessRightsV2/Actions/Actions.tsx +0 -60
- package/src/components/Form/AccessRightsV2/Actions/useActions.ts +0 -70
- package/src/components/Form/AccessRightsV2/List/Item.tsx +0 -90
- package/src/components/Form/AccessRightsV2/List/List.styles.tsx +0 -45
- package/src/components/Form/AccessRightsV2/List/List.tsx +0 -52
- package/src/components/Form/AccessRightsV2/List/ListItemSkeleton.tsx +0 -18
- package/src/components/Form/AccessRightsV2/List/ListSkeleton.tsx +0 -22
- package/src/components/Form/AccessRightsV2/List/RemoveAccessRight.tsx +0 -38
- package/src/components/Form/AccessRightsV2/List/StateChip.tsx +0 -28
- package/src/components/Form/AccessRightsV2/List/useItem.ts +0 -64
- package/src/components/Form/AccessRightsV2/Provider.tsx +0 -13
- package/src/components/Form/AccessRightsV2/ShareInput/ContactSwitch.tsx +0 -42
- package/src/components/Form/AccessRightsV2/ShareInput/ShareInput.styles.ts +0 -9
- package/src/components/Form/AccessRightsV2/ShareInput/ShareInput.tsx +0 -77
- package/src/components/Form/AccessRightsV2/ShareInput/useShareInput.tsx +0 -109
- package/src/components/Form/AccessRightsV2/Stats/Stats.tsx +0 -36
- package/src/components/Form/AccessRightsV2/atoms.ts +0 -97
- package/src/components/Form/AccessRightsV2/common/RoleSelectField.styles.tsx +0 -7
- package/src/components/Form/AccessRightsV2/common/RoleSelectField.tsx +0 -45
- package/src/components/Form/AccessRightsV2/models.ts +0 -54
- package/src/components/Form/AccessRightsV2/storiesData.ts +0 -221
- 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-
|
|
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.
|
|
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: '
|
|
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
|
-
<
|
|
69
|
+
<div className={classes.logo}>
|
|
70
70
|
<CentreonLogo />
|
|
71
|
-
</
|
|
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 =
|
|
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(
|
|
249
|
+
setOptions(moreOptions.concat(newOptions.result));
|
|
259
250
|
|
|
260
|
-
setOptions(moreOptions.concat(
|
|
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
|
|
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 = ({
|
|
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
|
-
|
|
59
|
-
|
|
66
|
+
const skeleton = isFederatedComponent ? <MenuSkeleton /> : <PageSkeleton />;
|
|
67
|
+
|
|
68
|
+
return isLoading ? (
|
|
69
|
+
skeleton
|
|
60
70
|
) : (
|
|
61
|
-
<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
|
|
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
|
+
});
|
package/src/Module/index.tsx
CHANGED
|
@@ -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
|
|
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({
|
|
@@ -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
|
|
16
|
+
const { classes } = useStyles();
|
|
19
17
|
|
|
20
18
|
return (
|
|
21
19
|
<MuiListItemText
|
|
22
|
-
className={
|
|
20
|
+
className={classes.text}
|
|
23
21
|
primary={primaryText}
|
|
24
22
|
secondary={secondaryText}
|
|
25
23
|
/>
|