@centreon/ui 24.4.48 → 24.4.49

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 (137) hide show
  1. package/package.json +36 -29
  2. package/public/mockServiceWorker.js +1 -1
  3. package/src/Button/Icon/index.tsx +1 -1
  4. package/src/Button/Save/StartIcon.tsx +3 -3
  5. package/src/Button/Save/index.tsx +9 -5
  6. package/src/Checkbox/Checkbox.tsx +2 -2
  7. package/src/Checkbox/CheckboxGroup/index.tsx +2 -2
  8. package/src/Dashboard/Item.tsx +1 -1
  9. package/src/Dashboard/Layout.tsx +2 -2
  10. package/src/Dialog/Confirm/index.tsx +10 -2
  11. package/src/Dialog/index.tsx +9 -2
  12. package/src/FallbackPage/FallbackPage.tsx +3 -3
  13. package/src/FileDropZone/index.tsx +3 -1
  14. package/src/Form/Form.cypress.spec.tsx +133 -0
  15. package/src/Form/Inputs/List/Content.tsx +62 -0
  16. package/src/Form/Inputs/List/List.styles.ts +29 -0
  17. package/src/Form/Inputs/List/List.tsx +58 -0
  18. package/src/Form/Inputs/List/useList.ts +81 -0
  19. package/src/Form/Inputs/index.tsx +3 -1
  20. package/src/Form/Inputs/models.ts +9 -1
  21. package/src/Graph/BarStack/BarStack.cypress.spec.tsx +154 -0
  22. package/src/Graph/BarStack/BarStack.stories.tsx +123 -0
  23. package/src/Graph/BarStack/BarStack.styles.ts +36 -0
  24. package/src/Graph/BarStack/BarStack.tsx +14 -0
  25. package/src/Graph/BarStack/ResponsiveBarStack.tsx +208 -0
  26. package/src/Graph/BarStack/index.ts +1 -0
  27. package/src/Graph/BarStack/models.ts +19 -0
  28. package/src/Graph/BarStack/useResponsiveBarStack.ts +139 -0
  29. package/src/Graph/Gauge/Gauge.cypress.spec.tsx +102 -0
  30. package/src/Graph/Gauge/Gauge.tsx +1 -1
  31. package/src/Graph/HeatMap/HeatMap.cypress.spec.tsx +145 -0
  32. package/src/Graph/HeatMap/HeatMap.stories.tsx +0 -25
  33. package/src/Graph/HeatMap/ResponsiveHeatMap.tsx +8 -2
  34. package/src/Graph/Legend/Legend.tsx +21 -0
  35. package/src/Graph/Legend/index.ts +1 -0
  36. package/src/Graph/Legend/models.ts +11 -0
  37. package/src/Graph/LineChart/BasicComponents/Lines/Threshold/Circle.tsx +2 -2
  38. package/src/Graph/LineChart/BasicComponents/Thresholds.tsx +2 -2
  39. package/src/Graph/LineChart/BasicComponents/useFilterLines.ts +1 -1
  40. package/src/Graph/LineChart/InteractiveComponents/AnchorPoint/GuidingLines.tsx +2 -2
  41. package/src/Graph/LineChart/InteractiveComponents/Annotations/EventAnnotations.tsx +1 -1
  42. package/src/Graph/LineChart/Legend/Legend.styles.ts +1 -1
  43. package/src/Graph/LineChart/Legend/LegendHeader.tsx +1 -1
  44. package/src/Graph/LineChart/Legend/useInteractiveValues.ts +2 -2
  45. package/src/Graph/LineChart/Legend/useLegend.ts +3 -3
  46. package/src/Graph/LineChart/helpers/doc.ts +16 -13
  47. package/src/Graph/LineChart/helpers/index.ts +1 -1
  48. package/src/Graph/LineChart/index.stories.tsx +4 -2
  49. package/src/Graph/LineChart/index.tsx +1 -1
  50. package/src/Graph/PieChart/PieChart.cypress.spec.tsx +169 -0
  51. package/src/Graph/PieChart/PieChart.stories.tsx +194 -0
  52. package/src/Graph/PieChart/PieChart.styles.ts +39 -0
  53. package/src/Graph/PieChart/PieChart.tsx +14 -0
  54. package/src/Graph/PieChart/ResponsivePie.tsx +251 -0
  55. package/src/Graph/PieChart/index.ts +1 -0
  56. package/src/Graph/PieChart/models.ts +19 -0
  57. package/src/Graph/PieChart/useResponsivePie.ts +86 -0
  58. package/src/Graph/SingleBar/SingleBar.cypress.spec.tsx +121 -0
  59. package/src/Graph/SingleBar/Thresholds.tsx +2 -2
  60. package/src/Graph/Text/Text.cypress.spec.tsx +101 -0
  61. package/src/Graph/Text/Text.stories.tsx +60 -4
  62. package/src/Graph/Text/Text.tsx +1 -1
  63. package/src/Graph/common/testUtils.ts +71 -0
  64. package/src/Graph/common/timeSeries/index.ts +22 -14
  65. package/src/Graph/common/utils.ts +19 -0
  66. package/src/Graph/index.ts +3 -0
  67. package/src/Graph/translatedLabels.ts +1 -0
  68. package/src/InputField/Select/Autocomplete/Connected/index.tsx +10 -7
  69. package/src/InputField/Select/Autocomplete/Draggable/SortableList.tsx +1 -1
  70. package/src/InputField/Select/Autocomplete/Draggable/SortableListContent.tsx +1 -1
  71. package/src/InputField/Select/Autocomplete/Draggable/index.tsx +1 -1
  72. package/src/InputField/Select/Autocomplete/index.tsx +121 -115
  73. package/src/InputField/Select/IconPopover/index.tsx +2 -2
  74. package/src/InputField/Select/index.tsx +1 -1
  75. package/src/InputField/Text/index.tsx +2 -2
  76. package/src/Listing/ActionBar/index.tsx +9 -8
  77. package/src/Listing/Cell/DataCell.styles.ts +3 -0
  78. package/src/Listing/Cell/DataCell.tsx +23 -5
  79. package/src/Listing/Header/ListingHeader.tsx +1 -1
  80. package/src/Listing/Listing.cypress.spec.tsx +80 -4
  81. package/src/Listing/Listing.styles.ts +4 -7
  82. package/src/Listing/index.stories.tsx +37 -3
  83. package/src/Listing/index.test.tsx +1 -1
  84. package/src/Listing/index.tsx +4 -3
  85. package/src/Listing/models.ts +1 -0
  86. package/src/Module/Module.cypress.spec.tsx +129 -0
  87. package/src/Module/index.tsx +2 -4
  88. package/src/RichTextEditor/RichTextEditor.tsx +12 -1
  89. package/src/SortableItems/index.tsx +2 -7
  90. package/src/ThemeProvider/index.tsx +24 -0
  91. package/src/TimePeriods/CustomTimePeriod/CompactCustomTimePeriod.styles.ts +6 -7
  92. package/src/TimePeriods/CustomTimePeriod/PopoverCustomTimePeriod/PickersStartEndDate.tsx +8 -3
  93. package/src/TimePeriods/CustomTimePeriod/PopoverCustomTimePeriod/models.ts +0 -2
  94. package/src/TimePeriods/DateTimePickerInput.tsx +56 -19
  95. package/src/TimePeriods/ResolutionTimePeriod.cypress.spec.tsx +12 -9
  96. package/src/TimePeriods/TimePeriods.cypress.spec.tsx +9 -33
  97. package/src/TimePeriods/helpers/index.ts +1 -1
  98. package/src/TimePeriods/index.stories.tsx +12 -4
  99. package/src/TimePeriods/index.tsx +2 -2
  100. package/src/api/QueryProvider.tsx +1 -1
  101. package/src/api/TestQueryProvider.tsx +1 -1
  102. package/src/api/useFetchQuery/index.ts +27 -23
  103. package/src/api/useMutationQuery/index.test.ts +4 -4
  104. package/src/api/useMutationQuery/index.ts +60 -25
  105. package/src/components/Button/Icon/IconButton.tsx +6 -2
  106. package/src/components/DataTable/DataListing.tsx +6 -0
  107. package/src/components/DataTable/DataTable.cypress.spec.tsx +193 -0
  108. package/src/components/DataTable/DataTable.stories.tsx +40 -0
  109. package/src/components/DataTable/DataTable.styles.ts +3 -0
  110. package/src/components/DataTable/DataTable.tsx +3 -3
  111. package/src/components/DataTable/Item/DataTableItem.styles.ts +7 -2
  112. package/src/components/DataTable/Item/DataTableItem.tsx +4 -4
  113. package/src/components/DataTable/index.ts +3 -1
  114. package/src/components/Form/AccessRights/ShareInput/ContactSwitch.tsx +3 -3
  115. package/src/components/Form/AccessRights/ShareInput/ShareInput.tsx +1 -0
  116. package/src/components/Form/Dashboard/DashboardForm.tsx +15 -12
  117. package/src/components/Layout/PageLayout/PageLayout.tsx +1 -1
  118. package/src/components/Layout/PageLayout/PageLayoutActions.tsx +1 -0
  119. package/src/components/Layout/PageLayout/PageLayoutBody.tsx +1 -0
  120. package/src/components/Layout/PageLayout/PageLayoutHeader.tsx +5 -1
  121. package/src/components/Layout/PageLayout/PageQuickAccess.tsx +76 -0
  122. package/src/components/Layout/PageLayout/index.ts +3 -1
  123. package/src/components/Layout/PageLayout.cypress.spec.tsx +66 -0
  124. package/src/components/Modal/Modal.styles.ts +1 -1
  125. package/src/components/Tooltip/ConfirmationTooltip/ConfirmationTooltip.stories.tsx +3 -3
  126. package/src/components/Tooltip/ConfirmationTooltip/ConfirmationTooltip.tsx +1 -1
  127. package/src/components/Tooltip/ConfirmationTooltip/models.ts +1 -1
  128. package/src/index.ts +2 -2
  129. package/src/queryParameters/url/index.ts +5 -1
  130. package/src/utils/index.ts +1 -1
  131. package/src/utils/useFullscreen/useFullscreenListener.ts +10 -7
  132. package/src/utils/{useLicenseExpirationWarning.cypress.spec.tsx → useLicenseExpirationWarning.test.tsx} +48 -37
  133. package/src/utils/useLicenseExpirationWarning.ts +18 -18
  134. package/src/utils/usePluralizedTranslation.ts +21 -0
  135. package/src/screens/dashboard/DashboardsDetail.stories.tsx +0 -108
  136. package/src/screens/dashboard/DashboardsOverview.stories.tsx +0 -281
  137. package/src/utils/useDateTimePickerAdapter.ts +0 -309
