@centreon/ui 23.10.1-sync-release-33038.0 → 23.10.1-sync-release-34346.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 +6 -1
- package/public/mockServiceWorker.js +2 -2
- package/src/InputField/Select/Autocomplete/Connected/index.tsx +12 -3
- package/src/Module/LicensedModule/LicenseCheck/index.tsx +24 -9
- package/src/Module/LicensedModule/index.tsx +7 -1
- package/src/Typography/Subtitle.tsx +55 -0
- package/src/api/useFetchQuery/index.ts +7 -1
- package/src/api/useMutationQuery/index.ts +8 -1
- package/src/components/Form/AccessRightsV2/AccessRights.cypress.spec.tsx +350 -0
- package/src/components/Form/AccessRightsV2/AccessRights.stories.tsx +119 -0
- package/src/components/Form/AccessRightsV2/AccessRights.styles.ts +10 -0
- package/src/components/Form/AccessRightsV2/AccessRights.tsx +60 -0
- package/src/components/Form/AccessRightsV2/Actions/Actions.styles.ts +14 -0
- package/src/components/Form/AccessRightsV2/Actions/Actions.tsx +81 -0
- package/src/components/Form/AccessRightsV2/Actions/useActions.ts +79 -0
- package/src/components/Form/AccessRightsV2/List/Item.tsx +90 -0
- package/src/components/Form/AccessRightsV2/List/List.styles.tsx +45 -0
- package/src/components/Form/AccessRightsV2/List/List.tsx +52 -0
- package/src/components/Form/AccessRightsV2/List/ListItemSkeleton.tsx +18 -0
- package/src/components/Form/AccessRightsV2/List/ListSkeleton.tsx +22 -0
- package/src/components/Form/AccessRightsV2/List/RemoveAccessRight.tsx +38 -0
- package/src/components/Form/AccessRightsV2/List/StateChip.tsx +28 -0
- package/src/components/Form/AccessRightsV2/List/useItem.ts +64 -0
- package/src/components/Form/AccessRightsV2/Provider.tsx +15 -0
- package/src/components/Form/AccessRightsV2/ShareInput/ContactSwitch.tsx +42 -0
- package/src/components/Form/AccessRightsV2/ShareInput/ShareInput.styles.ts +9 -0
- package/src/components/Form/AccessRightsV2/ShareInput/ShareInput.tsx +77 -0
- package/src/components/Form/AccessRightsV2/ShareInput/useShareInput.tsx +109 -0
- package/src/components/Form/AccessRightsV2/Stats/Stats.tsx +36 -0
- package/src/components/Form/AccessRightsV2/atoms.ts +97 -0
- package/src/components/Form/AccessRightsV2/common/RoleSelectField.styles.tsx +7 -0
- package/src/components/Form/AccessRightsV2/common/RoleSelectField.tsx +45 -0
- package/src/components/Form/AccessRightsV2/models.ts +54 -0
- package/src/components/Form/AccessRightsV2/storiesData.ts +221 -0
- package/src/components/Form/AccessRightsV2/useAccessRightsInitValues.ts +51 -0
- package/src/components/Form/index.ts +1 -0
- package/src/components/List/Item/ListItem.styles.ts +6 -0
- package/src/components/List/Item/ListItem.tsx +3 -1
- package/src/components/List/Item/Text.tsx +5 -3
- package/src/index.ts +1 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@centreon/ui",
|
|
3
|
-
"version": "23.10.1-sync-release-
|
|
3
|
+
"version": "23.10.1-sync-release-34346.0",
|
|
4
4
|
"description": "Centreon UI Components",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"eslint": "eslint ./src --ext .js,.jsx,.ts,.tsx --max-warnings 0",
|
|
@@ -119,6 +119,8 @@
|
|
|
119
119
|
"d3-array": "3.2.0",
|
|
120
120
|
"humanize-duration": "^3.27.3",
|
|
121
121
|
"lexical": "0.11.3",
|
|
122
|
+
"msw": "0.49.1",
|
|
123
|
+
"msw-storybook-addon": "^1.10.0",
|
|
122
124
|
"notistack": "^2.0.8",
|
|
123
125
|
"react-grid-layout": "^1.3.4",
|
|
124
126
|
"react-html-parser": "^2.0.2",
|
|
@@ -152,5 +154,8 @@
|
|
|
152
154
|
"jest-junit": {
|
|
153
155
|
"suiteName": "jest tests",
|
|
154
156
|
"output": "./junit.xml"
|
|
157
|
+
},
|
|
158
|
+
"msw": {
|
|
159
|
+
"workerDirectory": "public"
|
|
155
160
|
}
|
|
156
161
|
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
/* tslint:disable */
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
|
-
* Mock Service Worker (
|
|
5
|
+
* Mock Service Worker (0.49.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
|
+
}
|
|
@@ -33,6 +33,7 @@ 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;
|
|
36
37
|
conditionField?: keyof SelectEntry;
|
|
37
38
|
field: string;
|
|
38
39
|
getEndpoint: ({ search, page }) => string;
|
|
@@ -62,6 +63,7 @@ const ConnectedAutocompleteField = (
|
|
|
62
63
|
queryKey,
|
|
63
64
|
allowUniqOption,
|
|
64
65
|
baseEndpoint,
|
|
66
|
+
changeIdValue,
|
|
65
67
|
...props
|
|
66
68
|
}: ConnectedAutoCompleteFieldProps<TData> &
|
|
67
69
|
Omit<AutocompleteFieldProps, 'options'>): JSX.Element => {
|
|
@@ -238,17 +240,24 @@ const ConnectedAutocompleteField = (
|
|
|
238
240
|
|
|
239
241
|
const moreOptions = page > 1 ? options : [];
|
|
240
242
|
|
|
243
|
+
const formattedList = changeIdValue
|
|
244
|
+
? newOptions.result.map((item) => ({
|
|
245
|
+
...item,
|
|
246
|
+
id: changeIdValue(item)
|
|
247
|
+
}))
|
|
248
|
+
: newOptions.result;
|
|
249
|
+
|
|
241
250
|
if (!isEmpty(labelKey) && !isNil(labelKey)) {
|
|
242
|
-
const list =
|
|
251
|
+
const list = formattedList.map((item) =>
|
|
243
252
|
renameKey({ key: labelKey, newKey: 'name', object: item })
|
|
244
253
|
);
|
|
245
254
|
setOptions(moreOptions.concat(list as Array<TData>));
|
|
246
255
|
|
|
247
256
|
return;
|
|
248
257
|
}
|
|
249
|
-
setOptions(moreOptions.concat(
|
|
258
|
+
setOptions(moreOptions.concat(formattedList));
|
|
250
259
|
|
|
251
|
-
setOptions(moreOptions.concat(
|
|
260
|
+
setOptions(moreOptions.concat(formattedList as Array<TData>));
|
|
252
261
|
|
|
253
262
|
const total = prop('total', newOptions.meta) || 1;
|
|
254
263
|
const limit = prop('limit', newOptions.meta) || 1;
|
|
@@ -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
|
) : (
|
|
@@ -40,10 +47,11 @@ const Content = ({ children, isValid }: ContentProps): JSX.Element => {
|
|
|
40
47
|
};
|
|
41
48
|
|
|
42
49
|
const LicenseCheck = ({
|
|
50
|
+
isFederatedComponent,
|
|
43
51
|
children,
|
|
44
52
|
moduleName
|
|
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
|
|
|
@@ -5,13 +5,19 @@ import LicenseCheck, { LicenseCheckProps } from './LicenseCheck';
|
|
|
5
5
|
type Props = ModuleProps & LicenseCheckProps;
|
|
6
6
|
|
|
7
7
|
const LicensedModule = ({
|
|
8
|
+
isFederatedComponent,
|
|
8
9
|
moduleName,
|
|
9
10
|
children,
|
|
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,55 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
|
|
3
|
+
import { type, equals } from 'ramda';
|
|
4
|
+
import { useTranslation } from 'react-i18next';
|
|
5
|
+
|
|
6
|
+
import { Typography } from '@mui/material';
|
|
7
|
+
import HelpOutlineIcon from '@mui/icons-material/HelpOutline';
|
|
8
|
+
|
|
9
|
+
import { Tooltip } from '../components';
|
|
10
|
+
|
|
11
|
+
interface Props {
|
|
12
|
+
children: ReactNode;
|
|
13
|
+
secondaryLabel?: string | Array<string>;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const Subtitle = ({ children, secondaryLabel }: Props): JSX.Element => {
|
|
17
|
+
const { t } = useTranslation();
|
|
18
|
+
|
|
19
|
+
const containsSeveralSecondaryLabels = equals(type(secondaryLabel), 'Array');
|
|
20
|
+
|
|
21
|
+
return (
|
|
22
|
+
<Typography variant="subtitle1">
|
|
23
|
+
<strong>{children}</strong>
|
|
24
|
+
{secondaryLabel && (
|
|
25
|
+
<Tooltip
|
|
26
|
+
aria-label={
|
|
27
|
+
containsSeveralSecondaryLabels
|
|
28
|
+
? secondaryLabel[0]
|
|
29
|
+
: (secondaryLabel as string)
|
|
30
|
+
}
|
|
31
|
+
followCursor={false}
|
|
32
|
+
label={
|
|
33
|
+
containsSeveralSecondaryLabels ? (
|
|
34
|
+
<>
|
|
35
|
+
{secondaryLabel.map((label) => (
|
|
36
|
+
<p key={label}>{t(label)}</p>
|
|
37
|
+
))}
|
|
38
|
+
</>
|
|
39
|
+
) : (
|
|
40
|
+
t(secondaryLabel)
|
|
41
|
+
)
|
|
42
|
+
}
|
|
43
|
+
placement="right"
|
|
44
|
+
>
|
|
45
|
+
<HelpOutlineIcon
|
|
46
|
+
color="primary"
|
|
47
|
+
sx={{ ml: 1, verticalAlign: 'middle' }}
|
|
48
|
+
/>
|
|
49
|
+
</Tooltip>
|
|
50
|
+
)}
|
|
51
|
+
</Typography>
|
|
52
|
+
);
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
export default Subtitle;
|
|
@@ -21,6 +21,7 @@ export interface UseFetchQueryProps<T> {
|
|
|
21
21
|
catchError?: (props: CatchErrorProps) => void;
|
|
22
22
|
decoder?: JsonDecoder.Decoder<T>;
|
|
23
23
|
defaultFailureMessage?: string;
|
|
24
|
+
doNotCancelCallsOnUnmount?: boolean;
|
|
24
25
|
fetchHeaders?: HeadersInit;
|
|
25
26
|
getEndpoint: (params?: PrefetchEndpointParams) => string;
|
|
26
27
|
getQueryKey: () => QueryKey;
|
|
@@ -56,7 +57,8 @@ const useFetchQuery = <T extends object>({
|
|
|
56
57
|
isPaginated,
|
|
57
58
|
queryOptions,
|
|
58
59
|
httpCodesBypassErrorSnackbar = [],
|
|
59
|
-
baseEndpoint
|
|
60
|
+
baseEndpoint,
|
|
61
|
+
doNotCancelCallsOnUnmount = false
|
|
60
62
|
}: UseFetchQueryProps<T>): UseFetchQueryState<T> => {
|
|
61
63
|
const dataRef = useRef<T | undefined>(undefined);
|
|
62
64
|
|
|
@@ -168,6 +170,10 @@ const useFetchQuery = <T extends object>({
|
|
|
168
170
|
|
|
169
171
|
useEffect(() => {
|
|
170
172
|
return (): void => {
|
|
173
|
+
if (doNotCancelCallsOnUnmount) {
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
|
|
171
177
|
queryClient.cancelQueries(getQueryKey());
|
|
172
178
|
};
|
|
173
179
|
}, []);
|
|
@@ -81,7 +81,14 @@ const useMutationQuery = <T extends object, TMeta>({
|
|
|
81
81
|
{
|
|
82
82
|
onError,
|
|
83
83
|
onMutate,
|
|
84
|
-
onSuccess
|
|
84
|
+
onSuccess: (data, variables, context) => {
|
|
85
|
+
if (data?.isError) {
|
|
86
|
+
onError?.(data, variables, context);
|
|
87
|
+
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
onSuccess?.(data, variables, context);
|
|
91
|
+
}
|
|
85
92
|
}
|
|
86
93
|
);
|
|
87
94
|
|
|
@@ -0,0 +1,350 @@
|
|
|
1
|
+
import { Provider, createStore } from 'jotai';
|
|
2
|
+
|
|
3
|
+
import { Method, SnackbarProvider, TestQueryProvider } from '../../..';
|
|
4
|
+
|
|
5
|
+
import { AccessRights } from './AccessRights';
|
|
6
|
+
import {
|
|
7
|
+
buildResult,
|
|
8
|
+
emptyAccessRights,
|
|
9
|
+
labels,
|
|
10
|
+
removedAccessRights,
|
|
11
|
+
roles,
|
|
12
|
+
simpleAccessRights,
|
|
13
|
+
updatedAccessRights
|
|
14
|
+
} from './storiesData';
|
|
15
|
+
|
|
16
|
+
const initialize = ({
|
|
17
|
+
initialValues = simpleAccessRights,
|
|
18
|
+
loading = false,
|
|
19
|
+
link = 'link'
|
|
20
|
+
}): unknown => {
|
|
21
|
+
const cancel = cy.stub();
|
|
22
|
+
const save = cy.stub();
|
|
23
|
+
|
|
24
|
+
cy.interceptAPIRequest({
|
|
25
|
+
alias: 'getContacts',
|
|
26
|
+
method: Method.GET,
|
|
27
|
+
path: '**/contacts?**',
|
|
28
|
+
response: buildResult(false)
|
|
29
|
+
});
|
|
30
|
+
cy.interceptAPIRequest({
|
|
31
|
+
alias: 'getContactGroups',
|
|
32
|
+
method: Method.GET,
|
|
33
|
+
path: '**/contact-groups?**',
|
|
34
|
+
response: buildResult(true)
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
cy.mount({
|
|
38
|
+
Component: (
|
|
39
|
+
<SnackbarProvider>
|
|
40
|
+
<TestQueryProvider>
|
|
41
|
+
<Provider store={createStore()}>
|
|
42
|
+
<AccessRights
|
|
43
|
+
cancel={cancel}
|
|
44
|
+
endpoints={{
|
|
45
|
+
contact: '/contacts',
|
|
46
|
+
contactGroup: '/contact-groups'
|
|
47
|
+
}}
|
|
48
|
+
initialValues={initialValues}
|
|
49
|
+
labels={labels}
|
|
50
|
+
link={link}
|
|
51
|
+
loading={loading}
|
|
52
|
+
roles={roles}
|
|
53
|
+
submit={save}
|
|
54
|
+
/>
|
|
55
|
+
</Provider>
|
|
56
|
+
</TestQueryProvider>
|
|
57
|
+
</SnackbarProvider>
|
|
58
|
+
)
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
return {
|
|
62
|
+
cancel,
|
|
63
|
+
save
|
|
64
|
+
};
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
describe('Access rights', () => {
|
|
68
|
+
it('displays the access rights in loading state', () => {
|
|
69
|
+
initialize({ loading: true });
|
|
70
|
+
|
|
71
|
+
cy.contains('Share dashboard with').should('be.visible');
|
|
72
|
+
cy.contains('Contact').should('be.visible');
|
|
73
|
+
cy.contains('Contact group').should('be.visible');
|
|
74
|
+
cy.findByLabelText('Add a contact').should('be.visible');
|
|
75
|
+
cy.findByTestId('add_role').should('be.disabled');
|
|
76
|
+
cy.findByTestId('add').should('be.disabled');
|
|
77
|
+
cy.findByLabelText('Copy link').should('be.visible');
|
|
78
|
+
cy.findByLabelText('Cancel').should('be.visible');
|
|
79
|
+
cy.findByLabelText('Save').should('be.visible');
|
|
80
|
+
|
|
81
|
+
cy.makeSnapshot();
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
it('displays the access rights without link', () => {
|
|
85
|
+
initialize({ link: null });
|
|
86
|
+
|
|
87
|
+
cy.findByLabelText('Copy link').should('not.exist');
|
|
88
|
+
|
|
89
|
+
cy.makeSnapshot();
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
it('displays the access rights with an empty list', () => {
|
|
93
|
+
initialize({ initialValues: emptyAccessRights });
|
|
94
|
+
|
|
95
|
+
cy.contains('The contact list is empty').should('be.visible');
|
|
96
|
+
|
|
97
|
+
cy.makeSnapshot();
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
it('displays the access rights with an empty list', () => {
|
|
101
|
+
initialize({});
|
|
102
|
+
|
|
103
|
+
simpleAccessRights.forEach(({ name, email, isContactGroup, role }) => {
|
|
104
|
+
cy.contains(name).should('be.visible');
|
|
105
|
+
cy.contains(email).should('be.visible');
|
|
106
|
+
cy.get(`[data-groupChip="${name}"]`).should(
|
|
107
|
+
isContactGroup ? 'be.visible' : 'not.exist'
|
|
108
|
+
);
|
|
109
|
+
cy.findByTestId(`role-${name}`).should('have.value', role);
|
|
110
|
+
cy.findByTestId(`remove-${name}`).should('be.visible');
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
cy.makeSnapshot();
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
it('displays a removed chip when the corresponding icon is clicked', () => {
|
|
117
|
+
initialize({});
|
|
118
|
+
|
|
119
|
+
cy.findByTestId(`remove-Leah McGlynn`).should(
|
|
120
|
+
'have.attr',
|
|
121
|
+
'data-removed',
|
|
122
|
+
'false'
|
|
123
|
+
);
|
|
124
|
+
|
|
125
|
+
cy.findByTestId(`remove-Leah McGlynn`).click();
|
|
126
|
+
|
|
127
|
+
cy.findByTestId(`remove-Leah McGlynn`).should(
|
|
128
|
+
'have.attr',
|
|
129
|
+
'data-removed',
|
|
130
|
+
'true'
|
|
131
|
+
);
|
|
132
|
+
cy.contains(labels.list.removed).should('be.visible');
|
|
133
|
+
|
|
134
|
+
cy.makeSnapshot();
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
it('restores the contact when the contact is removed and the corresponding icon is clicked', () => {
|
|
138
|
+
initialize({});
|
|
139
|
+
|
|
140
|
+
cy.findByTestId(`remove-Leah McGlynn`).click();
|
|
141
|
+
|
|
142
|
+
cy.findByTestId(`remove-Leah McGlynn`).should(
|
|
143
|
+
'have.attr',
|
|
144
|
+
'data-removed',
|
|
145
|
+
'true'
|
|
146
|
+
);
|
|
147
|
+
cy.contains(labels.list.removed).should('be.visible');
|
|
148
|
+
|
|
149
|
+
cy.findByTestId(`remove-Leah McGlynn`).click();
|
|
150
|
+
|
|
151
|
+
cy.findByTestId(`remove-Leah McGlynn`).should(
|
|
152
|
+
'have.attr',
|
|
153
|
+
'data-removed',
|
|
154
|
+
'false'
|
|
155
|
+
);
|
|
156
|
+
cy.contains(labels.list.removed).should('not.exist');
|
|
157
|
+
|
|
158
|
+
cy.makeSnapshot();
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
it('submits the new acces rights list without the removed contact', () => {
|
|
162
|
+
const { save } = initialize({});
|
|
163
|
+
|
|
164
|
+
cy.findByTestId(`remove-Leah McGlynn`).click();
|
|
165
|
+
|
|
166
|
+
cy.findByTestId(`remove-Leah McGlynn`).should(
|
|
167
|
+
'have.attr',
|
|
168
|
+
'data-removed',
|
|
169
|
+
'true'
|
|
170
|
+
);
|
|
171
|
+
cy.contains(labels.list.removed).should('be.visible');
|
|
172
|
+
cy.contains('1 removed').should('be.visible');
|
|
173
|
+
|
|
174
|
+
cy.contains(labels.actions.save)
|
|
175
|
+
.click()
|
|
176
|
+
.then(() => {
|
|
177
|
+
expect(save).to.have.been.calledWith(removedAccessRights);
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
cy.makeSnapshot();
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
it('submits the new acces rights list with the updated contact', () => {
|
|
184
|
+
const { save } = initialize({});
|
|
185
|
+
|
|
186
|
+
cy.findByTestId(`role-Leah McGlynn`).parent().click();
|
|
187
|
+
|
|
188
|
+
cy.get('li[data-value="editor"]').click();
|
|
189
|
+
cy.contains(labels.list.updated).should('be.visible');
|
|
190
|
+
cy.contains('1 updated').should('be.visible');
|
|
191
|
+
|
|
192
|
+
cy.contains(labels.actions.save)
|
|
193
|
+
.click()
|
|
194
|
+
.then(() => {
|
|
195
|
+
expect(save).to.have.been.calledWith(updatedAccessRights);
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
cy.makeSnapshot();
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
it('removes the updated chip when the contact role is updated and its initial role is assigned back', () => {
|
|
202
|
+
initialize({});
|
|
203
|
+
|
|
204
|
+
cy.findByTestId(`role-Leah McGlynn`).parent().click();
|
|
205
|
+
|
|
206
|
+
cy.get('li[data-value="editor"]').click();
|
|
207
|
+
cy.contains(labels.list.updated).should('be.visible');
|
|
208
|
+
|
|
209
|
+
cy.get('li[data-value="viewer"]').click();
|
|
210
|
+
cy.contains(labels.list.updated).should('not.exist');
|
|
211
|
+
|
|
212
|
+
cy.makeSnapshot();
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
it('retrieves contacts when the contact radio is selected', () => {
|
|
216
|
+
initialize({});
|
|
217
|
+
|
|
218
|
+
cy.contains(labels.add.contact).click();
|
|
219
|
+
cy.findByLabelText(labels.add.autocompleteContact).click();
|
|
220
|
+
|
|
221
|
+
cy.waitForRequest('@getContacts');
|
|
222
|
+
|
|
223
|
+
cy.makeSnapshot();
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
it('retrieves contact groups when the contact group radio is selected', () => {
|
|
227
|
+
initialize({});
|
|
228
|
+
|
|
229
|
+
cy.contains(labels.add.contactGroup).click();
|
|
230
|
+
cy.findByLabelText(labels.add.autocompleteContactGroup).click();
|
|
231
|
+
|
|
232
|
+
cy.waitForRequest('@getContactGroups');
|
|
233
|
+
|
|
234
|
+
cy.makeSnapshot();
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
it('adds the contact as viewer when a contact is selected and the corresponding button is clicked', () => {
|
|
238
|
+
initialize({});
|
|
239
|
+
|
|
240
|
+
cy.contains(labels.add.contact).click();
|
|
241
|
+
cy.findByLabelText(labels.add.autocompleteContact).click();
|
|
242
|
+
|
|
243
|
+
cy.waitForRequest('@getContacts');
|
|
244
|
+
|
|
245
|
+
cy.contains('Entity 10').click();
|
|
246
|
+
|
|
247
|
+
cy.findByTestId('add').click();
|
|
248
|
+
|
|
249
|
+
cy.contains('Entity 10').should('be.visible');
|
|
250
|
+
|
|
251
|
+
cy.findByTestId('role-Entity 10').should('have.value', 'viewer');
|
|
252
|
+
cy.contains(labels.list.added).should('be.visible');
|
|
253
|
+
|
|
254
|
+
cy.makeSnapshot();
|
|
255
|
+
});
|
|
256
|
+
|
|
257
|
+
it('adds the contact group as editor when a contact group is selected and the corresponding button is clicked', () => {
|
|
258
|
+
initialize({});
|
|
259
|
+
|
|
260
|
+
cy.contains(labels.add.contactGroup).click();
|
|
261
|
+
cy.findByLabelText(labels.add.autocompleteContactGroup).click();
|
|
262
|
+
|
|
263
|
+
cy.waitForRequest('@getContactGroups');
|
|
264
|
+
|
|
265
|
+
cy.contains('Entity Group 10').click();
|
|
266
|
+
cy.findByTestId('add_role').parent().click();
|
|
267
|
+
cy.get('li[data-value="editor"]').click();
|
|
268
|
+
cy.findByTestId('add').click();
|
|
269
|
+
|
|
270
|
+
cy.contains('Entity Group 10').should('be.visible');
|
|
271
|
+
|
|
272
|
+
cy.findByTestId('role-Entity Group 10').should('have.value', 'editor');
|
|
273
|
+
cy.contains(labels.list.added).should('be.visible');
|
|
274
|
+
cy.contains('1 added').should('be.visible');
|
|
275
|
+
|
|
276
|
+
cy.makeSnapshot();
|
|
277
|
+
});
|
|
278
|
+
|
|
279
|
+
it('displays statistics when a contact is added, a contact is updated and a contact is removed', () => {
|
|
280
|
+
initialize({});
|
|
281
|
+
|
|
282
|
+
cy.contains(labels.add.contactGroup).click();
|
|
283
|
+
cy.findByLabelText(labels.add.autocompleteContactGroup).click();
|
|
284
|
+
|
|
285
|
+
cy.waitForRequest('@getContactGroups');
|
|
286
|
+
|
|
287
|
+
cy.contains('Entity Group 10').click();
|
|
288
|
+
cy.findByTestId('add_role').parent().click();
|
|
289
|
+
cy.get('li[data-value="editor"]').click();
|
|
290
|
+
cy.findByTestId('add').click();
|
|
291
|
+
|
|
292
|
+
cy.contains('Entity Group 10').should('be.visible');
|
|
293
|
+
|
|
294
|
+
cy.findByTestId(`role-Leah McGlynn`).parent().click();
|
|
295
|
+
cy.get('li[data-value="editor"]').click();
|
|
296
|
+
|
|
297
|
+
cy.findByTestId('remove-Jody Blanda').click();
|
|
298
|
+
|
|
299
|
+
cy.contains('1 added | 1 updated | 1 removed').should('be.visible');
|
|
300
|
+
|
|
301
|
+
cy.makeSnapshot();
|
|
302
|
+
});
|
|
303
|
+
|
|
304
|
+
it('clears the autocomplete when a contact is selected and the contact type is changed', () => {
|
|
305
|
+
initialize({});
|
|
306
|
+
|
|
307
|
+
cy.contains(labels.add.contact).click();
|
|
308
|
+
cy.findByLabelText(labels.add.autocompleteContact).click();
|
|
309
|
+
|
|
310
|
+
cy.waitForRequest('@getContacts');
|
|
311
|
+
|
|
312
|
+
cy.contains('Entity 10').click();
|
|
313
|
+
cy.findByLabelText(labels.add.autocompleteContact).should(
|
|
314
|
+
'have.value',
|
|
315
|
+
'Entity 10'
|
|
316
|
+
);
|
|
317
|
+
|
|
318
|
+
cy.contains(labels.add.contactGroup).click();
|
|
319
|
+
cy.findByLabelText(labels.add.autocompleteContactGroup).should(
|
|
320
|
+
'have.value',
|
|
321
|
+
''
|
|
322
|
+
);
|
|
323
|
+
|
|
324
|
+
cy.makeSnapshot();
|
|
325
|
+
});
|
|
326
|
+
|
|
327
|
+
it('removes the contact from the list when the contact has been to the list and the corresponding button is clicked', () => {
|
|
328
|
+
initialize({});
|
|
329
|
+
|
|
330
|
+
cy.contains(labels.add.contact).click();
|
|
331
|
+
cy.findByLabelText(labels.add.autocompleteContact).click();
|
|
332
|
+
|
|
333
|
+
cy.waitForRequest('@getContacts');
|
|
334
|
+
|
|
335
|
+
cy.contains('Entity 10').click();
|
|
336
|
+
|
|
337
|
+
cy.findByTestId('add').click();
|
|
338
|
+
|
|
339
|
+
cy.contains('Entity 10').should('be.visible');
|
|
340
|
+
|
|
341
|
+
cy.contains(labels.list.added).should('be.visible');
|
|
342
|
+
|
|
343
|
+
cy.findByTestId('remove-Entity 10').click();
|
|
344
|
+
|
|
345
|
+
cy.contains('Entity 10').should('not.exist');
|
|
346
|
+
cy.contains(labels.list.added).should('not.exist');
|
|
347
|
+
|
|
348
|
+
cy.makeSnapshot();
|
|
349
|
+
});
|
|
350
|
+
});
|