@centreon/ui 24.4.48 → 24.4.49

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 (137) hide show
  1. package/package.json +36 -29
  2. package/public/mockServiceWorker.js +1 -1
  3. package/src/Button/Icon/index.tsx +1 -1
  4. package/src/Button/Save/StartIcon.tsx +3 -3
  5. package/src/Button/Save/index.tsx +9 -5
  6. package/src/Checkbox/Checkbox.tsx +2 -2
  7. package/src/Checkbox/CheckboxGroup/index.tsx +2 -2
  8. package/src/Dashboard/Item.tsx +1 -1
  9. package/src/Dashboard/Layout.tsx +2 -2
  10. package/src/Dialog/Confirm/index.tsx +10 -2
  11. package/src/Dialog/index.tsx +9 -2
  12. package/src/FallbackPage/FallbackPage.tsx +3 -3
  13. package/src/FileDropZone/index.tsx +3 -1
  14. package/src/Form/Form.cypress.spec.tsx +133 -0
  15. package/src/Form/Inputs/List/Content.tsx +62 -0
  16. package/src/Form/Inputs/List/List.styles.ts +29 -0
  17. package/src/Form/Inputs/List/List.tsx +58 -0
  18. package/src/Form/Inputs/List/useList.ts +81 -0
  19. package/src/Form/Inputs/index.tsx +3 -1
  20. package/src/Form/Inputs/models.ts +9 -1
  21. package/src/Graph/BarStack/BarStack.cypress.spec.tsx +154 -0
  22. package/src/Graph/BarStack/BarStack.stories.tsx +123 -0
  23. package/src/Graph/BarStack/BarStack.styles.ts +36 -0
  24. package/src/Graph/BarStack/BarStack.tsx +14 -0
  25. package/src/Graph/BarStack/ResponsiveBarStack.tsx +208 -0
  26. package/src/Graph/BarStack/index.ts +1 -0
  27. package/src/Graph/BarStack/models.ts +19 -0
  28. package/src/Graph/BarStack/useResponsiveBarStack.ts +139 -0
  29. package/src/Graph/Gauge/Gauge.cypress.spec.tsx +102 -0
  30. package/src/Graph/Gauge/Gauge.tsx +1 -1
  31. package/src/Graph/HeatMap/HeatMap.cypress.spec.tsx +145 -0
  32. package/src/Graph/HeatMap/HeatMap.stories.tsx +0 -25
  33. package/src/Graph/HeatMap/ResponsiveHeatMap.tsx +8 -2
  34. package/src/Graph/Legend/Legend.tsx +21 -0
  35. package/src/Graph/Legend/index.ts +1 -0
  36. package/src/Graph/Legend/models.ts +11 -0
  37. package/src/Graph/LineChart/BasicComponents/Lines/Threshold/Circle.tsx +2 -2
  38. package/src/Graph/LineChart/BasicComponents/Thresholds.tsx +2 -2
  39. package/src/Graph/LineChart/BasicComponents/useFilterLines.ts +1 -1
  40. package/src/Graph/LineChart/InteractiveComponents/AnchorPoint/GuidingLines.tsx +2 -2
  41. package/src/Graph/LineChart/InteractiveComponents/Annotations/EventAnnotations.tsx +1 -1
  42. package/src/Graph/LineChart/Legend/Legend.styles.ts +1 -1
  43. package/src/Graph/LineChart/Legend/LegendHeader.tsx +1 -1
  44. package/src/Graph/LineChart/Legend/useInteractiveValues.ts +2 -2
  45. package/src/Graph/LineChart/Legend/useLegend.ts +3 -3
  46. package/src/Graph/LineChart/helpers/doc.ts +16 -13
  47. package/src/Graph/LineChart/helpers/index.ts +1 -1
  48. package/src/Graph/LineChart/index.stories.tsx +4 -2
  49. package/src/Graph/LineChart/index.tsx +1 -1
  50. package/src/Graph/PieChart/PieChart.cypress.spec.tsx +169 -0
  51. package/src/Graph/PieChart/PieChart.stories.tsx +194 -0
  52. package/src/Graph/PieChart/PieChart.styles.ts +39 -0
  53. package/src/Graph/PieChart/PieChart.tsx +14 -0
  54. package/src/Graph/PieChart/ResponsivePie.tsx +251 -0
  55. package/src/Graph/PieChart/index.ts +1 -0
  56. package/src/Graph/PieChart/models.ts +19 -0
  57. package/src/Graph/PieChart/useResponsivePie.ts +86 -0
  58. package/src/Graph/SingleBar/SingleBar.cypress.spec.tsx +121 -0
  59. package/src/Graph/SingleBar/Thresholds.tsx +2 -2
  60. package/src/Graph/Text/Text.cypress.spec.tsx +101 -0
  61. package/src/Graph/Text/Text.stories.tsx +60 -4
  62. package/src/Graph/Text/Text.tsx +1 -1
  63. package/src/Graph/common/testUtils.ts +71 -0
  64. package/src/Graph/common/timeSeries/index.ts +22 -14
  65. package/src/Graph/common/utils.ts +19 -0
  66. package/src/Graph/index.ts +3 -0
  67. package/src/Graph/translatedLabels.ts +1 -0
  68. package/src/InputField/Select/Autocomplete/Connected/index.tsx +10 -7
  69. package/src/InputField/Select/Autocomplete/Draggable/SortableList.tsx +1 -1
  70. package/src/InputField/Select/Autocomplete/Draggable/SortableListContent.tsx +1 -1
  71. package/src/InputField/Select/Autocomplete/Draggable/index.tsx +1 -1
  72. package/src/InputField/Select/Autocomplete/index.tsx +121 -115
  73. package/src/InputField/Select/IconPopover/index.tsx +2 -2
  74. package/src/InputField/Select/index.tsx +1 -1
  75. package/src/InputField/Text/index.tsx +2 -2
  76. package/src/Listing/ActionBar/index.tsx +9 -8
  77. package/src/Listing/Cell/DataCell.styles.ts +3 -0
  78. package/src/Listing/Cell/DataCell.tsx +23 -5
  79. package/src/Listing/Header/ListingHeader.tsx +1 -1
  80. package/src/Listing/Listing.cypress.spec.tsx +80 -4
  81. package/src/Listing/Listing.styles.ts +4 -7
  82. package/src/Listing/index.stories.tsx +37 -3
  83. package/src/Listing/index.test.tsx +1 -1
  84. package/src/Listing/index.tsx +4 -3
  85. package/src/Listing/models.ts +1 -0
  86. package/src/Module/Module.cypress.spec.tsx +129 -0
  87. package/src/Module/index.tsx +2 -4
  88. package/src/RichTextEditor/RichTextEditor.tsx +12 -1
  89. package/src/SortableItems/index.tsx +2 -7
  90. package/src/ThemeProvider/index.tsx +24 -0
  91. package/src/TimePeriods/CustomTimePeriod/CompactCustomTimePeriod.styles.ts +6 -7
  92. package/src/TimePeriods/CustomTimePeriod/PopoverCustomTimePeriod/PickersStartEndDate.tsx +8 -3
  93. package/src/TimePeriods/CustomTimePeriod/PopoverCustomTimePeriod/models.ts +0 -2
  94. package/src/TimePeriods/DateTimePickerInput.tsx +56 -19
  95. package/src/TimePeriods/ResolutionTimePeriod.cypress.spec.tsx +12 -9
  96. package/src/TimePeriods/TimePeriods.cypress.spec.tsx +9 -33
  97. package/src/TimePeriods/helpers/index.ts +1 -1
  98. package/src/TimePeriods/index.stories.tsx +12 -4
  99. package/src/TimePeriods/index.tsx +2 -2
  100. package/src/api/QueryProvider.tsx +1 -1
  101. package/src/api/TestQueryProvider.tsx +1 -1
  102. package/src/api/useFetchQuery/index.ts +27 -23
  103. package/src/api/useMutationQuery/index.test.ts +4 -4
  104. package/src/api/useMutationQuery/index.ts +60 -25
  105. package/src/components/Button/Icon/IconButton.tsx +6 -2
  106. package/src/components/DataTable/DataListing.tsx +6 -0
  107. package/src/components/DataTable/DataTable.cypress.spec.tsx +193 -0
  108. package/src/components/DataTable/DataTable.stories.tsx +40 -0
  109. package/src/components/DataTable/DataTable.styles.ts +3 -0
  110. package/src/components/DataTable/DataTable.tsx +3 -3
  111. package/src/components/DataTable/Item/DataTableItem.styles.ts +7 -2
  112. package/src/components/DataTable/Item/DataTableItem.tsx +4 -4
  113. package/src/components/DataTable/index.ts +3 -1
  114. package/src/components/Form/AccessRights/ShareInput/ContactSwitch.tsx +3 -3
  115. package/src/components/Form/AccessRights/ShareInput/ShareInput.tsx +1 -0
  116. package/src/components/Form/Dashboard/DashboardForm.tsx +15 -12
  117. package/src/components/Layout/PageLayout/PageLayout.tsx +1 -1
  118. package/src/components/Layout/PageLayout/PageLayoutActions.tsx +1 -0
  119. package/src/components/Layout/PageLayout/PageLayoutBody.tsx +1 -0
  120. package/src/components/Layout/PageLayout/PageLayoutHeader.tsx +5 -1
  121. package/src/components/Layout/PageLayout/PageQuickAccess.tsx +76 -0
  122. package/src/components/Layout/PageLayout/index.ts +3 -1
  123. package/src/components/Layout/PageLayout.cypress.spec.tsx +66 -0
  124. package/src/components/Modal/Modal.styles.ts +1 -1
  125. package/src/components/Tooltip/ConfirmationTooltip/ConfirmationTooltip.stories.tsx +3 -3
  126. package/src/components/Tooltip/ConfirmationTooltip/ConfirmationTooltip.tsx +1 -1
  127. package/src/components/Tooltip/ConfirmationTooltip/models.ts +1 -1
  128. package/src/index.ts +2 -2
  129. package/src/queryParameters/url/index.ts +5 -1
  130. package/src/utils/index.ts +1 -1
  131. package/src/utils/useFullscreen/useFullscreenListener.ts +10 -7
  132. package/src/utils/{useLicenseExpirationWarning.cypress.spec.tsx → useLicenseExpirationWarning.test.tsx} +48 -37
  133. package/src/utils/useLicenseExpirationWarning.ts +18 -18
  134. package/src/utils/usePluralizedTranslation.ts +21 -0
  135. package/src/screens/dashboard/DashboardsDetail.stories.tsx +0 -108
  136. package/src/screens/dashboard/DashboardsOverview.stories.tsx +0 -281
  137. package/src/utils/useDateTimePickerAdapter.ts +0 -309
