@centreon/ui 23.10.118 → 23.10.119

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 (64) hide show
  1. package/package.json +12 -14
  2. package/src/Button/Save/StartIcon.tsx +3 -3
  3. package/src/Dashboard/Item.tsx +1 -1
  4. package/src/FileDropZone/index.tsx +1 -3
  5. package/src/Form/Inputs/CheckboxGroup.tsx +4 -1
  6. package/src/Form/Inputs/index.tsx +1 -1
  7. package/src/Graph/LineChart/BasicComponents/Lines/Threshold/index.tsx +4 -5
  8. package/src/Graph/LineChart/BasicComponents/useFilterLines.ts +1 -1
  9. package/src/Graph/LineChart/InteractiveComponents/Annotations/Annotation/index.tsx +3 -2
  10. package/src/Graph/LineChart/InteractiveComponents/Annotations/EventAnnotations.tsx +1 -1
  11. package/src/Graph/LineChart/Legend/useLegend.ts +5 -5
  12. package/src/Graph/LineChart/LineChart.tsx +2 -5
  13. package/src/Graph/LineChart/helpers/doc.ts +13 -16
  14. package/src/Graph/LineChart/helpers/index.ts +1 -1
  15. package/src/Graph/LineChart/index.stories.tsx +2 -1
  16. package/src/Graph/Text/Text.stories.tsx +4 -60
  17. package/src/Graph/common/timeSeries/index.ts +3 -3
  18. package/src/InputField/Select/Autocomplete/Connected/index.tsx +7 -10
  19. package/src/InputField/Select/Autocomplete/Draggable/SortableList.tsx +1 -1
  20. package/src/InputField/Select/Autocomplete/Draggable/SortableListContent.tsx +1 -1
  21. package/src/InputField/Select/Autocomplete/Draggable/index.tsx +1 -1
  22. package/src/InputField/Select/IconPopover/index.tsx +2 -2
  23. package/src/InputField/Select/index.tsx +1 -1
  24. package/src/Listing/Header/ListingHeader.tsx +1 -1
  25. package/src/Listing/index.stories.tsx +1 -12
  26. package/src/Listing/index.tsx +1 -1
  27. package/src/RichTextEditor/RichTextEditor.cypress.spec.tsx +52 -100
  28. package/src/RichTextEditor/RichTextEditor.tsx +4 -20
  29. package/src/RichTextEditor/plugins/ToolbarPlugin/AlignPicker.tsx +20 -21
  30. package/src/RichTextEditor/plugins/ToolbarPlugin/BlockButtons.tsx +77 -35
  31. package/src/RichTextEditor/plugins/ToolbarPlugin/FormatButtons.tsx +83 -29
  32. package/src/RichTextEditor/plugins/ToolbarPlugin/MacrosButton.tsx +39 -23
  33. package/src/RichTextEditor/plugins/ToolbarPlugin/ToolbarPlugin.styles.ts +14 -24
  34. package/src/RichTextEditor/plugins/ToolbarPlugin/UndoRedoButtons.tsx +0 -6
  35. package/src/RichTextEditor/plugins/ToolbarPlugin/index.tsx +10 -5
  36. package/src/RichTextEditor/translatedLabels.ts +0 -3
  37. package/src/SortableItems/index.tsx +7 -2
  38. package/src/TimePeriods/CustomTimePeriod/PopoverCustomTimePeriod/PickersStartEndDate.tsx +3 -8
  39. package/src/TimePeriods/CustomTimePeriod/PopoverCustomTimePeriod/models.ts +2 -0
  40. package/src/TimePeriods/DateTimePickerInput.tsx +17 -45
  41. package/src/TimePeriods/TimePeriods.cypress.spec.tsx +33 -9
  42. package/src/TimePeriods/helpers/index.ts +1 -1
  43. package/src/api/QueryProvider.tsx +1 -1
  44. package/src/api/TestQueryProvider.tsx +1 -1
  45. package/src/api/useFetchQuery/index.ts +24 -28
  46. package/src/api/useMutationQuery/index.ts +17 -39
  47. package/src/components/DataTable/Item/DataTableItem.tsx +2 -2
  48. package/src/components/Form/AccessRights/__fixtures__/contactAccessRight.mock.ts +0 -2
  49. package/src/components/Form/AccessRights/useAccessRightsForm.utils.ts +1 -1
  50. package/src/components/Form/Dashboard/DashboardForm.tsx +12 -15
  51. package/src/components/ItemComposition/ItemComposition.tsx +2 -4
  52. package/src/components/Menu/Button/MenuButton.tsx +2 -4
  53. package/src/components/Menu/MenuItem.tsx +3 -5
  54. package/src/components/Menu/MenuItems.tsx +3 -4
  55. package/src/index.ts +0 -1
  56. package/src/queryParameters/url/index.ts +1 -5
  57. package/src/screens/dashboard/DashboardsDetail.stories.tsx +108 -0
  58. package/src/screens/dashboard/DashboardsOverview.stories.tsx +281 -0
  59. package/src/utils/index.ts +1 -0
  60. package/src/utils/useDateTimePickerAdapter.ts +309 -0
  61. package/src/utils/{useLicenseExpirationWarning.test.tsx → useLicenseExpirationWarning.cypress.spec.tsx} +37 -48
  62. package/src/utils/useLicenseExpirationWarning.ts +18 -18
  63. package/src/RichTextEditor/plugins/ToolbarPlugin/LinkButton.tsx +0 -106
  64. package/src/RichTextEditor/plugins/ToolbarPlugin/ListButton.tsx +0 -155
