Feature - Replace tables with a more advanced component

- Replaced Table in Reportees table with mui-datatable package
- Removed Sorting function in Reportees component and using default mui-datatble sorting feature
This commit is contained in:
Shilpa Gowda 2019-06-12 19:15:45 +05:30
Родитель cce6da53c4
Коммит 39ada188a7
3 изменённых файлов: 122 добавлений и 163 удалений

Просмотреть файл

@ -31,6 +31,7 @@
"chart.js": "^2.7.3",
"mitt": "^1.1.3",
"moment": "^2.23.0",
"mui-datatables": "^2.4.0",
"prop-types": "^15",
"query-string": "^6.2.0",
"react": "^16",

Просмотреть файл

@ -1,92 +1,14 @@
import React from 'react';
import PropTypes from 'prop-types';
import { withStyles } from '@material-ui/core/styles';
import Table from '@material-ui/core/Table';
import TableBody from '@material-ui/core/TableBody';
import TableCell from '@material-ui/core/TableCell';
import TableHead from '@material-ui/core/TableHead';
import TableRow from '@material-ui/core/TableRow';
import TableSortLabel from '@material-ui/core/TableSortLabel';
import Tooltip from '@material-ui/core/Tooltip';
import { withStyles, createMuiTheme, MuiThemeProvider } from '@material-ui/core/styles';
import MUIDataTable from 'mui-datatables';
import CONFIG from '../../config';
const styles = {
root: {},
};
function propertyComparatorAscending(a, b, orderBy) {
const valueA = a[orderBy];
const valueB = b[orderBy];
// Values can either be strings or objects with a "count" property.
// Case 1: they're strings.
if (typeof valueA === 'string') {
return valueA.localeCompare(valueB);
}
// Case 2: they're objects with a count property.
const countA = valueA ? valueA.count : 0;
const countB = valueB ? valueB.count : 0;
return countA - countB;
}
function stableSort(array, cmp) {
const stabilizedThis = array.map((el, index) => [el, index]);
stabilizedThis.sort((a, b) => {
const order = cmp(a[0], b[0]);
if (order !== 0) return order;
return a[1] - b[1];
});
const result = stabilizedThis.map(el => el[0]);
return result;
}
function getSorting(order, orderBy) {
return order === 'asc'
? (a, b) => propertyComparatorAscending(a, b, orderBy)
: (a, b) => -propertyComparatorAscending(a, b, orderBy);
}
function TableHeadCell({
metricUid, orderBy, order, label, onClick,
}) {
return (
<TableCell
align="right"
sortDirection={orderBy === metricUid ? order : false}
>
<Tooltip
title="Click to sort the table by this column"
placement="bottom-end"
>
<TableSortLabel
active={orderBy === metricUid}
direction={order}
onClick={onClick}
>
{label}
</TableSortLabel>
</Tooltip>
</TableCell>
);
}
TableHeadCell.propTypes = {
metricUid: PropTypes.string.isRequired,
orderBy: PropTypes.string.isRequired,
order: PropTypes.string.isRequired,
label: PropTypes.string.isRequired,
onClick: PropTypes.func.isRequired,
};
class Reportees extends React.PureComponent {
state = {
orderBy: 'cn',
order: 'asc',
};
getMergedProps() {
const { metrics, partialOrg, ldapEmail } = this.props;
@ -99,111 +21,94 @@ class Reportees extends React.PureComponent {
...reportee,
...metrics[reportee.bugzillaEmail],
}));
return reporteesWithMetrics;
// Sort dataset in ascending order and return
return reporteesWithMetrics.sort((a, b) => a.cn.localeCompare(b.cn));
}
createSortHandler = property => (event) => {
this.handleRequestSort(event, property);
};
handleRequestSort = (event, property) => {
const { order, orderBy } = this.state;
let newOrder;
// If we click on the same column several times in a row, we simply switch
// the prevous value.
if (orderBy === property) {
newOrder = order === 'asc' ? 'desc' : 'asc';
} else if (property === 'cn') {
// For most properties we want to order in the descending order first.
// ... except when sorting by cn.
newOrder = 'asc';
} else {
newOrder = 'desc';
}
this.setState({
orderBy: property,
order: newOrder,
});
};
// Custom styles to override default MUI theme
getMuiTheme = () => createMuiTheme({
overrides: {
MUIDataTableBodyCell: {
root: {
textAlign: 'center',
},
},
},
});
render() {
const { classes } = this.props;
const { order, orderBy } = this.state;
// MUI table options
const options = {
filter: true,
selectableRows: false,
sort: true,
responsive: 'stacked',
rowsPerPage: 10,
download: false,
print: false,
viewColumns: false,
};
const metricsAsArray = Object.entries(CONFIG.reporteesMetrics);
const tableHeader = [];
// Form Table column headers using metricsArray
// Add Full name directly into columns Heading array
const firstColumn = {
name: 'cn',
label: 'Full Name',
};
tableHeader.push(firstColumn);
// push other columns from metricsAsArray in the config.js file to tableHeader array
metricsAsArray.forEach(([metricUid, { label }]) => {
const column = {
name: `${metricUid}`,
label,
options: {
filter: false,
customBodyRender: value => (
<a
href={value !== undefined ? value.link : '#'}
target="_blank"
rel="noopener noreferrer"
>
{ value !== undefined ? value.count : '' }
</a>
),
},
};
tableHeader.push(column);
});
return (
<div className={classes.root}>
<Table>
<TableHead>
<TableRow>
<TableHeadCell
metricUid="cn"
orderBy={orderBy}
order={order}
label="Full Name"
onClick={this.createSortHandler('cn')}
/>
{metricsAsArray.map(([metricUid, { label }]) => (
<TableHeadCell
key={metricUid}
metricUid={metricUid}
orderBy={orderBy}
order={order}
label={label}
onClick={this.createSortHandler(metricUid)}
/>
))}
</TableRow>
</TableHead>
<TableBody>
{stableSort(
this.getMergedProps(),
getSorting(order, orderBy),
)
.map(({
cn, mail, bugzillaEmail, ...metricsValues
}) => (
<TableRow key={mail}>
<TableCell key={mail}>{cn}</TableCell>
{metricsAsArray.map(([metricUid]) => {
const countLink = metricsValues[metricUid];
return (
<TableCell align="right" key={metricUid}>
{countLink && (
<a
key={countLink.link}
href={countLink.link}
target="_blank"
rel="noopener noreferrer"
>
{countLink.count}
</a>
)}
</TableCell>
);
})}
</TableRow>
))}
</TableBody>
</Table>
<MuiThemeProvider theme={this.getMuiTheme()}>
<MUIDataTable
title="Reportees"
data={this.getMergedProps()}
columns={tableHeader}
options={options}
/>
</MuiThemeProvider>
</div>
);
}
}
Reportees.propTypes = {
classes: PropTypes.shape({}).isRequired,
ldapEmail: PropTypes.string.isRequired,
ldapEmail: PropTypes.string,
partialOrg: PropTypes.shape({}).isRequired,
metrics: PropTypes.shape({}),
};
Reportees.defaultProps = {
metrics: {},
ldapEmail: '',
};
export default withStyles(styles)(Reportees);

