Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(tablecard): do not require the threshold column be shown in a table #998

Merged
merged 8 commits into from
Mar 13, 2020
2 changes: 1 addition & 1 deletion src/components/BarChartCard/BarChartCard.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import isNil from 'lodash/isNil';
import uniqBy from 'lodash/uniqBy';
import groupBy from 'lodash/groupBy';

import { BarChartCardPropTypes, CardPropTypes } from '../../constants/PropTypes';
import { BarChartCardPropTypes, CardPropTypes } from '../../constants/CardPropTypes';
import { CARD_SIZES, BAR_CHART_TYPES, BAR_CHART_LAYOUTS } from '../../constants/LayoutConstants';
import Card from '../Card/Card';
import { settings } from '../../constants/Settings';
Expand Down
2 changes: 1 addition & 1 deletion src/components/Card/Card.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {
DASHBOARD_COLUMNS,
DASHBOARD_SIZES,
} from '../../constants/LayoutConstants';
import { CardPropTypes } from '../../constants/PropTypes';
import { CardPropTypes } from '../../constants/CardPropTypes';
import { getCardMinSize } from '../../utils/componentUtilityFunctions';
import { getUpdatedCardSize } from '../../utils/cardUtilityFunctions';

Expand Down
2 changes: 1 addition & 1 deletion src/components/Dashboard/DashboardGrid.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
DASHBOARD_BREAKPOINTS,
DASHBOARD_COLUMNS,
} from '../../constants/LayoutConstants';
import { DashboardLayoutPropTypes } from '../../constants/PropTypes';
import { DashboardLayoutPropTypes } from '../../constants/CardPropTypes';

const GridLayout = WidthProvider(Responsive);

Expand Down
134 changes: 67 additions & 67 deletions src/components/Dashboard/__snapshots__/Dashboard.story.storyshot

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/components/GaugeCard/GaugeCard.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React, { useState, useEffect } from 'react';
import classnames from 'classnames';

import { CARD_CONTENT_PADDING } from '../../constants/LayoutConstants';
import { CardPropTypes, GaugeCardPropTypes } from '../../constants/PropTypes';
import { CardPropTypes, GaugeCardPropTypes } from '../../constants/CardPropTypes';
import Card from '../Card/Card';
import { settings } from '../../constants/Settings';

Expand Down
2 changes: 1 addition & 1 deletion src/components/ImageCard/ImageCard.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import styled from 'styled-components';
import isNil from 'lodash/isNil';
import Image32 from '@carbon/icons-react/lib/image/32';

import { ImageCardPropTypes, CardPropTypes } from '../../constants/PropTypes';
import { ImageCardPropTypes, CardPropTypes } from '../../constants/CardPropTypes';
import { CARD_SIZES } from '../../constants/LayoutConstants';
import Card from '../Card/Card';
import { getUpdatedCardSize } from '../../utils/cardUtilityFunctions';
Expand Down
2 changes: 1 addition & 1 deletion src/components/ListCard/ListCard.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import PropTypes from 'prop-types';
import classNames from 'classnames';

import { CARD_CONTENT_PADDING } from '../../constants/LayoutConstants';
import { CardPropTypes } from '../../constants/PropTypes';
import { CardPropTypes } from '../../constants/CardPropTypes';
import Card from '../Card/Card';

const ListCard = ({
Expand Down
1 change: 1 addition & 0 deletions src/components/PageTitleBar/_page-title-bar.scss
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
}
.#{$prefix}--tab-content {
padding: unset;
padding-top: 1rem;
}