@@ -1,38 +1,76 @@
1
1
  import { useState, useCallback, useEffect, useMemo } from 'react';
2
2
 
3
+ import { makeStyles } from 'tss-react/mui';
3
4
  import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
4
5
  import {
5
6
  $getSelection,
6
7
  $isRangeSelection,
7
8
  FORMAT_TEXT_COMMAND,
9
+ RangeSelection,
8
10
  SELECTION_CHANGE_COMMAND,
9
- TextFormatType
11
+ TextFormatType,
12
+ ElementNode,
13
+ TextNode
10
14
  } from 'lexical';
15
+ import { $isLinkNode, TOGGLE_LINK_COMMAND } from '@lexical/link';
16
+ import { $isAtNodeEnd } from '@lexical/selection';
11
17
  import { mergeRegister } from '@lexical/utils';
18
+ import { useAtom } from 'jotai';
12
19
 
13
- import FormatTextIcon from '@mui/icons-material/FormatColorText';
14
20
  import FormatBoldIcon from '@mui/icons-material/FormatBold';
15
21
  import FormatItalicIcon from '@mui/icons-material/FormatItalic';
16
22
  import FormatUnderlinedIcon from '@mui/icons-material/FormatUnderlined';
17
23
  import StrikethroughSIcon from '@mui/icons-material/StrikethroughS';
24
+ import LinkIcon from '@mui/icons-material/Link';
25
+ import { alpha } from '@mui/material';
18
26
 
19
- import { Menu } from '../../../components';
20
-
21
- import { useStyles } from './ToolbarPlugin.styles';
27
+ import { IconButton } from '../../..';
28
+ import { isInsertingLinkAtom } from '../../atoms';
22
29
 
23
30
  const LowPriority = 1;
24
31
 
32
+ const useStyles = makeStyles()((theme) => ({
33
+ buttonSelected: {
34
+ backgroundColor: alpha(
35
+ theme.palette.primary.main,
36
+ theme.palette.action.activatedOpacity
37
+ )
38
+ },
39
+ container: {
40
+ columnGap: theme.spacing(1),
41
+ display: 'flex',
42
+ marginBottom: theme.spacing(1)
43
+ }
44
+ }));
45
+
46
+ const getSelectedNode = (selection: RangeSelection): ElementNode | TextNode => {
47
+ const { anchor } = selection;
48
+ const { focus } = selection;
49
+ const anchorNode = selection.anchor.getNode();
50
+ const focusNode = selection.focus.getNode();
51
+ if (anchorNode === focusNode) {
52
+ return anchorNode;
53
+ }
54
+ const isBackward = selection.isBackward();
55
+ if (isBackward) {
56
+ return $isAtNodeEnd(focus) ? anchorNode : focusNode;
57
+ }
58
+
59
+ return $isAtNodeEnd(anchor) ? focusNode : anchorNode;
60
+ };
61
+
25
62
  interface Props {
26
63
  disabled: boolean;
27
64
  }
