@talend/react-components
Version:
Set of react components.
135 lines (132 loc) • 4.14 kB
JavaScript
import PropTypes from 'prop-types';
import classNames from 'classnames';
import toFlat from '../toflat';
import JSONLike from '../JSONLike';
import theme from './Table.module.scss';
/**
* @param {Object} data
* @param {Bool} isFlat
* @return {Array<String>}
*/
import { union } from "lodash";
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
export function getKeys(data, isFlat) {
if (isFlat) {
return Object.keys(toFlat(data));
}
return Object.keys(data);
}
export function getAbsolutePath(index, key, flat) {
if (flat) {
return `$[${index}]${key.replace('$', '')}`;
}
return `$[${index}]['${key}']`;
}
export function getHeaders(keys, isFlat, baseId) {
return keys.map(key => {
// This transforms $['id'][0]['foo'] into id[0].foo
const adaptedKey = isFlat ? key.replace(/^\$\['/g, '').replace(/']\['/g, '.').replace(/]\['/g, '].').replace(/']\[/g, '[').replace(/']/g, '') : key;
return {
id: `${baseId}-${adaptedKey}`,
key,
header: adaptedKey
};
});
}
/**
* We construct the jsx dispayed for the header.
* If there is a type we add it.
* @param {array} headersDefinitions
* @param {object} schema
*/
export function buildContentHeaders(headersDefinitions, schema) {
return headersDefinitions.map(({
header,
id
}, index) => {
let type;
if (schema) {
type = schema.get(header);
}
if (!type) {
return /*#__PURE__*/_jsx("th", {
id: id,
children: header
}, index);
}
return /*#__PURE__*/_jsxs("th", {
id: id,
children: [/*#__PURE__*/_jsx("div", {
children: header
}), /*#__PURE__*/_jsx("div", {
className: classNames('text-right'),
children: type
})]
}, index);
});
}
function Table({
flat,
data,
title,
...props
}) {
if (!Array.isArray(data) && !Array.isArray(data.dataset)) {
return null;
}
// The datas can be an array or an array in an object. We assign the value correctly here.
const dataset = Array.isArray(data) ? data : data.dataset;
/**
* because we want to display all the possible table header keys
* for each row of the dataset we try to find each possible key
* and merge them into a array of unique values
* this may not be performant or good UX for huge heterogenous datasets
* because it require to run a recursive exploratory function on each member of the dataset
* and it may show to many column to the end user
*/
const keys = dataset.reduce((accumulator, currentValue) => union(getKeys(currentValue, flat), accumulator), []);
const headers = getHeaders(keys, flat, props.id);
const tableClassName = classNames(theme.table, 'tc-object-viewer', 'table table-bordered table-striped table-hover');
return /*#__PURE__*/_jsxs("table", {
className: tableClassName,
id: props.id,
children: [/*#__PURE__*/_jsx("caption", {
className: "sr-only",
children: title
}), /*#__PURE__*/_jsx("thead", {
children: /*#__PURE__*/_jsx("tr", {
children: buildContentHeaders(headers, data.schema)
})
}), /*#__PURE__*/_jsx("tbody", {
children: dataset.map((row, index) => {
const flattenRow = flat ? toFlat(row) : row;
return /*#__PURE__*/_jsx("tr", {
children: headers.map(({
key,
id
}, j) => {
const path = getAbsolutePath(index, key, flat);
return /*#__PURE__*/_jsx("td", {
headers: id,
children: /*#__PURE__*/_jsx(JSONLike, {
data: flattenRow[key],
...props,
jsonpath: path,
nativeValueClassName: theme.nativevalue
})
}, j);
})
}, index);
})
})]
});
}
Table.displayName = 'Table';
Table.propTypes = {
id: PropTypes.string.isRequired,
title: PropTypes.string.isRequired,
flat: PropTypes.bool,
data: PropTypes.oneOfType([PropTypes.bool, PropTypes.number, PropTypes.string, PropTypes.object, PropTypes.array]).isRequired
};
export default Table;
//# sourceMappingURL=Table.component.js.map