@centreon/ui 24.4.36 → 24.4.38

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 (156) hide show
  1. package/package.json +14 -19
  2. package/public/mockServiceWorker.js +1 -1
  3. package/src/Button/Icon/index.stories.tsx +1 -1
  4. package/src/Button/Icon/index.tsx +2 -2
  5. package/src/Button/Save/StartIcon.tsx +3 -3
  6. package/src/Button/Save/index.tsx +5 -9
  7. package/src/Checkbox/Checkbox.tsx +2 -2
  8. package/src/Checkbox/CheckboxGroup/index.tsx +2 -2
  9. package/src/Dashboard/Item.tsx +1 -1
  10. package/src/Dashboard/Layout.tsx +2 -2
  11. package/src/Dialog/index.tsx +1 -1
  12. package/src/FallbackPage/FallbackPage.tsx +3 -3
  13. package/src/FileDropZone/index.tsx +1 -3
  14. package/src/Form/Inputs/CheckboxGroup.tsx +4 -1
  15. package/src/Form/Inputs/index.tsx +1 -3
  16. package/src/Form/Inputs/models.ts +1 -9
  17. package/src/Graph/LineChart/BasicComponents/Lines/Threshold/Circle.tsx +2 -2
  18. package/src/Graph/LineChart/BasicComponents/Lines/Threshold/index.tsx +4 -5
  19. package/src/Graph/LineChart/BasicComponents/Thresholds.tsx +2 -2
  20. package/src/Graph/LineChart/BasicComponents/useFilterLines.ts +1 -1
  21. package/src/Graph/LineChart/InteractiveComponents/AnchorPoint/GuidingLines.tsx +2 -2
  22. package/src/Graph/LineChart/InteractiveComponents/Annotations/Annotation/index.tsx +3 -2
  23. package/src/Graph/LineChart/InteractiveComponents/Annotations/EventAnnotations.tsx +1 -1
  24. package/src/Graph/LineChart/Legend/useLegend.ts +3 -3
  25. package/src/Graph/LineChart/helpers/doc.ts +13 -16
  26. package/src/Graph/LineChart/helpers/index.ts +1 -1
  27. package/src/Graph/LineChart/index.stories.tsx +2 -4
  28. package/src/Graph/SingleBar/Thresholds.tsx +2 -2
  29. package/src/Graph/Text/Text.stories.tsx +4 -60
  30. package/src/Graph/common/timeSeries/index.ts +3 -3
  31. package/src/InputField/Select/Autocomplete/Connected/index.tsx +7 -10
  32. package/src/InputField/Select/Autocomplete/Draggable/SortableList.tsx +1 -1
  33. package/src/InputField/Select/Autocomplete/Draggable/SortableListContent.tsx +1 -1
  34. package/src/InputField/Select/Autocomplete/Draggable/index.tsx +1 -1
  35. package/src/InputField/Select/Autocomplete/index.tsx +115 -121
  36. package/src/InputField/Select/IconPopover/index.tsx +3 -3
  37. package/src/InputField/Select/index.tsx +1 -1
  38. package/src/InputField/Text/index.tsx +2 -2
  39. package/src/Listing/ActionBar/index.tsx +1 -2
  40. package/src/Listing/Cell/DataCell.tsx +1 -15
  41. package/src/Listing/Header/ListingHeader.tsx +1 -1
  42. package/src/Listing/Listing.styles.ts +3 -2
  43. package/src/Listing/index.stories.tsx +1 -12
  44. package/src/Listing/index.tsx +2 -1
  45. package/src/Module/index.tsx +4 -2
  46. package/src/Panel/index.tsx +1 -1
  47. package/src/RichTextEditor/RichTextEditor.tsx +1 -12
  48. package/src/SortableItems/index.tsx +7 -2
  49. package/src/ThemeProvider/index.tsx +0 -24
  50. package/src/TimePeriods/CustomTimePeriod/CompactCustomTimePeriod.styles.ts +7 -6
  51. package/src/TimePeriods/CustomTimePeriod/PopoverCustomTimePeriod/PickersStartEndDate.tsx +3 -8
  52. package/src/TimePeriods/CustomTimePeriod/PopoverCustomTimePeriod/models.ts +2 -0
  53. package/src/TimePeriods/DateTimePickerInput.tsx +19 -56
  54. package/src/TimePeriods/ResolutionTimePeriod.cypress.spec.tsx +9 -12
  55. package/src/TimePeriods/TimePeriods.cypress.spec.tsx +33 -9
  56. package/src/TimePeriods/helpers/index.ts +1 -1
  57. package/src/TimePeriods/index.stories.tsx +4 -12
  58. package/src/TimePeriods/index.tsx +2 -2
  59. package/src/api/QueryProvider.tsx +1 -1
  60. package/src/api/TestQueryProvider.tsx +1 -1
  61. package/src/api/useFetchQuery/index.ts +23 -27
  62. package/src/api/useMutationQuery/index.ts +21 -45
  63. package/src/components/Button/Icon/IconButton.tsx +2 -6
  64. package/src/components/DataTable/DataTable.stories.tsx +0 -40
  65. package/src/components/DataTable/DataTable.styles.ts +0 -3
  66. package/src/components/DataTable/DataTable.tsx +3 -3
  67. package/src/components/DataTable/Item/DataTableItem.styles.ts +2 -7
  68. package/src/components/DataTable/Item/DataTableItem.tsx +4 -4
  69. package/src/components/DataTable/index.ts +1 -3
  70. package/src/components/Form/{AccessRightsV2 → AccessRights}/AccessRights.cypress.spec.tsx +23 -0
  71. package/src/components/Form/{AccessRightsV2 → AccessRights}/ShareInput/ContactSwitch.tsx +9 -1
  72. package/src/components/Form/{AccessRightsV2 → AccessRights}/ShareInput/ShareInput.styles.ts +8 -0
  73. package/src/components/Form/{AccessRightsV2 → AccessRights}/ShareInput/useShareInput.tsx +4 -0
  74. package/src/components/Form/{AccessRightsV2 → AccessRights}/models.ts +1 -0
  75. package/src/components/Form/{AccessRightsV2 → AccessRights}/storiesData.ts +1 -0
  76. package/src/components/Form/Dashboard/DashboardForm.tsx +12 -15
  77. package/src/components/Form/index.ts +2 -2
  78. package/src/components/Layout/PageLayout/PageLayout.tsx +1 -1
  79. package/src/components/Layout/PageLayout/PageLayoutActions.tsx +0 -1
  80. package/src/components/Layout/PageLayout/PageLayoutBody.tsx +0 -1
  81. package/src/components/Layout/PageLayout/PageLayoutHeader.tsx +1 -5
  82. package/src/components/Layout/PageLayout/index.ts +1 -3
  83. package/src/components/Modal/Modal.styles.ts +1 -1
  84. package/src/components/Tooltip/ConfirmationTooltip/ConfirmationTooltip.stories.tsx +3 -3
  85. package/src/components/Tooltip/ConfirmationTooltip/ConfirmationTooltip.tsx +1 -1
  86. package/src/components/Tooltip/ConfirmationTooltip/models.ts +1 -1
  87. package/src/index.ts +2 -2
  88. package/src/queryParameters/url/index.ts +1 -5
  89. package/src/screens/dashboard/DashboardsDetail.stories.tsx +108 -0
  90. package/src/screens/dashboard/DashboardsOverview.stories.tsx +281 -0
  91. package/src/utils/index.ts +1 -2
  92. package/src/utils/useDateTimePickerAdapter.ts +309 -0
  93. package/src/utils/{useLicenseExpirationWarning.test.tsx → useLicenseExpirationWarning.cypress.spec.tsx} +37 -48
  94. package/src/utils/useLicenseExpirationWarning.ts +18 -18
  95. package/src/Form/Form.cypress.spec.tsx +0 -133
  96. package/src/Form/Inputs/List/Content.tsx +0 -62
  97. package/src/Form/Inputs/List/List.styles.ts +0 -29
  98. package/src/Form/Inputs/List/List.tsx +0 -58
  99. package/src/Form/Inputs/List/useList.ts +0 -81
  100. package/src/Module/Module.cypress.spec.tsx +0 -129
  101. package/src/components/DataTable/DataListing.tsx +0 -6
  102. package/src/components/DataTable/DataTable.cypress.spec.tsx +0 -193
  103. package/src/components/Form/AccessRights/AccessRights.resource.ts +0 -45
  104. package/src/components/Form/AccessRights/AccessRightsForm.stories.tsx +0 -59
  105. package/src/components/Form/AccessRights/AccessRightsForm.styles.ts +0 -21
  106. package/src/components/Form/AccessRights/AccessRightsForm.tsx +0 -67
  107. package/src/components/Form/AccessRights/AccessRightsFormActions.tsx +0 -80
  108. package/src/components/Form/AccessRights/Input/AddAction.tsx +0 -31
  109. package/src/components/Form/AccessRights/Input/ContactAccessRightInput.stories.tsx +0 -54
  110. package/src/components/Form/AccessRights/Input/ContactAccessRightInput.tsx +0 -72
  111. package/src/components/Form/AccessRights/Input/ContactAccessRightsInput.styles.ts +0 -22
  112. package/src/components/Form/AccessRights/Input/ContactInputField.tsx +0 -105
  113. package/src/components/Form/AccessRights/Input/RoleInputField.tsx +0 -29
  114. package/src/components/Form/AccessRights/List/ContactAccessRightsList.stories.tsx +0 -97
  115. package/src/components/Form/AccessRights/List/ContactAccessRightsList.styles.ts +0 -71
  116. package/src/components/Form/AccessRights/List/ContactAccessRightsList.tsx +0 -51
  117. package/src/components/Form/AccessRights/List/ContactAccessRightsListItem.stories.tsx +0 -116
  118. package/src/components/Form/AccessRights/List/ContactAccessRightsListItem.tsx +0 -118
  119. package/src/components/Form/AccessRights/List/ContactAccessRightsListItemSkeleton.tsx +0 -26
  120. package/src/components/Form/AccessRights/List/ContactAccessRightsListSkeleton.tsx +0 -28
  121. package/src/components/Form/AccessRights/Stats/AccessRightsStats.styles.ts +0 -18
  122. package/src/components/Form/AccessRights/Stats/AccessRightsStats.tsx +0 -41
  123. package/src/components/Form/AccessRights/__fixtures__/contactAccessRight.mock.ts +0 -54
  124. package/src/components/Form/AccessRights/common/GroupLabel.styles.ts +0 -18
  125. package/src/components/Form/AccessRights/common/GroupLabel.tsx +0 -15
  126. package/src/components/Form/AccessRights/common/Input.styles.ts +0 -48
  127. package/src/components/Form/AccessRights/common/RoleInputSelect.styles.ts +0 -11
  128. package/src/components/Form/AccessRights/common/RoleInputSelect.tsx +0 -57
  129. package/src/components/Form/AccessRights/index.ts +0 -3
  130. package/src/components/Form/AccessRights/useAccessRightsForm.test.tsx +0 -531
  131. package/src/components/Form/AccessRights/useAccessRightsForm.tsx +0 -282
  132. package/src/components/Form/AccessRights/useAccessRightsForm.utils.ts +0 -41
  133. package/src/components/Layout/PageLayout/PageQuickAccess.tsx +0 -76
  134. package/src/components/Layout/PageLayout.cypress.spec.tsx +0 -66
  135. package/src/utils/usePluralizedTranslation.ts +0 -21
  136. /package/src/components/Form/{AccessRightsV2 → AccessRights}/AccessRights.stories.tsx +0 -0
  137. /package/src/components/Form/{AccessRightsV2 → AccessRights}/AccessRights.styles.ts +0 -0
  138. /package/src/components/Form/{AccessRightsV2 → AccessRights}/AccessRights.tsx +0 -0
  139. /package/src/components/Form/{AccessRightsV2 → AccessRights}/Actions/Actions.styles.ts +0 -0
  140. /package/src/components/Form/{AccessRightsV2 → AccessRights}/Actions/Actions.tsx +0 -0
  141. /package/src/components/Form/{AccessRightsV2 → AccessRights}/Actions/useActions.ts +0 -0
  142. /package/src/components/Form/{AccessRightsV2 → AccessRights}/List/Item.tsx +0 -0
  143. /package/src/components/Form/{AccessRightsV2 → AccessRights}/List/List.styles.tsx +0 -0
  144. /package/src/components/Form/{AccessRightsV2 → AccessRights}/List/List.tsx +0 -0
  145. /package/src/components/Form/{AccessRightsV2 → AccessRights}/List/ListItemSkeleton.tsx +0 -0
  146. /package/src/components/Form/{AccessRightsV2 → AccessRights}/List/ListSkeleton.tsx +0 -0
  147. /package/src/components/Form/{AccessRightsV2 → AccessRights}/List/RemoveAccessRight.tsx +0 -0
  148. /package/src/components/Form/{AccessRightsV2 → AccessRights}/List/StateChip.tsx +0 -0
  149. /package/src/components/Form/{AccessRightsV2 → AccessRights}/List/useItem.ts +0 -0
  150. /package/src/components/Form/{AccessRightsV2 → AccessRights}/Provider.tsx +0 -0
  151. /package/src/components/Form/{AccessRightsV2 → AccessRights}/ShareInput/ShareInput.tsx +0 -0
  152. /package/src/components/Form/{AccessRightsV2 → AccessRights}/Stats/Stats.tsx +0 -0
  153. /package/src/components/Form/{AccessRightsV2 → AccessRights}/atoms.ts +0 -0
  154. /package/src/components/Form/{AccessRightsV2 → AccessRights}/common/RoleSelectField.styles.tsx +0 -0
  155. /package/src/components/Form/{AccessRightsV2 → AccessRights}/common/RoleSelectField.tsx +0 -0
  156. /package/src/components/Form/{AccessRightsV2 → AccessRights}/useAccessRightsInitValues.ts +0 -0