28
65
 
29
66
  const FormatButtons = ({ disabled }: Props): JSX.Element => {
30
- const { classes } = useStyles();
67
+ const { classes, cx } = useStyles();
31
68
 
32
69
  const [isBold, setIsBold] = useState(false);
33
70
  const [isItalic, setIsItalic] = useState(false);
34
71
  const [isUnderline, setIsUnderline] = useState(false);
35
72
  const [isStrikeThrough, setIsStrikeThrough] = useState(false);
73
+ const [isLink, setIsLink] = useAtom(isInsertingLinkAtom);
36
74
 
37
75
  const [editor] = useLexicalComposerContext();
38
76
 
@@ -45,8 +83,24 @@ const FormatButtons = ({ disabled }: Props): JSX.Element => {
45
83
  setIsItalic(selection.hasFormat('italic'));
46
84
  setIsUnderline(selection.hasFormat('underline'));
47
85
  setIsStrikeThrough(selection.hasFormat('strikethrough'));
86
+
87
+ const node = getSelectedNode(selection);
88
+ const parent = node.getParent();
89
+ if ($isLinkNode(parent) || $isLinkNode(node)) {
90
+ setIsLink(true);
91
+ } else {
92
+ setIsLink(false);
93
+ }
48
94
  }, [editor]);
49
95
 