&-header {
Expand Down
8 changes: 4 additions & 4 deletions src/components/Table/TablePropTypes.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,13 @@ export const RowActionsStatePropTypes = PropTypes.arrayOf(

export const EmptyStatePropTypes = PropTypes.oneOfType([
PropTypes.shape({
message: PropTypes.string.isRequired,
message: PropTypes.node.isRequired,
/* Show a different message if no content is in the table matching the filters */
messageWithFilters: PropTypes.string,
messageWithFilters: PropTypes.node,
/* If a label is not provided, no action button will be rendered */
buttonLabel: PropTypes.string,
buttonLabel: PropTypes.node,
/* Show a different button label if no content is in the table matching the filters */
buttonLabelWithFilters: PropTypes.string,
buttonLabelWithFilters: PropTypes.node,
}),
/* If a React element is provided, it will be rendered in place of the default */
PropTypes.element,
Expand Down
88 changes: 54 additions & 34 deletions src/components/TableCard/TableCard.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@ import styled from 'styled-components';
import moment from 'moment';
import isNil from 'lodash/isNil';
import uniqBy from 'lodash/uniqBy';
import find from 'lodash/find';
import cloneDeep from 'lodash/cloneDeep';
import capitalize from 'lodash/capitalize';
import OverFlowMenuIcon from '@carbon/icons-react/lib/overflow-menu--vertical/20';

import { CardPropTypes, TableCardPropTypes } from '../../constants/PropTypes';
import { CardPropTypes, TableCardPropTypes } from '../../constants/CardPropTypes';
import Card, { defaultProps as CardDefaultProps } from '../Card/Card';
import { CARD_SIZES } from '../../constants/LayoutConstants';
import StatefulTable from '../Table/StatefulTable';
Expand Down Expand Up @@ -215,10 +216,14 @@ export const findMatchingThresholds = (thresholds, item, columnId) => {
// If I don't have a threshold currently for this column
currentThresholdIndex < 0
) {
highestSeverityThreshold.push(threshold); //eslint-disable-line
highestSeverityThreshold.push({ ...threshold, currentValue: item[threshold.dataSourceId] }); //eslint-disable-line
} // The lowest severity is actually the most severe
else if (highestSeverityThreshold[currentThresholdIndex].severity > threshold.severity) {
highestSeverityThreshold[currentThresholdIndex] = threshold; //eslint-disable-line
// eslint-disable-next-line
highestSeverityThreshold[currentThresholdIndex] = {
...threshold,
currentValue: item[threshold.dataSourceId],
};
}
return highestSeverityThreshold;
}, []);
Expand Down Expand Up @@ -322,9 +327,9 @@ const TableCard = ({

return matchingThresholdValue ? (
<ThresholdIcon
title={`${matchingThresholdValue.dataSourceId} ${matchingThresholdValue.comparison} ${
matchingThresholdValue.value
}`}
title={`${matchingThresholdValue.dataSourceId}: ${matchingThresholdValue.currentValue} ${
matchingThresholdValue.comparison
} ${matchingThresholdValue.value}`}
{...matchingThresholdValue}
strings={strings}
renderIconByName={others.renderIconByName}
Expand Down Expand Up @@ -360,45 +365,59 @@ const TableCard = ({
// filter to get the indexes for each one
const columnsUpdated = cloneDeep(columns);

const generateThresholdColumn = (columnId, index) => ({
id: `iconColumn-${columnId}`,
label: uniqueThresholds[index].label
? uniqueThresholds[index].label
: `${capitalize(columnId)} ${strings.severityLabel}`,
width: uniqueThresholds[index].width,
isSortable: true,
renderDataFunction: renderThresholdIcon,
priority: 1,
filter: {
placeholderText: strings.selectSeverityPlaceholder,
options: [
{
id: 1,
text: strings.criticalLabel,
},
{
id: 2,
text: strings.moderateLabel,
},
{
id: 3,
text: strings.lowLabel,
},
],
},
});

// Don't add the icon column in sample mode
if (!isEditable) {
const indexes = columns
.map((column, index) =>
uniqueThresholds.filter(item => item.dataSourceId === column.dataSourceId)[0]
? { i: index, columnId: column.dataSourceId }
? { i: index, columnId: column.dataSourceId } // Find the column and put the threshold next to it
: null
)
.filter(i => !isNil(i));
indexes.forEach(({ i, columnId }, index) =>
columnsUpdated.splice(index !== 0 ? i + 1 : i, 0, {
id: `iconColumn-${columnId}`,
label: uniqueThresholds[index].label
? uniqueThresholds[index].label
: `${capitalize(columnId)} ${strings.severityLabel}`,
width: '200px',
isSortable: true,
renderDataFunction: renderThresholdIcon,
priority: 1,
filter: {
placeholderText: strings.selectSeverityPlaceholder,
options: [
{
id: 1,
text: strings.criticalLabel,
},
{
id: 2,
text: strings.moderateLabel,
},
{
id: 3,
text: strings.lowLabel,
},
],
},
})
columnsUpdated.splice(index !== 0 ? i + 1 : i, 0, generateThresholdColumn(columnId, index))
);
// Check for any threshold columns that weren't matched (if the column was hidden) and add to the end of the array
const missingThresholdColumns = uniqueThresholds.filter(
threshold => !find(columnsUpdated, column => threshold.dataSourceId === column.dataSourceId)
);
columnsUpdated.splice(
columnsUpdated.length,
0,
...missingThresholdColumns.map(({ dataSourceId }, index) =>
generateThresholdColumn(dataSourceId, index)
)
);
}

const newColumns = thresholds ? columnsUpdated : columns;

const columnsToRender = useMemo(
Expand Down Expand Up @@ -623,6 +642,7 @@ const TableCard = ({
<StyledStatefulTable
columns={columnsToRender}
data={tableDataWithTimestamp}
id={`table-for-card-${id}`}
scottdickerson marked this conversation as resolved.
Show resolved Hide resolved
isExpanded={isExpanded}
secondaryTitle={title}
tooltip={tooltip}
Expand Down
108 changes: 59 additions & 49 deletions src/components/TableCard/TableCard.story.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -230,57 +230,67 @@ storiesOf('Watson IoT/TableCard', module)
</div>
);
})
.add('table with thresholds only with value', () => {
const size = select('size', [CARD_SIZES.LARGE, CARD_SIZES.LARGEWIDE], CARD_SIZES.LARGEWIDE);
.add(
'table with thresholds only with icon',
() => {
const size = select('size', [CARD_SIZES.LARGE, CARD_SIZES.LARGEWIDE], CARD_SIZES.LARGEWIDE);

const thresholds = [
// this threshold is applied to the whole row, not a particular attribute
{
dataSourceId: 'count',
comparison: '<',
value: 5,
severity: 3, // High threshold, medium, or low used for sorting and defined filtration
},
{
dataSourceId: 'count',
comparison: '>=',
value: 10,
severity: 1, // High threshold, medium, or low used for sorting and defined filtration
label: 'Count Sev',
},
{
dataSourceId: 'count',
comparison: '=',
value: 7,
severity: 2, // High threshold, medium, or low used for sorting and defined filtration
},
{
dataSourceId: 'pressure',
comparison: '>=',
value: 10,
severity: 1,
label: 'Pressure Sev',
showOnContent: true,
},
];
const thresholds = [
// this threshold is applied to the whole row, not a particular attribute
{
dataSourceId: 'count',
comparison: '<',
value: 5,
severity: 3, // High threshold, medium, or low used for sorting and defined filtration
},
{
dataSourceId: 'count',
comparison: '>=',
value: 10,
severity: 1, // High threshold, medium, or low used for sorting and defined filtration
label: 'Count Sev',
},
{
dataSourceId: 'count',
comparison: '=',
value: 7,
severity: 2, // High threshold, medium, or low used for sorting and defined filtration
},
{
dataSourceId: 'pressure',
comparison: '>=',
value: 10,
severity: 1,
label: 'Pressure Sev',
showOnContent: true,
},
];

return (
<div style={{ width: `${getCardMinSize('lg', size).x}px`, margin: 20 }}>
<TableCard
title={text('title', 'Open Alerts')}
id="table-list"
tooltip={text('Tooltip text', "Here's a Tooltip")}
content={{
columns: tableColumns,
thresholds,
}}
values={tableData}
onCardAction={(id, type, payload) => action('onCardAction', id, type, payload)}
size={size}
/>
</div>
);
})
return (
<div style={{ width: `${getCardMinSize('lg', size).x}px`, margin: 20 }}>
<TableCard
title={text('title', 'Open Alerts')}
id="table-list"
tooltip={text('Tooltip text', "Here's a Tooltip")}
content={{
columns: [...tableColumns.slice(0, 1), tableColumns[2]],
thresholds,
}}
values={tableData}
onCardAction={(id, type, payload) => action('onCardAction', id, type, payload)}
size={size}
/>
</div>
);
},
{
info: {
text: `
If you don't pass the underlying 'pressure' or 'count' column we will show the threshold icon columns at the right of the table
`,
},
}
)
.add('table with custom column sort', () => {
const size = select('size', [CARD_SIZES.LARGE, CARD_SIZES.LARGEWIDE], CARD_SIZES.LARGEWIDE);

Expand Down
Loading