@centreon/ui 25.3.3 → 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 (187) hide show
  1. package/package.json +25 -11
  2. package/public/mockServiceWorker.js +8 -31
  3. package/src/ActionsList/index.tsx +1 -0
  4. package/src/Button/Icon/index.tsx +3 -1
  5. package/src/Button/Save/index.stories.tsx +1 -0
  6. package/src/Checkbox/Checkbox.tsx +3 -1
  7. package/src/Checkbox/CheckboxGroup/index.tsx +6 -1
  8. package/src/Colors/index.tsx +1 -1
  9. package/src/Dashboard/Dashboard.styles.ts +1 -1
  10. package/src/Dashboard/Layout.tsx +1 -1
  11. package/src/Dialog/UnsavedChanges/index.stories.tsx +1 -0
  12. package/src/Form/CollapsibleGroup.tsx +13 -13
  13. package/src/Form/Form.cypress.spec.tsx +137 -2
  14. package/src/Form/Form.stories.tsx +11 -31
  15. package/src/Form/Form.tsx +2 -0
  16. package/src/Form/Inputs/Checkbox.tsx +3 -2
  17. package/src/Form/Inputs/ConnectedAutocomplete.tsx +6 -1
  18. package/src/Form/Inputs/Grid.tsx +18 -29
  19. package/src/Form/Inputs/SubGroupDivider.tsx +7 -0
  20. package/src/Form/Inputs/Text.tsx +1 -0
  21. package/src/Form/Inputs/index.tsx +31 -24
  22. package/src/Form/Inputs/models.ts +8 -1
  23. package/src/Form/Section/FormSection.tsx +34 -0
  24. package/src/Form/Section/PanelTabs.tsx +13 -0
  25. package/src/Form/Section/navigateToSection.ts +9 -0
  26. package/src/Form/storiesData.tsx +14 -4
  27. package/src/Graph/BarChart/BarChart.cypress.spec.tsx +46 -6
  28. package/src/Graph/BarChart/BarChart.stories.tsx +60 -0
  29. package/src/Graph/BarChart/BarChart.tsx +56 -32
  30. package/src/Graph/BarChart/BarGroup.tsx +22 -32
  31. package/src/Graph/BarChart/MemoizedGroup.tsx +8 -11
  32. package/src/Graph/BarChart/ResponsiveBarChart.tsx +145 -32
  33. package/src/Graph/BarChart/Tooltip/BarChartTooltip.tsx +2 -2
  34. package/src/Graph/Chart/BasicComponents/Lines/StackedLines/index.tsx +7 -1
  35. package/src/Graph/Chart/BasicComponents/Lines/StackedLines/useStackedLines.ts +18 -45
  36. package/src/Graph/Chart/BasicComponents/Lines/index.tsx +42 -28
  37. package/src/Graph/Chart/Chart.cypress.spec.tsx +85 -15
  38. package/src/Graph/Chart/Chart.stories.tsx +84 -1
  39. package/src/Graph/Chart/Chart.tsx +17 -4
  40. package/src/Graph/Chart/InteractiveComponents/AnchorPoint/RegularAnchorPoint.tsx +8 -2
  41. package/src/Graph/Chart/InteractiveComponents/AnchorPoint/StackedAnchorPoint.tsx +10 -3
  42. package/src/Graph/Chart/InteractiveComponents/AnchorPoint/useTickGraph.ts +19 -2
  43. package/src/Graph/Chart/InteractiveComponents/Annotations/Annotation/index.tsx +1 -1
  44. package/src/Graph/Chart/InteractiveComponents/GraphValueTooltip/useGraphValueTooltip.ts +2 -4
  45. package/src/Graph/Chart/InteractiveComponents/ZoomPreview/index.tsx +14 -3
  46. package/src/Graph/Chart/InteractiveComponents/ZoomPreview/models.ts +3 -0
  47. package/src/Graph/Chart/InteractiveComponents/ZoomPreview/useZoomPreview.ts +12 -10
  48. package/src/Graph/Chart/InteractiveComponents/index.tsx +63 -5
  49. package/src/Graph/Chart/Legend/index.tsx +26 -2
  50. package/src/Graph/Chart/helpers/index.ts +4 -3
  51. package/src/Graph/Chart/index.tsx +45 -45
  52. package/src/Graph/Chart/models.ts +8 -0
  53. package/src/Graph/Chart/useChartData.ts +14 -2
  54. package/src/Graph/Gauge/Gauge.tsx +18 -14
  55. package/src/Graph/Gauge/ResponsiveGauge.tsx +10 -6
  56. package/src/Graph/Gauge/useResizeObserver.ts +68 -0
  57. package/src/Graph/SingleBar/ResponsiveSingleBar.tsx +18 -16
  58. package/src/Graph/SingleBar/ThresholdLine.tsx +4 -4
  59. package/src/Graph/SingleBar/models.ts +1 -0
  60. package/src/Graph/Text/Text.styles.ts +2 -2
  61. package/src/Graph/Text/Text.tsx +23 -10
  62. package/src/Graph/Timeline/ResponsiveTimeline.tsx +4 -0
  63. package/src/Graph/Timeline/Timeline.tsx +21 -4
  64. package/src/Graph/Tree/Links.tsx +2 -2
  65. package/src/Graph/Tree/Tree.tsx +2 -2
  66. package/src/Graph/Tree/constants.ts +1 -1
  67. package/src/Graph/common/BaseChart/BaseChart.tsx +6 -1
  68. package/src/Graph/common/BaseChart/ChartSvgWrapper.tsx +5 -4
  69. package/src/Graph/common/BaseChart/Header/index.tsx +3 -1
  70. package/src/Graph/common/BaseChart/useComputeBaseChartDimensions.ts +13 -9
  71. package/src/Graph/common/timeSeries/index.test.ts +20 -0
  72. package/src/Graph/common/timeSeries/index.ts +225 -44
  73. package/src/Graph/common/timeSeries/models.ts +6 -2
  74. package/src/Graph/common/utils.ts +45 -12
  75. package/src/Graph/index.ts +3 -1
  76. package/src/Graph/mockedData/dataWithMissingPoint.json +74 -0
  77. package/src/Graph/mockedData/pingServiceWithStackedKeys.json +205 -0
  78. package/src/Icon/RegexIcon.tsx +20 -0
  79. package/src/Icon/index.ts +1 -0
  80. package/src/InputField/Select/Autocomplete/Connected/Multi/MultiConnectedAutocompleteField.cypress.spec.tsx +68 -14
  81. package/src/InputField/Select/Autocomplete/Connected/index.tsx +49 -14
  82. package/src/InputField/Select/Autocomplete/Multi/Listbox.tsx +78 -0
  83. package/src/InputField/Select/Autocomplete/Multi/Multi.styles.ts +26 -0
  84. package/src/InputField/Select/Autocomplete/Multi/Multi.tsx +124 -0
  85. package/src/InputField/Select/Autocomplete/Multi/index.tsx +1 -117
  86. package/src/InputField/Select/Autocomplete/index.tsx +28 -17
  87. package/src/InputField/Select/Option.tsx +3 -3
  88. package/src/InputField/Select/index.tsx +4 -0
  89. package/src/InputField/Text/index.tsx +4 -2
  90. package/src/InputField/translatedLabels.ts +4 -0
  91. package/src/Listing/ActionBar/Pagination.tsx +10 -23
  92. package/src/Listing/ActionBar/PaginationActions.tsx +1 -10
  93. package/src/Listing/ActionBar/index.tsx +1 -1
  94. package/src/Listing/Cell/DataCell.tsx +6 -6
  95. package/src/Listing/Cell/EllipsisTypography.tsx +10 -32
  96. package/src/Listing/Cell/index.tsx +57 -89
  97. package/src/Listing/Checkbox.tsx +8 -20
  98. package/src/Listing/Header/Cell/ListingHeaderCell.tsx +17 -14
  99. package/src/Listing/Header/Cell/SelectActionListingHeaderCell.tsx +5 -9
  100. package/src/Listing/Header/ListingHeader.tsx +2 -5
  101. package/src/Listing/Header/_internals/Label.tsx +1 -17
  102. package/src/Listing/Row/EmptyRow.tsx +2 -6
  103. package/src/Listing/Row/Row.tsx +7 -36
  104. package/src/Listing/index.stories.tsx +1 -0
  105. package/src/Listing/index.tsx +26 -26
  106. package/src/Listing/useStyleTable.ts +58 -32
  107. package/src/ListingPage/index.stories.tsx +1 -0
  108. package/src/Module/index.tsx +8 -2
  109. package/src/MultiSelectEntries/index.stories.tsx +1 -0
  110. package/src/MultiSelectEntries/index.tsx +1 -1
  111. package/src/Pagination/Pagination.cypress.spec.tsx +137 -0
  112. package/src/Pagination/Pagination.stories.tsx +46 -0
  113. package/src/Pagination/Pagination.styles.ts +56 -0
  114. package/src/Pagination/Pagination.tsx +146 -0
  115. package/src/Pagination/index.ts +3 -0
  116. package/src/Pagination/utils.ts +7 -0
  117. package/src/SortableItems/index.stories.tsx +2 -2
  118. package/src/StoryBookThemeProvider/index.tsx +3 -1
  119. package/src/ThemeProvider/base.css +49 -0
  120. package/src/ThemeProvider/index.tsx +21 -47
  121. package/src/ThemeProvider/palettes.ts +5 -3
  122. package/src/ThemeProvider/tailwindcss.css +230 -0
  123. package/src/TimePeriods/CustomTimePeriod/PopoverCustomTimePeriod/PickersStartEndDate.tsx +9 -11
  124. package/src/TimePeriods/CustomTimePeriod/PopoverCustomTimePeriod/models.ts +1 -0
  125. package/src/TimePeriods/DateTimePickerInput.tsx +3 -1
  126. package/src/api/customFetch.ts +0 -9
  127. package/src/api/models.ts +9 -0
  128. package/src/api/useBulkResponse.ts +58 -0
  129. package/src/api/useGraphQuery/index.ts +108 -12
  130. package/src/components/Avatar/Avatar.stories.tsx +1 -0
  131. package/src/components/Button/Button.module.css +38 -0
  132. package/src/components/Button/Button.stories.tsx +25 -0
  133. package/src/components/Button/Button.tsx +2 -5
  134. package/src/components/CrudPage/Actions/Actions.styles.ts +15 -1
  135. package/src/components/CrudPage/Actions/Actions.tsx +7 -4
  136. package/src/components/CrudPage/Actions/Search.tsx +15 -14
  137. package/src/components/CrudPage/CrudPage.stories.tsx +1 -0
  138. package/src/components/CrudPage/CrudPageRoot.tsx +1 -1
  139. package/src/components/DataTable/DataTable.stories.tsx +1 -0
  140. package/src/components/DataTable/EmptyState/DataTableEmptyState.stories.tsx +1 -0
  141. package/src/components/DataTable/EmptyState/DataTableEmptyState.styles.ts +3 -1
  142. package/src/components/DataTable/EmptyState/DataTableEmptyState.tsx +4 -1
  143. package/src/components/DataTable/Item/DataTableItem.stories.tsx +1 -0
  144. package/src/components/Form/AccessRights/AccessRights.stories.tsx +1 -0
  145. package/src/components/Form/AccessRights/ShareInput/ShareInput.tsx +4 -3
  146. package/src/components/Form/AccessRights/ShareInput/useShareInput.tsx +15 -10
  147. package/src/components/Form/FormActions.tsx +21 -12
  148. package/src/components/Header/PageHeader/PageHeader.styles.ts +5 -5
  149. package/src/components/Layout/AreaIndicator.tsx +4 -6
  150. package/src/components/Layout/PageLayout/PageLayout.stories.tsx +1 -0
  151. package/src/components/Layout/PageLayout/PageLayout.styles.ts +1 -1
  152. package/src/components/Layout/PageLayout/PageLayout.tsx +9 -3
  153. package/src/components/Layout/PageLayout/PageLayoutActions.tsx +5 -3
  154. package/src/components/Layout/PageLayout/PageLayoutBody.tsx +5 -3
  155. package/src/components/Layout/PageLayout/PageLayoutHeader.tsx +5 -3
  156. package/src/components/Layout/PageLayout/PageQuickAccess.tsx +17 -17
  157. package/src/components/Menu/Button/MenuButton.tsx +6 -6
  158. package/src/components/Menu/MenuDivider.tsx +1 -5
  159. package/src/components/Menu/MenuItem.tsx +1 -5
  160. package/src/components/Menu/MenuItems.tsx +5 -4
  161. package/src/components/Modal/ConfirmationModal/ConfirmationModal.stories.tsx +1 -0
  162. package/src/components/Modal/ConfirmationModal/ConfirmationModal.tsx +4 -1
  163. package/src/components/Modal/Modal.stories.tsx +21 -0
  164. package/src/components/Modal/Modal.styles.ts +1 -19
  165. package/src/components/Modal/Modal.tsx +1 -1
  166. package/src/components/Modal/ModalBody.tsx +6 -4
  167. package/src/components/Modal/ModalHeader.tsx +9 -5
  168. package/src/components/Modal/modal.module.css +16 -0
  169. package/src/components/Tabs/Tab.styles.ts +0 -6
  170. package/src/components/Tabs/Tabs.tsx +37 -15
  171. package/src/index.ts +4 -0
  172. package/src/queryParameters/url/index.ts +7 -2
  173. package/src/utils/index.ts +1 -0
  174. package/src/utils/useLocale/index.ts +9 -0
  175. package/src/utils/useLocale/useLocale.cypress.spec.tsx +38 -0
  176. package/src/utils/useLocaleDateTimeFormat/index.ts +4 -2
  177. package/src/utils/usePluralizedTranslation.ts +2 -3
  178. package/src/Listing/Cell/DataCell.styles.ts +0 -27
  179. package/src/Listing/Header/Cell/ListingHeaderCell.styles.ts +0 -71
  180. package/src/Listing/Header/Cell/SelectActionListingHeaderCell.styles.ts +0 -26
  181. package/src/Listing/Header/ListingHeader.styles.ts +0 -16
  182. package/src/Listing/Listing.styles.ts +0 -78
  183. package/src/Listing/Row/EmptyRow.styles.ts +0 -14
  184. package/src/components/Button/Button.styles.ts +0 -44
  185. package/src/components/Layout/AreaIndicator.styles.ts +0 -33
  186. package/src/components/Menu/Button/MenuButton.styles.ts +0 -27
  187. package/src/components/Menu/Menu.styles.ts +0 -68