@@ -0,0 +1,71 @@
1
+ export const successThresholds = {
2
+ critical: [
3
+ {
4
+ label: 'Critical',
5
+ value: 1.5
6
+ }
7
+ ],
8
+ enabled: true,
9
+ warning: [
10
+ {
11
+ label: 'Warning',
12
+ value: 0.5
13
+ }
14
+ ]
15
+ };
16
+
17
+ export const warningThresholds = {
18
+ critical: [
19
+ {
20
+ label: 'Critical',
21
+ value: 1.5
22
+ }
23
+ ],
24
+ enabled: true,
25
+ warning: [
26
+ {
27
+ label: 'Warning',
28
+ value: 0.4
29
+ }
30
+ ]
31
+ };
32
+
33
+ export const criticalThresholds = {
34
+ critical: [
35
+ {
36
+ label: 'Critical',
37
+ value: 0.3
38
+ }
39
+ ],
40
+ enabled: true,
41
+ warning: [
42
+ {
43
+ label: 'Warning',
44
+ value: 0.2
45
+ }
46
+ ]
47
+ };
48
+
49
+ export const rangedThresholds = {
50
+ critical: [
51
+ {
52
+ label: 'Critical',
53
+ value: 0.55
54
+ },
55
+ {
56
+ label: 'Critical',
57
+ value: 0.65
58
+ }
59
+ ],
60
+ enabled: true,
61
+ warning: [
62
+ {
63
+ label: 'Warning',
64
+ value: 0.13
65
+ },
66
+ {
67
+ label: 'Warning',
68
+ value: 0.5
69
+ }
70
+ ]
71
+ };
@@ -179,7 +179,7 @@ const getMetricValuesForUnit = ({
179
179
  ) as Array<number>;
180
180
 
181
181
  return pipe(
182
- filter(propEq('unit', unit)) as (line) => Array<Line>,
182
+ filter(propEq(unit, 'unit')) as (line) => Array<Line>,
183
183
  map(prop('metric_id')),
184
184
  map(getTimeSeriesValuesForMetric),
185
185
  flatten,
@@ -203,7 +203,7 @@ const getLineForMetric = ({
203
203
  lines,
204
204
  metric_id
205
205
  }: LineForMetricProps): Line | undefined =>
206
- find(propEq('metric_id', metric_id), lines);
206
+ find(propEq(metric_id, 'metric_id'), lines);
207
207
 
208
208
  interface LinesTimeSeries {
209
209
  lines: Array<Line>;
@@ -275,7 +275,7 @@ interface HasStackedLines {
275
275
  }
276
276
 
277
277
  const hasUnitStackedLines = ({ lines, unit }: HasStackedLines): boolean =>
278
- pipe(getSortedStackedLines, any(propEq('unit', unit)))(lines);
278
+ pipe(getSortedStackedLines, any(propEq(unit, 'unit')))(lines);
279
279
 
280
280
  const getTimeSeriesForLines = ({
281
281
  lines,
@@ -476,15 +476,7 @@ const registerMsUnitToNumeral = (): null => {
476
476
 
477
477
  registerMsUnitToNumeral();
478
478
 
479
- const formatMetricValue = ({
480
- value,
481
- unit,
482
- base = 1000
483
- }: FormatMetricValueProps): string | null => {
484
- if (isNil(value)) {
485
- return null;
486
- }
487
-
479
+ const getBase1024 = ({ unit, base }): boolean => {
488
480
  const base2Units = [
489
481
  'B',
490
482
  'bytes',
@@ -497,7 +489,19 @@ const formatMetricValue = ({
497
489
  'b'
498
490
  ];
499
491
 
500
- const base1024 = base2Units.includes(unit) || Number(base) === 1024;
492
+ return base2Units.includes(unit) || Number(base) === 1024;
493
+ };
494
+
495
+ const formatMetricValue = ({
496
+ value,
497
+ unit,
498
+ base = 1000
499
+ }: FormatMetricValueProps): string | null => {
500
+ if (isNil(value)) {
501
+ return null;
502
+ }
503
+
504
+ const base1024 = getBase1024({ base, unit });
501
505
 
502
506
  const formatSuffix = cond([
503
507
  [equals('ms'), always(' ms')],
@@ -525,6 +529,8 @@ const formatMetricValueWithUnit = ({
525
529
  return null;
526
530
  }
527
531
 
532
+ const base1024 = getBase1024({ base, unit });
533
+
528
534
  if (isRaw) {
529
535
  const unitText = equals('%', unit) ? unit : ` ${unit}`;
530
536
 
@@ -537,7 +543,9 @@ const formatMetricValueWithUnit = ({
537
543
 
538
544
  const formattedMetricValue = formatMetricValue({ base, unit, value });
539
545
 
540
- return formattedMetricValue;
546
+ return base1024 || !unit || equals(unit, 'ms')
547
+ ? formattedMetricValue
548
+ : `${formattedMetricValue} ${unit}`;
541
549
  };
542
550
 
543
551
  const getStackedYScale = ({
@@ -11,6 +11,7 @@ import {
11
11
  lte,
12
12
  pluck
13
13
  } from 'ramda';
14
+ import numeral from 'numeral';
14
15
 
15
16
  import { Theme } from '@mui/material';
16
17
 
@@ -73,3 +74,21 @@ export const getColorFromDataAndTresholds = ({
73
74
  [T, always(theme.palette.error.main)]
74
75
  ])(data);
75
76
  };
77
+
78
+ interface ValueByUnitProps {
79
+ total: number;
80
+ unit: 'percentage' | 'number';
81
+ value: number;
82
+ }
83
+
84
+ export const getValueByUnit = ({
85
+ unit,
86
+ value,
87
+ total
88
+ }: ValueByUnitProps): string => {
89
+ if (equals(unit, 'number')) {
90
+ return numeral(value).format('0a').toUpperCase();
91
+ }
92
+
93
+ return `${((value * 100) / total).toFixed(1)}%`;
94
+ };
@@ -2,4 +2,7 @@ export { default as LineChart } from './LineChart';
2
2
  export { Gauge } from './Gauge';
3
3
  export { SingleBar } from './SingleBar';
4
4
  export { Text as GraphText } from './Text';
5
+
5
6
  export { HeatMap } from './HeatMap';
7
+ export { BarStack } from './BarStack';
8
+ export { PieChart } from './PieChart';
@@ -0,0 +1 @@
1
+ export const labelNoDataFound = 'No Data Available';
@@ -292,13 +292,16 @@ const ConnectedAutocompleteField = (
292
292
  }
293
293
  }, [optionsOpen]);
294
294
 
295
- useEffect(() => {
296
- setSearchParameter(
297
- !isEmpty(searchConditions)
298
- ? { conditions: searchConditions }
299
- : undefined
300
- );
301
- }, useDeepCompare([searchConditions]));
295
+ useEffect(
296
+ () => {
297
+ setSearchParameter(
298
+ !isEmpty(searchConditions)
299
+ ? { conditions: searchConditions }
300
+ : undefined
301
+ );
302
+ },
303
+ useDeepCompare([searchConditions])
304
+ );
302
305
 
303
306
  useEffect(() => {
304
307
  if (!autocompleteChangedValue && !props?.value) {
@@ -49,7 +49,7 @@ const SortableList = ({
49
49
  const dragEnd = ({ items: newItems }): void =>
50
50
  changeItemsOrder(
51
51
  map(
52
- (item) => find(propEq('id', item), items),
52
+ (item) => find(propEq(item, 'id'), items),
53
53
  newItems
54
54
  ) as Array<DraggableSelectEntry>
55
55
  );
@@ -49,7 +49,7 @@ const SortableListContent = ({
49
49
  return;
50
50
  }
51
51
 
52
- const itemIndex = findIndex(propEq('id', id), items);
52
+ const itemIndex = findIndex(propEq(id, 'id'), items);
53
53
 
54
54
  itemHover?.(null);
55
55
  itemClick?.({ index: itemIndex, item: { createOption, id, name } });
@@ -77,7 +77,7 @@ const DraggableAutocomplete = (
77
77
  const deleteValue = (id): void => {
78
78
  itemHover?.(null);
79
79
  setSelectedValues((values: Array<DraggableSelectEntry>) => {
80
- const index = findIndex(propEq('id', id), values);
80
+ const index = findIndex(propEq(id, 'id'), values);
81
81
 
82
82
  const newSelectedValues = remove(index, 1, values);
83
83
 
@@ -141,126 +141,132 @@ type Multiple = boolean;
141
141
  type DisableClearable = boolean;
142
142
  type FreeSolo = boolean;
143
143
 
144
- const AutocompleteField = ({
145
- options,
146
- label,
147
- placeholder,
148
- loading = false,
149
- onTextChange = (): void => undefined,
150
- endAdornment = undefined,
151
- inputValue,
152
- displayOptionThumbnail = false,
153
- required = false,
154
- error,
155
- displayPopupIcon = true,
156
- autoFocus = false,
157
- hideInput = false,
158
- dataTestId,
159
- autoSize = false,
160
- autoSizeDefaultWidth = 0,
161
- autoSizeCustomPadding,
162
- getOptionItemLabel = (option) => option.name,
163
- ...autocompleteProps
164
- }: Props): JSX.Element => {
165
- const { classes, cx } = useStyles({ hideInput });
166
- const { t } = useTranslation();
167
- const theme = useTheme();
144
+ const AutocompleteField = React.forwardRef(
145
+ (
146
+ {
147
+ options,
148
+ label,
149
+ placeholder,
150
+ loading = false,
151
+ onTextChange = (): void => undefined,
152
+ endAdornment = undefined,
153
+ inputValue,
154
+ displayOptionThumbnail = false,
155
+ required = false,
156
+ error,
157
+ displayPopupIcon = true,
158
+ autoFocus = false,
159
+ hideInput = false,
160
+ dataTestId,
161
+ autoSize = false,
162
+ autoSizeDefaultWidth = 0,
163
+ autoSizeCustomPadding,
164
+ getOptionItemLabel = (option) => option.name,
165
+ ...autocompleteProps
166
+ }: Props,
167
+ ref?: React.ForwardedRef<HTMLDivElement>
168
+ ): JSX.Element => {
169
+ const { classes, cx } = useStyles({ hideInput });
170
+ const { t } = useTranslation();
171
+ const theme = useTheme();
168
172
 
169
- const areSelectEntriesEqual = (option, value): boolean => {
170
- const identifyingProps = ['id', 'name'];
173
+ const areSelectEntriesEqual = (option, value): boolean => {
174
+ const identifyingProps = ['id', 'name'];
171
175
 
172
- return equals(
173
- pick(identifyingProps, option),
174
- pick(identifyingProps, value)
176
+ return equals(
177
+ pick(identifyingProps, option),
178
+ pick(identifyingProps, value)
179
+ );
180
+ };
181
+
182
+ const renderInput = (params): JSX.Element => (
183
+ <TextField
184
+ {...params}
185
+ InputLabelProps={{
186
+ classes: {
187
+ marginDense: classes.inputLabel,
188
+ shrink: classes.inputLabelShrink
189
+ }
190
+ }}
191
+ InputProps={{
192
+ ...params.InputProps,
193
+ endAdornment: (
194
+ <>
195
+ {endAdornment && (
196
+ <InputAdornment position="end">{endAdornment}</InputAdornment>
197
+ )}
198
+ {params.InputProps.endAdornment}
199
+ </>
200
+ ),
201
+ style: {
202
+ background: 'transparent',
203
+ paddingRight: theme.spacing(5)
204
+ }
205
+ }}
206
+ autoFocus={autoFocus}
207
+ autoSize={autoSize}
208
+ autoSizeCustomPadding={7 + (autoSizeCustomPadding || 0)}
209
+ autoSizeDefaultWidth={autoSizeDefaultWidth}
210
+ classes={{
211
+ root: classes.textfield
212
+ }}
213
+ error={error}
214
+ externalValueForAutoSize={autocompleteProps?.value?.name}
215
+ inputProps={{
216
+ ...params.inputProps,
217
+ 'aria-label': label,
218
+ 'data-testid': dataTestId || label,
219
+ id: getNormalizedId(label || '')
220
+ }}
221
+ label={label}
222
+ placeholder={isNil(placeholder) ? t(searchLabel) : placeholder}
223
+ required={required}
224
+ value={inputValue || undefined}
225
+ onChange={onTextChange}
226
+ />
175
227
  );
176
- };
177
228
 
178
- const renderInput = (params): JSX.Element => (
179
- <TextField
180
- {...params}
181
- InputLabelProps={{
182
- classes: {
183
- marginDense: classes.inputLabel,
184
- shrink: classes.inputLabelShrink
185
- }
186
- }}
187
- InputProps={{
188
- ...params.InputProps,
189
- endAdornment: (
190
- <>
191
- {endAdornment && (
192
- <InputAdornment position="end">{endAdornment}</InputAdornment>
193
- )}
194
- {params.InputProps.endAdornment}
195
- </>
196
- ),
197
- style: {
198
- background: 'transparent',
199
- paddingRight: theme.spacing(5)
229
+ return (
230
+ <Autocomplete
231
+ disableClearable
232
+ classes={{
233
+ groupLabel: classes.inputLabel,
234
+ inputRoot: cx([
235
+ classes.input,
236
+ label ? classes.inputWithLabel : classes.inputWithoutLabel
237
+ ]),
238
+ popper: classes.popper,
239
+ root: classes.textfield
240
+ }}
241
+ forcePopupIcon={displayPopupIcon}
242
+ getOptionLabel={(option): string =>
243
+ (option as SelectEntry)?.name?.toString() || ''
200
244
  }
201
- }}
202
- autoFocus={autoFocus}
203
- autoSize={autoSize}
204
- autoSizeCustomPadding={7 + (autoSizeCustomPadding || 0)}
205
- autoSizeDefaultWidth={autoSizeDefaultWidth}
206
- classes={{
207
- root: classes.textfield
208
- }}
209
- error={error}
210
- externalValueForAutoSize={autocompleteProps?.value?.name}
211
- inputProps={{
212
- ...params.inputProps,
213
- 'aria-label': label,
214
- 'data-testid': dataTestId || label,
215
- id: getNormalizedId(label || '')
216
- }}
217
- label={label}
218
- placeholder={isNil(placeholder) ? t(searchLabel) : placeholder}
219
- required={required}
220
- value={inputValue || undefined}
221
- onChange={onTextChange}
222
- />
223
- );
224
-
225
- return (
226
- <Autocomplete
227
- disableClearable
228
- classes={{
229
- groupLabel: classes.inputLabel,
230
- inputRoot: cx([
231
- classes.input,
232
- label ? classes.inputWithLabel : classes.inputWithoutLabel
233
- ]),
234
- popper: classes.popper,
235
- root: classes.textfield
236
- }}
237
- forcePopupIcon={displayPopupIcon}
238
- getOptionLabel={(option): string =>
239
- (option as SelectEntry)?.name?.toString() || ''
240
- }
241
- isOptionEqualToValue={areSelectEntriesEqual}
242
- loading={loading}
243
- loadingText={<LoadingIndicator />}
244
- options={options}
245
- renderInput={renderInput}
246
- renderOption={(props, option): JSX.Element => {
247
- return (
248
- <li
249
- className={classes.options}
250
- {...(props as React.HTMLAttributes<HTMLLIElement>)}
251
- >
252
- <Option
253
- thumbnailUrl={displayOptionThumbnail ? option.url : undefined}
245
+ isOptionEqualToValue={areSelectEntriesEqual}
246
+ loading={loading}
247
+ loadingText={<LoadingIndicator />}
248
+ options={options}
249
+ ref={ref}
250
+ renderInput={renderInput}
251
+ renderOption={(props, option): JSX.Element => {
252
+ return (
253
+ <li
254
+ className={classes.options}
255
+ {...(props as React.HTMLAttributes<HTMLLIElement>)}
254
256
  >
255
- {getOptionItemLabel(option)}
256
- </Option>
257
- </li>
258
- );
259
- }}
260
- size="small"
261
- {...autocompleteProps}
262
- />
263
- );
264
- };
257
+ <Option
258
+ thumbnailUrl={displayOptionThumbnail ? option.url : undefined}
259
+ >
260
+ {getOptionItemLabel(option)}
261
+ </Option>
262
+ </li>
263
+ );
264
+ }}
265
+ size="small"
266
+ {...autocompleteProps}
267
+ />
268
+ );
269
+ }
270
+ );
265
271
 
266
272
  export default AutocompleteField;
@@ -73,14 +73,14 @@ const IconPopoverMultiAutocomplete = ({
73
73
  };
74
74
 
75
75
  const isSelected = (id: number | string): boolean => {
76
- return pipe(find(propEq('id', id)), Boolean)(value);
76
+ return pipe(find(propEq(id, 'id')), Boolean)(value);
77
77
  };
78
78
 
79
79
  const unSelect = (option: SelectEntry): void => {
80
80
  const { id } = option;
81
81
 
82
82
  const updatedValue = isSelected(id)
83
- ? reject(propEq('id', id), value)
83
+ ? reject(propEq(id, 'id'), value)
84
84
  : [...value, option];
85
85
 
86
86
  onChange(updatedValue);
@@ -69,7 +69,7 @@ const SelectField = ({
69
69
  const { classes, cx } = useStyles();
70
70
 
71
71
  const getOption = (id): SelectEntry => {
72
- return options.find(propEq('id', id)) as SelectEntry;
72
+ return options.find(propEq(id, 'id')) as SelectEntry;
73
73
  };
74
74
 
75
75
  const changeOption = (event): void => {
@@ -154,9 +154,9 @@ const TextField = forwardRef(
154
154
  helperText={displayErrorInTooltip ? undefined : error}
155
155
  id={getNormalizedId(dataTestId || '')}
156
156
  inputProps={{
157
- ...rest.inputProps,
158
157
  'aria-label': ariaLabel,
159
- 'data-testid': dataTestId
158
+ 'data-testid': dataTestId,
159
+ ...rest.inputProps
160
160
  }}
161
161
  label={label}
162
162
  ref={ref}
@@ -174,14 +174,15 @@ const MemoListingActionBar = ({
174
174
  </IconButton>
175
175
  )}
176
176
  <div className={classes.ModeViewer} />
177
- {columnConfiguration?.selectedColumnIds && (
178
- <ColumnMultiSelect
179
- columnConfiguration={columnConfiguration}
180
- columns={columns}
181
- onResetColumns={onResetColumns}
182
- onSelectColumns={onSelectColumns}
183
- />
184
- )}
177
+ {columnConfiguration?.selectedColumnIds &&
178
+ columnConfiguration?.sortable && (
179
+ <ColumnMultiSelect
180
+ columnConfiguration={columnConfiguration}
181
+ columns={columns}
182
+ onResetColumns={onResetColumns}
183
+ onSelectColumns={onSelectColumns}
184
+ />
185
+ )}
185
186
  {paginated && (
186
187
  <StyledPagination
187
188
  ActionsComponent={PaginationActions}
@@ -8,6 +8,9 @@ const useStyles = makeStyles()((theme) => ({
8
8
  overflow: 'hidden',
9
9
  whiteSpace: 'nowrap'
10
10
  },
11
+ clickable: {
12
+ cursor: 'default'
13
+ },
11
14
  componentColumn: {
12
15
  width: theme.spacing(2.75)
13
16
  },
@@ -46,7 +46,7 @@ const DataCell = ({
46
46
  labelCollapse,
47
47
  labelExpand
48
48
  }: Props): JSX.Element | null => {
49
- const { classes } = useStyles();
49
+ const { classes, cx } = useStyles();
50
50
  const { dataStyle } = useStyleTable({ listingVariant });
51
51
 
52
52
  const commonCellProps = {
@@ -64,7 +64,7 @@ const DataCell = ({
64
64
 
65
65
  const cellByColumnType = {
66
66
  [ColumnType.string]: (): JSX.Element => {
67
- const { getFormattedString, isTruncated, getColSpan } = column;
67
+ const { getFormattedString, isTruncated, getColSpan, align } = column;
68
68
 
69
69
  const colSpan = getColSpan?.(isRowSelected);
70
70
 
@@ -87,6 +87,7 @@ const DataCell = ({
87
87
  isRowHighlighted={isRowHighlighted}
88
88
  listingVariant={listingVariant}
89
89
  style={{
90
+ alignItems: align,
90
91
  gridColumn
91
92
  }}
92
93
  {...commonCellProps}
@@ -99,7 +100,7 @@ const DataCell = ({
99
100
  );
100
101
  },
101
102
  [ColumnType.component]: (): JSX.Element | null => {
102
- const { getHiddenCondition, clickable } = column;
103
+ const { getHiddenCondition, clickable, align } = column;
103
104
  const Component = column.Component as (
104
105
  props: ComponentColumnProps
105
106
  ) => JSX.Element;
@@ -107,14 +108,31 @@ const DataCell = ({
107
108
  const isCellHidden = getHiddenCondition?.(isRowSelected);
108
109
 
109
110
  if (isCellHidden) {
110
- return null;
111
+ return (
112
+ <Cell
113
+ className={classes.cell}
114
+ isRowHighlighted={isRowHighlighted}
115
+ listingVariant={listingVariant}
116
+ onClick={(e): void => {
117
+ if (!clickable) {
118
+ return;
119
+ }
120
+ e.preventDefault();
121
+ e.stopPropagation();
122
+ }}
123
+ {...commonCellProps}
124
+ />
125
+ );
111
126
  }
112
127
 
113
128
  return (
114
129
  <Cell
115
- className={classes.cell}
130
+ className={cx(classes.cell, clickable && classes.clickable)}
116
131
  isRowHighlighted={isRowHighlighted}
117
132
  listingVariant={listingVariant}
133
+ style={{
134
+ alignItems: align
135
+ }}
118
136
  onClick={(e): void => {
119
137
  if (!clickable) {
120
138
  return;
@@ -71,7 +71,7 @@ const ListingHeader = ({
71
71
  });
72
72
 
73
73
  const getColumnById = (id: string): Column => {
74
- return find(propEq('id', id), columns) as Column;
74
+ return find(propEq(id, 'id'), columns) as Column;
75
75
  };
76
76
 
77
77
  const Content = React.useCallback(