@centreon/ui 24.11.2 → 24.11.4

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 (75) hide show
  1. package/package.json +2 -3
  2. package/src/Dashboard/Dashboard.styles.ts +4 -3
  3. package/src/Dashboard/DashboardLayout.stories.tsx +1 -1
  4. package/src/Dashboard/Grid.tsx +17 -11
  5. package/src/Dashboard/Layout.tsx +56 -27
  6. package/src/FileDropZone/index.tsx +21 -23
  7. package/src/Form/CollapsibleGroup.tsx +3 -2
  8. package/src/Form/Form.cypress.spec.tsx +39 -0
  9. package/src/Form/Form.tsx +1 -0
  10. package/src/Form/Inputs/Autocomplete.tsx +27 -4
  11. package/src/Form/Inputs/ConnectedAutocomplete.tsx +20 -10
  12. package/src/Form/Inputs/File.tsx +69 -0
  13. package/src/Form/Inputs/Grid.tsx +30 -2
  14. package/src/Form/Inputs/Radio.tsx +12 -4
  15. package/src/Form/Inputs/Switch.tsx +10 -2
  16. package/src/Form/Inputs/Text.tsx +13 -4
  17. package/src/Form/Inputs/index.tsx +5 -2
  18. package/src/Form/Inputs/models.ts +18 -2
  19. package/src/Form/storiesData.tsx +15 -3
  20. package/src/Form/translatedLabels.ts +1 -0
  21. package/src/Graph/BarChart/BarChart.tsx +4 -1
  22. package/src/Graph/BarChart/ResponsiveBarChart.tsx +3 -2
  23. package/src/Graph/Chart/Chart.tsx +9 -2
  24. package/src/Graph/Chart/InteractiveComponents/AnchorPoint/useTickGraph.ts +2 -2
  25. package/src/Graph/Chart/InteractiveComponents/index.tsx +10 -2
  26. package/src/Graph/Chart/helpers/index.ts +5 -5
  27. package/src/Graph/Chart/index.tsx +7 -0
  28. package/src/Graph/Chart/models.ts +1 -0
  29. package/src/Graph/common/timeSeries/index.ts +15 -8
  30. package/src/InputField/Text/index.tsx +1 -1
  31. package/src/Listing/index.tsx +39 -27
  32. package/src/Listing/models.ts +8 -0
  33. package/src/MultiSelectEntries/index.tsx +0 -2
  34. package/src/PopoverMenu/index.tsx +9 -2
  35. package/src/SortableItems/index.tsx +1 -0
  36. package/src/ThemeProvider/index.tsx +1 -1
  37. package/src/ThemeProvider/palettes.ts +4 -4
  38. package/src/api/customFetch.ts +4 -1
  39. package/src/components/CrudPage/Actions/Actions.styles.ts +16 -0
  40. package/src/components/CrudPage/Actions/Actions.tsx +24 -0
  41. package/src/components/CrudPage/Actions/AddButton.tsx +23 -0
  42. package/src/components/CrudPage/Actions/Filters.tsx +25 -0
  43. package/src/components/CrudPage/Actions/Search.tsx +31 -0
  44. package/src/components/CrudPage/Actions/useSearch.tsx +24 -0
  45. package/src/components/CrudPage/Columns/Actions.tsx +88 -0
  46. package/src/components/CrudPage/CrudPage.cypress.spec.tsx +559 -0
  47. package/src/components/CrudPage/CrudPage.stories.tsx +278 -0
  48. package/src/components/CrudPage/CrudPageRoot.tsx +142 -0
  49. package/src/components/CrudPage/DeleteModal.tsx +77 -0
  50. package/src/components/CrudPage/Form/AddModal.tsx +35 -0
  51. package/src/components/CrudPage/Form/Buttons.tsx +98 -0
  52. package/src/components/CrudPage/Form/UpdateModal.tsx +60 -0
  53. package/src/components/CrudPage/Listing.tsx +63 -0
  54. package/src/components/CrudPage/atoms.ts +30 -0
  55. package/src/components/CrudPage/hooks/useDeleteItem.ts +53 -0
  56. package/src/components/CrudPage/hooks/useGetItem.ts +36 -0
  57. package/src/components/CrudPage/hooks/useGetItems.ts +67 -0
  58. package/src/components/CrudPage/hooks/useListingQueryKey.ts +31 -0
  59. package/src/components/CrudPage/index.tsx +7 -0
  60. package/src/components/CrudPage/models.ts +118 -0
  61. package/src/components/CrudPage/utils.ts +4 -0
  62. package/src/components/DataTable/DataTable.cypress.spec.tsx +2 -1
  63. package/src/components/DataTable/DataTable.stories.tsx +17 -0
  64. package/src/components/DataTable/DataTable.styles.ts +1 -1
  65. package/src/components/DataTable/EmptyState/DataTableEmptyState.styles.ts +3 -1
  66. package/src/components/DataTable/EmptyState/DataTableEmptyState.tsx +6 -0
  67. package/src/components/DataTable/Item/DataTableItem.styles.ts +28 -2
  68. package/src/components/DataTable/Item/DataTableItem.tsx +19 -4
  69. package/src/components/Layout/AreaIndicator.tsx +1 -1
  70. package/src/components/Layout/PageLayout/PageLayout.styles.ts +7 -2
  71. package/src/components/Layout/PageLayout/PageLayoutBody.tsx +1 -0
  72. package/src/components/Modal/Modal.styles.ts +1 -1
  73. package/src/components/Zoom/Zoom.tsx +2 -2
  74. package/src/components/Zoom/ZoomContent.tsx +2 -2
  75. package/src/components/index.ts +1 -0
