@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.
- package/package.json +25 -11
- package/public/mockServiceWorker.js +8 -31
- package/src/ActionsList/index.tsx +1 -0
- package/src/Button/Icon/index.tsx +3 -1
- package/src/Button/Save/index.stories.tsx +1 -0
- package/src/Checkbox/Checkbox.tsx +3 -1
- package/src/Checkbox/CheckboxGroup/index.tsx +6 -1
- package/src/Colors/index.tsx +1 -1
- package/src/Dashboard/Dashboard.styles.ts +1 -1
- package/src/Dashboard/Layout.tsx +1 -1
- package/src/Dialog/UnsavedChanges/index.stories.tsx +1 -0
- package/src/Form/CollapsibleGroup.tsx +13 -13
- package/src/Form/Form.cypress.spec.tsx +137 -2
- package/src/Form/Form.stories.tsx +11 -31
- package/src/Form/Form.tsx +2 -0
- package/src/Form/Inputs/Checkbox.tsx +3 -2
- package/src/Form/Inputs/ConnectedAutocomplete.tsx +6 -1
- package/src/Form/Inputs/Grid.tsx +18 -29
- package/src/Form/Inputs/SubGroupDivider.tsx +7 -0
- package/src/Form/Inputs/Text.tsx +1 -0
- package/src/Form/Inputs/index.tsx +31 -24
- package/src/Form/Inputs/models.ts +8 -1
- package/src/Form/Section/FormSection.tsx +34 -0
- package/src/Form/Section/PanelTabs.tsx +13 -0
- package/src/Form/Section/navigateToSection.ts +9 -0
- package/src/Form/storiesData.tsx +14 -4
- package/src/Graph/BarChart/BarChart.cypress.spec.tsx +46 -6
- package/src/Graph/BarChart/BarChart.stories.tsx +60 -0
- package/src/Graph/BarChart/BarChart.tsx +56 -32
- package/src/Graph/BarChart/BarGroup.tsx +22 -32
- package/src/Graph/BarChart/MemoizedGroup.tsx +8 -11
- package/src/Graph/BarChart/ResponsiveBarChart.tsx +145 -32
- package/src/Graph/BarChart/Tooltip/BarChartTooltip.tsx +2 -2
- package/src/Graph/Chart/BasicComponents/Lines/StackedLines/index.tsx +7 -1
- package/src/Graph/Chart/BasicComponents/Lines/StackedLines/useStackedLines.ts +18 -45
- package/src/Graph/Chart/BasicComponents/Lines/index.tsx +42 -28
- package/src/Graph/Chart/Chart.cypress.spec.tsx +85 -15
- package/src/Graph/Chart/Chart.stories.tsx +84 -1
- package/src/Graph/Chart/Chart.tsx +17 -4
- package/src/Graph/Chart/InteractiveComponents/AnchorPoint/RegularAnchorPoint.tsx +8 -2
- package/src/Graph/Chart/InteractiveComponents/AnchorPoint/StackedAnchorPoint.tsx +10 -3
- package/src/Graph/Chart/InteractiveComponents/AnchorPoint/useTickGraph.ts +19 -2
- package/src/Graph/Chart/InteractiveComponents/Annotations/Annotation/index.tsx +1 -1
- package/src/Graph/Chart/InteractiveComponents/GraphValueTooltip/useGraphValueTooltip.ts +2 -4
- package/src/Graph/Chart/InteractiveComponents/ZoomPreview/index.tsx +14 -3
- package/src/Graph/Chart/InteractiveComponents/ZoomPreview/models.ts +3 -0
- package/src/Graph/Chart/InteractiveComponents/ZoomPreview/useZoomPreview.ts +12 -10
- package/src/Graph/Chart/InteractiveComponents/index.tsx +63 -5
- package/src/Graph/Chart/Legend/index.tsx +26 -2
- package/src/Graph/Chart/helpers/index.ts +4 -3
- package/src/Graph/Chart/index.tsx +45 -45
- package/src/Graph/Chart/models.ts +8 -0
- package/src/Graph/Chart/useChartData.ts +14 -2
- package/src/Graph/Gauge/Gauge.tsx +18 -14
- package/src/Graph/Gauge/ResponsiveGauge.tsx +10 -6
- package/src/Graph/Gauge/useResizeObserver.ts +68 -0
- package/src/Graph/SingleBar/ResponsiveSingleBar.tsx +18 -16
- package/src/Graph/SingleBar/ThresholdLine.tsx +4 -4
- package/src/Graph/SingleBar/models.ts +1 -0
- package/src/Graph/Text/Text.styles.ts +2 -2
- package/src/Graph/Text/Text.tsx +23 -10
- package/src/Graph/Timeline/ResponsiveTimeline.tsx +4 -0
- package/src/Graph/Timeline/Timeline.tsx +21 -4
- package/src/Graph/Tree/Links.tsx +2 -2
- package/src/Graph/Tree/Tree.tsx +2 -2
- package/src/Graph/Tree/constants.ts +1 -1
- package/src/Graph/common/BaseChart/BaseChart.tsx +6 -1
- package/src/Graph/common/BaseChart/ChartSvgWrapper.tsx +5 -4
- package/src/Graph/common/BaseChart/Header/index.tsx +3 -1
- package/src/Graph/common/BaseChart/useComputeBaseChartDimensions.ts +13 -9
- package/src/Graph/common/timeSeries/index.test.ts +20 -0
- package/src/Graph/common/timeSeries/index.ts +225 -44
- package/src/Graph/common/timeSeries/models.ts +6 -2
- package/src/Graph/common/utils.ts +45 -12
- package/src/Graph/index.ts +3 -1
- package/src/Graph/mockedData/dataWithMissingPoint.json +74 -0
- package/src/Graph/mockedData/pingServiceWithStackedKeys.json +205 -0
- package/src/Icon/RegexIcon.tsx +20 -0
- package/src/Icon/index.ts +1 -0
- package/src/InputField/Select/Autocomplete/Connected/Multi/MultiConnectedAutocompleteField.cypress.spec.tsx +68 -14
- package/src/InputField/Select/Autocomplete/Connected/index.tsx +49 -14
- package/src/InputField/Select/Autocomplete/Multi/Listbox.tsx +78 -0
- package/src/InputField/Select/Autocomplete/Multi/Multi.styles.ts +26 -0
- package/src/InputField/Select/Autocomplete/Multi/Multi.tsx +124 -0
- package/src/InputField/Select/Autocomplete/Multi/index.tsx +1 -117
- package/src/InputField/Select/Autocomplete/index.tsx +28 -17
- package/src/InputField/Select/Option.tsx +3 -3
- package/src/InputField/Select/index.tsx +4 -0
- package/src/InputField/Text/index.tsx +4 -2
- package/src/InputField/translatedLabels.ts +4 -0
- package/src/Listing/ActionBar/Pagination.tsx +10 -23
- package/src/Listing/ActionBar/PaginationActions.tsx +1 -10
- package/src/Listing/ActionBar/index.tsx +1 -1
- package/src/Listing/Cell/DataCell.tsx +6 -6
- package/src/Listing/Cell/EllipsisTypography.tsx +10 -32
- package/src/Listing/Cell/index.tsx +57 -89
- package/src/Listing/Checkbox.tsx +8 -20
- package/src/Listing/Header/Cell/ListingHeaderCell.tsx +17 -14
- package/src/Listing/Header/Cell/SelectActionListingHeaderCell.tsx +5 -9
- package/src/Listing/Header/ListingHeader.tsx +2 -5
- package/src/Listing/Header/_internals/Label.tsx +1 -17
- package/src/Listing/Row/EmptyRow.tsx +2 -6
- package/src/Listing/Row/Row.tsx +7 -36
- package/src/Listing/index.stories.tsx +1 -0
- package/src/Listing/index.tsx +26 -26
- package/src/Listing/useStyleTable.ts +58 -32
- package/src/ListingPage/index.stories.tsx +1 -0
- package/src/Module/index.tsx +8 -2
- package/src/MultiSelectEntries/index.stories.tsx +1 -0
- package/src/MultiSelectEntries/index.tsx +1 -1
- package/src/Pagination/Pagination.cypress.spec.tsx +137 -0
- package/src/Pagination/Pagination.stories.tsx +46 -0
- package/src/Pagination/Pagination.styles.ts +56 -0
- package/src/Pagination/Pagination.tsx +146 -0
- package/src/Pagination/index.ts +3 -0
- package/src/Pagination/utils.ts +7 -0
- package/src/SortableItems/index.stories.tsx +2 -2
- package/src/StoryBookThemeProvider/index.tsx +3 -1
- package/src/ThemeProvider/base.css +49 -0
- package/src/ThemeProvider/index.tsx +21 -47
- package/src/ThemeProvider/palettes.ts +5 -3
- package/src/ThemeProvider/tailwindcss.css +230 -0
- package/src/TimePeriods/CustomTimePeriod/PopoverCustomTimePeriod/PickersStartEndDate.tsx +9 -11
- package/src/TimePeriods/CustomTimePeriod/PopoverCustomTimePeriod/models.ts +1 -0
- package/src/TimePeriods/DateTimePickerInput.tsx +3 -1
- package/src/api/customFetch.ts +0 -9
- package/src/api/models.ts +9 -0
- package/src/api/useBulkResponse.ts +58 -0
- package/src/api/useGraphQuery/index.ts +108 -12
- package/src/components/Avatar/Avatar.stories.tsx +1 -0
- package/src/components/Button/Button.module.css +38 -0
- package/src/components/Button/Button.stories.tsx +25 -0
- package/src/components/Button/Button.tsx +2 -5
- package/src/components/CrudPage/Actions/Actions.styles.ts +15 -1
- package/src/components/CrudPage/Actions/Actions.tsx +7 -4
- package/src/components/CrudPage/Actions/Search.tsx +15 -14
- package/src/components/CrudPage/CrudPage.stories.tsx +1 -0
- package/src/components/CrudPage/CrudPageRoot.tsx +1 -1
- package/src/components/DataTable/DataTable.stories.tsx +1 -0
- package/src/components/DataTable/EmptyState/DataTableEmptyState.stories.tsx +1 -0
- package/src/components/DataTable/EmptyState/DataTableEmptyState.styles.ts +3 -1
- package/src/components/DataTable/EmptyState/DataTableEmptyState.tsx +4 -1
- package/src/components/DataTable/Item/DataTableItem.stories.tsx +1 -0
- package/src/components/Form/AccessRights/AccessRights.stories.tsx +1 -0
- package/src/components/Form/AccessRights/ShareInput/ShareInput.tsx +4 -3
- package/src/components/Form/AccessRights/ShareInput/useShareInput.tsx +15 -10
- package/src/components/Form/FormActions.tsx +21 -12
- package/src/components/Header/PageHeader/PageHeader.styles.ts +5 -5
- package/src/components/Layout/AreaIndicator.tsx +4 -6
- package/src/components/Layout/PageLayout/PageLayout.stories.tsx +1 -0
- package/src/components/Layout/PageLayout/PageLayout.styles.ts +1 -1
- package/src/components/Layout/PageLayout/PageLayout.tsx +9 -3
- package/src/components/Layout/PageLayout/PageLayoutActions.tsx +5 -3
- package/src/components/Layout/PageLayout/PageLayoutBody.tsx +5 -3
- package/src/components/Layout/PageLayout/PageLayoutHeader.tsx +5 -3
- package/src/components/Layout/PageLayout/PageQuickAccess.tsx +17 -17
- package/src/components/Menu/Button/MenuButton.tsx +6 -6
- package/src/components/Menu/MenuDivider.tsx +1 -5
- package/src/components/Menu/MenuItem.tsx +1 -5
- package/src/components/Menu/MenuItems.tsx +5 -4
- package/src/components/Modal/ConfirmationModal/ConfirmationModal.stories.tsx +1 -0
- package/src/components/Modal/ConfirmationModal/ConfirmationModal.tsx +4 -1
- package/src/components/Modal/Modal.stories.tsx +21 -0
- package/src/components/Modal/Modal.styles.ts +1 -19
- package/src/components/Modal/Modal.tsx +1 -1
- package/src/components/Modal/ModalBody.tsx +6 -4
- package/src/components/Modal/ModalHeader.tsx +9 -5
- package/src/components/Modal/modal.module.css +16 -0
- package/src/components/Tabs/Tab.styles.ts +0 -6
- package/src/components/Tabs/Tabs.tsx +37 -15
- package/src/index.ts +4 -0
- package/src/queryParameters/url/index.ts +7 -2
- package/src/utils/index.ts +1 -0
- package/src/utils/useLocale/index.ts +9 -0
- package/src/utils/useLocale/useLocale.cypress.spec.tsx +38 -0
- package/src/utils/useLocaleDateTimeFormat/index.ts +4 -2
- package/src/utils/usePluralizedTranslation.ts +2 -3
- package/src/Listing/Cell/DataCell.styles.ts +0 -27
- package/src/Listing/Header/Cell/ListingHeaderCell.styles.ts +0 -71
- package/src/Listing/Header/Cell/SelectActionListingHeaderCell.styles.ts +0 -26
- package/src/Listing/Header/ListingHeader.styles.ts +0 -16
- package/src/Listing/Listing.styles.ts +0 -78
- package/src/Listing/Row/EmptyRow.styles.ts +0 -14
- package/src/components/Button/Button.styles.ts +0 -44
- package/src/components/Layout/AreaIndicator.styles.ts +0 -33
- package/src/components/Menu/Button/MenuButton.styles.ts +0 -27
- package/src/components/Menu/Menu.styles.ts +0 -68
package/src/Form/Inputs/Grid.tsx
CHANGED
|
@@ -1,39 +1,14 @@
|
|
|
1
|
-
import { makeStyles } from 'tss-react/mui';
|
|
2
|
-
|
|
3
1
|
import { InputPropsWithoutGroup } from './models';
|
|
4
2
|
|
|
5
3
|
import { Box, Typography } from '@mui/material';
|
|
6
4
|
import { FormikValues, useFormikContext } from 'formik';
|
|
5
|
+
import { isNotEmpty, isNotNil } from 'ramda';
|
|
7
6
|
import { getInput } from '.';
|
|
8
7
|
|
|
9
|
-
interface StylesProps {
|
|
10
|
-
alignItems?: string;
|
|
11
|
-
columns?: number;
|
|
12
|
-
gridTemplateColumns?: string;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
const useStyles = makeStyles<StylesProps>()(
|
|
16
|
-
(theme, { columns, gridTemplateColumns, alignItems }) => ({
|
|
17
|
-
gridFields: {
|
|
18
|
-
alignItems: alignItems || 'flex-start',
|
|
19
|
-
columnGap: theme.spacing(4),
|
|
20
|
-
display: 'grid',
|
|
21
|
-
gridTemplateColumns: gridTemplateColumns || `repeat(${columns}, 1fr)`,
|
|
22
|
-
rowGap: theme.spacing(2)
|
|
23
|
-
}
|
|
24
|
-
})
|
|
25
|
-
);
|
|
26
|
-
|
|
27
8
|
const Grid = ({
|
|
28
9
|
grid,
|
|
29
10
|
hideInput
|
|
30
11
|
}: InputPropsWithoutGroup): JSX.Element | null => {
|
|
31
|
-
const { classes, cx } = useStyles({
|
|
32
|
-
alignItems: grid?.alignItems,
|
|
33
|
-
columns: grid?.columns.length,
|
|
34
|
-
gridTemplateColumns: grid?.gridTemplateColumns
|
|
35
|
-
});
|
|
36
|
-
|
|
37
12
|
const { values } = useFormikContext<FormikValues>();
|
|
38
13
|
|
|
39
14
|
if (hideInput?.(values) ?? false) {
|
|
@@ -43,20 +18,34 @@ const Grid = ({
|
|
|
43
18
|
const className = grid?.className || '';
|
|
44
19
|
|
|
45
20
|
return (
|
|
46
|
-
<div
|
|
21
|
+
<div
|
|
22
|
+
className={`${className} grid gap-3`}
|
|
23
|
+
style={{
|
|
24
|
+
gridTemplateColumns: className
|
|
25
|
+
? grid?.gridTemplateColumns || undefined
|
|
26
|
+
: grid?.gridTemplateColumns ||
|
|
27
|
+
`repeat(${grid?.columns.length || 1}, 1fr)`,
|
|
28
|
+
alignItems: grid?.alignItems || 'flex-start'
|
|
29
|
+
}}
|
|
30
|
+
>
|
|
47
31
|
{grid?.columns.map((field) => {
|
|
48
32
|
const Input = getInput(field.type);
|
|
49
33
|
|
|
34
|
+
const key =
|
|
35
|
+
isNotNil(field.label) || isNotEmpty(field.label)
|
|
36
|
+
? field.label
|
|
37
|
+
: field.additionalLabel;
|
|
38
|
+
|
|
50
39
|
if (field.hideInput?.(values) ?? false) {
|
|
51
40
|
return null;
|
|
52
41
|
}
|
|
53
42
|
|
|
54
43
|
return (
|
|
55
|
-
<Box sx={{ width: '100%' }} key={
|
|
44
|
+
<Box sx={{ width: '100%' }} key={key}>
|
|
56
45
|
{field.additionalLabel && (
|
|
57
46
|
<Typography
|
|
58
47
|
sx={{ marginBottom: 0.5, color: 'primary.main' }}
|
|
59
|
-
className={
|
|
48
|
+
className={field?.additionalLabelClassName}
|
|
60
49
|
variant="h6"
|
|
61
50
|
>
|
|
62
51
|
{field.additionalLabel}
|
package/src/Form/Inputs/Text.tsx
CHANGED
|
@@ -20,6 +20,8 @@ import {
|
|
|
20
20
|
groupBy,
|
|
21
21
|
isEmpty,
|
|
22
22
|
isNil,
|
|
23
|
+
isNotEmpty,
|
|
24
|
+
isNotNil,
|
|
23
25
|
keys,
|
|
24
26
|
last,
|
|
25
27
|
not,
|
|
@@ -41,6 +43,7 @@ import Grid from './Grid';
|
|
|
41
43
|
import List from './List/List';
|
|
42
44
|
import LoadingSkeleton from './LoadingSkeleton';
|
|
43
45
|
import RadioInput from './Radio';
|
|
46
|
+
import { SubgroupDivider } from './SubGroupDivider';
|
|
44
47
|
import SwitchInput from './Switch';
|
|
45
48
|
import TextInput from './Text';
|
|
46
49
|
import { Group, InputProps, InputPropsWithoutGroup, InputType } from './models';
|
|
@@ -80,6 +83,11 @@ export const getInput = cond<
|
|
|
80
83
|
],
|
|
81
84
|
[equals(InputType.List) as (b: InputType) => boolean, always(List)],
|
|
82
85
|
[equals(InputType.File) as (b: InputType) => boolean, always(File)],
|
|
86
|
+
[equals(InputType.Text) as (b: InputType) => boolean, always(TextInput)],
|
|
87
|
+
[
|
|
88
|
+
equals(InputType.Divider) as (b: InputType) => boolean,
|
|
89
|
+
always(SubgroupDivider)
|
|
90
|
+
],
|
|
83
91
|
[T, always(TextInput)]
|
|
84
92
|
]);
|
|
85
93
|
|
|
@@ -114,9 +122,8 @@ const useStyles = makeStyles<StylesProps>()((theme, { groupDirection }) => ({
|
|
|
114
122
|
inputs: {
|
|
115
123
|
display: 'flex',
|
|
116
124
|
flexDirection: 'column',
|
|
117
|
-
|
|
118
|
-
rowGap: theme.spacing(2)
|
|
119
|
-
marginBottom: theme.spacing(1)
|
|
125
|
+
margin: theme.spacing(2, 0),
|
|
126
|
+
rowGap: theme.spacing(2)
|
|
120
127
|
}
|
|
121
128
|
}));
|
|
122
129
|
|
|
@@ -203,6 +210,7 @@ const Inputs = ({
|
|
|
203
210
|
? find(propEq(groupName, 'name'), groups)
|
|
204
211
|
: ({} as Group);
|
|
205
212
|
|
|
213
|
+
const hasGroupDivider = !groups[index]?.isDividerHidden;
|
|
206
214
|
const isFirstElement = areGroupsOpen || equals(index, 0);
|
|
207
215
|
|
|
208
216
|
return (
|
|
@@ -217,22 +225,19 @@ const Inputs = ({
|
|
|
217
225
|
>
|
|
218
226
|
<div className={classes.inputs}>
|
|
219
227
|
{groupedInputs.map((inputProps) => {
|
|
228
|
+
const key =
|
|
229
|
+
isNotNil(inputProps.label) || isNotEmpty(inputProps.label)
|
|
230
|
+
? inputProps.label
|
|
231
|
+
: inputProps.additionalLabel;
|
|
232
|
+
|
|
220
233
|
if (isLoading) {
|
|
221
|
-
return
|
|
222
|
-
<LoadingSkeleton
|
|
223
|
-
input={inputProps}
|
|
224
|
-
key={inputProps.label}
|
|
225
|
-
/>
|
|
226
|
-
);
|
|
234
|
+
return <LoadingSkeleton input={inputProps} key={key} />;
|
|
227
235
|
}
|
|
228
236
|
|
|
229
237
|
const Input = getInput(inputProps.type);
|
|
230
238
|
|
|
231
239
|
return (
|
|
232
|
-
<div
|
|
233
|
-
className={classes.inputWrapper}
|
|
234
|
-
key={inputProps.label}
|
|
235
|
-
>
|
|
240
|
+
<div className={classes.inputWrapper} key={key}>
|
|
236
241
|
{inputProps.additionalLabel && (
|
|
237
242
|
<Typography
|
|
238
243
|
className={cx(
|
|
@@ -253,17 +258,19 @@ const Inputs = ({
|
|
|
253
258
|
</div>
|
|
254
259
|
</CollapsibleGroup>
|
|
255
260
|
</div>
|
|
256
|
-
{
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
261
|
+
{hasGroupDivider &&
|
|
262
|
+
hasGroupTitle &&
|
|
263
|
+
not(equals(lastGroup, groupName as string)) && (
|
|
264
|
+
<Divider
|
|
265
|
+
flexItem
|
|
266
|
+
className={classes.divider}
|
|
267
|
+
orientation={
|
|
268
|
+
equals(groupDirection, GroupDirection.Horizontal)
|
|
269
|
+
? 'vertical'
|
|
270
|
+
: 'horizontal'
|
|
271
|
+
}
|
|
272
|
+
/>
|
|
273
|
+
)}
|
|
267
274
|
</Fragment>
|
|
268
275
|
);
|
|
269
276
|
})}
|
|
@@ -4,6 +4,7 @@ import { SvgIconProps, TypographyProps } from '@mui/material';
|
|
|
4
4
|
|
|
5
5
|
import { SelectEntry } from '../../InputField/Select';
|
|
6
6
|
import { ConditionsSearchParameter } from '../../api/buildListingEndpoint/models';
|
|
7
|
+
import { QueryParameter } from '../../queryParameters/models';
|
|
7
8
|
|
|
8
9
|
export enum InputType {
|
|
9
10
|
Switch = 0,
|
|
@@ -20,7 +21,8 @@ export enum InputType {
|
|
|
20
21
|
Checkbox = 11,
|
|
21
22
|
CheckboxGroup = 12,
|
|
22
23
|
List = 13,
|
|
23
|
-
File = 14
|
|
24
|
+
File = 14,
|
|
25
|
+
Divider = 15
|
|
24
26
|
}
|
|
25
27
|
|
|
26
28
|
interface FieldsTableGetRequiredProps {
|
|
@@ -55,10 +57,14 @@ export interface InputProps {
|
|
|
55
57
|
};
|
|
56
58
|
connectedAutocomplete?: {
|
|
57
59
|
additionalConditionParameters: Array<ConditionsSearchParameter>;
|
|
60
|
+
customQueryParameters: Array<QueryParameter>;
|
|
58
61
|
chipColor?: string;
|
|
59
62
|
endpoint?: string;
|
|
60
63
|
filterKey?: string;
|
|
61
64
|
getRenderedOptionText?: (option) => string | JSX.Element;
|
|
65
|
+
disableSelectAll?: boolean;
|
|
66
|
+
limitTags?: number;
|
|
67
|
+
decoder?;
|
|
62
68
|
};
|
|
63
69
|
file?: {
|
|
64
70
|
multiple?: boolean;
|
|
@@ -133,4 +139,5 @@ export interface Group {
|
|
|
133
139
|
name: string;
|
|
134
140
|
order: number;
|
|
135
141
|
titleAttributes?: TypographyProps;
|
|
142
|
+
isDividerHidden?: boolean;
|
|
136
143
|
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { Box, TabsProps } from '@mui/material';
|
|
2
|
+
import { isNil } from 'ramda';
|
|
3
|
+
import { useMemo } from 'react';
|
|
4
|
+
import { Tabs } from '../../components/Tabs';
|
|
5
|
+
import { Group } from '../Inputs/models';
|
|
6
|
+
import { groupToTab } from './PanelTabs';
|
|
7
|
+
import { useNavigateToSection } from './navigateToSection';
|
|
8
|
+
|
|
9
|
+
export interface FormSectionProps extends TabsProps {
|
|
10
|
+
groups?: Group[];
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const FormSection = ({ groups }: FormSectionProps) => {
|
|
14
|
+
if (isNil(groups) || groups.length < 4) {
|
|
15
|
+
return null;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const navigateToSection = useNavigateToSection();
|
|
19
|
+
const tabMemo = useMemo(() => groupToTab(groups), [groups]);
|
|
20
|
+
|
|
21
|
+
return (
|
|
22
|
+
<Box className="sticky top-0 bg-background-paper z-100">
|
|
23
|
+
<Tabs
|
|
24
|
+
variant="scrollable"
|
|
25
|
+
scrollButtons={false}
|
|
26
|
+
tabs={tabMemo}
|
|
27
|
+
defaultTab={tabMemo[0].value}
|
|
28
|
+
onChange={navigateToSection}
|
|
29
|
+
/>
|
|
30
|
+
</Box>
|
|
31
|
+
);
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export { FormSection };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { prop, sortBy } from 'ramda';
|
|
2
|
+
import { TabI } from 'src/components/Tabs/Tabs';
|
|
3
|
+
import { Group } from '../Inputs/models';
|
|
4
|
+
|
|
5
|
+
const groupToTab = (groups: Array<Group>): Array<TabI> => {
|
|
6
|
+
const sortedGroups = sortBy(prop('order'), groups);
|
|
7
|
+
|
|
8
|
+
return sortedGroups.map((group) => {
|
|
9
|
+
return { value: group.name, label: group.name };
|
|
10
|
+
});
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export { groupToTab };
|
package/src/Form/storiesData.tsx
CHANGED
|
@@ -157,12 +157,16 @@ export const basicFormGroups: Array<Group> = [
|
|
|
157
157
|
{
|
|
158
158
|
EndIcon: () => <HelpOutlineIcon />,
|
|
159
159
|
TooltipContent: (): JSX.Element => <Typography>Tooltip content</Typography>,
|
|
160
|
+
name: 'Third group',
|
|
161
|
+
order: 3
|
|
162
|
+
},
|
|
163
|
+
{
|
|
160
164
|
name: 'Second group',
|
|
161
165
|
order: 2
|
|
162
166
|
},
|
|
163
167
|
{
|
|
164
|
-
name: '
|
|
165
|
-
order:
|
|
168
|
+
name: 'Fourth group',
|
|
169
|
+
order: 4
|
|
166
170
|
}
|
|
167
171
|
];
|
|
168
172
|
|
|
@@ -215,6 +219,12 @@ export const basicFormInputs: Array<InputProps> = [
|
|
|
215
219
|
},
|
|
216
220
|
type: InputType.Radio
|
|
217
221
|
},
|
|
222
|
+
{
|
|
223
|
+
fieldName: 'div',
|
|
224
|
+
group: 'First group',
|
|
225
|
+
label: 'divider',
|
|
226
|
+
type: InputType.Divider
|
|
227
|
+
},
|
|
218
228
|
{
|
|
219
229
|
additionalLabel: 'Notifications',
|
|
220
230
|
fieldName: '',
|
|
@@ -226,12 +236,12 @@ export const basicFormInputs: Array<InputProps> = [
|
|
|
226
236
|
direction: 'horizontal'
|
|
227
237
|
},
|
|
228
238
|
fieldName: 'notifications.channels',
|
|
229
|
-
label: '
|
|
239
|
+
label: 'mail',
|
|
230
240
|
type: InputType.Checkbox
|
|
231
241
|
},
|
|
232
242
|
{
|
|
233
243
|
fieldName: 'notifications.includeServices',
|
|
234
|
-
label: '
|
|
244
|
+
label: 'Include services for this host',
|
|
235
245
|
type: InputType.Checkbox
|
|
236
246
|
},
|
|
237
247
|
{
|
|
@@ -4,10 +4,12 @@ import { useAtomValue } from 'jotai';
|
|
|
4
4
|
|
|
5
5
|
import { userAtom } from '@centreon/ui-context';
|
|
6
6
|
|
|
7
|
+
import dataMissingPoint from '../mockedData/dataWithMissingPoint.json';
|
|
7
8
|
import dataLastWeek from '../mockedData/lastWeek.json';
|
|
8
9
|
import dataPingService from '../mockedData/pingService.json';
|
|
9
10
|
import dataPingServiceMixedStacked from '../mockedData/pingServiceMixedStacked.json';
|
|
10
11
|
import dataPingServiceStacked from '../mockedData/pingServiceStacked.json';
|
|
12
|
+
import dataPingServiceLinesStackKeys from '../mockedData/pingServiceWithStackedKeys.json';
|
|
11
13
|
|
|
12
14
|
import BarChart, { BarChartProps } from './BarChart';
|
|
13
15
|
|
|
@@ -30,10 +32,20 @@ const initialize = ({
|
|
|
30
32
|
tooltip,
|
|
31
33
|
axis,
|
|
32
34
|
orientation,
|
|
33
|
-
barStyle
|
|
35
|
+
barStyle,
|
|
36
|
+
min,
|
|
37
|
+
max
|
|
34
38
|
}: Pick<
|
|
35
39
|
BarChartProps,
|
|
36
|
-
|
|
40
|
+
| 'data'
|
|
41
|
+
| 'legend'
|
|
42
|
+
| 'axis'
|
|
43
|
+
| 'barStyle'
|
|
44
|
+
| 'orientation'
|
|
45
|
+
| 'tooltip'
|
|
46
|
+
| 'start'
|
|
47
|
+
| 'min'
|
|
48
|
+
| 'max'
|
|
37
49
|
>): void => {
|
|
38
50
|
cy.adjustViewport();
|
|
39
51
|
|
|
@@ -47,6 +59,8 @@ const initialize = ({
|
|
|
47
59
|
legend={legend}
|
|
48
60
|
orientation={orientation ?? 'horizontal'}
|
|
49
61
|
tooltip={tooltip}
|
|
62
|
+
min={min}
|
|
63
|
+
max={max}
|
|
50
64
|
{...defaultArgs}
|
|
51
65
|
/>
|
|
52
66
|
</div>
|
|
@@ -138,8 +152,6 @@ describe('Bar chart', () => {
|
|
|
138
152
|
cy.contains(':40 AM').should('be.visible');
|
|
139
153
|
|
|
140
154
|
cy.findByTestId('stacked-bar-3-0-0.16196').should('be.visible');
|
|
141
|
-
|
|
142
|
-
cy.makeSnapshot();
|
|
143
155
|
});
|
|
144
156
|
|
|
145
157
|
it(`displays bar chart ${orientation}ly with a mix of stacked and non-stacked data centered in zero`, () => {
|
|
@@ -250,8 +262,6 @@ describe('Bar chart', () => {
|
|
|
250
262
|
cy.contains('0.11 ms').should('be.visible');
|
|
251
263
|
|
|
252
264
|
cy.findByTestId('stacked-bar-3-0-0.16196').should('be.visible');
|
|
253
|
-
|
|
254
|
-
cy.makeSnapshot();
|
|
255
265
|
});
|
|
256
266
|
|
|
257
267
|
it('displays a tooltip with a single metric when a stacked bar is hovered and a prop is set', () => {
|
|
@@ -291,4 +301,34 @@ describe('Bar chart', () => {
|
|
|
291
301
|
cy.contains('05/31/2023').should('be.visible');
|
|
292
302
|
cy.contains('06/07/2023').should('be.visible');
|
|
293
303
|
});
|
|
304
|
+
|
|
305
|
+
it('displays the bar chart according to min and max boundaries', () => {
|
|
306
|
+
initialize({
|
|
307
|
+
data: dataLastWeek,
|
|
308
|
+
min: -0.05,
|
|
309
|
+
max: 1
|
|
310
|
+
});
|
|
311
|
+
|
|
312
|
+
cy.contains('05/31/2023').should('be.visible');
|
|
313
|
+
cy.contains('06/07/2023').should('be.visible');
|
|
314
|
+
cy.contains('1 s').should('be.visible');
|
|
315
|
+
cy.contains('1%').should('be.visible');
|
|
316
|
+
});
|
|
317
|
+
|
|
318
|
+
it('displays the stacked bar chart correctly when a point is missing compare to the time serie', () => {
|
|
319
|
+
initialize({ data: dataMissingPoint });
|
|
320
|
+
|
|
321
|
+
cy.findByTestId('stacked-bar-2-0-139').should('be.visible');
|
|
322
|
+
|
|
323
|
+
cy.makeSnapshot();
|
|
324
|
+
});
|
|
325
|
+
|
|
326
|
+
it('displays the stacked bar chart with bars stacked together', () => {
|
|
327
|
+
initialize({ data: dataPingServiceLinesStackKeys });
|
|
328
|
+
|
|
329
|
+
cy.findByTestId('stacked-bar-3-0-0.05336').should('be.visible');
|
|
330
|
+
cy.findByTestId('stacked-bar-4-0-0.06684').should('be.visible');
|
|
331
|
+
|
|
332
|
+
cy.makeSnapshot();
|
|
333
|
+
});
|
|
294
334
|
});
|
|
@@ -5,7 +5,10 @@ import { LineChartData } from '../common/models';
|
|
|
5
5
|
import dataPingService from '../mockedData/pingService.json';
|
|
6
6
|
import dataPingServiceMixedStacked from '../mockedData/pingServiceMixedStacked.json';
|
|
7
7
|
import dataPingServiceStacked from '../mockedData/pingServiceStacked.json';
|
|
8
|
+
import dataPingServiceStackeKey from '../mockedData/pingServiceWithStackedKeys.json';
|
|
8
9
|
|
|
10
|
+
import { ClickAwayListener } from '@mui/material';
|
|
11
|
+
import { useState } from 'react';
|
|
9
12
|
import BarChart from './BarChart';
|
|
10
13
|
|
|
11
14
|
const meta: Meta<typeof BarChart> = {
|
|
@@ -250,3 +253,60 @@ export const mixedStackedVertical: Story = {
|
|
|
250
253
|
},
|
|
251
254
|
render: Template
|
|
252
255
|
};
|
|
256
|
+
|
|
257
|
+
export const mixedStackedMinMax: Story = {
|
|
258
|
+
args: {
|
|
259
|
+
...defaultArgs,
|
|
260
|
+
data: dataPingServiceMixedStacked,
|
|
261
|
+
min: 10,
|
|
262
|
+
max: 20
|
|
263
|
+
},
|
|
264
|
+
render: Template
|
|
265
|
+
};
|
|
266
|
+
|
|
267
|
+
const LegendSecondaryClick = (args) => {
|
|
268
|
+
const [position, setPosition] = useState<Array<[number, number]> | null>(
|
|
269
|
+
null
|
|
270
|
+
);
|
|
271
|
+
|
|
272
|
+
return (
|
|
273
|
+
<>
|
|
274
|
+
<Template
|
|
275
|
+
{...args}
|
|
276
|
+
legend={{
|
|
277
|
+
secondaryClick: ({ position }) => setPosition(position)
|
|
278
|
+
}}
|
|
279
|
+
/>
|
|
280
|
+
{position && (
|
|
281
|
+
<ClickAwayListener onClickAway={() => setPosition(null)}>
|
|
282
|
+
<div
|
|
283
|
+
className="absolute py-1 px-2 rounded-sm bg-background-widget shadow-md"
|
|
284
|
+
style={{ left: position?.[0], top: position?.[1] }}
|
|
285
|
+
open={Boolean(position)}
|
|
286
|
+
onClose={() => setPosition(null)}
|
|
287
|
+
>
|
|
288
|
+
menu
|
|
289
|
+
</div>
|
|
290
|
+
</ClickAwayListener>
|
|
291
|
+
)}
|
|
292
|
+
</>
|
|
293
|
+
);
|
|
294
|
+
};
|
|
295
|
+
|
|
296
|
+
export const withLegendSecondaryClick: Story = {
|
|
297
|
+
args: defaultArgs,
|
|
298
|
+
render: (args) => (
|
|
299
|
+
<LegendSecondaryClick
|
|
300
|
+
{...args}
|
|
301
|
+
data={dataPingService as unknown as LineChartData}
|
|
302
|
+
/>
|
|
303
|
+
)
|
|
304
|
+
};
|
|
305
|
+
|
|
306
|
+
export const stackKey: Story = {
|
|
307
|
+
args: {
|
|
308
|
+
...defaultArgs,
|
|
309
|
+
data: dataPingServiceStackeKey
|
|
310
|
+
},
|
|
311
|
+
render: Template
|
|
312
|
+
};
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import { useRef } from 'react';
|
|
2
|
-
|
|
3
1
|
import dayjs from 'dayjs';
|
|
4
2
|
import 'dayjs/locale/en';
|
|
5
3
|
import 'dayjs/locale/es';
|
|
@@ -12,12 +10,14 @@ import { Provider } from 'jotai';
|
|
|
12
10
|
|
|
13
11
|
import { Box } from '@mui/material';
|
|
14
12
|
|
|
15
|
-
import
|
|
13
|
+
import Loading from '../../LoadingSkeleton';
|
|
16
14
|
import LoadingSkeleton from '../Chart/LoadingSkeleton';
|
|
17
15
|
import { LineChartProps } from '../Chart/models';
|
|
18
16
|
import useChartData from '../Chart/useChartData';
|
|
19
17
|
import { LineChartData, Thresholds } from '../common/models';
|
|
20
18
|
|
|
19
|
+
import { ReactElement } from 'react';
|
|
20
|
+
import useResizeObserver from 'use-resize-observer';
|
|
21
21
|
import ResponsiveBarChart from './ResponsiveBarChart';
|
|
22
22
|
import { BarStyle } from './models';
|
|
23
23
|
|
|
@@ -27,7 +27,20 @@ dayjs.extend(timezonePlugin);
|
|
|
27
27
|
|
|
28
28
|
export interface BarChartProps
|
|
29
29
|
extends Partial<
|
|
30
|
-
Pick<
|
|
30
|
+
Pick<
|
|
31
|
+
LineChartProps,
|
|
32
|
+
| 'tooltip'
|
|
33
|
+
| 'legend'
|
|
34
|
+
| 'height'
|
|
35
|
+
| 'axis'
|
|
36
|
+
| 'header'
|
|
37
|
+
| 'min'
|
|
38
|
+
| 'max'
|
|
39
|
+
| 'boundariesUnit'
|
|
40
|
+
| 'timeShiftZones'
|
|
41
|
+
| 'zoomPreview'
|
|
42
|
+
| 'annotationEvent'
|
|
43
|
+
>
|
|
31
44
|
> {
|
|
32
45
|
barStyle?: BarStyle;
|
|
33
46
|
data?: LineChartData;
|
|
@@ -59,10 +72,16 @@ const BarChart = ({
|
|
|
59
72
|
opacity: 1,
|
|
60
73
|
radius: 0.2
|
|
61
74
|
},
|
|
62
|
-
skipIntersectionObserver
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
75
|
+
skipIntersectionObserver,
|
|
76
|
+
min,
|
|
77
|
+
max,
|
|
78
|
+
boundariesUnit,
|
|
79
|
+
zoomPreview,
|
|
80
|
+
timeShiftZones,
|
|
81
|
+
annotationEvent
|
|
82
|
+
}: BarChartProps): ReactElement => {
|
|
83
|
+
const { adjustedData } = useChartData({ data, end, start, min, max });
|
|
84
|
+
const { ref, width, height: responsiveHeight } = useResizeObserver();
|
|
66
85
|
|
|
67
86
|
if (loading && !adjustedData) {
|
|
68
87
|
return (
|
|
@@ -75,30 +94,35 @@ const BarChart = ({
|
|
|
75
94
|
|
|
76
95
|
return (
|
|
77
96
|
<Provider>
|
|
78
|
-
<Box
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
97
|
+
<Box ref={ref} sx={{ height: '100%', overflow: 'hidden', width: '100%' }}>
|
|
98
|
+
{!responsiveHeight ? (
|
|
99
|
+
<Loading height={height || '100%'} width={width} />
|
|
100
|
+
) : (
|
|
101
|
+
<ResponsiveBarChart
|
|
102
|
+
axis={axis}
|
|
103
|
+
barStyle={barStyle}
|
|
104
|
+
graphData={adjustedData}
|
|
105
|
+
graphRef={ref}
|
|
106
|
+
header={header}
|
|
107
|
+
height={height || responsiveHeight || 0}
|
|
108
|
+
legend={legend}
|
|
109
|
+
limitLegend={limitLegend}
|
|
110
|
+
orientation={orientation}
|
|
111
|
+
thresholdUnit={thresholdUnit}
|
|
112
|
+
thresholds={thresholds}
|
|
113
|
+
tooltip={tooltip}
|
|
114
|
+
width={width || 0}
|
|
115
|
+
skipIntersectionObserver={skipIntersectionObserver}
|
|
116
|
+
min={min}
|
|
117
|
+
max={max}
|
|
118
|
+
boundariesUnit={boundariesUnit}
|
|
119
|
+
zoomPreview={zoomPreview}
|
|
120
|
+
timeShiftZones={timeShiftZones}
|
|
121
|
+
annotationEvent={annotationEvent}
|
|
122
|
+
start={start}
|
|
123
|
+
end={end}
|
|
124
|
+
/>
|
|
125
|
+
)}
|
|
102
126
|
</Box>
|
|
103
127
|
</Provider>
|
|
104
128
|
);
|