@@ -1,4 +1,6 @@
1
- import { Button } from '@mui/material';
1
+ import { Button, Typography } from '@mui/material';
2
+
3
+ import { ListingVariant } from '@centreon/ui-context';
2
4
 
3
5
  import { ColumnType } from './models';
4
6
 
@@ -12,6 +14,12 @@ const ButtonColumn = ({ row }: Props): JSX.Element => (
12
14
  <Button size="small">Click to reveal details about {row.name}</Button>
13
15
  );
14
16
 
17
+ const LargeText = (): JSX.Element => (
18
+ <Typography sx={{ whiteSpace: 'normal' }}>
19
+ This is a large text that fills the content
20
+ </Typography>
21
+ );
22
+
15
23
  const generateSubItems = (parentIndex: number): Array<unknown> => {
16
24
  return tenElements.map((__, subIndex) => ({
17
25
  active: false,
@@ -37,6 +45,28 @@ const listingWithSubItems = tenElements.map((_, index) => ({
37
45
  subItems: index % 2 === 0 ? generateSubItems(index) : undefined
38
46
  }));
39
47
 
48
+ const defaultColumn = [
49
+ {
50
+ getFormattedString: ({ name }): string => name,
51
+ id: 'name',
52
+ label: 'Name',
53
+ type: ColumnType.string
54
+ },
55
+ {
56
+ getFormattedString: ({ description }): string => description,
57
+ id: 'description',
58
+ label: 'Description',
59
+ type: ColumnType.string
60
+ },
61
+ {
62
+ Component: LargeText,
63
+ id: '#',
64
+ label: 'Custom',
65
+ type: ColumnType.component,
66
+ width: '100px'
67
+ }
68
+ ];
69
+
40
70
  const columnsWithSubItems = [
41
71
  {
42
72
  getFormattedString: ({ name }): string => name,
@@ -62,7 +92,27 @@ const columnsWithSubItems = [
62
92
 
63
93
  const expandedItems = [0, 8];
64
94
 
65
- const mountListing = (): void => {
95
+ const mountListingResponsive = (listingVariant: ListingVariant): void => {
96
+ cy.viewport('macbook-13');
97
+
98
+ cy.mount({
99
+ Component: (
100
+ <div style={{ height: '100vh' }}>
101
+ <Listing
102
+ isResponsive
103
+ columns={defaultColumn}
104
+ currentPage={1}
105
+ limit={10}
106
+ listingVariant={listingVariant}
107
+ rows={listingWithSubItems}
108
+ totalRows={10}
109
+ />
110
+ </div>
111
+ )
112
+ });
113
+ };
114
+
115
+ const mountListingForSubItems = (): void => {
66
116
  cy.viewport('macbook-13');
67
117
 
68
118
  cy.mount({
@@ -89,9 +139,9 @@ const mountListing = (): void => {
89
139
  };
90
140
 
91
141
  describe('Listing', () => {
92
- beforeEach(mountListing);
93
-
94
142
  it('expands the row when the corresponding icon si clicked', () => {
143
+ mountListingForSubItems();
144
+
95
145
  cy.contains('E0').should('be.visible');
96
146
 
97
147
  expandedItems.forEach((index) => {
@@ -111,6 +161,8 @@ describe('Listing', () => {
111
161
  });
112
162
 
113
163
  it('collapses the row when the corresponding icon si clicked', () => {
164
+ mountListingForSubItems();
165
+
114
166
  cy.contains('Sub item 100').should('be.visible');
115
167
 
116
168
  cy.findByLabelText('Collapse 0').click();
@@ -119,4 +171,28 @@ describe('Listing', () => {
119
171
 
120
172
  cy.makeSnapshot();
121
173
  });
174
+
175
+ it('displays the last column on several lines in compact mode when the isResponsive prop is set', () => {
176
+ mountListingResponsive(ListingVariant.compact);
177
+
178
+ cy.get('.MuiTable-root').should(
179
+ 'have.css',
180
+ 'grid-template-rows',
181
+ '30px 85px 85px 85px 85px 85px 85px 85px 85px 85px 85px'
182
+ );
183
+
184
+ cy.makeSnapshot();
185
+ });
186
+
187
+ it('displays the last column on several lines in extended mode when the isResponsive prop is set', () => {
188
+ mountListingResponsive(ListingVariant.extended);
189
+
190
+ cy.get('.MuiTable-root').should(
191
+ 'have.css',
192
+ 'grid-template-rows',
193
+ '38px 85px 85px 85px 85px 85px 85px 85px 85px 85px 85px'
194
+ );
195
+
196
+ cy.makeSnapshot();
197
+ });
122
198
  });
@@ -1,7 +1,5 @@
1
1
  import { makeStyles } from 'tss-react/mui';
2
2
 
3
- import { ListingVariant } from '@centreon/ui-context';
4
-
5
3
  import { TableStyleAtom as TableStyle } from './models';
6
4
 
7
5
  const loadingIndicatorHeight = 3;
@@ -9,13 +7,12 @@ const loadingIndicatorHeight = 3;
9
7
  interface StylesProps {
10
8
  dataStyle: TableStyle;
11
9
  getGridTemplateColumn: string;
12
- limit: number;
13
- listingVariant: ListingVariant;
10
+ isResponsive: string;
14
11
  rows: Array<unknown>;
15
12
  }
16
13
 
17
14
  const useListingStyles = makeStyles<StylesProps>()(
18
- (theme, { dataStyle, getGridTemplateColumn, rows, limit }) => ({
15
+ (theme, { dataStyle, getGridTemplateColumn, rows, isResponsive }) => ({
19
16
  actionBar: {
20
17
  alignItems: 'center',
21
18
  display: 'flex'
@@ -56,8 +53,8 @@ const useListingStyles = makeStyles<StylesProps>()(
56
53
  display: 'grid',
57
54
  gridTemplateColumns: getGridTemplateColumn,
58
55
  gridTemplateRows: `${theme.spacing(dataStyle.header.height / 8)} repeat(${
59
- rows?.length || limit
60
- }, ${dataStyle.body.height}px)`,
56
+ rows?.length || 1
57
+ }, ${isResponsive ? 'auto' : `${dataStyle.body.height}px`})`,
61
58
  position: 'relative'
62
59
  },
63
60
  tableBody: {
@@ -40,7 +40,7 @@ const useStyles = makeStyles()((theme) => ({
40
40
  }));
41
41
 
42
42
  const ComponentColumn = ({ row, isSelected }): JSX.Element => (
43
- <>
43
+ <div style={{ display: 'flex', flexDirection: 'row', flexWrap: 'wrap' }}>
44
44
  <span>
45
45
  {'I am '}
46
46
  <b>{`${isSelected ? 'selected' : 'not selected'}`}</b>
@@ -50,7 +50,7 @@ const ComponentColumn = ({ row, isSelected }): JSX.Element => (
50
50
  {'I am '}
51
51
  <b>{`${row.active ? 'active' : 'not active'}`}</b>
52
52
  </span>
53
- </>
53
+ </div>
54
54
  );
55
55
 
56
56
  const ButtonColumn = ({ row }): JSX.Element => (
@@ -366,6 +366,16 @@ const columnsWithSubItems = [
366
366
  }
367
367
  ];
368
368
 
369
+ const TemplateSubItems = (args): JSX.Element => {
370
+ const { classes } = useStyles();
371
+
372
+ return (
373
+ <div className={classes.listing}>
374
+ <Listing {...args} />
375
+ </div>
376
+ );
377
+ };
378
+
369
379
  export const ListingWithSubItems = {
370
380
  args: {
371
381
  checkable: true,
@@ -382,5 +392,29 @@ export const ListingWithSubItems = {
382
392
  labelExpand: 'Expand'
383
393
  },
384
394
  totalRows: 10
385
- }
395
+ },
396
+ render: TemplateSubItems
397
+ };
398
+
399
+ export const ListingWithResponsive = {
400
+ args: {
401
+ checkable: true,
402
+ columns: [
403
+ ...defaultColumns,
404
+ {
405
+ Component: ComponentColumn,
406
+ id: '##',
407
+ label: 'Responsive',
408
+ type: ColumnType.component,
409
+ width: '140px'
410
+ }
411
+ ],
412
+ currentPage: 1,
413
+ isResponsive: true,
414
+ limit: 10,
415
+ loading: false,
416
+ rows: listingWithSubItems,
417
+ totalRows: 10
418
+ },
419
+ render: TemplateSubItems
386
420
  };
@@ -216,7 +216,7 @@ describe('Listing', () => {
216
216
  <Listing
217
217
  columnConfiguration={{
218
218
  selectedColumnIds: columns.map(prop('id')),
219
- sortable: false
219
+ sortable: true
220
220
  }}
221
221
  columns={columns}
222
222
  rows={rows}
@@ -69,7 +69,7 @@ const getVisibleColumns = ({
69
69
  }
70
70
 
71
71
  return selectedColumnIds.map((id) =>
72
- columns.find(propEq('id', id))
72
+ columns.find(propEq(id, 'id'))
73
73
  ) as Array<Column>;
74
74
  };
75
75
 
@@ -102,6 +102,7 @@ export interface Props<TRow> {
102
102
  getId?: (row: TRow) => RowId;
103
103
  headerMemoProps?: Array<unknown>;
104
104
  innerScrollDisabled?: boolean;
105
+ isResponsive?: boolean;
105
106
  limit?: number;
106
107
  listingVariant?: ListingVariant;
107
108
  loading?: boolean;
@@ -147,6 +148,7 @@ const Listing = <TRow extends { id: RowId }>({
147
148
  columns,
148
149
  columnConfiguration = defaultColumnConfiguration,
149
150
  customPaginationClassName,
151
+ isResponsive = false,
150
152
  onResetColumns,
151
153
  onSelectColumns,
152
154
  rows = [],
@@ -233,8 +235,7 @@ const Listing = <TRow extends { id: RowId }>({
233
235
  const { classes } = useListingStyles({
234
236
  dataStyle,
235
237
  getGridTemplateColumn,
236
- limit,
237
- listingVariant,
238
+ isResponsive,
238
239
  rows: rowsToDisplay
239
240
  });
240
241
 
@@ -15,6 +15,7 @@ export interface ComponentColumnProps {
15
15
 
16
16
  export interface Column {
17
17
  Component?: (props: ComponentColumnProps) => JSX.Element | null;
18
+ align?: 'start' | 'end' | 'center';
18
19
  clickable?: boolean;
19
20
  compact?: boolean;
20
21
  disablePadding?: boolean;
@@ -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({
@@ -12,6 +12,7 @@ import { LinkPlugin } from '@lexical/react/LexicalLinkPlugin';
12
12
  import { equals } from 'ramda';
13
13
  import { ListPlugin } from '@lexical/react/LexicalListPlugin';
14
14
  import { OnChangePlugin } from '@lexical/react/LexicalOnChangePlugin';
15
+ import { $generateHtmlFromNodes } from '@lexical/html';
15
16
 
16
17
  import { Typography } from '@mui/material';
17
18
 
@@ -38,6 +39,7 @@ export interface RichTextEditorProps {
38
39
  openLinkInNewTab?: boolean;
39
40
  placeholder?: string;
40
41
  resetEditorToInitialStateCondition?: () => boolean;
42
+ setHtmlString?: (htmlString: string) => void;
41
43
  toolbarClassName?: string;
42
44
  toolbarPositions?: 'start' | 'end';
43
45
  }
@@ -143,6 +145,7 @@ const RichTextEditor = ({
143
145
  openLinkInNewTab = true,
144
146
  initialize,
145
147
  displayBlockButtons = true,
148
+ setHtmlString,
146
149
  toolbarClassName
147
150
  }: RichTextEditorProps): JSX.Element => {
148
151
  const { classes } = useStyles({ toolbarPositions });
@@ -178,6 +181,13 @@ const RichTextEditor = ({
178
181
  }
179
182
  };
180
183
 
184
+ const change = (state: EditorState, editor: LexicalEditor): void => {
185
+ editor.update(() => {
186
+ setHtmlString?.($generateHtmlFromNodes(editor, null));
187
+ });
188
+ getEditorState?.(state, editor);
189
+ };
190
+
181
191
  return (
182
192
  <LexicalComposer initialConfig={initialConfig}>
183
193
  <div className={classes.container}>
@@ -210,6 +220,7 @@ const RichTextEditor = ({
210
220
  resetEditorToInitialStateCondition={
211
221
  resetEditorToInitialStateCondition
212
222
  }
223
+ setHtmlString={setHtmlString}
213
224
  onBlur={onBlur}
214
225
  />
215
226
  }
@@ -218,7 +229,7 @@ const RichTextEditor = ({
218
229
  <HistoryPlugin />
219
230
  <LinkPlugin />
220
231
  <ListPlugin />
221
- <OnChangePlugin onChange={getEditorState} />
232
+ <OnChangePlugin onChange={change} />
222
233
  <AutoCompleteLinkPlugin openLinkInNewTab={openLinkInNewTab} />
223
234
  <FloatingLinkEditorPlugin
224
235
  editable={editable}
@@ -15,11 +15,7 @@ import {
15
15
  DragEndEvent,
16
16
  Over
17
17
  } from '@dnd-kit/core';
18
- import {
19
- SortableContext,
20
- sortableKeyboardCoordinates,
21
- SortingStrategy
22
- } from '@dnd-kit/sortable';
18
+ import { SortableContext, SortingStrategy } from '@dnd-kit/sortable';
23
19
  import {
24
20
  equals,
25
21
  find,
@@ -117,7 +113,6 @@ const SortableItems = <T extends { [propertyToFilterItemsOn]: string }>({
117
113
  useSensor(MouseSensor),
118
114
  useSensor(PointerSensor),
119
115
  useSensor(KeyboardSensor, {
120
- coordinateGetter: sortableKeyboardCoordinates,
121
116
  keyboardCodes: {
122
117
  cancel: ['Escape'],
123
118
  end: ['Space', 'Enter'],
@@ -169,7 +164,7 @@ const SortableItems = <T extends { [propertyToFilterItemsOn]: string }>({
169
164
  };
170
165
 
171
166
  const getItemById = (id): T | undefined =>
172
- find(propEq(propertyToFilterItemsOn, id), items);
167
+ find(propEq(id, propertyToFilterItemsOn), items);
173
168
 
174
169
  const activeItem = getItemById(activeId) as Record<string, unknown>;
175
170
 
@@ -147,6 +147,30 @@ export const getTheme = (mode: ThemeMode): ThemeOptions => ({
147
147
  },
148
148
  MuiCssBaseline: {
149
149
  styleOverrides: (theme) => `
150
+ ::-webkit-scrollbar {
151
+ height: ${theme.spacing(1)};
152
+ width: ${theme.spacing(1)};
153
+ background-color: transparent;
154
+ }
155
+ ::-webkit-scrollbar-thumb {
156
+ background-color: ${
157
+ equals(mode, 'dark')
158
+ ? theme.palette.divider
159
+ : theme.palette.text.disabled
160
+ };
161
+ border-radius: ${theme.spacing(0.5)};
162
+ }
163
+ ::-webkit-scrollbar-thumb:hover {
164
+ background-color: ${theme.palette.primary.main};
165
+ }
166
+ * {
167
+ scrollbar-color: ${
168
+ equals(mode, 'dark')
169
+ ? theme.palette.divider
170
+ : theme.palette.text.disabled
171
+ } ${theme.palette.background.default};
172
+ scrollbar-width: thin;
173
+ }
150
174
  html {
151
175
  margin: 0;
152
176
  padding: 0;
@@ -12,22 +12,21 @@ const useStyles = makeStyles()((theme) => ({
12
12
  },
13
13
  containerDates: {
14
14
  display: 'flex',
15
- gap: theme.spacing(0.5),
16
15
  [theme.breakpoints.down('sm')]: {
17
- columnGap: theme.spacing(0.5),
18
- flexDirection: 'column'
16
+ flexDirection: 'column',
17
+ gap: theme.spacing(0.5)
19
18
  }
20
19
  },
21
20
  date: {
22
- minWidth: theme.spacing(12.5),
21
+ minWidth: theme.spacing(12),
23
22
  textAlign: 'start'
24
23
  },
25
24
  error: {
26
25
  textAlign: 'center'
27
26
  },
28
27
  label: {
29
- minWidth: theme.spacing(3),
30
- textAlign: 'start'
28
+ minWidth: theme.spacing(3.5),
29
+ textAlign: 'end'
31
30
  },
32
31
 
33
32
  picker: {
@@ -39,7 +38,7 @@ const useStyles = makeStyles()((theme) => ({
39
38
  },
40
39
  timeContainer: {
41
40
  alignItems: 'center',
42
- columnGap: theme.spacing(1),
41
+ columnGap: theme.spacing(0.5),
43
42
  display: 'flex',
44
43
  flexDirection: 'row',
45
44
  [theme.breakpoints.down('sm')]: {
@@ -2,12 +2,15 @@ import { useAtomValue } from 'jotai';
2
2
  import { makeStyles } from 'tss-react/mui';
3
3
  import { equals } from 'ramda';
4
4
  import { useTranslation } from 'react-i18next';
5
+ import dayjs from 'dayjs';
6
+ import utc from 'dayjs/plugin/utc';
7
+ import timezone from 'dayjs/plugin/timezone';
5
8
 
9
+ import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
6
10
  import { Typography } from '@mui/material';
7
11
  import { LocalizationProvider } from '@mui/x-date-pickers';
8
12
 
9
13
  import { userAtom } from '@centreon/ui-context';
10
- import { useDateTimePickerAdapter } from '@centreon/ui';
11
14
 
12
15
  import DateTimePickerInput from '../../DateTimePickerInput';
13
16
  import {
@@ -20,6 +23,9 @@ import ErrorText from './ErrorText';
20
23
  import { PickersData, PickersStartEndDateDirection } from './models';
21
24
  import { PickersStartEndDateModel } from './usePickersStartEndDate';
22
25
 
26
+ dayjs.extend(utc);
27
+ dayjs.extend(timezone);
28
+
23
29
  const useStyles = makeStyles()((theme) => ({
24
30
  error: {
25
31
  textAlign: 'center'
@@ -104,7 +110,6 @@ const PickersStartEndDate = ({
104
110
  direction = PickersStartEndDateDirection.column
105
111
  }: Props): JSX.Element => {
106
112
  const { classes, cx } = useStyles();
107
- const { Adapter } = useDateTimePickerAdapter();
108
113
 
109
114
  const { locale } = useAtomValue(userAtom);
110
115
  const error = useAtomValue(errorTimePeriodAtom);
@@ -126,7 +131,7 @@ const PickersStartEndDate = ({
126
131
  return (
127
132
  <LocalizationProvider
128
133
  adapterLocale={locale.substring(0, 2)}
129
- dateAdapter={Adapter}
134
+ dateAdapter={AdapterDayjs}
130
135
  >
131
136
  <div className={styleContainer}>
132
137
  <PickerDateWithLabel
@@ -18,8 +18,6 @@ export interface PickersData {
18
18
  getError?: (value: boolean) => void;
19
19
  isDisabledEndPicker?: boolean;
20
20
  isDisabledStartPicker?: boolean;
21
- onCloseEndPicker?: (isClosed: boolean) => void;
22
- onCloseStartPicker?: (isClosed: boolean) => void;
23
21
  rangeEndDate?: RangeDate;
24
22
  rangeStartDate?: RangeDate;
25
23
  }