Просмотреть файл

@ -5646,11 +5646,41 @@ lodash.clonedeep@^4.5.0:
resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef"
integrity sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=
lodash.find@^4.6.0:
version "4.6.0"
resolved "https://registry.yarnpkg.com/lodash.find/-/lodash.find-4.6.0.tgz#cb0704d47ab71789ffa0de8b97dd926fb88b13b1"
integrity sha1-ywcE1Hq3F4n/oN6Ll92Sb7iLE7E=
lodash.flow@^3.1.0:
version "3.5.0"
resolved "https://registry.yarnpkg.com/lodash.flow/-/lodash.flow-3.5.0.tgz#87bf40292b8cf83e4e8ce1a3ae4209e20071675a"
integrity sha1-h79AKSuM+D5OjOGjrkIJ4gBxZ1o=
lodash.get@^4.4.2:
version "4.4.2"
resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99"
integrity sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=
lodash.isequal@^4.5.0:
version "4.5.0"
resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0"
integrity sha1-QVxEePK8wwEgwizhDtMib30+GOA=
lodash.isundefined@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/lodash.isundefined/-/lodash.isundefined-3.0.1.tgz#23ef3d9535565203a66cefd5b830f848911afb48"
integrity sha1-I+89lTVWUgOmbO/VuDD4SJEa+0g=
lodash.memoize@^4.1.2:
version "4.1.2"
resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe"
integrity sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=
lodash.merge@^4.6.0:
version "4.6.1"
resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.1.tgz#adc25d9cb99b9391c59624f379fbba60d7111d54"
integrity sha512-AOYza4+Hf5z1/0Hztxpm2/xiPZgi/cjMqdnKTUWTBSKchJlxXXuUSxCCl8rJlf4g6yww/j6mA8nC8Hw/EZWxKQ==
lodash.omit@^4.5.0:
version "4.5.0"
resolved "https://registry.yarnpkg.com/lodash.omit/-/lodash.omit-4.5.0.tgz#6eb19ae5a1ee1dd9df0b969e66ce0b7fa30b5e60"
@ -6042,6 +6072,22 @@ ms@^2.1.1:
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a"
integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==
mui-datatables@^2.4.0:
version "2.4.0"
resolved "https://registry.yarnpkg.com/mui-datatables/-/mui-datatables-2.4.0.tgz#7bc967e5daac8e359bf217fc06c7635badd6533b"
integrity sha512-JmQjmuatUpOZPDUOOGvu4qZUSTXNwf+dQvyTX0yLosdmWJcXL9EYgrDQy2Fca3iqWDEfcLa7zdW/24zdjnltHA==
dependencies:
classnames "^2.2.5"
lodash.clonedeep "^4.5.0"
lodash.find "^4.6.0"
lodash.get "^4.4.2"
lodash.isequal "^4.5.0"
lodash.isundefined "^3.0.1"
lodash.memoize "^4.1.2"
lodash.merge "^4.6.0"
prop-types "^15.6.0"
react-to-print "^2.0.0-alpha.7"
multicast-dns-service-types@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz#899f11d9686e5e05cb91b35d5f0e63b773cfc901"
@ -7238,6 +7284,13 @@ react-test-renderer@^16.6.3:
react-is "^16.8.6"
scheduler "^0.13.6"
react-to-print@^2.0.0-alpha.7:
version "2.1.2"
resolved "https://registry.yarnpkg.com/react-to-print/-/react-to-print-2.1.2.tgz#6fb30cb79fc90f773dce76d25e2a896efd31b461"
integrity sha512-oCbFoqPxIWG2lMigp9RMEp3bw5jU2uAjs3N3EdikfemDraLTFuh+kcXdr4eazmH+734TvpCQ70sgcCOfjmXyRQ==
dependencies:
prop-types "^15.6.2"
react-transition-group@^2.2.1:
version "2.9.0"
resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-2.9.0.tgz#df9cdb025796211151a436c69a8f3b97b5b07c8d"