@@ -4,6 +4,7 @@ import { Default as DefaultPageHeaderStory } from '../../Header/PageHeader/PageH
4
4
  import { AreaIndicator } from '../AreaIndicator';
5
5
 
6
6
  import { PageLayout } from './index';
7
+ import '../../../ThemeProvider/tailwindcss.css';
7
8
 
8
9
  const meta: Meta<typeof PageLayout> = {
9
10
  argTypes: {
@@ -29,7 +29,7 @@ export const useStyles = makeStyles()((theme) => ({
29
29
  display: 'grid',
30
30
  gridTemplateRows: 'auto',
31
31
  overflow: 'hidden',
32
- padding: theme.spacing(1.5, 3, 1.5)
32
+ padding: theme.spacing(0, 3, 1.5)
33
33
  },
34
34
  pageLayoutHeader: {
35
35
  '[data-variant="fixed-header"] &': {
@@ -5,16 +5,22 @@ import { useStyles } from './PageLayout.styles';
5
5
  type PageLayoutProps = {
6
6
  children: Array<ReactNode> | ReactNode;
7
7
  variant?: 'default' | 'fixed-header';
8
+ className?: string;
8
9
  };
9
10
 
10
11
  export const PageLayout = ({
11
12
  children,
12
- variant = 'default'
13
+ variant = 'default',
14
+ className
13
15
  }: PageLayoutProps): ReactElement => {
14
- const { classes } = useStyles();
16
+ const { classes, cx } = useStyles();
15
17
 
16
18
  return (
17
- <section className={classes.pageLayout} data-variant={variant} id="page">
19
+ <section
20
+ className={cx(classes.pageLayout, className)}
21
+ data-variant={variant}
22
+ id="page"
23
+ >
18
24
  {children}
19
25
  </section>
20
26
  );
@@ -5,17 +5,19 @@ import { useStyles } from './PageLayout.styles';
5
5
  interface PageLayoutActionsProps {
6
6
  children: Array<ReactNode> | ReactNode;
7
7
  rowReverse?: boolean;
8
+ className?: string;
8
9
  }
9
10
 
10
11
  export const PageLayoutActions = ({
11
12
  children,
12
- rowReverse
13
+ rowReverse,
14
+ className
13
15
  }: PageLayoutActionsProps): ReactElement => {
14
- const { classes } = useStyles();
16
+ const { classes, cx } = useStyles();
15
17
 
16
18
  return (
17
19
  <section
18
- className={classes.pageLayoutActions}
20
+ className={cx(classes.pageLayoutActions, className)}
19
21
  data-row-reverse={rowReverse}
20
22
  id="actions"
21
23
  >
@@ -5,17 +5,19 @@ import { useStyles } from './PageLayout.styles';
5
5
  type PageLayoutBodyProps = {
6
6
  children: Array<ReactNode> | ReactNode;
7
7
  hasBackground?: boolean;
8
+ className?: string;
8
9
  };
9
10
 
10
11
  export const PageLayoutBody = ({
11
12
  children,
12
- hasBackground = false
13
+ hasBackground = false,
14
+ className
13
15
  }: PageLayoutBodyProps): ReactElement => {
14
- const { classes } = useStyles();
16
+ const { classes, cx } = useStyles();
15
17
 
16
18
  return (
17
19
  <section
18
- className={classes.pageLayoutBody}
20
+ className={cx(classes.pageLayoutBody, className)}
19
21
  data-has-background={hasBackground}
20
22
  data-has-actions={!!children?.length}
21
23
  id="page-body"
@@ -4,15 +4,17 @@ import { useStyles } from './PageLayout.styles';
4
4
 
5
5
  type PageLayoutHeaderProps = {
6
6
  children: Array<ReactNode> | ReactNode;
7
+ className?: string;
7
8
  };
8
9
 
9
10
  export const PageLayoutHeader = ({
10
- children
11
+ children,
12
+ className
11
13
  }: PageLayoutHeaderProps): JSX.Element => {
12
- const { classes } = useStyles();
14
+ const { classes, cx } = useStyles();
13
15
 
14
16
  return (
15
- <header className={classes.pageLayoutHeader} id="header">
17
+ <header className={cx(classes.pageLayoutHeader, className)} id="header">
16
18
  {children}
17
19
  </header>
18
20
  );
@@ -11,10 +11,11 @@ interface NamedEntity {
11
11
  }
12
12
 
13
13
  type Props = {
14
- create: () => void;
14
+ create?: () => void;
15
15
  elements: Array<NamedEntity>;
16
16
  goBack: () => void;
17
17
  isActive: (id: number | string) => boolean;
18
+ isDisabled?: (id: number | string) => boolean;
18
19
  labels: {
19
20
  create: string;
20
21
  goBack: string;
@@ -25,6 +26,7 @@ type Props = {
25
26
  export const PageQuickAccess = ({
26
27
  elements,
27
28
  isActive,
29
+ isDisabled,
28
30
  navigateToElement,
29
31
  goBack,
30
32
  create,
@@ -40,25 +42,23 @@ export const PageQuickAccess = ({
40
42
  <Menu.Item
41
43
  key={`${element.id}`}
42
44
  onClick={navigateToElement(element.id)}
43
- {...(isActive(element.id) && {
44
- isActive: true,
45
- isDisabled: true
46
- })}
45
+ isActive={isActive(element.id)}
46
+ isDisabled={isDisabled?.(element.id)}
47
47
  >
48
48
  {element.name}
49
49
  </Menu.Item>
50
50
  ))}
51
51
  <Menu.Divider key="divider" />
52
- <Menu.Item key="create">
53
- <>
54
- <Button
55
- icon={<ArrowBackIcon />}
56
- iconVariant="start"
57
- variant="ghost"
58
- onClick={goBack}
59
- >
60
- {t(labels.goBack)}
61
- </Button>
52
+ <div className="px-2 pb-2 flex gap-4">
53
+ <Button
54
+ icon={<ArrowBackIcon />}
55
+ iconVariant="start"
56
+ variant="ghost"
57
+ onClick={goBack}
58
+ >
59
+ {t(labels.goBack)}
60
+ </Button>
61
+ {create && (
62
62
  <Button
63
63
  icon={<AddIcon />}
64
64
  iconVariant="start"
@@ -67,8 +67,8 @@ export const PageQuickAccess = ({
67
67
  >
68
68
  {t(labels.create)}
69
69
  </Button>
70
- </>
71
- </Menu.Item>
70
+ )}
71
+ </div>
72
72
  </Menu.Items>
73
73
  </Menu>
74
74
  );
@@ -10,8 +10,6 @@ import { DataTestAttributes } from '../../../@types/data-attributes';
10
10
  import { Button, ButtonProps } from '../../Button';
11
11
  import { useMenu } from '../useMenu';
12
12
 
13
- import { useStyles } from './MenuButton.styles';
14
-
15
13
  type MenuButtonProps = {
16
14
  ariaLabel?: string;
17
15
  children?: ReactNode;
@@ -33,8 +31,6 @@ const MenuButton = ({
33
31
  className,
34
32
  ...attr
35
33
  }: MenuButtonProps): ReactElement => {
36
- const { cx, classes } = useStyles();
37
-
38
34
  const { isMenuOpen, setIsMenuOpen, setAnchorEl, onOpen } = useMenu();
39
35
 
40
36
  const onToggle = useCallback(
@@ -52,14 +48,18 @@ const MenuButton = ({
52
48
  <Button
53
49
  {...attr}
54
50
  aria-label={ariaLabel}
55
- className={cx(classes.menuButton, className)}
51
+ className={`${isMenuOpen ? 'bg-primary-main/8 text-text-primary-main' : 'text-text-secondary'} ${className}`}
56
52
  data-is-active={isMenuOpen}
57
53
  size={size}
58
54
  variant={variant}
59
55
  onClick={onToggle}
60
56
  >
61
57
  {children || <MenuIcon />}
62
- {hasArrow && <ArrowDropDownIcon className={classes.buttonIcon} />}
58
+ {hasArrow && (
59
+ <ArrowDropDownIcon
60
+ className={`transform-gpu transition-[rotate] ${isMenuOpen ? 'rotate-180' : 'rotate-0'}`}
61
+ />
62
+ )}
63
63
  </Button>
64
64
  );
65
65
  };
@@ -2,12 +2,8 @@ import { ReactElement } from 'react';
2
2
 
3
3
  import { Divider as MuiDivider } from '@mui/material';
4
4
 
5
- import { useStyles } from './Menu.styles';
6
-
7
5
  const MenuDivider = (): ReactElement => {
8
- const { classes } = useStyles();
9
-
10
- return <MuiDivider className={classes.menuDivider} />;
6
+ return <MuiDivider />;
11
7
  };
12
8
 
13
9
  export { MenuDivider };
@@ -2,8 +2,6 @@ import { ReactElement, ReactNode } from 'react';
2
2
 
3
3
  import { MenuItem as MuiMenuItem } from '@mui/material';
4
4
 
5
- import { useStyles } from './Menu.styles';
6
-
7
5
  type MenuItemProps = {
8
6
  children?: ReactNode;
9
7
  className?: string;
@@ -19,11 +17,9 @@ const MenuItem = ({
19
17
  isDisabled = false,
20
18
  className
21
19
  }: MenuItemProps): ReactElement => {
22
- const { cx, classes } = useStyles();
23
-
24
20
  return (
25
21
  <MuiMenuItem
26
- className={cx(classes.menuItem, className)}
22
+ className={className}
27
23
  data-is-active={isActive}
28
24
  data-is-disabled={isDisabled}
29
25
  disabled={isDisabled}
@@ -2,7 +2,6 @@ import { ReactElement, ReactNode } from 'react';
2
2
 
3
3
  import { Menu as MuiMenu } from '@mui/material';
4
4
 
5
- import { useStyles } from './Menu.styles';
6
5
  import { useMenu } from './useMenu';
7
6
 
8
7
  type MenuItemsProps = {
@@ -10,8 +9,6 @@ type MenuItemsProps = {
10
9
  className?: string;
11
10
  };
12
11
  const MenuItems = ({ children, className }: MenuItemsProps): ReactElement => {
13
- const { cx, classes } = useStyles();
14
-
15
12
  const { isMenuOpen, setIsMenuOpen, anchorEl, onClose } = useMenu();
16
13
 
17
14
  const onCloseMenu = (): void => {
@@ -22,7 +19,11 @@ const MenuItems = ({ children, className }: MenuItemsProps): ReactElement => {
22
19
  return (
23
20
  <MuiMenu
24
21
  anchorEl={anchorEl}
25
- className={cx(classes.menuItems, className)}
22
+ className={className}
23
+ classes={{
24
+ paper:
25
+ 'rounded-sm shadow-lg min-w-[240px] bg-background-paper border-1 border-divider'
26
+ }}
26
27
  open={isMenuOpen}
27
28
  variant="menu"
28
29
  onClick={onCloseMenu}
@@ -4,6 +4,7 @@ import { Provider, atom, createStore, useSetAtom } from 'jotai';
4
4
  import { Button } from '../../Button';
5
5
 
6
6
  import { ConfirmationModal } from './ConfirmationModal';
7
+ import '../../../ThemeProvider/tailwindcss.css';
7
8
 
8
9
  const meta: Meta<typeof ConfirmationModal> = {
9
10
  component: ConfirmationModal
@@ -19,6 +19,7 @@ export interface ConfirmationModalProps<TAtom> {
19
19
  onCancel?: (atomData: Awaited<TAtom> | null) => void;
20
20
  onClose?: (atomData: Awaited<TAtom> | null) => void;
21
21
  onConfirm?: (atomData: Awaited<TAtom> | null) => void;
22
+ size?: 'small' | 'medium' | 'large' | 'xlarge' | 'fullscreen';
22
23
  }
23
24
 
24
25
  interface GetLabelProps<TAtom> {
@@ -39,7 +40,8 @@ export const ConfirmationModal = <TAtom,>({
39
40
  onClose,
40
41
  hasCloseButton = true,
41
42
  isDanger,
42
- disabled
43
+ disabled,
44
+ size
43
45
  }: ConfirmationModalProps<TAtom>): JSX.Element => {
44
46
  const [atomData, setAtomData] = useAtom<TAtom | null>(atom);
45
47
 
@@ -72,6 +74,7 @@ export const ConfirmationModal = <TAtom,>({
72
74
  hasCloseButton={hasCloseButton}
73
75
  open={Boolean(atomData)}
74
76
  onClose={closeModal}
77
+ size={size}
75
78
  >
76
79
  <Modal.Header>{formattedLabels.title}</Modal.Header>
77
80
  <Modal.Body>{formattedLabels.description}</Modal.Body>
@@ -3,6 +3,8 @@ import { Meta, StoryObj } from '@storybook/react';
3
3
  import { Button } from '../Button';
4
4
 
5
5
  import { Modal } from '.';
6
+ import '../../ThemeProvider/tailwindcss.css';
7
+ import { basicFormWithCollapsibleGroups } from '../../Form/Form.stories';
6
8
 
7
9
  const meta: Meta<typeof Modal> = {
8
10
  argTypes: {
@@ -44,6 +46,25 @@ export const Default: Story = {
44
46
  )
45
47
  };
46
48
 
49
+ export const WithForm: Story = {
50
+ args: {
51
+ ...Default.args
52
+ },
53
+
54
+ render: (args) => (
55
+ <Modal {...args}>
56
+ <Modal.Header>Modal title</Modal.Header>
57
+ <Modal.Body>{basicFormWithCollapsibleGroups()}</Modal.Body>
58
+ <Modal.Actions
59
+ labels={{
60
+ cancel: 'Cancel',
61
+ confirm: 'Confirm'
62
+ }}
63
+ />
64
+ </Modal>
65
+ )
66
+ };
67
+
47
68
  export const AsDangerAction: Story = {
48
69
  args: {
49
70
  ...Default.args
@@ -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 {
@@ -133,6 +136,7 @@ export {
133
136
  } from './api/useGraphQuery';
134
137
  export { WidgetResourceType as ResourceType } from './api/useGraphQuery/models';
135
138
  export { default as QueryProvider, client } from './api/QueryProvider';
139
+ export { default as useBulkResponse } from './api/useBulkResponse';
136
140
  export {
137
141
  default as FileDropZone,
138
142
  transformFileListToArray
@@ -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
+ };