@@ -1,5 +1,5 @@
1
1
  import { FormikValues, useFormikContext } from 'formik';
2
- import { path, equals, includes, split, type } from 'ramda';
2
+ import { equals, includes, path, split, type } from 'ramda';
3
3
  import { useTranslation } from 'react-i18next';
4
4
 
5
5
  import {
@@ -26,12 +26,20 @@ const Radio = ({
26
26
  }: InputPropsWithoutGroup): JSX.Element => {
27
27
  const { t } = useTranslation();
28
28
 
29
- const { values, setFieldValue } = useFormikContext<FormikValues>();
29
+ const { values, setFieldValue, setFieldTouched, setValues, setTouched } =
30
+ useFormikContext<FormikValues>();
30
31
 
31
32
  const changeRadio = (_, value): void => {
32
33
  if (includes(value, ['true', 'false'])) {
33
34
  if (change) {
34
- change({ setFieldValue, value: equals(value, 'true') });
35
+ change({
36
+ setFieldValue,
37
+ value: equals(value, 'true'),
38
+ values,
39
+ setFieldTouched,
40
+ setValues,
41
+ setTouched
42
+ });
35
43
 
36
44
  return;
37
45
  }
@@ -42,7 +50,7 @@ const Radio = ({
42
50
  }
43
51
 
44
52
  if (change) {
45
- change({ setFieldValue, value });
53
+ change({ setFieldValue, value, values, setFieldTouched, setValues });
46
54
 
47
55
  return;
48
56
  }
@@ -22,11 +22,19 @@ const Switch = ({
22
22
  }: InputPropsWithoutGroup): JSX.Element => {
23
23
  const { t } = useTranslation();
24
24
 
25
- const { values, setFieldValue } = useFormikContext<FormikValues>();
25
+ const { values, setFieldValue, setFieldTouched, setValues, setTouched } =
26
+ useFormikContext<FormikValues>();
26
27
 
27
28
  const changeSwitchValue = (event: ChangeEvent<HTMLInputElement>): void => {
28
29
  if (change) {
29
- change({ setFieldValue, value: event.target.checked });
30
+ change({
31
+ setFieldValue,
32
+ value: event.target.checked,
33
+ values,
34
+ setFieldTouched,
35
+ setValues,
36
+ setTouched
37
+ });
30
38
 
31
39
  return;
32
40
  }
@@ -2,11 +2,11 @@ import { ChangeEvent, useCallback, useState } from 'react';
2
2
 
3
3
  import { FormikValues, useFormikContext } from 'formik';
4
4
  import {
5
- path,
6
5
  equals,
7
6
  gt,
8
7
  isEmpty,
9
8
  not,
9
+ path,
10
10
  split,
11
11
  type as variableType
12
12
  } from 'ramda';
@@ -42,7 +42,9 @@ const Text = ({
42
42
  touched,
43
43
  errors,
44
44
  handleBlur,
45
- setFieldTouched
45
+ setFieldTouched,
46
+ setValues,
47
+ setTouched
46
48
  } = useFormikContext<FormikValues>();
47
49
 
48
50
  const fieldNamePath = split('.', fieldName);
@@ -50,7 +52,14 @@ const Text = ({
50
52
  const changeText = (event: ChangeEvent<HTMLInputElement>): void => {
51
53
  const { value } = event.target;
52
54
  if (change) {
53
- change({ setFieldValue, value, setFieldTouched });
55
+ change({
56
+ setFieldValue,
57
+ value,
58
+ setFieldTouched,
59
+ setValues,
60
+ values,
61
+ setTouched
62
+ });
54
63
 
55
64
  return;
56
65
  }
@@ -113,7 +122,7 @@ const Text = ({
113
122
  return useMemoComponent({
114
123
  Component: (
115
124
  <TextField
116
- fullWidth
125
+ fullWidth={text?.fullWidth ?? true}
117
126
  EndAdornment={EndAdornment}
118
127
  ariaLabel={t(label) || ''}
119
128
  autoFocus={autoFocus}
@@ -36,6 +36,7 @@ import CheckboxGroup from './CheckboxGroup';
36
36
  import ConnectedAutocomplete from './ConnectedAutocomplete';
37
37
  import Custom from './Custom';
38
38
  import FieldsTable from './FieldsTable/FieldsTable';
39
+ import File from './File';
39
40
  import Grid from './Grid';
40
41
  import List from './List/List';
41
42
  import LoadingSkeleton from './LoadingSkeleton';
@@ -78,6 +79,7 @@ export const getInput = cond<
78
79
  always(CheckboxGroup)
79
80
  ],
80
81
  [equals(InputType.List) as (b: InputType) => boolean, always(List)],
82
+ [equals(InputType.File) as (b: InputType) => boolean, always(File)],
81
83
  [T, always(TextInput)]
82
84
  ]);
83
85
 
@@ -113,7 +115,8 @@ const useStyles = makeStyles<StylesProps>()((theme, { groupDirection }) => ({
113
115
  display: 'flex',
114
116
  flexDirection: 'column',
115
117
  marginTop: theme.spacing(1),
116
- rowGap: theme.spacing(2)
118
+ rowGap: theme.spacing(2),
119
+ marginBottom: theme.spacing(1)
117
120
  }
118
121
  }));
119
122
 
@@ -165,7 +168,7 @@ const Inputs = ({
165
168
  );
166
169
 
167
170
  return pluck('name', usedGroups);
168
- }, []);
171
+ }, [inputsByGroup, groups]);
169
172
 
170
173
  const sortedInputsByGroup = useMemo(
171
174
  () =>
@@ -19,7 +19,8 @@ export enum InputType {
19
19
  Custom = 10,
20
20
  Checkbox = 11,
21
21
  CheckboxGroup = 12,
22
- List = 13
22
+ List = 13,
23
+ File = 14
23
24
  }
24
25
 
25
26
  interface FieldsTableGetRequiredProps {
@@ -37,8 +38,16 @@ export interface InputProps {
37
38
  autocomplete?: {
38
39
  creatable?: boolean;
39
40
  options: Array<SelectEntry>;
41
+ fullWidth?: boolean;
40
42
  };
41
- change?: ({ setFieldValue, value, setFieldTouched }) => void;
43
+ change?: ({
44
+ setFieldValue,
45
+ value,
46
+ setFieldTouched,
47
+ setValues,
48
+ values,
49
+ setTouched
50
+ }) => void;
42
51
  checkbox?: {
43
52
  direction?: 'horizontal' | 'vertical';
44
53
  labelPlacement?: LabelPlacement;
@@ -51,6 +60,12 @@ export interface InputProps {
51
60
  filterKey?: string;
52
61
  getRenderedOptionText?: (option) => string | JSX.Element;
53
62
  };
63
+ file?: {
64
+ multiple?: boolean;
65
+ accept?: string;
66
+ maxFileSize?: number;
67
+ CustomDropZoneContent: ({ files }) => JSX.Element;
68
+ };
54
69
  custom?: {
55
70
  Component: React.ComponentType<InputPropsWithoutGroup>;
56
71
  };
@@ -103,6 +118,7 @@ export interface InputProps {
103
118
  placeholder?: string;
104
119
  type?: string;
105
120
  min?: number;
121
+ fullWidth?: boolean;
106
122
  };
107
123
  type: InputType;
108
124
  }
@@ -8,7 +8,7 @@ import { Typography } from '@mui/material';
8
8
  import { SelectEntry } from '../InputField/Select';
9
9
  import { Listing } from '../api/models';
10
10
 
11
- import { array, boolean, number, object, string } from 'yup';
11
+ import { array, boolean, mixed, number, object, string } from 'yup';
12
12
  import {
13
13
  Group,
14
14
  InputProps,
@@ -78,7 +78,8 @@ export const basicFormValidationSchema = object().shape({
78
78
  })
79
79
  ),
80
80
  scopes: array().of(string().min(3, '3 characters min').required('Required')),
81
- sports: array().of(selectEntryValidationSchema.required('Required'))
81
+ sports: array().of(selectEntryValidationSchema.required('Required')),
82
+ file: mixed()
82
83
  });
83
84
 
84
85
  const roleEntries: Array<SelectEntry> = [
@@ -134,7 +135,8 @@ export const basicFormInitialValues = {
134
135
  }
135
136
  ],
136
137
  scopes: [],
137
- sports: []
138
+ sports: [],
139
+ file: null
138
140
  };
139
141
 
140
142
  export const classOptions = [...Array(10).keys()].map((idx) => ({
@@ -444,6 +446,16 @@ export const basicFormInputs: Array<InputProps> = [
444
446
  multilineRows: 4
445
447
  },
446
448
  type: InputType.Text
449
+ },
450
+ {
451
+ fieldName: 'file',
452
+ group: 'First group',
453
+ label: 'File',
454
+ type: InputType.File,
455
+ file: {
456
+ accept: 'image/*',
457
+ multiple: true
458
+ }
447
459
  }
448
460
  ];
449
461
 
@@ -5,3 +5,4 @@ export const labelSaved = 'Saved';
5
5
  export const labelReset = 'Reset';
6
6
  export const labelDisplayThePassword = 'Display the password';
7
7
  export const labelHideThePassword = 'Hide the password';
8
+ export const labelDropOrSelectAFile = 'Drop or select a file';
@@ -38,6 +38,7 @@ export interface BarChartProps
38
38
  start: string;
39
39
  thresholdUnit?: string;
40
40
  thresholds?: Thresholds;
41
+ skipIntersectionObserver?: boolean;
41
42
  }
42
43
 
43
44
  const BarChart = ({
@@ -57,7 +58,8 @@ const BarChart = ({
57
58
  barStyle = {
58
59
  opacity: 1,
59
60
  radius: 0.2
60
- }
61
+ },
62
+ skipIntersectionObserver
61
63
  }: BarChartProps): JSX.Element => {
62
64
  const { adjustedData } = useChartData({ data, end, start });
63
65
  const lineChartRef = useRef<HTMLDivElement | null>(null);
@@ -93,6 +95,7 @@ const BarChart = ({
93
95
  thresholds={thresholds}
94
96
  tooltip={tooltip}
95
97
  width={width}
98
+ skipIntersectionObserver={skipIntersectionObserver}
96
99
  />
97
100
  )}
98
101
  </ParentSize>
@@ -54,7 +54,8 @@ const ResponsiveBarChart = ({
54
54
  limitLegend,
55
55
  orientation,
56
56
  tooltip,
57
- barStyle
57
+ barStyle,
58
+ skipIntersectionObserver
58
59
  }: Props): JSX.Element => {
59
60
  const { title, timeSeries, baseAxis, lines } = graphData;
60
61
 
@@ -149,7 +150,7 @@ const ResponsiveBarChart = ({
149
150
  [axis?.showGridLines]
150
151
  );
151
152
 
152
- if (!isInViewport) {
153
+ if (!isInViewport && !skipIntersectionObserver) {
153
154
  return (
154
155
  <Skeleton
155
156
  height={graphSvgRef?.current?.clientHeight ?? graphHeight}
@@ -56,6 +56,10 @@ interface Props extends LineChartProps {
56
56
  shapeLines?: GlobalAreaLines;
57
57
  thresholdUnit?: string;
58
58
  thresholds?: ThresholdsModel;
59
+ transformMatrix?: {
60
+ fx?: (pointX: number) => number;
61
+ fy?: (pointY: number) => number;
62
+ }
59
63
  }
60
64
 
61
65
  const filterLines = (lines: Array<Line>, displayThreshold): Array<Line> => {
@@ -97,7 +101,9 @@ const Chart = ({
97
101
  },
98
102
  thresholds,
99
103
  thresholdUnit,
100
- limitLegend
104
+ limitLegend,
105
+ skipIntersectionObserver,
106
+ transformMatrix
101
107
  }: Props): JSX.Element => {
102
108
  const { classes } = useChartStyles();
103
109
 
@@ -219,7 +225,7 @@ const Chart = ({
219
225
  [axis?.showGridLines]
220
226
  );
221
227
 
222
- if (!isInViewport) {
228
+ if (!isInViewport && !skipIntersectionObserver) {
223
229
  return (
224
230
  <Skeleton
225
231
  height={graphSvgRef?.current?.clientHeight ?? graphHeight}
@@ -319,6 +325,7 @@ const Chart = ({
319
325
  graphInterval
320
326
  }}
321
327
  zoomData={{ ...zoomPreview }}
328
+ transformMatrix={transformMatrix}
322
329
  />
323
330
  {thresholds?.enabled && (
324
331
  <Thresholds
@@ -58,10 +58,10 @@ const useTickGraph = ({
58
58
  return;
59
59
  }
60
60
  const mousePositionTimeTick = mousePosition
61
- ? getTimeValue({ timeSeries, x: mousePosition[0], xScale }).timeTick
61
+ ? getTimeValue({ timeSeries, x: mousePosition[0], xScale })?.timeTick
62
62
  : 0;
63
63
  const timeTickValue = mousePosition
64
- ? new Date(mousePositionTimeTick)
64
+ ? new Date(mousePositionTimeTick || 0)
65
65
  : null;
66
66
 
67
67
  setTickAxisBottom(timeTickValue);
@@ -76,13 +76,18 @@ interface Props {
76
76
  commonData: CommonData;
77
77
  timeShiftZonesData: TimeShiftZonesData;
78
78
  zoomData: ZoomPreviewModel;
79
+ transformMatrix?: {
80
+ fx?: (pointX: number) => number;
81
+ fy?: (pointY: number) => number;
82
+ }
79
83
  }
80
84
 
81
85
  const InteractionWithGraph = ({
82
86
  zoomData,
83
87
  commonData,
84
88
  annotationData,
85
- timeShiftZonesData
89
+ timeShiftZonesData,
90
+ transformMatrix
86
91
  }: Props): JSX.Element => {
87
92
  const { classes } = useStyles();
88
93
 
@@ -127,7 +132,10 @@ const InteractionWithGraph = ({
127
132
  if (!mousePoint) {
128
133
  return;
129
134
  }
130
- updateMousePosition([mousePoint.x, mousePoint.y]);
135
+ updateMousePosition([
136
+ transformMatrix?.fx?.(mousePoint.x) ?? mousePoint.x,
137
+ transformMatrix?.fy?.(mousePoint.y) ?? mousePoint.y
138
+ ]);
131
139
  };
132
140
 
133
141
  const mouseDown = (event): void => {
@@ -2,15 +2,15 @@ import dayjs from 'dayjs';
2
2
  import durationPlugin from 'dayjs/plugin/duration';
3
3
  import { gt, gte, isEmpty, isNil, prop, propEq, reject, sortBy } from 'ramda';
4
4
 
5
- import { LineChartData } from '../../common/models';
5
+ import type { LineChartData } from '../../common/models';
6
6
  import {
7
7
  getLineData,
8
8
  getTimeSeries,
9
9
  getTimeValue
10
10
  } from '../../common/timeSeries';
11
- import { LinesData } from '../BasicComponents/Lines/models';
11
+ import type { LinesData } from '../BasicComponents/Lines/models';
12
12
  import { dateFormat, timeFormat } from '../common';
13
- import { GetDate, GraphInterval } from '../models';
13
+ import type { GetDate, GraphInterval } from '../models';
14
14
 
15
15
  dayjs.extend(durationPlugin);
16
16
 
@@ -56,11 +56,11 @@ export const displayArea = (data: unknown): boolean =>
56
56
  !isEmpty(data) && !isNil(data);
57
57
 
58
58
  export const getDate = ({ positionX, xScale, timeSeries }: GetDate): Date => {
59
- const { timeTick } = getTimeValue({
59
+ const timeValue = getTimeValue({
60
60
  timeSeries,
61
61
  x: positionX,
62
62
  xScale
63
63
  });
64
64
 
65
- return new Date(timeTick);
65
+ return new Date(timeValue?.timeTick || 0);
66
66
  };
@@ -34,6 +34,10 @@ interface Props extends Partial<LineChartProps> {
34
34
  thresholds?: Thresholds;
35
35
  getRef?: (ref: MutableRefObject<HTMLDivElement | null>) => void;
36
36
  containerStyle?: string;
37
+ transformMatrix?: {
38
+ fx?: (pointX: number) => number;
39
+ fy?: (pointY: number) => number;
40
+ }
37
41
  }
38
42
 
39
43
  const WrapperChart = ({
@@ -65,6 +69,7 @@ const WrapperChart = ({
65
69
  thresholdUnit,
66
70
  limitLegend,
67
71
  getRef,
72
+ transformMatrix,
68
73
  ...rest
69
74
  }: Props): JSX.Element | null => {
70
75
  const { classes, cx } = useChartStyles();
@@ -120,6 +125,8 @@ const WrapperChart = ({
120
125
  tooltip={tooltip}
121
126
  width={width ?? responsiveWidth}
122
127
  zoomPreview={zoomPreview}
128
+ skipIntersectionObserver={rest.skipIntersectionObserver}
129
+ transformMatrix={transformMatrix}
123
130
  />
124
131
  );
125
132
  }}
@@ -120,6 +120,7 @@ export interface LineChartProps {
120
120
  tooltip?: Tooltip;
121
121
  width: number;
122
122
  zoomPreview?: InteractedZone;
123
+ skipIntersectionObserver?: boolean;
123
124
  }
124
125
 
125
126
  export interface Area {
@@ -14,6 +14,7 @@ import {
14
14
  filter,
15
15
  find,
16
16
  flatten,
17
+ gt,
17
18
  head,
18
19
  identity,
19
20
  includes,
@@ -298,13 +299,17 @@ const getTimeSeriesForLines = ({
298
299
  return map(
299
300
  ({ timeTick, ...metricsValue }): TimeValue => ({
300
301
  ...reduce(
301
- (acc, metric_id): Omit<TimeValue, 'timePick'> => ({
302
- ...acc,
303
- [metric_id]:
304
- invert && metricsValue[metric_id]
305
- ? negate(metricsValue[metric_id])
306
- : metricsValue[metric_id]
307
- }),
302
+ (acc, metric_id): Omit<TimeValue, 'timePick'> => {
303
+ return {
304
+ ...acc,
305
+ [metric_id]:
306
+ invert &&
307
+ metricsValue[metric_id] &&
308
+ gt(metricsValue[metric_id], 0)
309
+ ? negate(metricsValue[metric_id])
310
+ : metricsValue[metric_id]
311
+ };
312
+ },
308
313
  {},
309
314
  metrics
310
315
  ),
@@ -363,7 +368,9 @@ const getScale = ({
363
368
  const isLogScale = equals(scale, 'logarithmic');
364
369
  const minValue = Math.min(
365
370
  hasDisplayAsBar && 0,
366
- invert ? negate(getMax(graphValues)) : getMin(graphValues),
371
+ invert && graphValues.every(lt(0))
372
+ ? negate(getMax(graphValues))
373
+ : getMin(graphValues),
367
374
  getMin(stackedValues),
368
375
  Math.min(...thresholds)
369
376
  );
@@ -77,7 +77,7 @@ const OptionalLabelInputAdornment = ({
77
77
  type SizeVariant = 'large' | 'medium' | 'small' | 'compact';
78
78
 
79
79
  export type TextProps = {
80
- EndAdornment?: React.FC;
80
+ EndAdornment?: React.FC | JSX.Element;
81
81
  StartAdornment?: React.FC;
82
82
  ariaLabel?: string;
83
83
  autoSize?: boolean;
@@ -139,6 +139,7 @@ export interface Props<TRow> {
139
139
  totalRows?: number;
140
140
  viewerModeConfiguration?: ViewerModeConfiguration;
141
141
  widthToMoveTablePagination?: number;
142
+ isActionBarVisible: boolean;
142
143
  }
143
144
 
144
145
  const defaultColumnConfiguration = {
@@ -147,7 +148,13 @@ const defaultColumnConfiguration = {
147
148
 
148
149
  export const performanceRowsLimit = 60;
149
150
 
150
- const Listing = <TRow extends { id: RowId; internalListingParentId?: RowId }>({
151
+ const Listing = <
152
+ TRow extends {
153
+ id: RowId;
154
+ internalListingParentId?: RowId;
155
+ internalListingParentRow: TRow;
156
+ }
157
+ >({
151
158
  customListingComponent,
152
159
  displayCustomListing,
153
160
  limit = 10,
@@ -191,7 +198,8 @@ const Listing = <TRow extends { id: RowId; internalListingParentId?: RowId }>({
191
198
  getRowProperty: () => '',
192
199
  labelCollapse: 'Collapse',
193
200
  labelExpand: 'Expand'
194
- }
201
+ },
202
+ isActionBarVisible = true
195
203
  }: Props<TRow>): JSX.Element => {
196
204
  const currentVisibleColumns = getVisibleColumns({
197
205
  columnConfiguration,
@@ -246,7 +254,8 @@ const Listing = <TRow extends { id: RowId; internalListingParentId?: RowId }>({
246
254
  row,
247
255
  ...row[subItems.getRowProperty()].map((subRow) => ({
248
256
  ...subRow,
249
- internalListingParentId: row.id
257
+ internalListingParentId: row.id,
258
+ internalListingParentRow: row
250
259
  }))
251
260
  ];
252
261
  }
@@ -517,30 +526,33 @@ const Listing = <TRow extends { id: RowId; internalListingParentId?: RowId }>({
517
526
  className={classes.container}
518
527
  ref={containerRef as RefObject<HTMLDivElement>}
519
528
  >
520
- <div
521
- className={classes.actionBar}
522
- ref={actionBarRef as RefObject<HTMLDivElement>}
523
- >
524
- <ListingActionBar
525
- actions={actions}
526
- actionsBarMemoProps={actionsBarMemoProps}
527
- columnConfiguration={columnConfiguration}
528
- columns={columns}
529
- currentPage={currentPage}
530
- customPaginationClassName={customPaginationClassName}
531
- limit={limit}
532
- listingVariant={listingVariant}
533
- moveTablePagination={moveTablePagination}
534
- paginated={paginated}
535
- totalRows={totalRows}
536
- viewerModeConfiguration={viewerModeConfiguration}
537
- widthToMoveTablePagination={widthToMoveTablePagination}
538
- onLimitChange={changeLimit}
539
- onPaginate={onPaginate}
540
- onResetColumns={onResetColumns}
541
- onSelectColumns={onSelectColumns}
542
- />
543
- </div>
529
+ {
530
+ isActionBarVisible &&
531
+ <div
532
+ className={classes.actionBar}
533
+ ref={actionBarRef as RefObject<HTMLDivElement>}
534
+ >
535
+ <ListingActionBar
536
+ actions={actions}
537
+ actionsBarMemoProps={actionsBarMemoProps}
538
+ columnConfiguration={columnConfiguration}
539
+ columns={columns}
540
+ currentPage={currentPage}
541
+ customPaginationClassName={customPaginationClassName}
542
+ limit={limit}
543
+ listingVariant={listingVariant}
544
+ moveTablePagination={moveTablePagination}
545
+ paginated={paginated}
546
+ totalRows={totalRows}
547
+ viewerModeConfiguration={viewerModeConfiguration}
548
+ widthToMoveTablePagination={widthToMoveTablePagination}
549
+ onLimitChange={changeLimit}
550
+ onPaginate={onPaginate}
551
+ onResetColumns={onResetColumns}
552
+ onSelectColumns={onSelectColumns}
553
+ />
554
+ </div>
555
+ }
544
556
 
545
557
  <ParentSize
546
558
  parentSizeStyles={{
@@ -76,3 +76,11 @@ export interface TableStyleAtom {
76
76
  width: number;
77
77
  };
78
78
  }
79
+
80
+ export interface ListingSubItems {
81
+ canCheckSubItems: boolean;
82
+ enable: boolean;
83
+ getRowProperty: (row?) => string;
84
+ labelCollapse: string;
85
+ labelExpand: string;
86
+ }
@@ -134,8 +134,6 @@ const MultiSelectEntries = ({
134
134
  [classes.container]: true
135
135
  } as CxArg)}
136
136
  ref={hoverRef as Ref<HTMLDivElement>}
137
- role="button"
138
- tabIndex={0}
139
137
  onClick={onClick}
140
138
  onKeyDown={onClick}
141
139
  >
@@ -10,6 +10,7 @@ import {
10
10
  } from '@mui/material';
11
11
  import type { PopperProps } from '@mui/material/Popper';
12
12
 
13
+ import { equals, type } from 'ramda';
13
14
  import { IconButton } from '..';
14
15
 
15
16
  const useStyles = makeStyles()((theme) => ({
@@ -29,8 +30,9 @@ interface PopoverData {
29
30
 
30
31
  interface Props {
31
32
  canOpen?: boolean;
32
- children: (props?) => JSX.Element;
33
+ children: (props?) => JSX.Element | JSX.Element;
33
34
  className?: string;
35
+ tooltipClassName?: string;
34
36
  dataTestId?: string;
35
37
  getPopoverData?: (data: PopoverData) => void;
36
38
  icon: JSX.Element;
@@ -52,6 +54,7 @@ const PopoverMenu = ({
52
54
  className,
53
55
  dataTestId,
54
56
  getPopoverData,
57
+ tooltipClassName,
55
58
  popperProps
56
59
  }: Props): JSX.Element => {
57
60
  const { classes, cx } = useStyles();
@@ -113,7 +116,11 @@ const PopoverMenu = ({
113
116
  onResizeCapture={(): undefined => undefined}
114
117
  {...popperProps}
115
118
  >
116
- <Paper>{children({ close })}</Paper>
119
+ <Paper className={tooltipClassName}>
120
+ {equals(type(children), 'Function')
121
+ ? children({ close })
122
+ : children}
123
+ </Paper>
117
124
  </Popper>
118
125
  </ClickAwayListener>
119
126
  )}
@@ -185,6 +185,7 @@ const SortableItems = <T extends { [propertyToFilterItemsOn]: string }>({
185
185
  >
186
186
  <SortableContext items={sortableItemsIds} strategy={sortingStrategy}>
187
187
  <RootComponent>
188
+ {/* biome-ignore lint: */}
188
189
  <>
189
190
  {sortableItemsIds.map((sortableItemId, index) => {
190
191
  const item = getItemById(sortableItemId) as