@centreon/ui 24.4.1-MON-34459-fullscreen-mode.0 → 24.4.1-MON-develop-dashboard.1

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 (41) hide show
  1. package/package.json +4 -1
  2. package/src/Graph/BarStack/BarStack.cypress.spec.tsx +154 -0
  3. package/src/Graph/BarStack/BarStack.stories.tsx +123 -0
  4. package/src/Graph/BarStack/BarStack.styles.ts +36 -0
  5. package/src/Graph/BarStack/BarStack.tsx +14 -0
  6. package/src/Graph/BarStack/ResponsiveBarStack.tsx +208 -0
  7. package/src/Graph/BarStack/index.ts +1 -0
  8. package/src/Graph/BarStack/models.ts +19 -0
  9. package/src/Graph/BarStack/useResponsiveBarStack.ts +139 -0
  10. package/src/Graph/Legend/Legend.tsx +21 -0
  11. package/src/Graph/Legend/index.ts +1 -0
  12. package/src/Graph/Legend/models.ts +11 -0
  13. package/src/Graph/PieChart/PieChart.cypress.spec.tsx +169 -0
  14. package/src/Graph/PieChart/PieChart.stories.tsx +194 -0
  15. package/src/Graph/PieChart/PieChart.styles.ts +39 -0
  16. package/src/Graph/PieChart/PieChart.tsx +14 -0
  17. package/src/Graph/PieChart/ResponsivePie.tsx +251 -0
  18. package/src/Graph/PieChart/index.ts +1 -0
  19. package/src/Graph/PieChart/models.ts +19 -0
  20. package/src/Graph/PieChart/useResponsivePie.ts +86 -0
  21. package/src/Graph/common/utils.ts +19 -0
  22. package/src/Graph/index.ts +2 -0
  23. package/src/Graph/translatedLabels.ts +1 -0
  24. package/src/Listing/ActionBar/index.tsx +9 -8
  25. package/src/Listing/Cell/DataCell.styles.ts +3 -0
  26. package/src/Listing/Cell/DataCell.tsx +8 -4
  27. package/src/Listing/Listing.cypress.spec.tsx +80 -4
  28. package/src/Listing/Listing.styles.ts +3 -5
  29. package/src/Listing/index.stories.tsx +25 -2
  30. package/src/Listing/index.test.tsx +1 -1
  31. package/src/Listing/index.tsx +3 -1
  32. package/src/Listing/models.ts +1 -0
  33. package/src/components/Form/AccessRights/ShareInput/ContactSwitch.tsx +3 -3
  34. package/src/components/Form/AccessRights/ShareInput/ShareInput.tsx +1 -0
  35. package/src/utils/index.ts +0 -1
  36. package/src/utils/useFullscreen/Fullscreen.cypress.spec.tsx +0 -109
  37. package/src/utils/useFullscreen/atoms.ts +0 -3
  38. package/src/utils/useFullscreen/index.ts +0 -2
  39. package/src/utils/useFullscreen/translatedLabels.ts +0 -1
  40. package/src/utils/useFullscreen/useFullscreen.ts +0 -73
  41. package/src/utils/useFullscreen/useFullscreenListener.ts +0 -54
