@centreon/ui 25.3.4 → 25.4.0-MON-191119-npm-develop.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.
Files changed (176) hide show
  1. package/package.json +25 -11
  2. package/public/mockServiceWorker.js +8 -31
  3. package/src/Button/Save/index.stories.tsx +1 -0
  4. package/src/Checkbox/Checkbox.tsx +3 -1
  5. package/src/Checkbox/CheckboxGroup/index.tsx +6 -1
  6. package/src/Colors/index.tsx +1 -1
  7. package/src/Dashboard/Dashboard.styles.ts +1 -1
  8. package/src/Dashboard/Layout.tsx +1 -1
  9. package/src/Dialog/UnsavedChanges/index.stories.tsx +1 -0
  10. package/src/Form/CollapsibleGroup.tsx +13 -13
  11. package/src/Form/Form.cypress.spec.tsx +137 -2
  12. package/src/Form/Form.stories.tsx +11 -31
  13. package/src/Form/Form.tsx +2 -0
  14. package/src/Form/Inputs/Checkbox.tsx +3 -2
  15. package/src/Form/Inputs/ConnectedAutocomplete.tsx +6 -1
  16. package/src/Form/Inputs/Grid.tsx +18 -29
  17. package/src/Form/Inputs/SubGroupDivider.tsx +7 -0
  18. package/src/Form/Inputs/Text.tsx +1 -0
  19. package/src/Form/Inputs/index.tsx +31 -24
  20. package/src/Form/Inputs/models.ts +8 -1
  21. package/src/Form/Section/FormSection.tsx +34 -0
  22. package/src/Form/Section/PanelTabs.tsx +13 -0
  23. package/src/Form/Section/navigateToSection.ts +9 -0
  24. package/src/Form/storiesData.tsx +14 -4
  25. package/src/Graph/BarChart/BarChart.cypress.spec.tsx +46 -6
  26. package/src/Graph/BarChart/BarChart.stories.tsx +60 -0
  27. package/src/Graph/BarChart/BarChart.tsx +56 -32
  28. package/src/Graph/BarChart/BarGroup.tsx +22 -32
  29. package/src/Graph/BarChart/MemoizedGroup.tsx +8 -11
  30. package/src/Graph/BarChart/ResponsiveBarChart.tsx +145 -32
  31. package/src/Graph/BarChart/Tooltip/BarChartTooltip.tsx +2 -2
  32. package/src/Graph/Chart/BasicComponents/Lines/StackedLines/index.tsx +7 -1
  33. package/src/Graph/Chart/BasicComponents/Lines/StackedLines/useStackedLines.ts +18 -45
  34. package/src/Graph/Chart/BasicComponents/Lines/index.tsx +42 -28
  35. package/src/Graph/Chart/Chart.cypress.spec.tsx +85 -15
  36. package/src/Graph/Chart/Chart.stories.tsx +84 -1
  37. package/src/Graph/Chart/Chart.tsx +17 -4
  38. package/src/Graph/Chart/InteractiveComponents/AnchorPoint/RegularAnchorPoint.tsx +8 -2
  39. package/src/Graph/Chart/InteractiveComponents/AnchorPoint/StackedAnchorPoint.tsx +10 -3
  40. package/src/Graph/Chart/InteractiveComponents/AnchorPoint/useTickGraph.ts +19 -2
  41. package/src/Graph/Chart/InteractiveComponents/GraphValueTooltip/useGraphValueTooltip.ts +2 -4
  42. package/src/Graph/Chart/InteractiveComponents/ZoomPreview/index.tsx +14 -3
  43. package/src/Graph/Chart/InteractiveComponents/ZoomPreview/models.ts +3 -0
  44. package/src/Graph/Chart/InteractiveComponents/ZoomPreview/useZoomPreview.ts +12 -10
  45. package/src/Graph/Chart/InteractiveComponents/index.tsx +63 -5
  46. package/src/Graph/Chart/Legend/index.tsx +26 -2
  47. package/src/Graph/Chart/index.tsx +45 -45
  48. package/src/Graph/Chart/models.ts +8 -0
  49. package/src/Graph/Chart/useChartData.ts +14 -2
  50. package/src/Graph/Gauge/Gauge.tsx +18 -14
  51. package/src/Graph/Gauge/ResponsiveGauge.tsx +10 -6
  52. package/src/Graph/Gauge/useResizeObserver.ts +68 -0
  53. package/src/Graph/SingleBar/ResponsiveSingleBar.tsx +18 -16
  54. package/src/Graph/SingleBar/ThresholdLine.tsx +4 -4
  55. package/src/Graph/SingleBar/models.ts +1 -0
  56. package/src/Graph/Text/Text.styles.ts +2 -2
  57. package/src/Graph/Text/Text.tsx +23 -10
  58. package/src/Graph/Timeline/ResponsiveTimeline.tsx +4 -0
  59. package/src/Graph/Timeline/Timeline.tsx +21 -4
  60. package/src/Graph/Tree/Links.tsx +2 -2
  61. package/src/Graph/Tree/Tree.tsx +2 -2
  62. package/src/Graph/Tree/constants.ts +1 -1
  63. package/src/Graph/common/BaseChart/BaseChart.tsx +6 -1
  64. package/src/Graph/common/BaseChart/ChartSvgWrapper.tsx +5 -4
  65. package/src/Graph/common/BaseChart/Header/index.tsx +3 -1
  66. package/src/Graph/common/BaseChart/useComputeBaseChartDimensions.ts +13 -9
  67. package/src/Graph/common/timeSeries/index.test.ts +20 -0
  68. package/src/Graph/common/timeSeries/index.ts +225 -44
  69. package/src/Graph/common/timeSeries/models.ts +6 -2
  70. package/src/Graph/common/utils.ts +45 -12
  71. package/src/Graph/index.ts +3 -1
  72. package/src/Graph/mockedData/dataWithMissingPoint.json +74 -0
  73. package/src/Graph/mockedData/pingServiceWithStackedKeys.json +205 -0
  74. package/src/Icon/RegexIcon.tsx +20 -0
  75. package/src/Icon/index.ts +1 -0
  76. package/src/InputField/Select/Autocomplete/Connected/Multi/MultiConnectedAutocompleteField.cypress.spec.tsx +68 -14
  77. package/src/InputField/Select/Autocomplete/Connected/index.tsx +49 -14
  78. package/src/InputField/Select/Autocomplete/Multi/Listbox.tsx +78 -0
  79. package/src/InputField/Select/Autocomplete/Multi/Multi.styles.ts +26 -0
  80. package/src/InputField/Select/Autocomplete/Multi/Multi.tsx +124 -0
  81. package/src/InputField/Select/Autocomplete/Multi/index.tsx +1 -117
  82. package/src/InputField/Select/Autocomplete/index.tsx +28 -17
  83. package/src/InputField/Select/Option.tsx +3 -3
  84. package/src/InputField/Select/index.tsx +4 -0
  85. package/src/InputField/Text/index.tsx +4 -2
  86. package/src/InputField/translatedLabels.ts +4 -0
  87. package/src/Listing/ActionBar/Pagination.tsx +10 -23
  88. package/src/Listing/ActionBar/PaginationActions.tsx +1 -10
  89. package/src/Listing/ActionBar/index.tsx +1 -1
  90. package/src/Listing/Cell/DataCell.tsx +6 -6
  91. package/src/Listing/Cell/EllipsisTypography.tsx +10 -32
  92. package/src/Listing/Cell/index.tsx +37 -76
  93. package/src/Listing/Checkbox.tsx +8 -20
  94. package/src/Listing/Header/Cell/ListingHeaderCell.tsx +17 -14
  95. package/src/Listing/Header/Cell/SelectActionListingHeaderCell.tsx +5 -9
  96. package/src/Listing/Header/ListingHeader.tsx +2 -5
  97. package/src/Listing/Header/_internals/Label.tsx +1 -17
  98. package/src/Listing/Row/EmptyRow.tsx +2 -6
  99. package/src/Listing/Row/Row.tsx +7 -36
  100. package/src/Listing/index.stories.tsx +1 -0
  101. package/src/Listing/index.tsx +26 -26
  102. package/src/Listing/useStyleTable.ts +58 -32
  103. package/src/ListingPage/index.stories.tsx +1 -0
  104. package/src/Module/index.tsx +8 -2
  105. package/src/MultiSelectEntries/index.stories.tsx +1 -0
  106. package/src/MultiSelectEntries/index.tsx +1 -1
  107. package/src/Pagination/Pagination.cypress.spec.tsx +137 -0
  108. package/src/Pagination/Pagination.stories.tsx +46 -0
  109. package/src/Pagination/Pagination.styles.ts +56 -0
  110. package/src/Pagination/Pagination.tsx +146 -0
  111. package/src/Pagination/index.ts +3 -0
  112. package/src/Pagination/utils.ts +7 -0
  113. package/src/SortableItems/index.stories.tsx +2 -2
  114. package/src/StoryBookThemeProvider/index.tsx +3 -1
  115. package/src/ThemeProvider/base.css +49 -0
  116. package/src/ThemeProvider/index.tsx +21 -47
  117. package/src/ThemeProvider/palettes.ts +3 -1
  118. package/src/ThemeProvider/tailwindcss.css +230 -0
  119. package/src/TimePeriods/CustomTimePeriod/PopoverCustomTimePeriod/PickersStartEndDate.tsx +9 -11
  120. package/src/TimePeriods/CustomTimePeriod/PopoverCustomTimePeriod/models.ts +1 -0
  121. package/src/TimePeriods/DateTimePickerInput.tsx +3 -1
  122. package/src/api/models.ts +9 -0
  123. package/src/api/useGraphQuery/index.ts +108 -12
  124. package/src/components/Avatar/Avatar.stories.tsx +1 -0
  125. package/src/components/Button/Button.module.css +38 -0
  126. package/src/components/Button/Button.stories.tsx +25 -0
  127. package/src/components/Button/Button.tsx +2 -5
  128. package/src/components/CrudPage/CrudPage.stories.tsx +1 -0
  129. package/src/components/CrudPage/CrudPageRoot.tsx +1 -1
  130. package/src/components/DataTable/DataTable.stories.tsx +1 -0
  131. package/src/components/DataTable/EmptyState/DataTableEmptyState.stories.tsx +1 -0
  132. package/src/components/DataTable/EmptyState/DataTableEmptyState.styles.ts +3 -1
  133. package/src/components/DataTable/EmptyState/DataTableEmptyState.tsx +4 -1
  134. package/src/components/DataTable/Item/DataTableItem.stories.tsx +1 -0
  135. package/src/components/Form/AccessRights/AccessRights.stories.tsx +1 -0
  136. package/src/components/Form/AccessRights/ShareInput/ShareInput.tsx +4 -3
  137. package/src/components/Form/AccessRights/ShareInput/useShareInput.tsx +15 -10
  138. package/src/components/Form/FormActions.tsx +21 -12
  139. package/src/components/Layout/AreaIndicator.tsx +4 -6
  140. package/src/components/Layout/PageLayout/PageLayout.stories.tsx +1 -0
  141. package/src/components/Layout/PageLayout/PageLayout.tsx +9 -3
  142. package/src/components/Layout/PageLayout/PageLayoutActions.tsx +5 -3
  143. package/src/components/Layout/PageLayout/PageLayoutBody.tsx +5 -3
  144. package/src/components/Layout/PageLayout/PageLayoutHeader.tsx +5 -3
  145. package/src/components/Layout/PageLayout/PageQuickAccess.tsx +17 -17
  146. package/src/components/Menu/Button/MenuButton.tsx +6 -6
  147. package/src/components/Menu/MenuDivider.tsx +1 -5
  148. package/src/components/Menu/MenuItem.tsx +1 -5
  149. package/src/components/Menu/MenuItems.tsx +5 -4
  150. package/src/components/Modal/ConfirmationModal/ConfirmationModal.stories.tsx +1 -0
  151. package/src/components/Modal/ConfirmationModal/ConfirmationModal.tsx +4 -1
  152. package/src/components/Modal/Modal.stories.tsx +21 -0
  153. package/src/components/Modal/Modal.styles.ts +1 -19
  154. package/src/components/Modal/Modal.tsx +1 -1
  155. package/src/components/Modal/ModalBody.tsx +6 -4
  156. package/src/components/Modal/ModalHeader.tsx +9 -5
  157. package/src/components/Modal/modal.module.css +16 -0
  158. package/src/components/Tabs/Tab.styles.ts +0 -6
  159. package/src/components/Tabs/Tabs.tsx +37 -15
  160. package/src/index.ts +3 -0
  161. package/src/queryParameters/url/index.ts +7 -2
  162. package/src/utils/index.ts +1 -0
  163. package/src/utils/useLocale/index.ts +9 -0
  164. package/src/utils/useLocale/useLocale.cypress.spec.tsx +38 -0
  165. package/src/utils/useLocaleDateTimeFormat/index.ts +4 -2
  166. package/src/utils/usePluralizedTranslation.ts +2 -3
  167. package/src/Listing/Cell/DataCell.styles.ts +0 -27
  168. package/src/Listing/Header/Cell/ListingHeaderCell.styles.ts +0 -71
  169. package/src/Listing/Header/Cell/SelectActionListingHeaderCell.styles.ts +0 -26
  170. package/src/Listing/Header/ListingHeader.styles.ts +0 -16
  171. package/src/Listing/Listing.styles.ts +0 -78
  172. package/src/Listing/Row/EmptyRow.styles.ts +0 -14
  173. package/src/components/Button/Button.styles.ts +0 -44
  174. package/src/components/Layout/AreaIndicator.styles.ts +0 -33
  175. package/src/components/Menu/Button/MenuButton.styles.ts +0 -27
  176. package/src/components/Menu/Menu.styles.ts +0 -68
