@centreon/ui 25.10.28 → 25.11.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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@centreon/ui",
3
- "version": "25.10.28",
3
+ "version": "25.11.0",
4
4
  "description": "Centreon UI Components",
5
5
  "scripts": {
6
6
  "update:deps": "pnpx npm-check-updates -i --format group",
@@ -46,7 +46,7 @@ export const getYAnchorPoint = ({
46
46
  return null;
47
47
  }
48
48
 
49
- return yScale(timeValue[1] as number);
49
+ return yScale(timeValue[0] as number);
50
50
  };
51
51
 
52
52
  const StackedAnchorPoint = ({
@@ -9,9 +9,11 @@ import {
9
9
  find,
10
10
  isEmpty,
11
11
  isNil,
12
+ isNotNil,
12
13
  keys,
13
14
  map,
14
15
  negate,
16
+ omit,
15
17
  pick,
16
18
  pipe,
17
19
  pluck,
@@ -212,6 +214,39 @@ const InteractionWithGraph = ({
212
214
  yScalesPerUnit
213
215
  });
214
216
 
217
+ if (isNotNil(lineData?.stackOrder)) {
218
+ const test = Object.entries(omit(['timeTick'], timeValue)).reduce(
219
+ (acc, [key, value]) => {
220
+ const line = getLineForMetric({
221
+ lines,
222
+ metric_id: Number(key)
223
+ });
224
+
225
+ const isBelowStackOrder =
226
+ isNotNil(line?.stackOrder) &&
227
+ (line?.stackOrder as number) >= (lineData.stackOrder as number);
228
+
229
+ if (isBelowStackOrder) {
230
+ return acc + value;
231
+ }
232
+
233
+ return acc;
234
+ },
235
+ 0
236
+ );
237
+
238
+ const y0 = yScale(test);
239
+
240
+ const diffBetweenY0AndPointPosition = Math.abs(
241
+ y0 - margin.top - (graphHeight - pointPosition[1])
242
+ );
243
+
244
+ return {
245
+ ...acc,
246
+ [metricId]: diffBetweenY0AndPointPosition
247
+ };
248
+ }
249
+
215
250
  const y0 = yScale(value);
216
251
 
217
252
  const diffBetweenY0AndPointPosition = Math.abs(
@@ -1,4 +1,4 @@
1
- import { useCallback, useEffect, useState } from 'react';
1
+ import { ReactElement, useCallback, useEffect, useState } from 'react';
2
2
 
3
3
  import {
4
4
  equals,
@@ -44,7 +44,7 @@ export interface ConnectedAutoCompleteFieldProps<TData> {
44
44
  field: string;
45
45
  getEndpoint: ({ search, page }) => string;
46
46
  decoder?;
47
- getRenderedOptionText: (option: TData) => string;
47
+ getRenderedOptionText?: (option: TData) => ReactElement | string;
48
48
  getRequestHeaders?: HeadersInit;
49
49
  initialPage: number;
50
50
  labelKey?: string;
@@ -53,9 +53,9 @@ export interface ConnectedAutoCompleteFieldProps<TData> {
53
53
  }
54
54
 
55
55
  const ConnectedAutocompleteField = (
56
- AutocompleteField: (props) => JSX.Element,
56
+ AutocompleteField: (props) => ReactElement,
57
57
  multiple: boolean
58
- ): ((props) => JSX.Element) => {
58
+ ): ((props) => ReactElement) => {
59
59
  const InnerConnectedAutocompleteField = <TData extends { name: string }>({
60
60
  initialPage = 1,
61
61
  getEndpoint,
@@ -74,7 +74,7 @@ const ConnectedAutocompleteField = (
74
74
  changeIdValue,
75
75
  ...props
76
76
  }: ConnectedAutoCompleteFieldProps<TData> &
77
- Omit<AutocompleteFieldProps, 'options'>): JSX.Element => {
77
+ Omit<AutocompleteFieldProps, 'options'>): ReactElement => {
78
78
  const [options, setOptions] = useState<Array<TData>>([]);
79
79
  const [page, setPage] = useState(1);
80
80
  const [maxPage, setMaxPage] = useState(initialPage);
@@ -221,7 +221,7 @@ const ConnectedAutocompleteField = (
221
221
  debounce(event.target.value);
222
222
  };
223
223
 
224
- const renderOptions = (renderProps, option, { selected }): JSX.Element => {
224
+ const renderOptions = (renderProps, option, { selected }): ReactElement => {
225
225
  const { value } = props;
226
226
 
227
227
  const lastValue = Array.isArray(value) ? last(value) : value;
@@ -13,6 +13,7 @@ import { AutocompleteSlotsAndSlotProps } from '@mui/material/Autocomplete';
13
13
  import { TextFieldSlotsAndSlotProps } from '@mui/material/TextField';
14
14
  import { UseAutocompleteProps } from '@mui/material/useAutocomplete';
15
15
 
16
+ import type { AutocompleteRenderOptionState } from '@mui/material/Autocomplete';
16
17
  import { ForwardedRef, HTMLAttributes, ReactElement, forwardRef } from 'react';
17
18
  import { SelectEntry } from '..';
18
19
  import { getNormalizedId } from '../../../utils';
@@ -33,6 +34,11 @@ export type Props = {
33
34
  error?: string;
34
35
  getOptionItemLabel?: (option) => string;
35
36
  hideInput?: boolean;
37
+ renderOption?: (
38
+ renderProps: HTMLAttributes<HTMLLIElement>,
39
+ option: SelectEntry,
40
+ state: AutocompleteRenderOptionState
41
+ ) => ReactElement;
36
42
  label: string;
37
43
  loading?: boolean;
38
44
  onTextChange?;
@@ -52,7 +58,7 @@ export type Props = {
52
58
  > &
53
59
  UseAutocompleteProps<SelectEntry, Multiple, DisableClearable, FreeSolo>;
54
60
 
55
- const LoadingIndicator = (): JSX.Element => {
61
+ const LoadingIndicator = (): ReactElement => {
56
62
  const { classes } = useAutoCompleteStyles({});
57
63
 
58
64
  return (
@@ -90,10 +96,11 @@ const AutocompleteField = forwardRef(
90
96
  forceInputRenderValue = false,
91
97
  textFieldSlotsAndSlotProps,
92
98
  autocompleteSlotsAndSlotProps,
99
+ renderOption,
93
100
  ...autocompleteProps
94
101
  }: Props,
95
102
  ref?: ForwardedRef<HTMLDivElement>
96
- ): JSX.Element => {
103
+ ): ReactElement => {
97
104
  const { classes, cx } = useAutoCompleteStyles({ hideInput });
98
105
  const { t } = useTranslation();
99
106
  const theme = useTheme();
@@ -107,7 +114,24 @@ const AutocompleteField = forwardRef(
107
114
  );
108
115
  };
109
116
 
110
- const renderInput = (params): JSX.Element => {
117
+ const renderOptions = renderOption
118
+ ? renderOption
119
+ : (props, option): ReactElement => {
120
+ return (
121
+ <li
122
+ className={classes.options}
123
+ {...(props as HTMLAttributes<HTMLLIElement>)}
124
+ >
125
+ <Option
126
+ thumbnailUrl={displayOptionThumbnail ? option.url : undefined}
127
+ >
128
+ {getOptionItemLabel(option)}
129
+ </Option>
130
+ </li>
131
+ );
132
+ };
133
+
134
+ const renderInput = (params): ReactElement => {
111
135
  return (
112
136
  <TextField
113
137
  {...params}
@@ -202,20 +226,7 @@ const AutocompleteField = forwardRef(
202
226
  options={options}
203
227
  ref={ref}
204
228
  renderInput={renderInput}
205
- renderOption={(props, option): JSX.Element => {
206
- return (
207
- <li
208
- className={classes.options}
209
- {...(props as HTMLAttributes<HTMLLIElement>)}
210
- >
211
- <Option
212
- thumbnailUrl={displayOptionThumbnail ? option.url : undefined}
213
- >
214
- {getOptionItemLabel(option)}
215
- </Option>
216
- </li>
217
- );
218
- }}
229
+ renderOption={renderOptions}
219
230
  size="small"
220
231
  slotProps={{
221
232
  ...autocompleteSlotsAndSlotProps?.slotProps,
@@ -1,4 +1,4 @@
1
- import { RefObject, forwardRef } from 'react';
1
+ import { ReactElement, RefObject, forwardRef } from 'react';
2
2
 
3
3
  import { equals, isNil } from 'ramda';
4
4
  import { makeStyles } from 'tss-react/mui';
@@ -28,12 +28,12 @@ const useStyles = makeStyles()((theme) => ({
28
28
 
29
29
  interface Props {
30
30
  checkboxSelected?: boolean;
31
- children: string;
31
+ children: string | ReactElement;
32
32
  thumbnailUrl?: string;
33
33
  }
34
34
 
35
35
  const Option = forwardRef(
36
- ({ children, checkboxSelected, thumbnailUrl }: Props, ref): JSX.Element => {
36
+ ({ children, checkboxSelected, thumbnailUrl }: Props, ref): ReactElement => {
37
37
  const { classes } = useStyles();
38
38
 
39
39
  return (
@@ -107,14 +107,16 @@ const PickersStartEndDate = ({
107
107
  const maxEnd = rangeEndDate?.max;
108
108
  const minEnd = rangeEndDate?.min || startDate;
109
109
 
110
- const isColumn = equals(direction, PickersStartEndDateDirection.column)
110
+ const isColumn = equals(direction, PickersStartEndDateDirection.column);
111
111
 
112
112
  return (
113
113
  <LocalizationProvider
114
114
  adapterLocale={locale.substring(0, 2)}
115
115
  dateAdapter={AdapterDayjs}
116
116
  >
117
- <div className={`flex ${isColumn ? 'flex-col justify-center' : 'flex-row items-center py-2 px-4'} gap-2 ${className}`}>
117
+ <div
118
+ className={`flex ${isColumn ? 'flex-col justify-center' : 'flex-row items-center py-2 px-4'} gap-2 ${className}`}
119
+ >
118
120
  <PickerDateWithLabel
119
121
  changeDate={changeDate}
120
122
  date={startDate}
@@ -8,6 +8,7 @@ import { SelectEntry, SingleConnectedAutocompleteField } from '../../../..';
8
8
  import RoleSelectField from '../common/RoleSelectField';
9
9
  import { Endpoints, Labels } from '../models';
10
10
 
11
+ import { ReactElement } from 'react';
11
12
  import ContactSwitch from './ContactSwitch';
12
13
  import { useShareInputStyles } from './ShareInput.styles';
13
14
  import useShareInput from './useShareInput';
@@ -18,18 +19,18 @@ interface Props {
18
19
  roles: Array<SelectEntry>;
19
20
  }
20
21
 
21
- const ShareInput = ({ labels, endpoints, roles }: Props): JSX.Element => {
22
+ const ShareInput = ({ labels, endpoints, roles }: Props): ReactElement => {
22
23
  const { t } = useTranslation();
23
24
  const { classes } = useShareInputStyles();
24
25
 
25
26
  const {
26
- renderOption,
27
27
  selectedContact,
28
28
  getOptionDisabled,
29
29
  getEndpoint,
30
30
  selectContact,
31
31
  isContactGroup,
32
32
  selectedRole,
33
+ getRenderedOptionText,
33
34
  setSelectedRole,
34
35
  add,
35
36
  changeIdValue
@@ -46,6 +47,7 @@ const ShareInput = ({ labels, endpoints, roles }: Props): JSX.Element => {
46
47
  disableClearable={false}
47
48
  field="name"
48
49
  getEndpoint={getEndpoint}
50
+ getRenderedOptionText={getRenderedOptionText}
49
51
  getOptionDisabled={getOptionDisabled}
50
52
  label={t(
51
53
  isContactGroup
@@ -53,7 +55,6 @@ const ShareInput = ({ labels, endpoints, roles }: Props): JSX.Element => {
53
55
  : t(labels.autocompleteContact)
54
56
  )}
55
57
  queryKey={isContactGroup ? labels.contactGroup : labels.contact}
56
- renderOption={renderOption}
57
58
  value={selectedContact}
58
59
  onChange={selectContact}
59
60
  />
@@ -1,10 +1,15 @@
1
- import { Dispatch, SetStateAction, useEffect, useState } from 'react';
1
+ import {
2
+ Dispatch,
3
+ ReactElement,
4
+ SetStateAction,
5
+ useEffect,
6
+ useState
7
+ } from 'react';
2
8
 
3
9
  import { useAtomValue, useSetAtom } from 'jotai';
4
10
  import { equals, includes, isNil } from 'ramda';
5
11
 
6
12
  import CheckCircleIcon from '@mui/icons-material/CheckCircle';
7
- import { ListItemText, MenuItem } from '@mui/material';
8
13
 
9
14
  import { SelectEntry, buildListingEndpoint } from '../../../..';
10
15
  import {
@@ -20,7 +25,7 @@ interface UseShareInputState {
20
25
  getEndpoint: (parameters) => string;
21
26
  getOptionDisabled: (option) => boolean;
22
27
  isContactGroup: boolean;
23
- renderOption: (attr, option) => JSX.Element;
28
+ getRenderedOptionText: (option: unknown) => ReactElement | string;
24
29
  selectContact: (_, entry) => void;
25
30
  selectedContact: AccessRightInitialValues | null;
26
31
  selectedRole: string;
@@ -40,7 +45,7 @@ const useShareInput = (endpoints: Endpoints): UseShareInputState => {
40
45
 
41
46
  const selectContact = (_, entry): void => {
42
47
  setSelectedContact(entry);
43
- if (equals('editor', entry.most_permissive_role)) {
48
+ if (equals('editor', entry?.most_permissive_role)) {
44
49
  return;
45
50
  }
46
51
  setSelectedRole('viewer');
@@ -71,14 +76,14 @@ const useShareInput = (endpoints: Endpoints): UseShareInputState => {
71
76
  }
72
77
  });
73
78
 
74
- const renderOption = (attr, option): JSX.Element => {
79
+ const getRenderedOptionText = (option): ReactElement => {
75
80
  return (
76
- <MenuItem {...attr}>
77
- <ListItemText>{option.name}</ListItemText>
78
- {includes(option.id, accessRightIds) && (
81
+ <>
82
+ {option?.name}
83
+ {includes(option?.id, accessRightIds) && (
79
84
  <CheckCircleIcon color="success" />
80
85
  )}
81
- </MenuItem>
86
+ </>
82
87
  );
83
88
  };
84
89
 
@@ -102,7 +107,7 @@ const useShareInput = (endpoints: Endpoints): UseShareInputState => {
102
107
  getEndpoint,
103
108
  getOptionDisabled,
104
109
  isContactGroup,
105
- renderOption,
110
+ getRenderedOptionText,
106
111
  selectContact,
107
112
  selectedContact,
108
113
  selectedRole,
@@ -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;