@@ -0,0 +1,251 @@
1
+ import { useRef } from 'react';
2
+
3
+ import { Pie } from '@visx/shape';
4
+ import { Group } from '@visx/group';
5
+ import { Text } from '@visx/text';
6
+ import numeral from 'numeral';
7
+ import { always, equals, gt, ifElse, lt } from 'ramda';
8
+ import { useTranslation } from 'react-i18next';
9
+
10
+ import { Typography, useTheme } from '@mui/material';
11
+
12
+ import { Tooltip } from '../../components';
13
+ import { Legend as LegendComponent } from '../Legend';
14
+ import { LegendProps } from '../Legend/models';
15
+ import { getValueByUnit } from '../common/utils';
16
+ import { labelNoDataFound } from '../translatedLabels';
17
+
18
+ import { PieProps } from './models';
19
+ import { usePieStyles } from './PieChart.styles';
20
+ import { useResponsivePie } from './useResponsivePie';
21
+
22
+ const DefaultLengd = ({ scale, direction }: LegendProps): JSX.Element => (
23
+ <LegendComponent direction={direction} scale={scale} />
24
+ );
25
+
26
+ type Placement = 'left' | 'right' | 'top' | 'bottom';
27
+
28
+ const getTooltipPlacement = ({ radianX, radianY }): Placement => {
29
+ if (gt(Math.abs(radianX), Math.abs(radianY))) {
30
+ return ifElse<[b: number], Placement, Placement>(
31
+ lt(0),
32
+ always<Placement>('right'),
33
+ always<Placement>('left')
34
+ )(radianX);
35
+ }
36
+
37
+ return ifElse<[b: number], Placement, Placement>(
38
+ lt(0),
39
+ always<Placement>('bottom'),
40
+ always<Placement>('top')
41
+ )(radianY);
42
+ };
43
+
44
+ const ResponsivePie = ({
45
+ title,
46
+ variant = 'pie',
47
+ width,
48
+ height,
49
+ data,
50
+ unit = 'number',
51
+ Legend = DefaultLengd,
52
+ displayLegend = true,
53
+ innerRadius: defaultInnerRadius = 40,
54
+ onArcClick,
55
+ displayValues,
56
+ TooltipContent,
57
+ legendDirection = 'column'
58
+ }: PieProps & { height: number; width: number }): JSX.Element => {
59
+ const { t } = useTranslation();
60
+ const theme = useTheme();
61
+
62
+ const legendRef = useRef(null);
63
+ const titleRef = useRef(null);
64
+
65
+ const {
66
+ half,
67
+ legendScale,
68
+ svgContainerSize,
69
+ svgSize,
70
+ svgWrapperWidth,
71
+ total,
72
+ innerRadius,
73
+ isContainsExactlyOneNonZeroValue,
74
+ areAllValuesNull
75
+ } = useResponsivePie({
76
+ data,
77
+ defaultInnerRadius,
78
+ height,
79
+ legendRef,
80
+ titleRef,
81
+ unit,
82
+ width
83
+ });
84
+
85
+ const { classes } = usePieStyles({ svgSize });
86
+
87
+ if (areAllValuesNull) {
88
+ return (
89
+ <div className={classes.container} style={{ height, width }}>
90
+ <Typography variant="h3">{t(labelNoDataFound)}</Typography>
91
+ </div>
92
+ );
93
+ }
94
+
95
+ return (
96
+ <div
97
+ className={classes.container}
98
+ style={{
99
+ height,
100
+ width
101
+ }}
102
+ >
103
+ <div
104
+ className={classes.svgWrapper}
105
+ style={{
106
+ height,
107
+ width: svgWrapperWidth
108
+ }}
109
+ >
110
+ {equals(variant, 'pie') && title && (
111
+ <div className={classes.title} data-testid="Title" ref={titleRef}>
112
+ {`${numeral(total).format('0a').toUpperCase()} `} {title}
113
+ </div>
114
+ )}
115
+ <div
116
+ className={classes.svgContainer}
117
+ data-testid="pieChart"
118
+ style={{
119
+ height: svgContainerSize,
120
+ width: svgContainerSize
121
+ }}
122
+ >
123
+ <svg data-variant={variant} height={svgSize} width={svgSize}>
124
+ <Group left={half} top={half}>
125
+ <Pie
126
+ cornerRadius={4}
127
+ data={data}
128
+ innerRadius={() => {
129
+ return equals(variant, 'pie') ? 0 : half - innerRadius;
130
+ }}
131
+ outerRadius={half}
132
+ pieValue={(items) => items.value}
133
+ >
134
+ {(pie) => {
135
+ return pie.arcs.map((arc) => {
136
+ const [centroidX, centroidY] = pie.path.centroid(arc);
137
+ const midAngle = Math.atan2(centroidY, centroidX);
138
+
139
+ const labelRadius = half * 0.8;
140
+
141
+ const labelX = Math.cos(midAngle) * labelRadius;
142
+ const labelY = Math.sin(midAngle) * labelRadius;
143
+
144
+ const angle = arc.endAngle - arc.startAngle;
145
+ const minAngle = 0.2;
146
+
147
+ const x = equals(variant, 'donut') ? centroidX : labelX;
148
+ const y = equals(variant, 'donut') ? centroidY : labelY;
149
+
150
+ const onClick = (): void => {
151
+ onArcClick?.(arc.data);
152
+ };
153
+
154
+ return (
155
+ <Tooltip
156
+ hasCaret
157
+ classes={{
158
+ tooltip: classes.pieChartTooltip
159
+ }}
160
+ followCursor={false}
161
+ key={arc.data.label}
162
+ label={
163
+ TooltipContent && (
164
+ <TooltipContent
165
+ color={arc.data.color}
166
+ label={arc.data.label}
167
+ title={title}
168
+ total={total}
169
+ value={arc.data.value}
170
+ />
171
+ )
172
+ }
173
+ leaveDelay={200}
174
+ placement={getTooltipPlacement({
175
+ radianX: Math.cos(midAngle),
176
+ radianY: Math.sin(midAngle)
177
+ })}
178
+ >
179
+ <g data-testid={arc.data.label} onClick={onClick}>
180
+ <path
181
+ d={pie.path(arc) as string}
182
+ fill={arc.data.color}
183
+ />
184
+ {displayValues &&
185
+ !isContainsExactlyOneNonZeroValue &&
186
+ angle > minAngle && (
187
+ <Text
188
+ data-testid="value"
189
+ dy=".33em"
190
+ fill="#000"
191
+ fontSize={12}
192
+ pointerEvents="none"
193
+ textAnchor="middle"
194
+ x={x}
195
+ y={y}
196
+ >
197
+ {getValueByUnit({
198
+ total,
199
+ unit,
200
+ value: arc.data.value
201
+ })}
202
+ </Text>
203
+ )}
204
+ </g>
205
+ </Tooltip>
206
+ );
207
+ });
208
+ }}
209
+ </Pie>
210
+ {equals(variant, 'donut') && title && (
211
+ <>
212
+ <Text
213
+ className={classes.title}
214
+ dy={lt(svgSize, 150) ? -10 : -15}
215
+ fill={theme.palette.text.primary}
216
+ textAnchor="middle"
217
+ >
218
+ {numeral(total).format('0a').toUpperCase()}
219
+ </Text>
220
+ <Text
221
+ className={classes.title}
222
+ data-testid="Title"
223
+ dy={lt(svgSize, 150) ? 10 : 15}
224
+ fill={theme.palette.text.primary}
225
+ textAnchor="middle"
226
+ >
227
+ {title}
228
+ </Text>
229
+ </>
230
+ )}
231
+ </Group>
232
+ </svg>
233
+ </div>
234
+ </div>
235
+ {displayLegend && (
236
+ <div data-testid="Legend" ref={legendRef}>
237
+ <Legend
238
+ data={data}
239
+ direction={legendDirection}
240
+ scale={legendScale}
241
+ title={title}
242
+ total={total}
243
+ unit={unit}
244
+ />
245
+ </div>
246
+ )}
247
+ </div>
248
+ );
249
+ };
250
+
251
+ export default ResponsivePie;
@@ -0,0 +1 @@
1
+ export { default as PieChart } from './PieChart';
@@ -0,0 +1,19 @@
1
+ export interface ArcType {
2
+ color: string;
3
+ label: string;
4
+ value: number;
5
+ }
6
+
7
+ export interface PieProps {
8
+ Legend?: ({ scale, direction, data, title, total, unit }) => JSX.Element;
9
+ TooltipContent?: (arcData) => JSX.Element | boolean | null;
10
+ data: Array<ArcType>;
11
+ displayLegend?: boolean;
12
+ displayValues?: boolean;
13
+ innerRadius?: number;
14
+ legendDirection?: 'row' | 'column';
15
+ onArcClick?: (ardata) => void;
16
+ title?: string;
17
+ unit?: 'percentage' | 'number';
18
+ variant?: 'pie' | 'donut';
19
+ }
@@ -0,0 +1,86 @@
1
+ import { equals, isEmpty, pluck, reject } from 'ramda';
2
+
3
+ import { LegendScale } from '../Legend/models';
4
+ import { getValueByUnit } from '../common/utils';
5
+
6
+ import { ArcType } from './models';
7
+
8
+ interface ResponsivePieProps {
9
+ data: Array<ArcType>;
10
+ defaultInnerRadius: number;
11
+ height: number;
12
+ legendRef;
13
+ titleRef;
14
+ unit: 'percentage' | 'number';
15
+ width: number;
16
+ }
17
+
18
+ interface ResponsivePieState {
19
+ areAllValuesNull: boolean;
20
+ half: number;
21
+ innerRadius: number;
22
+ isContainsExactlyOneNonZeroValue: boolean;
23
+ legendScale: LegendScale;
24
+ svgContainerSize: number;
25
+ svgSize: number;
26
+ svgWrapperWidth: number;
27
+ total: number;
28
+ }
29
+ export const useResponsivePie = ({
30
+ titleRef,
31
+ legendRef,
32
+ height,
33
+ width,
34
+ data,
35
+ unit,
36
+ defaultInnerRadius
37
+ }: ResponsivePieProps): ResponsivePieState => {
38
+ const heightOfTitle = titleRef.current?.offsetHeight || 0;
39
+ const widthOfLegend = legendRef.current?.offsetWidth || 0;
40
+
41
+ const horizontalGap = widthOfLegend > 0 ? 16 : 0;
42
+ const verticalGap = heightOfTitle > 0 ? 8 : 0;
43
+
44
+ const svgWrapperWidth = width - widthOfLegend - horizontalGap;
45
+
46
+ const svgContainerSize = Math.min(
47
+ height - heightOfTitle - verticalGap,
48
+ width - widthOfLegend - horizontalGap
49
+ );
50
+
51
+ const outerRadius = Math.min(32, svgContainerSize / 6);
52
+
53
+ const svgSize = svgContainerSize - outerRadius;
54
+
55
+ const half = svgSize / 2;
56
+
57
+ const total = Math.floor(data.reduce((acc, { value }) => acc + value, 0));
58
+
59
+ const innerRadius = Math.min(defaultInnerRadius, svgSize / 5);
60
+
61
+ const legendScale = {
62
+ domain: data.map(({ value }) => getValueByUnit({ total, unit, value })),
63
+ range: pluck('color', data)
64
+ };
65
+
66
+ const values = pluck('value', data);
67
+
68
+ const isContainsExactlyOneNonZeroValue = equals(
69
+ reject((value) => equals(value, 0), values).length,
70
+ 1
71
+ );
72
+
73
+ const areAllValuesNull = isEmpty(reject((value) => equals(value, 0), values));
74
+
75
+ return {
76
+ areAllValuesNull,
77
+ half,
78
+ innerRadius,
79
+ isContainsExactlyOneNonZeroValue,
80
+ legendScale,
81
+ svgContainerSize,
82
+ svgSize,
83
+ svgWrapperWidth,
84
+ total
85
+ };
86
+ };
@@ -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
+ };
@@ -4,3 +4,5 @@ export { SingleBar } from './SingleBar';
4
4
  export { Text as GraphText } from './Text';