@@ -8,7 +8,7 @@ const useStyles = makeStyles<{
8
8
  }>()((theme, props) => ({
9
9
  modal: {
10
10
  '& .MuiDialog-paper': {
11
- gap: theme.spacing(2),
11
+ gap: theme.spacing(3),
12
12
  padding: theme.spacing(2.5)
13
13
  },
14
14
  '&[data-size="fullscreen"]': {
@@ -65,15 +65,6 @@ const useStyles = makeStyles<{
65
65
  right: 0,
66
66
  zIndex: theme.zIndex.modal
67
67
  },
68
- modalBody: {
69
- '& > p': {
70
- '&:first-of-type': {
71
- margin: theme.spacing(0, 0, 1, 0)
72
- },
73
- margin: theme.spacing(1, 0, 1, 0),
74
- width: '90%'
75
- }
76
- },
77
68
  modalCloseButton: {
78
69
  position: 'absolute',
79
70
  right: theme.spacing(1),
@@ -81,15 +72,6 @@ const useStyles = makeStyles<{
81
72
  opacity: 0.6
82
73
  },
83
74
  top: theme.spacing(1)
84
- },
85
- modalHeader: {
86
- '& .MuiDialogTitle-root': {
87
- padding: theme.spacing(0)
88
- },
89
- display: 'flex',
90
- gap: theme.spacing(2),
91
-
92
- justifyContent: 'space-between'
93
75
  }
94
76
  }));
95
77
 
@@ -54,7 +54,7 @@ const Modal = ({
54
54
  TransitionProps={{
55
55
  direction: 'up'
56
56
  }}
57
- className={classes.modal}
57
+ className={`${classes.modal} gap-6`}
58
58
  data-size={size}
59
59
  open={open}
60
60
  onClose={onClose}
@@ -1,15 +1,17 @@
1
1
  import { ReactElement, ReactNode } from 'react';
2
2
 
3
- import { useStyles } from './Modal.styles';
3
+ import { modalBody } from './modal.module.css';
4
4
 
5
5
  export type ModalHeaderProps = {
6
6
  children?: ReactNode;
7
7
  };
8
8
 
9
9
  const ModalBody = ({ children }: ModalHeaderProps): ReactElement => {
10
- const { classes } = useStyles();
11
-
12
- return <div className={classes.modalBody}>{children}</div>;
10
+ return (
11
+ <div className={modalBody} data-testid="modal-body">
12
+ {children}
13
+ </div>
14
+ );
13
15
  };
14
16
 
15
17
  export { ModalBody };
@@ -2,7 +2,9 @@ import { ReactElement, ReactNode } from 'react';
2
2
 
3
3
  import { DialogTitleProps, DialogTitle as MuiDialogTitle } from '@mui/material';
4
4
 
5
- import { useStyles } from './Modal.styles';
5
+ import '../../../src/ThemeProvider/tailwindcss.css';
6
+
7
+ import { modalHeader } from './modal.module.css';
6
8
 
7
9
  export type ModalHeaderProps = {
8
10
  children?: ReactNode;
@@ -12,11 +14,13 @@ const ModalHeader = ({
12
14
  children,
13
15
  ...rest
14
16
  }: ModalHeaderProps & DialogTitleProps): ReactElement => {
15
- const { classes } = useStyles();
16
-
17
17
  return (
18
- <div className={classes.modalHeader}>
19
- <MuiDialogTitle color="primary" {...rest}>
18
+ <div className={modalHeader}>
19
+ <MuiDialogTitle
20
+ className="p-0 font-bold text-2xl"
21
+ color="primary"
22
+ {...rest}
23
+ >
20
24
  {children}
21
25
  </MuiDialogTitle>
22
26
  </div>
@@ -0,0 +1,16 @@
1
+ .modalHeader {
2
+ & .MuiDialogTitle-root {
3
+ padding: 0;
4
+ }
5
+
6
+ display: flex;
7
+ gap: var(--spacing-4);
8
+ justify-content: space-between;
9
+ }
10
+
11
+ .modalBody {
12
+ overflow-y: auto;
13
+ overflow-x: hidden;
14
+ height: 100%;
15
+ padding-right: var(--spacing-4); /* To prevent scrollbar from overlapping content */
16
+ }
@@ -5,12 +5,6 @@ export const useTabsStyles = makeStyles()((theme) => ({
5
5
  bottom: 'unset'
6
6
  },
7
7
  tab: {
8
- '&[aria-selected="true"]': {
9
- color: theme.palette.text.primary,
10
- fontWeight: theme.typography.fontWeightBold
11
- },
12
- color: theme.palette.text.primary,
13
- fontWeight: theme.typography.fontWeightRegular,
14
8
  marginRight: theme.spacing(2),
15
9
  minHeight: 0,
16
10
  minWidth: 0,
@@ -1,54 +1,76 @@
1
1
  import { useCallback, useState } from 'react';
2
2
 
3
- import { TabContext, TabList, TabListProps } from '@mui/lab';
4
- import { Tab } from '@mui/material';
3
+ import { TabContext } from '@mui/lab';
4
+ import { Tabs as MuiTabs, Tab, TabsProps } from '@mui/material';
5
5
 
6
6
  import { useTabsStyles } from './Tab.styles';
7
7
 
8
+ import '../../ThemeProvider/tailwindcss.css';
9
+
10
+ export interface TabI {
11
+ label: string;
12
+ value: string;
13
+ }
14
+
8
15
  type Props = {
9
- children: Array<JSX.Element>;
16
+ children?: Array<JSX.Element>;
10
17
  defaultTab: string;
11
- tabList?: TabListProps;
12
- tabs: Array<{
13
- label: string;
14
- value: string;
15
- }>;
18
+ tabList?: TabsProps;
19
+ variant?: 'standard' | 'scrollable' | 'fullWidth';
20
+ scrollButtons?: boolean | 'auto';
21
+ tabs: TabI[];
22
+ onChange?: (newValue: string) => void;
16
23
  };
17
24
 
18
25
  export const Tabs = ({
19
26
  children,
20
27
  defaultTab,
21
28
  tabs,
22
- tabList
29
+ tabList,
30
+ variant,
31
+ scrollButtons = 'auto',
32
+ onChange
23
33
  }: Props): JSX.Element => {
24
34
  const { classes } = useTabsStyles();
25
35
 
26
36
  const [selectedTab, setSelectedTab] = useState(defaultTab);
27
37
 
28
- const changeTab = useCallback((_, newValue: string): void => {
29
- setSelectedTab(newValue);
30
- }, []);
38
+ const changeTab = useCallback(
39
+ (_, newValue: string): void => {
40
+ if (onChange) onChange(newValue);
41
+
42
+ setSelectedTab(newValue);
43
+ },
44
+ [onChange]
45
+ );
46
+
47
+ const selectedTabStyle = ' font-bold text-primary-main';
48
+ const defaultTabStyle = ' font-normal';
31
49
 
32
50
  return (
33
51
  <TabContext value={selectedTab}>
34
- <TabList
52
+ <MuiTabs
53
+ scrollButtons={scrollButtons}
54
+ variant={variant}
35
55
  classes={{
36
56
  indicator: classes.indicator,
37
57
  root: classes.tabs
38
58
  }}
39
59
  onChange={changeTab}
60
+ value={selectedTab}
40
61
  {...tabList}
41
62
  >
42
63
  {tabs.map(({ value, label }) => (
43
64
  <Tab
44
65
  aria-label={label}
45
- className={classes.tab}
66
+ className={`${classes.tab} ${selectedTab === value ? selectedTabStyle : defaultTabStyle}`}
46
67
  key={value}
47
68
  label={label}
48
69
  value={value}
70
+ data-testid={`tab-${value}`}
49
71
  />
50
72
  ))}
51
- </TabList>
73
+ </MuiTabs>
52
74
  {children}
53
75
  </TabContext>
54
76
  );
package/src/index.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import type { Props as SingleAutocompleteFieldProps } from './InputField/Select/Autocomplete';
2
2
 
3
3
  export { default as IconButton } from './Button/Icon';
4
+ export { default as Pagination } from './Pagination';
4
5
 
5
6
  export { Checkbox, CheckboxGroup } from './Checkbox';
6
7
 
@@ -71,6 +72,7 @@ export { default as StatusChip } from './StatusChip';
71
72
  export type { Props as StatusChipProps } from './StatusChip';
72
73
 
73
74
  export type { Listing as ListingModel } from './api/models';
75
+ export type { ListingMap as ListingMapModel } from './api/models';
74
76
 
75
77
  export { default as useCancelTokenSource } from './api/useCancelTokenSource';
76
78
  export { getData, patchData, postData, putData, deleteData } from './api';
@@ -87,6 +89,7 @@ export type {
87
89
  SearchMatch
88
90
  } from './api/buildListingEndpoint/models';
89
91
  export { default as buildListingDecoder } from './api/buildListingDecoder';
92
+ export { customFetch } from './api/customFetch';
90
93
 
91
94
  export { default as ContentWithCircularLoading } from './ContentWithCircularProgress';
92
95
  export {
@@ -1,4 +1,4 @@
1
- import { fromPairs, startsWith } from 'ramda';
1
+ import { equals, fromPairs, startsWith } from 'ramda';
2
2
 
3
3
  import { QueryParameter } from '../models';
4
4
 
@@ -25,7 +25,12 @@ const getUrlQueryParameters = <
25
25
 
26
26
  const entries = [...urlParams.entries()].map<[string, string]>(
27
27
  ([key, value]) => {
28
- if (startsWith('/', value)) {
28
+ if (
29
+ startsWith('/', value) ||
30
+ (!equals('false', value) &&
31
+ !equals('true', value) &&
32
+ !equals(value.match(/^[a-zA-Z]/), null))
33
+ ) {
29
34
  return [key, value];
30
35
  }
31
36
 
@@ -28,3 +28,4 @@ export * from '../Graph/Chart/InteractiveComponents/TimeShiftZones/useTimeShiftZ
28
28
  export * from '../TimePeriods/helpers';
29
29
  export { lastDayPeriod, type Parameters } from '../TimePeriods/models';
30
30
  export * from './useLocaleTimezoneDate/useLocaleTimezoneDate';
31
+ export * from './useLocale';
@@ -0,0 +1,9 @@
1
+ import { browserLocaleAtom, userAtom } from '@centreon/ui-context';
2
+ import { useAtomValue } from 'jotai';
3
+
4
+ export const useLocale = () => {
5
+ const user = useAtomValue(userAtom);
6
+ const browserLocale = useAtomValue(browserLocaleAtom);
7
+
8
+ return user.locale || browserLocale;
9
+ };
@@ -0,0 +1,38 @@
1
+ import { browserLocaleAtom, userAtom } from '@centreon/ui-context';
2
+ import { Provider, createStore } from 'jotai';
3
+ import { useLocale } from '.';
4
+
5
+ const TestComponent = () => {
6
+ const locale = useLocale();
7
+
8
+ return <p>{locale}</p>;
9
+ };
10
+
11
+ const initialize = ({ userLocale, browserLocale }) => {
12
+ const store = createStore();
13
+
14
+ store.set(userAtom, { locale: userLocale });
15
+ store.set(browserLocaleAtom, browserLocale);
16
+
17
+ cy.mount({
18
+ Component: (
19
+ <Provider store={store}>
20
+ <TestComponent />
21
+ </Provider>
22
+ )
23
+ });
24
+ };
25
+
26
+ describe('useLocale', () => {
27
+ it('displays the user locale when the corresponding atom is set', () => {
28
+ initialize({ userLocale: 'fi', browserLocale: 'en' });
29
+
30
+ cy.contains('fi').should('be.visible');
31
+ });
32
+
33
+ it('displays the browser locale when the user locale is not set', () => {
34
+ initialize({ browserLocale: 'de', userLocale: null });
35
+
36
+ cy.contains('de').should('be.visible');
37
+ });
38
+ });
@@ -5,6 +5,7 @@ import { useAtomValue } from 'jotai';
5
5
 
6
6
  import { userAtom } from '@centreon/ui-context';
7
7
 
8
+ import { useLocale } from '../useLocale';
8
9
  import shortLocales from './sortLocales';
9
10
 
10
11
  interface FormatParameters {
@@ -28,10 +29,11 @@ const timeFormat = 'LT';
28
29
  const dateTimeFormat = `${dateFormat} ${timeFormat}`;
29
30
 
30
31
  const useLocaleDateTimeFormat = (): LocaleDateTimeFormat => {
31
- const { locale, timezone } = useAtomValue(userAtom);
32
+ const locale = useLocale();
33
+ const { timezone } = useAtomValue(userAtom);
32
34
 
33
35
  const format = ({ date, formatString }: FormatParameters): string => {
34
- const normalizedLocale = locale.substring(0, 2);
36
+ const normalizedLocale = locale?.substring(0, 2);
35
37
 
36
38
  const timezoneDate = dayjs(
37
39
  new Date(date).toLocaleString('en', { timeZone: timezone })
@@ -1,11 +1,10 @@
1
1
  import { useCallback } from 'react';
2
2
 
3
- import { useAtomValue } from 'jotai';
4
3
  import pluralize from 'pluralize';
5
4
  import { equals, includes } from 'ramda';
6
5
  import { useTranslation } from 'react-i18next';
7
6
 
8
- import { userAtom } from '@centreon/ui-context';
7
+ import { useLocale } from './useLocale';
9
8
 
10
9
  interface TProps {
11
10
  count: number;
@@ -16,7 +15,7 @@ export const usePluralizedTranslation = (): {
16
15
  pluralizedT: (props: TProps) => string;
17
16
  } => {
18
17
  const translation = useTranslation();
19
- const { locale } = useAtomValue(userAtom);
18
+ const locale = useLocale();
20
19
 
21
20
  const isNotPartitiveLocale = includes('fr', locale);
22
21
 
@@ -1,27 +0,0 @@
1
- import { makeStyles } from 'tss-react/mui';
2
-
3
- const useStyles = makeStyles()((theme) => ({
4
- cell: {
5
- alignItems: 'center',
6
- display: 'flex',
7
- height: '100%',
8
- overflow: 'hidden',
9
- whiteSpace: 'nowrap'
10
- },
11
- clickable: {
12
- cursor: 'default'
13
- },
14
- componentColumn: {
15
- width: theme.spacing(2.75)
16
- },
17
- rowNotHovered: {
18
- color: theme.palette.text.secondary
19
- },
20
- text: {
21
- overflow: 'hidden',
22
- textOverflow: 'ellipsis',
23
- whiteSpace: 'nowrap'
24
- }
25
- }));
26
-
27
- export { useStyles };
@@ -1,71 +0,0 @@
1
- import { makeStyles } from 'tss-react/mui';
2
-
3
- import { ListingVariant } from '@centreon/ui-context';
4
-
5
- import { getTextStyleByViewMode } from '../../useStyleTable';
6
-
7
- interface StylesProps {
8
- isDragging?: boolean;
9
- isInDragOverlay?: boolean;
10
- listingVariant?: ListingVariant;
11
- }
12
-
13
- const useStyles = makeStyles<StylesProps>()(
14
- (theme, { isDragging, isInDragOverlay, listingVariant }) => ({
15
- active: {
16
- '&, &:hover, &:focus': {
17
- color: theme.palette.common.white
18
- },
19
- '&.Mui-active': {
20
- '& .MuiTableSortLabel-icon': {
21
- color: theme.palette.common.white
22
- },
23
- color: theme.palette.common.white
24
- }
25
- },
26
- content: {
27
- alignItems: 'center',
28
- borderRadius: isDragging && isInDragOverlay ? theme.spacing(0.5) : 0,
29
- color: theme.palette.common.white,
30
- display: 'flex',
31
- height: '100%',
32
- justifyContent: 'space-between'
33
- },
34
- dragHandle: {
35
- '&, &.Mui-focus, &:focus': {
36
- color: theme.palette.common.white
37
- },
38
- color: theme.palette.common.white,
39
-
40
- cursor: isDragging ? 'grabbing' : 'grab',
41
- opacity: 0,
42
- padding: 0
43
- },
44
- simpleHeaderCellContent: {
45
- alignItems: 'center',
46
- display: 'inline-flex',
47
- marginRight: theme.spacing(2),
48
- userSelect: 'none'
49
- },
50
- tableCell: {
51
- backgroundColor: isInDragOverlay
52
- ? 'transparent'
53
- : theme.palette.background.listingHeader,
54
- borderBottom: 'none',
55
- height: 'inherit',
56
- padding: theme.spacing(0, 1),
57
- ...getTextStyleByViewMode({ listingVariant, theme }),
58
- '&:hover, &:focus-within, &[data-isdragging=true]': {
59
- '& .dragHandle': {
60
- opacity: 1
61
- }
62
- },
63
- '&[data-isindragoverlay=true]': {
64
- display: 'block',
65
- opacity: 0.7
66
- }
67
- }
68
- })
69
- );
70
-
71
- export { useStyles, type StylesProps };
@@ -1,26 +0,0 @@
1
- import { makeStyles } from 'tss-react/mui';
2
-
3
- const useStyles = makeStyles()((theme) => ({
4
- checkbox: {
5
- '&.Mui-checked': {
6
- color: theme.palette.common.white
7
- },
8
- '&.MuiCheckbox-indeterminate': {
9
- color: theme.palette.common.white
10
- },
11
- color: theme.palette.common.white
12
- },
13
- checkboxHeaderCell: {
14
- alignItems: 'center',
15
- backgroundColor: theme.palette.background.listingHeader,
16
- borderBottom: 'none',
17
- display: 'flex',
18
- justifyContent: 'start',
19
- lineHeight: 'inherit'
20
- },
21
- predefinedRowsMenu: {
22
- color: theme.palette.common.white
23
- }
24
- }));
25
-
26
- export { useStyles };
@@ -1,16 +0,0 @@
1
- import { makeStyles } from 'tss-react/mui';
2
-
3
- const useStyles = makeStyles()((theme) => ({
4
- headerLabelDragging: {
5
- cursor: 'grabbing'
6
- },
7
- root: {
8
- height: '100%',
9
- padding: theme.spacing(0, 1)
10
- },
11
- row: {
12
- display: 'contents'
13
- }
14
- }));
15
-
16
- export { useStyles };
@@ -1,78 +0,0 @@
1
- import { makeStyles } from 'tss-react/mui';
2
-
3
- import { TableStyleAtom as TableStyle } from './models';
4
-
5
- const loadingIndicatorHeight = 3;
6
-
7
- interface StylesProps {
8
- dataStyle: TableStyle;
9
- getGridTemplateColumn: string;
10
- isResponsive: string;
11
- rows: Array<unknown>;
12
- }
13
-
14
- const useListingStyles = makeStyles<StylesProps>()(
15
- (theme, { dataStyle, getGridTemplateColumn, rows, isResponsive }) => ({
16
- actionBar: {
17
- alignItems: 'center',
18
- display: 'flex'
19
- },
20
- checkbox: {
21
- justifyContent: 'start'
22
- },
23
- container: {
24
- background: 'none',
25
- display: 'flex',
26
- flexDirection: 'column',
27
- height: '100%',
28
- width: '100%'
29
- },
30
- listingContainer: {
31
- height: '100%',
32
- overflow: 'hidden',
33
- width: '100%'
34
- },
35
- loadingIndicator: {
36
- height: loadingIndicatorHeight,
37
- width: '100%'
38
- },
39
- table: {
40
- '.listingHeader': {
41
- backgroundColor: theme.palette.background.listingHeader,
42
- padding: theme.spacing(0, 1)
43
- },
44
- '.listingHeader > div > div': {
45
- backgroundColor: theme.palette.background.listingHeader,
46
- height: theme.spacing(dataStyle.header.height / 8)
47
- },
48
- '.listingHeader > div > div:first-of-type': {
49
- height: '100%',
50
- padding: theme.spacing(0, 0.5, 0, 1.5)
51
- },
52
- alignItems: 'center',
53
- display: 'grid',
54
- gridTemplateColumns: getGridTemplateColumn,
55
- gridTemplateRows: `${theme.spacing(dataStyle.header.height / 8)} repeat(${
56
- rows?.length || 1
57
- }, ${isResponsive ? 'auto' : `${dataStyle.body.height}px`})`,
58
- position: 'relative'
59
- },
60
- tableBody: {
61
- '.MuiTableRow-root > div:first-of-type': {
62
- paddingLeft: theme.spacing(1.5)
63
- },
64
-
65
- display: 'contents',
66
- 'div:first-of-type': {
67
- gridColumnStart: 1
68
- },
69
- position: 'relative'
70
- },
71
- tableWrapper: {
72
- borderBottom: 'none',
73
- overflow: 'auto'
74
- }
75
- })
76
- );
77
-
78
- export { useListingStyles, loadingIndicatorHeight };
@@ -1,14 +0,0 @@
1
- import { makeStyles } from 'tss-react/mui';
2
-
3
- const useStyles = makeStyles()(() => ({
4
- emptyDataCell: {
5
- flexDirection: 'column',
6
- gridColumn: 'auto / -1',
7
- justifyContent: 'center'
8
- },
9
- emptyDataRow: {
10
- display: 'contents'
11
- }
12
- }));
13
-
14
- export { useStyles };
@@ -1,44 +0,0 @@
1
- import { makeStyles } from 'tss-react/mui';
2
-
3
- const useStyles = makeStyles()((theme) => ({
4
- button: {
5
- '&[data-size="medium"]': {
6
- fontSize: '16px',
7
- height: 'unset',
8
- lineHeight: '24px'
9
- },
10
-
11
- '&[data-size="small"]': {
12
- '&[data-variant="primary"], &[data-variant="secondary"]': {
13
- paddingLeft: theme.spacing(2),
14
- paddingRight: theme.spacing(2)
15
- },
16
- fontSize: '14px',
17
- height: 'unset',
18
- lineHeight: '22px'
19
- },
20
-
21
- '&[data-variant="primary"]:not(:disabled)': {
22
- '&[data-is-danger="true"]': {
23
- backgroundColor: theme.palette.error.main
24
- },
25
-
26
- backgroundColor: theme.palette.primary.main
27
- },
28
-
29
- '&[data-variant="secondary"]:not(:disabled)': {
30
- '&[data-is-danger="true"]': {
31
- borderColor: theme.palette.error.main,
32
- color: theme.palette.error.main
33
- },
34
-
35
- borderColor: theme.palette.primary.main,
36
- color: theme.palette.primary.main
37
- },
38
-
39
- textWrap: 'noWrap',
40
- transition: 'unset'
41
- }
42
- }));
43
-
44
- export { useStyles };