96
+ const insertLink = useCallback(() => {
97
+ if (!isLink) {
98
+ editor.dispatchCommand(TOGGLE_LINK_COMMAND, 'https://');
99
+ } else {
100
+ editor.dispatchCommand(TOGGLE_LINK_COMMAND, null);
101
+ }
102
+ }, [editor, isLink]);
103
+
50
104
  useEffect(() => {
51
105
  return mergeRegister(
52
106
  editor.registerCommand(
@@ -90,34 +144,34 @@ const FormatButtons = ({ disabled }: Props): JSX.Element => {
90
144
  isSelected: isStrikeThrough,
91
145
  onClickFunction: toggleTextFormat('strikethrough'),
92
146
  type: 'strikethrough'
147
+ },
148
+ {
149
+ Icon: LinkIcon,
150
+ isSelected: isLink,
151
+ onClickFunction: insertLink,
152
+ type: 'link'
93
153
  }
94
154
  ],
95
- [isBold, isItalic, isUnderline, isStrikeThrough]
155
+ [isBold, isItalic, isUnderline, isStrikeThrough, isLink]
96
156
  );
97
157
 
98
158
  return (
99
- <Menu>
100
- <Menu.Button
101
- ariaLabel="format"
102
- className={classes.button}
103
- disabled={disabled}
104
- >
105
- <FormatTextIcon />
106
- </Menu.Button>
107
- <Menu.Items className={classes.menuItems}>
108
- <div className={classes.menu}>
109
- {formatButtons.map(({ Icon, onClickFunction, isSelected, type }) => (
110
- <Menu.Item
111
- isActive={isSelected}
112
- key={type}
113
- onClick={onClickFunction}
114
- >
115
- <Icon aria-label={type} />
116
- </Menu.Item>
117
- ))}
118
- </div>
119
- </Menu.Items>
120
- </Menu>
159
+ <>
160
+ {formatButtons.map(({ Icon, onClickFunction, isSelected, type }) => (
161
+ <IconButton
162
+ ariaLabel={type}
163
+ className={cx(isSelected && classes.buttonSelected)}
164
+ disabled={disabled}
165
+ key={type}
166
+ size="medium"
167
+ title={type}
168
+ tooltipPlacement="top"
169
+ onClick={onClickFunction}
170
+ >
171
+ <Icon />
172
+ </IconButton>
173
+ ))}
174
+ </>
121
175
  );
122
176
  };
123
177
 
@@ -1,11 +1,13 @@
1
+ import { useState } from 'react';
2
+
1
3
  import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
2
4
  import { createCommand, LexicalCommand } from 'lexical';
3
5
 
4
6
  import MacrosIcon from '@mui/icons-material/TerminalOutlined';
5
7
 
6
- import { Menu } from '../../../components';
8
+ import { ActionsList, IconButton, PopoverMenu } from '../../..';
7
9
 
8
- import { useStyles } from './ToolbarPlugin.styles';
10
+ import { useStyles } from '.';
9
11
 
10
12
  const LowPriority = 1;
11
13
 
@@ -25,12 +27,15 @@ export const standardMacros = [
25
27
 
26
28
  const MacrosButton = ({ disabled }: Props): JSX.Element => {
27
29
  const { classes } = useStyles();
30
+ const [arMacrosDiplayed, setAreMacrosDiplayed] = useState(false);
28
31
 
29
32
  const [editor] = useLexicalComposerContext();
30
33
 
31
34
  const INSERT_MACROS_COMMAND: LexicalCommand<string> = createCommand();
32
35
 
33
- const onClick = (macro): void => {
36
+ const onClick = (e): void => {
37
+ const macro = e.target.id || e.target.textContent.trim();
38
+
34
39
  editor.dispatchCommand(INSERT_MACROS_COMMAND, macro);
35
40
  };
36
41
 
@@ -48,27 +53,38 @@ const MacrosButton = ({ disabled }: Props): JSX.Element => {
48
53
  LowPriority
49
54
  );
50
55
 
56
+ const displayMacros = (): void => {
57
+ setAreMacrosDiplayed(true);
58
+ };
59
+
60
+ const actions = standardMacros.map((macro) => ({
61
+ label: macro,
62
+ onClick
63
+ }));
64
+
51
65
  return (
52
- <Menu>
53
- <Menu.Button
54
- ariaLabel="Macros"
55
- className={classes.button}
56
- disabled={disabled}
57
- >
58
- <MacrosIcon />
59
- </Menu.Button>
60
- <Menu.Items className={classes.menuItems}>
61
- {standardMacros.map((name) => (
62
- <Menu.Item
63
- className={classes.menuItem}
64
- key={name}
65
- onClick={(): void => onClick(name)}
66
- >
67
- {name}
68
- </Menu.Item>
69
- ))}
70
- </Menu.Items>
71
- </Menu>
66
+ <PopoverMenu
67
+ icon={
68
+ <IconButton
69
+ ariaLabel="Macros"
70
+ className={classes.macrosButton}
71
+ disabled={disabled}
72
+ title="Macros"
73
+ tooltipPlacement="top"
74
+ onClick={displayMacros}
75
+ >
76
+ <MacrosIcon />
77
+ </IconButton>
78
+ }
79
+ >
80
+ {(): JSX.Element => (
81
+ <div>
82
+ {arMacrosDiplayed && (
83
+ <ActionsList actions={actions} listItemClassName={classes.macros} />
84
+ )}
85
+ </div>
86
+ )}
87
+ </PopoverMenu>
72
88
  );
73
89
  };
74
90
 
@@ -1,32 +1,22 @@
1
1
  import { makeStyles } from 'tss-react/mui';
2
2
 
3
- import { alpha } from '@mui/system';
3
+ export const useBlockButtonsStyles = makeStyles()((theme) => ({
4
+ autocomplete: {
5
+ width: theme.spacing(17)
6
+ }
7
+ }));
4
8
 
5
- export const useStyles = makeStyles()((theme) => ({
9
+ export const useAlignPickerStyles = makeStyles()((theme) => ({
6
10
  button: {
7
- color: theme.palette.text.primary
8
- },
9
- buttonSelected: {
10
- backgroundColor: alpha(
11
- theme.palette.primary.main,
12
- theme.palette.action.activatedOpacity
13
- )
14
- },
15
- menu: {
11
+ alignItems: 'center',
16
12
  display: 'flex',
17
- flexDirection: 'row'
18
- },
19
- menuItem: {
20
- '&, &.MuiMenuItem-root': {
21
- fontSize: theme.typography.body2.fontSize
22
- }
13
+ flexDirection: 'row',
14
+ gap: theme.spacing(1)
23
15
  },
24
- menuItems: {
25
- '& > .MuiPaper-root.MuiMenu-paper': {
26
- minWidth: 0
27
- },
28
- '& ul, & ul.MuiMenu-list': {
29
- padding: 0
30
- }
16
+ option: {
17
+ alignItems: 'center',
18
+ display: 'flex',
19
+ flexDirection: 'row',
20
+ gap: theme.spacing(2)
31
21
  }
32
22
  }));
@@ -16,8 +16,6 @@ import RedoIcon from '@mui/icons-material/Redo';
16
16
  import { IconButton } from '../../..';
17
17
  import { labelRedo, labelUndo } from '../../translatedLabels';
18
18
 
19
- import { useStyles } from './ToolbarPlugin.styles';
20
-
21
19
  const LowPriority = 1;
22
20
 
23
21
  interface Props {
@@ -25,8 +23,6 @@ interface Props {
25
23
  }
26
24
 
27
25
  const UndoRedoButtons = ({ disabled }: Props): JSX.Element => {
28
- const { classes } = useStyles();
29
-
30
26
  const { t } = useTranslation();
31
27
 
32
28
  const [canUndo, setCanUndo] = useState(false);
@@ -72,7 +68,6 @@ const UndoRedoButtons = ({ disabled }: Props): JSX.Element => {
72
68
  <>
73
69
  <IconButton
74
70
  ariaLabel={translatedUndo}
75
- className={classes.button}
76
71
  disabled={!canUndo || disabled}
77
72
  title={translatedUndo}
78
73
  tooltipPlacement="top"
@@ -82,7 +77,6 @@ const UndoRedoButtons = ({ disabled }: Props): JSX.Element => {
82
77
  </IconButton>
83
78
  <IconButton
84
79
  ariaLabel={translatedRedo}
85
- className={classes.button}
86
80
  disabled={!canRedo || disabled}
87
81
  title={translatedRedo}
88
82
  tooltipPlacement="top"
@@ -5,10 +5,8 @@ import { Divider } from '@mui/material';
5
5
  import FormatButtons from './FormatButtons';
6
6
  import UndoRedoButtons from './UndoRedoButtons';
7
7
  import MacrosButton from './MacrosButton';
8
- import AlignPicker from './AlignPicker';
9
- import ListButton from './ListButton';
10
- import LinkButton from './LinkButton';
11
8
  import BlockButtons from './BlockButtons';
9
+ import AlignPicker from './AlignPicker';
12
10
 
13
11
  interface Props {
14
12
  className?: string;
@@ -24,6 +22,14 @@ export const useStyles = makeStyles()((theme) => ({
24
22
  columnGap: theme.spacing(1),
25
23
  display: 'flex',
26
24
  marginBottom: theme.spacing(1)
25
+ },
26
+ macros: {
27
+ '& span': {
28
+ fontSize: theme.typography.caption.fontSize
29
+ }
30
+ },
31
+ macrosButton: {
32
+ marginBottom: theme.spacing(0.5)
27
33
  }
28
34
  }));
29
35
 
@@ -45,10 +51,9 @@ const ToolbarPlugin = ({
45
51
  <BlockButtons disabled={disabled} />
46
52
  </>
47
53
  )}
54
+ <Divider flexItem orientation="vertical" />
48
55
  <FormatButtons disabled={disabled} />
49
56
  <AlignPicker disabled={disabled} />
50
- <ListButton disabled={disabled} />
51
- <LinkButton disabled={disabled} />
52
57
  {displayMacrosButton && (
53
58
  <>
54
59
  <Divider flexItem orientation="vertical" />
@@ -3,6 +3,3 @@ export const labelRedo = 'Redo';
3
3
  export const labelInputLink = 'Insert link';
4
4
  export const labelSavedLink = 'Saved link';
5
5
  export const labelEditLink = 'Edit link';
6
- export const labelAlignPicker = 'align picker';
7
- export const labelUnorderedList = 'Unordered List';
8
- export const labelOrderedList = 'Ordered List';
@@ -15,7 +15,11 @@ import {
15
15
  DragEndEvent,
16
16
  Over
17
17
  } from '@dnd-kit/core';
18
- import { SortableContext, SortingStrategy } from '@dnd-kit/sortable';
18
+ import {
19
+ SortableContext,
20
+ sortableKeyboardCoordinates,
21
+ SortingStrategy
22
+ } from '@dnd-kit/sortable';
19
23
  import {
20
24
  equals,
21
25
  find,
@@ -113,6 +117,7 @@ const SortableItems = <T extends { [propertyToFilterItemsOn]: string }>({
113
117
  useSensor(MouseSensor),
114
118
  useSensor(PointerSensor),
115
119
  useSensor(KeyboardSensor, {
120
+ coordinateGetter: sortableKeyboardCoordinates,
116
121
  keyboardCodes: {
117
122
  cancel: ['Escape'],
118
123
  end: ['Space', 'Enter'],
@@ -164,7 +169,7 @@ const SortableItems = <T extends { [propertyToFilterItemsOn]: string }>({
164
169
  };
165
170
 
166
171
  const getItemById = (id): T | undefined =>
167
- find(propEq(id, propertyToFilterItemsOn), items);
172
+ find(propEq(propertyToFilterItemsOn, id), items);
168
173
 
169
174
  const activeItem = getItemById(activeId) as Record<string, unknown>;
170
175
 
@@ -2,15 +2,12 @@ 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';
8
5
 
9
- import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
10
6
  import { Typography } from '@mui/material';
11
7
  import { LocalizationProvider } from '@mui/x-date-pickers';
12
8
 
13
9
  import { userAtom } from '@centreon/ui-context';
10
+ import { useDateTimePickerAdapter } from '@centreon/ui';
14
11
 
15
12
  import DateTimePickerInput from '../../DateTimePickerInput';
16
13
  import {
@@ -23,9 +20,6 @@ import ErrorText from './ErrorText';
23
20
  import { PickersData, PickersStartEndDateDirection } from './models';
24
21
  import { PickersStartEndDateModel } from './usePickersStartEndDate';
25
22
 
26
- dayjs.extend(utc);
27
- dayjs.extend(timezone);
28
-
29
23
  const useStyles = makeStyles()((theme) => ({
30
24
  error: {
31
25
  textAlign: 'center'
@@ -110,6 +104,7 @@ const PickersStartEndDate = ({
110
104
  direction = PickersStartEndDateDirection.column
111
105
  }: Props): JSX.Element => {
112
106
  const { classes, cx } = useStyles();
107
+ const { Adapter } = useDateTimePickerAdapter();
113
108
 
114
109
  const { locale } = useAtomValue(userAtom);
115
110
  const error = useAtomValue(errorTimePeriodAtom);
@@ -131,7 +126,7 @@ const PickersStartEndDate = ({
131
126
  return (
132
127
  <LocalizationProvider
133
128
  adapterLocale={locale.substring(0, 2)}
134
- dateAdapter={AdapterDayjs}
129
+ dateAdapter={Adapter}
135
130
  >
136
131
  <div className={styleContainer}>
137
132
  <PickerDateWithLabel
@@ -18,6 +18,8 @@ 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;
21
23
  rangeEndDate?: RangeDate;
22
24
  rangeStartDate?: RangeDate;
23
25
  }
@@ -1,29 +1,19 @@
1
- import { useCallback } from 'react';
1
+ import dayjs from 'dayjs';
2
2
 
3
- import dayjs, { Dayjs } from 'dayjs';
4
- import { useAtomValue } from 'jotai';
5
- import { equals } from 'ramda';
3
+ import { DateTimePicker } from '@mui/x-date-pickers';
6
4
 
7
- import { DateTimePicker, LocalizationProvider } from '@mui/x-date-pickers';
8
- import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
9
-
10
- import { userAtom } from '@centreon/ui-context';
5
+ import { useDateTimePickerAdapter } from '@centreon/ui';
11
6
 
12
7
  import { CustomTimePeriodProperty } from './models';
13
8
 
14
- interface ChangeDateProps {
15
- date: Date;
16
- property: CustomTimePeriodProperty | string;
17
- }
18
-
19
9
  interface Props {
20
- changeDate: (props: ChangeDateProps) => void;
10
+ changeDate: (props) => void;
21
11
  date: Date | null;
22
12
  desktopMediaQuery?: string;
23
13
  disabled?: boolean;
24
14
  maxDate?: Date;
25
15
  minDate?: Date;
26
- property: CustomTimePeriodProperty | string;
16
+ property: CustomTimePeriodProperty;
27
17
  }
28
18
 
29
19
  const DateTimePickerInput = ({
@@ -35,42 +25,24 @@ const DateTimePickerInput = ({
35
25
  disabled = false,
36
26
  desktopMediaQuery
37
27
  }: Props): JSX.Element => {
38
- const desktopPickerMediaQuery =
39
- '@media (min-width: 1024px) or (pointer: fine)';
40
-
41
- const { timezone, locale } = useAtomValue(userAtom);
42
-
43
- const isUTC = equals(timezone, 'UTC');
28
+ const { desktopPickerMediaQuery } = useDateTimePickerAdapter();
44
29
 
45
30
  const changeTime = (newValue: dayjs.Dayjs | null): void => {
46
31
  changeDate({ date: dayjs(newValue).toDate(), property });
47
32
  };
48
33
 
49
- const formatDate = useCallback(
50
- (currentDate: Date | null): Dayjs => {
51
- return isUTC ? dayjs.utc(currentDate) : dayjs.tz(currentDate, timezone);
52
- },
53
- [isUTC, timezone]
54
- );
55
-
56
34
  return (
57
- <LocalizationProvider
58
- adapterLocale={locale.substring(0, 2)}
59
- dateAdapter={AdapterDayjs}
60
- dateLibInstance={dayjs}
61
- >
62
- <DateTimePicker<dayjs.Dayjs>
63
- dayOfWeekFormatter={(dayOfWeek) =>
64
- dayOfWeek.substring(0, 2).toLocaleUpperCase()
65
- }
66
- desktopModeMediaQuery={desktopMediaQuery ?? desktopPickerMediaQuery}
67
- disabled={disabled}
68
- maxDate={maxDate && formatDate(maxDate)}
69
- minDate={minDate && formatDate(minDate)}
70
- value={formatDate(date)}
71
- onChange={changeTime}
72
- />
73
- </LocalizationProvider>
35
+ <DateTimePicker<dayjs.Dayjs>
36
+ dayOfWeekFormatter={(day: string): string =>
37
+ day.substring(0, 2).toUpperCase()
38
+ }
39
+ desktopModeMediaQuery={desktopMediaQuery ?? desktopPickerMediaQuery}
40
+ disabled={disabled}
41
+ maxDate={maxDate && dayjs(maxDate)}
42
+ minDate={minDate && dayjs(minDate)}
43
+ value={dayjs(date)}
44
+ onChange={changeTime}
45
+ />
74
46
  );
75
47
  };
76
48
 
@@ -3,10 +3,15 @@ import localizedFormatPlugin from 'dayjs/plugin/localizedFormat';
3
3
  import timezonePlugin from 'dayjs/plugin/timezone';
4
4
  import utcPlugin from 'dayjs/plugin/utc';
5
5
  import { Provider, createStore } from 'jotai';
6
- import { equals } from 'ramda';
6
+ import { equals, inc } from 'ramda';
7
7
  import { renderHook } from '@testing-library/react';
8
8
 
9
- import { useLocaleDateTimeFormat } from '@centreon/ui';
9
+ import { LocalizationProvider } from '@mui/x-date-pickers';
10
+
11
+ import {
12
+ useLocaleDateTimeFormat,
13
+ useDateTimePickerAdapter
14
+ } from '@centreon/ui';
10
15
  import { ListingVariant, userAtom } from '@centreon/ui-context';
11
16
 
12
17
  import { CustomTimePeriodProperty } from './models';
@@ -292,6 +297,10 @@ testData.forEach((item) =>
292
297
  beforeEach(() => {
293
298
  cy.viewport('macbook-13');
294
299
 
300
+ const { result } = renderHook(() => useDateTimePickerAdapter());
301
+
302
+ const { Adapter } = result.current;
303
+
295
304
  const store = createStore();
296
305
  store.set(userAtom, {
297
306
  ...retrievedUser,
@@ -302,16 +311,31 @@ testData.forEach((item) =>
302
311
  cy.mount({
303
312
  Component: (
304
313
  <Provider store={store}>
305
- <DateTimePickerInput
306
- changeDate={cy.stub()}
307
- date={new Date(item.initialDate)}
308
- property={CustomTimePeriodProperty.start}
309
- />
314
+ <LocalizationProvider adapterLocale="en" dateAdapter={Adapter}>
315
+ <DateTimePickerInput
316
+ changeDate={cy.stub()}
317
+ date={new Date(item.initialDate)}
318
+ desktopMediaQuery="@media (min-width: 1024px)"
319
+ property={CustomTimePeriodProperty.start}
320
+ />
321
+ </LocalizationProvider>
310
322
  </Provider>
311
323
  )
312
324
  });
313
325
  });
314
326
 
327
+ it('checks input calendar value contains correct date', () => {
328
+ const { result } = renderHook(() => useLocaleDateTimeFormat());
329
+ const { format } = result.current;
330
+
331
+ const dateInput = format({
332
+ date: dayjs(item.initialDate).tz(item.timezone),
333
+ formatString: 'L hh:mm A'
334
+ });
335
+
336
+ cy.get('input').should('have.value', dateInput);
337
+ });
338
+
315
339
  it(`displays the correct number of days for the current month when the ${item.button} button is clicked`, () => {
316
340
  cy.get('button').click();
317
341
  item.data.forEach((element) => {
@@ -365,7 +389,7 @@ testData.forEach((item) =>
365
389
 
366
390
  cy.get('[role="rowgroup"]').children().as('listWeeks');
367
391
 
368
- cy.get('@listWeeks').should('have.length', numberWeeks);
392
+ cy.get('@listWeeks').should('have.length', inc(numberWeeks));
369
393
  cy.get('@listWeeks').eq(0).as('firstWeek');
370
394
  cy.get('@firstWeek').children().as('listDaysInFirstWeek');
371
395
 
@@ -392,7 +416,7 @@ testData.forEach((item) =>
392
416
 
393
417
  cy.get('[role="rowgroup"]').children().as('listWeeks');
394
418
 
395
- cy.get('@listWeeks').should('have.length', numberWeeks);
419
+ cy.get('@listWeeks').should('have.length', inc(numberWeeks));
396
420
 
397
421
  cy.get('@listWeeks')
398
422
  .eq(numberWeeks - 1)
@@ -23,4 +23,4 @@ export const getTimePeriodById = ({
23
23
  id,
24
24
  timePeriods
25
25
  }: TimePeriodById): TimePeriod =>
26
- find<TimePeriod>(propEq(id, 'id'))(timePeriods) as TimePeriod;
26
+ find<TimePeriod>(propEq('id', id))(timePeriods) as TimePeriod;
@@ -7,7 +7,7 @@ const defaultCacheTime = 5 * 1_000;
7
7
  const client = new QueryClient({
8
8
  defaultOptions: {
9
9
  queries: {
10
- gcTime: defaultCacheTime,
10
+ cacheTime: defaultCacheTime,
11
11
  refetchOnWindowFocus: false,
12
12
  staleTime: defaultCacheTime,
13
13
  suspense: true
@@ -5,7 +5,7 @@ import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
5
5
  const client = new QueryClient({
6
6
  defaultOptions: {
7
7
  queries: {
8
- gcTime: 0,
8
+ cacheTime: 0,
9
9
  retry: false
10
10
  }
11
11
  }