Skip to content

Commit

Permalink
Merge pull request #1830 from carbon-design-system/expanded-row-times…
Browse files Browse the repository at this point in the history
…tamp

fix(TableCard): format timestamps in expanded rows
  • Loading branch information
kodiakhq[bot] authored Nov 30, 2020
2 parents 6b3b88d + d6c541b commit d12a06b
Show file tree
Hide file tree
Showing 15 changed files with 7,198 additions and 5,282 deletions.
24 changes: 12 additions & 12 deletions .storybook/__snapshots__/Welcome.story.storyshot
Original file line number Diff line number Diff line change
Expand Up @@ -3180,18 +3180,6 @@ exports[`Storybook Snapshot tests and console checks Storyshots 0/Getting Starte
TableCard
</div>
</div>
<div
className="bx--structured-list-row"
>
<div
className="bx--structured-list-td"
/>
<div
className="bx--structured-list-td"
>
findMatchingThresholds
</div>
</div>
<div
className="bx--structured-list-row"
>
Expand Down Expand Up @@ -3648,6 +3636,18 @@ exports[`Storybook Snapshot tests and console checks Storyshots 0/Getting Starte
replaceVariables
</div>
</div>
<div
className="bx--structured-list-row"
>
<div
className="bx--structured-list-td"
/>
<div
className="bx--structured-list-td"
>
findMatchingThresholds
</div>
</div>
<div
className="bx--structured-list-row"
>
Expand Down
6 changes: 4 additions & 2 deletions src/components/ImageCard/HotspotContent.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@ import PropTypes from 'prop-types';
import isNil from 'lodash/isNil';
import isEmpty from 'lodash/isEmpty';

import { formatNumberWithPrecision } from '../../utils/cardUtilityFunctions';
import { findMatchingThresholds } from '../TableCard/TableCard';
import {
formatNumberWithPrecision,
findMatchingThresholds,
} from '../../utils/cardUtilityFunctions';
import { settings } from '../../constants/Settings';

import CardIcon from './CardIcon';
Expand Down
3 changes: 2 additions & 1 deletion src/components/List/ListHeader/ListHeader.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { settings } from '../../../constants/Settings';
const { iotPrefix } = settings;

const propTypes = {
title: PropTypes.string.isRequired,
title: PropTypes.string,
buttons: PropTypes.arrayOf(PropTypes.node),
search: PropTypes.shape({
onChange: PropTypes.func,
Expand All @@ -29,6 +29,7 @@ const defaultProps = {
i18n: {
searchPlaceHolderText: 'Enter a value',
},
title: null,
};

const ListHeader = ({ title, buttons, search, i18n, isLoading }) => {
Expand Down
180 changes: 13 additions & 167 deletions src/components/TableCard/TableCard.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,16 @@ import { settings } from '../../constants/Settings';
import {
getUpdatedCardSize,
handleCardVariables,
formatNumberWithPrecision,
getVariables,
getResizeHandles,
findMatchingThresholds,
} from '../../utils/cardUtilityFunctions';
import icons from '../../utils/bundledIcons';

import {
createColumnsWithFormattedLinks,
determinePrecisionAndValue,
handleExpandedItemLinks,
} from './tableCardUtils';
import ThresholdIcon from './ThresholdIcon';

const { iotPrefix } = settings;
Expand Down Expand Up @@ -155,170 +159,6 @@ const defaultProps = {
expandLabel: 'Expand to fullscreen',
},
};
/**
* Returns an array of matching thresholds will only return the highest severity threshold for a column
* If passed a columnId, it filters the threshold check on the current column only
*/
export const findMatchingThresholds = (thresholds, item, columnId) => {
return thresholds
.filter((t) => {
const { comparison, value, dataSourceId } = t;
// Does the threshold apply to the current column?
if (columnId && !columnId.includes(dataSourceId)) {
return false;
}

switch (comparison) {
case '<':
return (
!isNil(item[dataSourceId]) && parseFloat(item[dataSourceId]) < value
);
case '>':
return parseFloat(item[dataSourceId]) > value;
case '=':
return (
parseFloat(item[dataSourceId]) === value ||
item[dataSourceId] === value
); // need to handle the string case
case '<=':
return (
!isNil(item[dataSourceId]) &&
parseFloat(item[dataSourceId]) <= value
);
case '>=':
return parseFloat(item[dataSourceId]) >= value;
default:
return false;
}
})
.reduce((highestSeverityThreshold, threshold) => {
const currentThresholdIndex = highestSeverityThreshold.findIndex(
(currentThreshold) =>
currentThreshold.dataSourceId === threshold.dataSourceId
);

if (
// If I don't have a threshold currently for this column
currentThresholdIndex < 0
) {
highestSeverityThreshold.push({
...threshold,
currentValue: item[threshold.dataSourceId],
});
} // The lowest severity is actually the most severe
else if (
highestSeverityThreshold[currentThresholdIndex].severity >
threshold.severity
) {
// eslint-disable-next-line no-param-reassign
highestSeverityThreshold[currentThresholdIndex] = {
...threshold,
currentValue: item[threshold.dataSourceId],
};
}
return highestSeverityThreshold;
}, []);
};

const determinePrecisionAndValue = (precision = 0, value, locale) => {
const precisionDefined = Number.isInteger(value) ? 0 : precision;

if (typeof value === 'number') {
return formatNumberWithPrecision(value, precisionDefined, locale);
}
if (isNil(value)) {
return '--';
}
return '--';
};

/**
* Updates the hrefs in each column to be us-able links. If href variables are on a table that has row specific values, the user
* should not pass in a cardVariables object as each variable with have multiple values.
* @param {array} columns - Array of TableCard columns
* @param {object} cardVariables - object of cardVariables
* @return {array} array of columns with formatted links and updated variable values
*/
export const createColumnsWithFormattedLinks = (columns, cardVariables) => {
return columns.map((column) => {
const { linkTemplate } = column;
if (linkTemplate) {
let variables;
if (!cardVariables) {
// fetch variables on the href
variables = linkTemplate.href ? getVariables(linkTemplate.href) : [];
}
return {
...column,
// eslint-disable-next-line react/prop-types
renderDataFunction: ({ value, row }) => {
let variableLink;
// if we have variables the value is based on its own row's context
if (variables && variables.length) {
variableLink = linkTemplate.href;
variables.forEach((variable) => {
const variableValue = row[variable];
variableLink = variableLink.replace(
`{${variable}}`,
variableValue
);
});
}
return (
<Link
href={variableLink || linkTemplate.href}
target={linkTemplate.target ? linkTemplate.target : null}>
{value}
</Link>
);
},
};
}
return column;
});
};

/**
* Updates expandedRow to have us-able links if any hrefs are found. If href variables are on a table that has row specific values, the user
* should not pass in a cardVariables object as each variable with have multiple values.
* @param {object} row - Object containing each value present on the row
* @param {array} expandedRow - Array of data to display when the row is expanded
* @param {object} cardVariables - object of cardVariables
* @return {array} Array of data with formatted links to display when the row is expanded
*/
export const handleExpandedItemLinks = (row, expandedRow, cardVariables) => {
// if the user has given us variable values, we can assume that they don't want them to be row specific
if (cardVariables) {
return expandedRow;
}

const updatedExpandedRow = [];

expandedRow.forEach((item) => {
const { linkTemplate } = item;
const variables = linkTemplate?.href ? getVariables(linkTemplate.href) : [];
let variableLink;
// if we have variables the value is based on its own row's context
if (variables && variables.length) {
variableLink = linkTemplate.href;
variables.forEach((variable) => {
const variableValue = row[variable];
variableLink = variableLink.replace(`{${variable}}`, variableValue);
});
}
if (linkTemplate) {
updatedExpandedRow.push({
...item,
linkTemplate: {
href: variableLink || linkTemplate.href,
},
});
} else {
updatedExpandedRow.push(item);
}
});
return updatedExpandedRow;
};

const TableCard = ({
id,
Expand Down Expand Up @@ -764,7 +604,13 @@ const TableCard = ({
{item ? item.label : '--'}
</p>
<span key={`${item.id}-value`}>
{item ? dataItem.values[item.id] : null}
{item
? item.type === 'TIMESTAMP'
? moment(dataItem.values[item.id]).format(
'L HH:mm'
)
: dataItem.values[item.id]
: null}
</span>
</>
)}
Expand Down
Loading

0 comments on commit d12a06b

Please sign in to comment.