5
5
 
6
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';
@@ -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;
@@ -126,9 +127,12 @@ const DataCell = ({
126
127
 
127
128
  return (
128
129
  <Cell
129
- className={classes.cell}
130
+ className={cx(classes.cell, clickable && classes.clickable)}
130
131
  isRowHighlighted={isRowHighlighted}
131
132
  listingVariant={listingVariant}
133
+ style={{
134
+ alignItems: align
135
+ }}
132
136
  onClick={(e): void => {
133
137
  if (!clickable) {
134
138
  return;
@@ -1,4 +1,6 @@
1
- import { Button } from '@mui/material';
1
+ import { Button, Typography } from '@mui/material';
2
+
3
+ import { ListingVariant } from '@centreon/ui-context';
2
4
 
3
5
  import { ColumnType } from './models';
4
6
 
@@ -12,6 +14,12 @@ const ButtonColumn = ({ row }: Props): JSX.Element => (
12
14
  <Button size="small">Click to reveal details about {row.name}</Button>
13
15
  );
14
16
 
17
+ const LargeText = (): JSX.Element => (
18
+ <Typography sx={{ whiteSpace: 'normal' }}>
19
+ This is a large text that fills the content
20
+ </Typography>
21
+ );
22
+
15
23
  const generateSubItems = (parentIndex: number): Array<unknown> => {
16
24
  return tenElements.map((__, subIndex) => ({
17
25
  active: false,
@@ -37,6 +45,28 @@ const listingWithSubItems = tenElements.map((_, index) => ({
37
45
  subItems: index % 2 === 0 ? generateSubItems(index) : undefined
38
46
  }));
39
47
 
48
+ const defaultColumn = [
49
+ {
50
+ getFormattedString: ({ name }): string => name,
51
+ id: 'name',
52
+ label: 'Name',
53
+ type: ColumnType.string
54
+ },
55
+ {
56
+ getFormattedString: ({ description }): string => description,
57
+ id: 'description',
58
+ label: 'Description',
59
+ type: ColumnType.string
60
+ },
61
+ {
62
+ Component: LargeText,
63
+ id: '#',
64
+ label: 'Custom',
65
+ type: ColumnType.component,
66
+ width: '100px'
67
+ }
68
+ ];
69
+
40
70
  const columnsWithSubItems = [
41
71
  {
42
72
  getFormattedString: ({ name }): string => name,
@@ -62,7 +92,27 @@ const columnsWithSubItems = [
62
92
 
63
93
  const expandedItems = [0, 8];
64
94
 
65
- const mountListing = (): void => {
95
+ const mountListingResponsive = (listingVariant: ListingVariant): void => {
96
+ cy.viewport('macbook-13');
97
+
98
+ cy.mount({
99
+ Component: (
100
+ <div style={{ height: '100vh' }}>
101
+ <Listing
102
+ isResponsive
103
+ columns={defaultColumn}
104
+ currentPage={1}
105
+ limit={10}
106
+ listingVariant={listingVariant}
107
+ rows={listingWithSubItems}
108
+ totalRows={10}
109
+ />
110
+ </div>
111
+ )
112
+ });
113
+ };
114
+
115
+ const mountListingForSubItems = (): void => {
66
116
  cy.viewport('macbook-13');
67
117
 
68
118
  cy.mount({
@@ -89,9 +139,9 @@ const mountListing = (): void => {
89
139
  };
90
140
 
91
141
  describe('Listing', () => {
92
- beforeEach(mountListing);
93
-
94
142
  it('expands the row when the corresponding icon si clicked', () => {
143
+ mountListingForSubItems();
144
+
95
145
  cy.contains('E0').should('be.visible');
96
146
 
97
147
  expandedItems.forEach((index) => {
@@ -111,6 +161,8 @@ describe('Listing', () => {
111
161
  });
112
162
 
113
163
  it('collapses the row when the corresponding icon si clicked', () => {
164
+ mountListingForSubItems();
165
+
114
166
  cy.contains('Sub item 100').should('be.visible');
115
167
 
116
168
  cy.findByLabelText('Collapse 0').click();
@@ -119,4 +171,28 @@ describe('Listing', () => {
119
171
 
120
172
  cy.makeSnapshot();
121
173
  });
174
+
175
+ it('displays the last column on several lines in compact mode when the isResponsive prop is set', () => {
176
+ mountListingResponsive(ListingVariant.compact);
177
+
178
+ cy.get('.MuiTable-root').should(
179
+ 'have.css',
180
+ 'grid-template-rows',
181
+ '30px 85px 85px 85px 85px 85px 85px 85px 85px 85px 85px'
182
+ );
183
+
184
+ cy.makeSnapshot();
185
+ });
186
+
187
+ it('displays the last column on several lines in extended mode when the isResponsive prop is set', () => {
188
+ mountListingResponsive(ListingVariant.extended);
189
+
190
+ cy.get('.MuiTable-root').should(
191
+ 'have.css',
192
+ 'grid-template-rows',
193
+ '38px 85px 85px 85px 85px 85px 85px 85px 85px 85px 85px'
194
+ );
195
+
196
+ cy.makeSnapshot();
197
+ });
122
198
  });
@@ -1,7 +1,5 @@
1
1
  import { makeStyles } from 'tss-react/mui';
2
2
 
3
- import { ListingVariant } from '@centreon/ui-context';
4
-
5
3
  import { TableStyleAtom as TableStyle } from './models';
6
4
 
7
5
  const loadingIndicatorHeight = 3;
@@ -9,12 +7,12 @@ const loadingIndicatorHeight = 3;
9
7
  interface StylesProps {
10
8
  dataStyle: TableStyle;
11
9
  getGridTemplateColumn: string;
12
- listingVariant: ListingVariant;
10
+ isResponsive: string;
13
11
  rows: Array<unknown>;
14
12
  }
15
13
 
16
14
  const useListingStyles = makeStyles<StylesProps>()(
17
- (theme, { dataStyle, getGridTemplateColumn, rows }) => ({
15
+ (theme, { dataStyle, getGridTemplateColumn, rows, isResponsive }) => ({
18
16
  actionBar: {
19
17
  alignItems: 'center',
20
18
  display: 'flex'
@@ -56,7 +54,7 @@ const useListingStyles = makeStyles<StylesProps>()(
56
54
  gridTemplateColumns: getGridTemplateColumn,
57
55
  gridTemplateRows: `${theme.spacing(dataStyle.header.height / 8)} repeat(${
58
56
  rows?.length || 1
59
- }, ${dataStyle.body.height}px)`,
57
+ }, ${isResponsive ? 'auto' : `${dataStyle.body.height}px`})`,
60
58
  position: 'relative'
61
59
  },
62
60
  tableBody: {
@@ -40,7 +40,7 @@ const useStyles = makeStyles()((theme) => ({
40
40
  }));
41
41
 
42
42
  const ComponentColumn = ({ row, isSelected }): JSX.Element => (
43
- <>
43
+ <div style={{ display: 'flex', flexDirection: 'row', flexWrap: 'wrap' }}>
44
44
  <span>
45
45
  {'I am '}
46
46
  <b>{`${isSelected ? 'selected' : 'not selected'}`}</b>
@@ -50,7 +50,7 @@ const ComponentColumn = ({ row, isSelected }): JSX.Element => (
50
50
  {'I am '}
51
51
  <b>{`${row.active ? 'active' : 'not active'}`}</b>
52
52
  </span>
53
- </>
53
+ </div>
54
54
  );
55
55
 
56
56
  const ButtonColumn = ({ row }): JSX.Element => (
@@ -395,3 +395,26 @@ export const ListingWithSubItems = {
395
395
  },
396
396
  render: TemplateSubItems
397
397
  };
398
+
399
+ export const ListingWithResponsive = {
400
+ args: {
401
+ checkable: true,
402
+ columns: [
403
+ ...defaultColumns,
404
+ {
405
+ Component: ComponentColumn,
406
+ id: '##',
407
+ label: 'Responsive',
408
+ type: ColumnType.component,
409
+ width: '140px'
410
+ }
411
+ ],
412
+ currentPage: 1,
413
+ isResponsive: true,
414
+ limit: 10,
415
+ loading: false,
416
+ rows: listingWithSubItems,
417
+ totalRows: 10
418
+ },
419
+ render: TemplateSubItems
420
+ };
@@ -216,7 +216,7 @@ describe('Listing', () => {
216
216
  <Listing
217
217
  columnConfiguration={{
218
218
  selectedColumnIds: columns.map(prop('id')),
219
- sortable: false
219
+ sortable: true
220
220
  }}
221
221
  columns={columns}
222
222
  rows={rows}