@centreon/ui 23.10.117 → 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.
- package/package.json +12 -14
- package/src/Button/Save/StartIcon.tsx +3 -3
- package/src/Dashboard/Item.tsx +1 -1
- package/src/FileDropZone/index.tsx +1 -3
- package/src/Form/Inputs/CheckboxGroup.tsx +4 -1
- package/src/Form/Inputs/index.tsx +1 -1
- package/src/Graph/LineChart/BasicComponents/Lines/Threshold/index.tsx +4 -5
- package/src/Graph/LineChart/BasicComponents/useFilterLines.ts +1 -1
- package/src/Graph/LineChart/InteractiveComponents/Annotations/Annotation/index.tsx +3 -2
- package/src/Graph/LineChart/InteractiveComponents/Annotations/EventAnnotations.tsx +1 -1
- package/src/Graph/LineChart/Legend/useLegend.ts +5 -5
- package/src/Graph/LineChart/helpers/doc.ts +13 -16
- package/src/Graph/LineChart/helpers/index.ts +1 -1
- package/src/Graph/LineChart/index.stories.tsx +2 -1
- package/src/Graph/Text/Text.stories.tsx +4 -60
- package/src/Graph/common/timeSeries/index.ts +3 -3
- package/src/InputField/Select/Autocomplete/Connected/index.tsx +7 -10
- package/src/InputField/Select/Autocomplete/Draggable/SortableList.tsx +1 -1
- package/src/InputField/Select/Autocomplete/Draggable/SortableListContent.tsx +1 -1
- package/src/InputField/Select/Autocomplete/Draggable/index.tsx +1 -1
- package/src/InputField/Select/IconPopover/index.tsx +2 -2
- package/src/InputField/Select/index.tsx +1 -1
- package/src/Listing/Header/ListingHeader.tsx +1 -1
- package/src/Listing/index.stories.tsx +1 -12
- package/src/Listing/index.tsx +1 -1
- package/src/RichTextEditor/RichTextEditor.cypress.spec.tsx +52 -100
- package/src/RichTextEditor/RichTextEditor.tsx +4 -20
- package/src/RichTextEditor/plugins/ToolbarPlugin/AlignPicker.tsx +20 -21
- package/src/RichTextEditor/plugins/ToolbarPlugin/BlockButtons.tsx +77 -35
- package/src/RichTextEditor/plugins/ToolbarPlugin/FormatButtons.tsx +83 -29
- package/src/RichTextEditor/plugins/ToolbarPlugin/MacrosButton.tsx +39 -23
- package/src/RichTextEditor/plugins/ToolbarPlugin/ToolbarPlugin.styles.ts +14 -24
- package/src/RichTextEditor/plugins/ToolbarPlugin/UndoRedoButtons.tsx +0 -6
- package/src/RichTextEditor/plugins/ToolbarPlugin/index.tsx +10 -5
- package/src/RichTextEditor/translatedLabels.ts +0 -3
- package/src/SortableItems/index.tsx +7 -2
- package/src/TimePeriods/CustomTimePeriod/PopoverCustomTimePeriod/PickersStartEndDate.tsx +3 -8
- package/src/TimePeriods/CustomTimePeriod/PopoverCustomTimePeriod/models.ts +2 -0
- package/src/TimePeriods/DateTimePickerInput.tsx +17 -45
- package/src/TimePeriods/TimePeriods.cypress.spec.tsx +33 -9
- package/src/TimePeriods/helpers/index.ts +1 -1
- package/src/api/QueryProvider.tsx +1 -1
- package/src/api/TestQueryProvider.tsx +1 -1
- package/src/api/useFetchQuery/index.ts +24 -28
- package/src/api/useMutationQuery/index.ts +17 -39
- package/src/components/DataTable/Item/DataTableItem.tsx +2 -2
- package/src/components/Form/AccessRights/__fixtures__/contactAccessRight.mock.ts +0 -2
- package/src/components/Form/AccessRights/useAccessRightsForm.utils.ts +1 -1
- package/src/components/Form/Dashboard/DashboardForm.tsx +12 -15
- package/src/components/ItemComposition/ItemComposition.tsx +2 -4
- package/src/components/Menu/Button/MenuButton.tsx +2 -4
- package/src/components/Menu/MenuItem.tsx +3 -5
- package/src/components/Menu/MenuItems.tsx +3 -4
- package/src/index.ts +0 -1
- package/src/queryParameters/url/index.ts +1 -5
- package/src/screens/dashboard/DashboardsDetail.stories.tsx +108 -0
- package/src/screens/dashboard/DashboardsOverview.stories.tsx +281 -0
- package/src/utils/index.ts +1 -0
- package/src/utils/useDateTimePickerAdapter.ts +309 -0
- package/src/utils/{useLicenseExpirationWarning.test.tsx → useLicenseExpirationWarning.cypress.spec.tsx} +37 -48
- package/src/utils/useLicenseExpirationWarning.ts +18 -18
- package/src/RichTextEditor/plugins/ToolbarPlugin/LinkButton.tsx +0 -106
- 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 {
|
|
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
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
{
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
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 {
|
|
8
|
+
import { ActionsList, IconButton, PopoverMenu } from '../../..';
|
|
7
9
|
|
|
8
|
-
import { useStyles } from '
|
|
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 = (
|
|
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
|
-
<
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
<
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
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
|
-
|
|
3
|
+
export const useBlockButtonsStyles = makeStyles()((theme) => ({
|
|
4
|
+
autocomplete: {
|
|
5
|
+
width: theme.spacing(17)
|
|
6
|
+
}
|
|
7
|
+
}));
|
|
4
8
|
|
|
5
|
-
export const
|
|
9
|
+
export const useAlignPickerStyles = makeStyles()((theme) => ({
|
|
6
10
|
button: {
|
|
7
|
-
|
|
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
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
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 {
|
|
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(
|
|
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={
|
|
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
|
|
1
|
+
import dayjs from 'dayjs';
|
|
2
2
|
|
|
3
|
-
import
|
|
4
|
-
import { useAtomValue } from 'jotai';
|
|
5
|
-
import { equals } from 'ramda';
|
|
3
|
+
import { DateTimePicker } from '@mui/x-date-pickers';
|
|
6
4
|
|
|
7
|
-
import {
|
|
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
|
|
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
|
|
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
|
-
<
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
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 {
|
|
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
|
-
<
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
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)
|