@@ -1,13 +1,6 @@
1
1
  import dayjs from 'dayjs';
2
- import { renderHook } from '@testing-library/react';
3
2
 
4
- import {
5
- getFetchCall,
6
- mockResponse,
7
- resetMocks,
8
- waitFor
9
- } from '../../test/testRenderer';
10
- import TestQueryProvider from '../api/TestQueryProvider';
3
+ import { TestQueryProvider, Method, SnackbarProvider } from '@centreon/ui';
11
4
 
12
5
  import { labelLicenseWarning } from './translatedLabel';
13
6
 
@@ -86,63 +79,59 @@ const getMockedResponse = (expirationDate): object => ({
86
79
  });
87
80
 
88
81
  const mockRequest = ({ expirationDate }: { expirationDate }): void => {
89
- resetMocks();
90
- mockResponse({
91
- data: getMockedResponse(expirationDate)
82
+ cy.interceptAPIRequest({
83
+ alias: 'getLicenseInformations',
84
+ method: Method.GET,
85
+ path: '**internal.php?object=centreon_module&action=list',
86
+ response: getMockedResponse(expirationDate)
92
87
  });
93
88
  };
94
89
 
95
- const showMessage = jest.fn();
90
+ const TestComponent = (): JSX.Element => {
91
+ useLicenseExpirationWarning({
92
+ module: 'centreon-autodiscovery-server'
93
+ });
96
94
 
97
- jest.mock('../Snackbar/useSnackbar', () => ({
98
- __esModule: true,
99
- default: jest
100
- .fn()
101
- .mockImplementation(() => ({ showWarningMessage: showMessage }))
102
- }));
95
+ return <div />;
96
+ };
103
97
 
104
- const initialize = (): void => {
105
- renderHook(
106
- () =>
107
- useLicenseExpirationWarning({
108
- module: 'centreon-autodiscovery-server'
109
- }),
110
- {
111
- wrapper: TestQueryProvider
112
- }
98
+ const TestWithQueryProvider = (): JSX.Element => {
99
+ return (
100
+ <TestQueryProvider>
101
+ <SnackbarProvider>
102
+ <TestComponent />
103
+ </SnackbarProvider>
104
+ </TestQueryProvider>
113
105
  );
114
106
  };
115
107
 
108
+ const initialize = (): void => {
109
+ cy.viewport('macbook-13');
110
+
111
+ cy.mount({
112
+ Component: <TestWithQueryProvider />
113
+ });
114
+ };
115
+
116
116
  const currentDate = dayjs();
117
117
 
118
118
  describe('License', () => {
119
+ beforeEach(initialize);
120
+
119
121
  it('does not display any warning message when the license expires in more than 15 days from the current date', () => {
120
122
  mockRequest({ expirationDate: currentDate.add(20, 'day') });
121
- initialize();
122
123
 
123
- waitFor(() => {
124
- expect(getFetchCall(0)).toEqual(
125
- 'internal.php?object=centreon_module&action=list'
126
- );
127
- });
124
+ cy.waitForRequest('@getLicenseInformations');
128
125
 
129
- expect(showMessage).not.toHaveBeenCalled();
126
+ cy.findByText(
127
+ labelLicenseWarning('centreon-autodiscovery-server', 20)
128
+ ).should('not.exist');
130
129
  });
131
-
132
130
  it('displays a warning message when the license expires within 15 days', () => {
133
131
  mockRequest({ expirationDate: currentDate.add(10.5, 'day') });
134
- initialize();
135
-
136
- waitFor(() => {
137
- expect(getFetchCall(0)).toEqual(
138
- 'internal.php?object=centreon_module&action=list'
139
- );
140
- });
141
-
142
- waitFor(() => {
143
- expect(showMessage).toHaveBeenCalledWith(
144
- labelLicenseWarning('centreon-autodiscovery-server', 10)
145
- );
146
- });
132
+
133
+ cy.findByText(labelLicenseWarning('centreon-autodiscovery-server', 10));
134
+
135
+ cy.makeSnapshot();
147
136
  });
148
137
  });
@@ -19,7 +19,7 @@ export const useLicenseExpirationWarning = ({ module }: Props): void => {
19
19
  const { t } = useTranslation();
20
20
  const { showWarningMessage } = useSnackbar();
21
21
 
22
- const { data } = useFetchQuery({
22
+ const { fetchQuery } = useFetchQuery({
23
23
  getEndpoint: () => extensionsEndpoint,
24
24
  getQueryKey: () => [module]
25
25
  });
@@ -28,25 +28,25 @@ export const useLicenseExpirationWarning = ({ module }: Props): void => {
28
28
 
29
29
  const getExpirationDate = pipe(
30
30
  path(['result', 'module', 'entities']),
31
- find(propEq(module, 'id')),
31
+ find(propEq('id', module)),
32
32
  path(['license', 'expiration_date'])
33
33
  ) as (data) => string;
34
34
 
35
35
  useEffect(() => {
36
- if (isNil(data)) {
37
- return;
38
- }
39
-
40
- const expirationDate = getExpirationDate(data);
41
-
42
- if (isNil(expirationDate)) {
43
- return;
44
- }
45
-
46
- const daysUntilExpiration = dayjs(expirationDate).diff(currentDate, 'day');
47
-
48
- if (lt(daysUntilExpiration, 15)) {
49
- showWarningMessage(t(labelLicenseWarning(module, daysUntilExpiration)));
50
- }
51
- }, [data]);
36
+ fetchQuery().then((response) => {
37
+ const expirationDate = getExpirationDate(response);
38
+ if (isNil(expirationDate)) {
39
+ return;
40
+ }
41
+
42
+ const daysUntilExpiration = dayjs(expirationDate).diff(
43
+ currentDate,
44
+ 'day'
45
+ );
46
+
47
+ if (lt(daysUntilExpiration, 15)) {
48
+ showWarningMessage(t(labelLicenseWarning(module, daysUntilExpiration)));
49
+ }
50
+ });
51
+ }, []);
52
52
  };
@@ -1,133 +0,0 @@
1
- import { object } from 'yup';
2
- import { faker } from '@faker-js/faker';
3
- import { useFormikContext } from 'formik';
4
-
5
- import { Typography } from '@mui/material';
6
-
7
- import { Button } from '../components';
8
-
9
- import { Form } from './Form';
10
- import { InputType } from './Inputs/models';
11
-
12
- faker.seed(42);
13
-
14
- const AddItem = ({ addItem }: { addItem: (item) => void }): JSX.Element => {
15
- const { values } = useFormikContext();
16
- const add = (): void => {
17
- addItem({
18
- alias: faker.company.name(),
19
- id: values.list.length,
20
- name: faker.person.firstName()
21
- });
22
- };
23
-
24
- return (
25
- <Button variant="ghost" onClick={add}>
26
- Add item
27
- </Button>
28
- );
29
- };
30
-
31
- const SortContent = ({
32
- name,
33
- alias
34
- }: {
35
- alias: string;
36
- name: string;
37
- }): JSX.Element => (
38
- <Typography>
39
- {name} ({alias})
40
- </Typography>
41
- );
42
-
43
- const initializeFormList = (): void => {
44
- cy.mount({
45
- Component: (
46
- <Form
47
- initialValues={{
48
- list: []
49
- }}
50
- inputs={[
51
- {
52
- fieldName: 'list',
53
- group: '',
54
- label: '',
55
- list: {
56
- AddItem,
57
- SortContent,
58
- addItemLabel: 'Add an item to the list',
59
- itemProps: ['id', 'name', 'alias'],
60
- sortLabel: 'Sort items'
61
- },
62
- type: InputType.List
63
- }
64
- ]}
65
- submit={cy.stub()}
66
- validationSchema={object()}
67
- />
68
- )
69
- });
70
- };
71
-
72
- describe('Form list', () => {
73
- beforeEach(initializeFormList);
74
-
75
- it('adds an element to the list', () => {
76
- cy.contains('Add an item to the list').should('be.visible');
77
- cy.contains('Sort items').should('be.visible');
78
-
79
- cy.contains('Add item').click();
80
-
81
- cy.findByLabelText('sort-0').should('be.visible');
82
- cy.findByLabelText('delete-0').should('be.visible');
83
- cy.contains('Christelle (Schinner - Wiegand)').should('be.visible');
84
-
85
- cy.makeSnapshot();
86
- });
87
-
88
- it('sorts elements in the list', () => {
89
- cy.contains('Add an item to the list').should('be.visible');
90
- cy.contains('Sort items').should('be.visible');
91
-
92
- cy.contains('Add item').click();
93
- cy.contains('Add item').click();
94
-
95
- cy.findByLabelText('sort-0').should('be.visible');
96
- cy.findByLabelText('delete-0').should('be.visible');
97
- cy.contains('Carley (Satterfield, Miller and Metz)').should('be.visible');
98
- cy.findByLabelText('sort-1').should('be.visible');
99
- cy.findByLabelText('delete-1').should('be.visible');
100
- cy.contains('Anderson (Crist - Bradtke)').should('be.visible');
101
-
102
- cy.moveSortableElementUsingAriaLabel({
103
- ariaLabel: 'sort-0',
104
- direction: 'down'
105
- });
106
-
107
- cy.contains('Carley (Satterfield, Miller and Metz)').should('be.visible');
108
- cy.contains('Anderson (Crist - Bradtke)').should('be.visible');
109
-
110
- cy.makeSnapshot();
111
- });
112
-
113
- it('removes an element from the list', () => {
114
- cy.contains('Add an item to the list').should('be.visible');
115
- cy.contains('Sort items').should('be.visible');
116
-
117
- cy.contains('Add item').click();
118
- cy.contains('Add item').click();
119
-
120
- cy.findByLabelText('sort-0').should('be.visible');
121
- cy.findByLabelText('delete-0').should('be.visible');
122
- cy.contains('Lea (Streich - Hartmann)').should('be.visible');
123
- cy.findByLabelText('sort-1').should('be.visible');
124
- cy.findByLabelText('delete-1').should('be.visible');
125
- cy.contains('Akeem (Quigley LLC)').should('be.visible');
126
-
127
- cy.findByLabelText('delete-0').click();
128
-
129
- cy.contains('Lea (Streich - Hartmann)').should('not.exist');
130
-
131
- cy.makeSnapshot();
132
- });
133
- });
@@ -1,62 +0,0 @@
1
- import { ReactNode } from 'react';
2
-
3
- import { DraggableSyntheticListeners } from '@dnd-kit/core';
4
-
5
- import KrilinIndicatorIcon from '@mui/icons-material/DragIndicator';
6
- import DeleteOutlineIcon from '@mui/icons-material/DeleteOutline';
7
-
8
- import { IconButton } from '../../../components';
9
-
10
- import { useListStyles } from './List.styles';
11
-
12
- export interface ContentProps {
13
- attributes;
14
- children: ReactNode;
15
- deleteItem: (id: string) => () => void;
16
- id: string;
17
- isDragging: boolean;
18
- isInDragOverlay?: boolean;
19
- itemRef: React.RefObject<HTMLDivElement>;
20
- listeners: DraggableSyntheticListeners;
21
- name: string;
22
- style;
23
- }
24
-
25
- const Content = ({
26
- listeners,
27
- itemRef,
28
- attributes,
29
- style,
30
- isDragging,
31
- id,
32
- children,
33
- deleteItem
34
- }: ContentProps): JSX.Element => {
35
- const { classes } = useListStyles();
36
-
37
- return (
38
- <div
39
- className={classes.content}
40
- ref={itemRef}
41
- {...attributes}
42
- style={style}
43
- >
44
- <IconButton
45
- data-dragging={isDragging}
46
- size="small"
47
- {...listeners}
48
- aria-label={`sort-${id}`}
49
- icon={<KrilinIndicatorIcon fontSize="small" />}
50
- />
51
- <div className={classes.innerContent}>{children}</div>
52
- <IconButton
53
- aria-label={`delete-${id}`}
54
- icon={<DeleteOutlineIcon color="error" fontSize="small" />}
55
- size="small"
56
- onClick={deleteItem(id)}
57
- />
58
- </div>
59
- );
60
- };
61
-
62
- export default Content;
@@ -1,29 +0,0 @@
1
- import { makeStyles } from 'tss-react/mui';
2
-
3
- export const useListStyles = makeStyles()((theme) => ({
4
- content: {
5
- '& [data-dragging="false"]': {
6
- cursor: 'grab'
7
- },
8
- '& [data-dragging="true"]': {
9
- cursor: 'grabbing'
10
- },
11
- alignItems: 'center',
12
- borderBottom: `1px dashed ${theme.palette.action.disabledBackground}`,
13
- display: 'flex',
14
- flexDirection: 'row',
15
- padding: theme.spacing(1, 0)
16
- },
17
- innerContent: {
18
- flexGrow: 1
19
- },
20
- items: {
21
- maxHeight: theme.spacing(16),
22
- overflowY: 'auto'
23
- },
24
- list: {
25
- display: 'flex',
26
- flexDirection: 'column',
27
- gap: theme.spacing(1)
28
- }
29
- }));
@@ -1,58 +0,0 @@
1
- import { ComponentType } from 'react';
2
-
3
- import { closestCenter } from '@dnd-kit/core';
4
- import { verticalListSortingStrategy } from '@dnd-kit/sortable';
5
- import { useTranslation } from 'react-i18next';
6
-
7
- import { InputPropsWithoutGroup } from '../models';
8
- import { SortableItems, Subtitle } from '../../..';
9
-
10
- import { useList } from './useList';
11
- import { useListStyles } from './List.styles';
12
- import Content, { ContentProps } from './Content';
13
-
14
- const List = ({
15
- list,
16
- fieldName
17
- }: InputPropsWithoutGroup): JSX.Element | null => {
18
- const { t } = useTranslation();
19
- const { classes } = useListStyles();
20
-
21
- const { addItem, sortList, sortedList, deleteItem } = useList({ fieldName });
22
-
23
- const { AddItem, addItemLabel, sortLabel, SortContent, itemProps } = list as {
24
- AddItem: ComponentType<{ addItem }>;
25
- SortContent: ComponentType;
26
- addItemLabel?: string;
27
- itemProps: Array<string>;
28
- sortLabel?: string;
29
- };
30
-
31
- return (
32
- <div className={classes.list}>
33
- {addItemLabel && <Subtitle>{t(addItemLabel)}</Subtitle>}
34
- <AddItem addItem={addItem} />
35
- {sortLabel && <Subtitle>{t(sortLabel)}</Subtitle>}
36
- <div className={classes.items}>
37
- <SortableItems
38
- updateSortableItemsOnItemsChange
39
- // eslint-disable-next-line react/no-unstable-nested-components
40
- Content={(props: Omit<ContentProps, 'children' | 'deleteItem'>) => (
41
- <Content {...props} deleteItem={deleteItem}>
42
- <SortContent {...props} />
43
- </Content>
44
- )}
45
- collisionDetection={closestCenter}
46
- itemProps={itemProps}
47
- items={sortedList}
48
- sortingStrategy={verticalListSortingStrategy}
49
- onDragEnd={({ items }): void => {
50
- sortList(items);
51
- }}
52
- />
53
- </div>
54
- </div>
55
- );
56
- };
57
-
58
- export default List;
@@ -1,81 +0,0 @@
1
- import { useMemo, useRef } from 'react';
2
-
3
- import { FormikValues, useFormikContext } from 'formik';
4
- import {
5
- append,
6
- equals,
7
- inc,
8
- isEmpty,
9
- pluck,
10
- prop,
11
- reject,
12
- sortBy
13
- } from 'ramda';
14
-
15
- import { SelectEntry } from '../../..';
16
-
17
- interface UseListState {
18
- addItem: (newItem: SelectEntry) => void;
19
- deleteItem: (id: string) => () => void;
20
- sortList: (items: Array<string>) => void;
21
- sortedList: Array<unknown>;
22
- }
23
-
24
- export const useList = ({ fieldName }): UseListState => {
25
- const { values, setFieldValue } = useFormikContext<FormikValues>();
26
- const maxOrder = useRef(0);
27
-
28
- const list = values[fieldName];
29
-
30
- const sortedList = useMemo(
31
- () =>
32
- sortBy(prop('order'), list).map(({ id, ...props }) => ({
33
- id: `${id}`,
34
- ...props
35
- })),
36
- [list]
37
- );
38
-
39
- const addItem = (newItem: SelectEntry): void => {
40
- setFieldValue(
41
- fieldName,
42
- append(
43
- {
44
- ...newItem,
45
- id: (newItem as SelectEntry).id as number,
46
- order: inc(maxOrder.current)
47
- },
48
- list
49
- )
50
- );
51
- };
52
-
53
- const deleteItem = (id: string) => (): void => {
54
- const newItems = reject((item) => equals(Number(id), item.id))(list);
55
-
56
- setFieldValue(fieldName, newItems);
57
- };
58
-
59
- const sortList = (items: Array<string>): void => {
60
- const newOrderedList = items.map((itemId, idx) => {
61
- const item = sortedList.find(({ id }) => equals(id, itemId));
62
-
63
- return {
64
- ...item,
65
- id: Number(item?.id),
66
- order: inc(idx)
67
- };
68
- });
69
-
70
- setFieldValue(fieldName, newOrderedList);
71
- };
72
-
73
- maxOrder.current = isEmpty(list) ? 0 : Math.max(...pluck('order', list));
74
-
75
- return {
76
- addItem,
77
- deleteItem,
78
- sortList,
79
- sortedList
80
- };
81
- };
@@ -1,129 +0,0 @@
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,6 +0,0 @@
1
- import { RowId } from '../../Listing/models';
2
- import { Listing, ListingProps } from '../..';
3
-
4
- export const DataListing = <TRow extends { id: RowId }>(
5
- props: ListingProps<TRow>
6
- ): JSX.Element => <Listing<TRow> {...props} />;