diff --git a/src/v2/components/UI/Table/index.jsx b/src/v2/components/UI/Table/index.jsx
new file mode 100644
index 00000000..cf69f534
--- /dev/null
+++ b/src/v2/components/UI/Table/index.jsx
@@ -0,0 +1,108 @@
+import React, {useState} from 'react';
+import {map, get} from 'lodash/fp';
+import {
+ TableBody,
+ Table,
+ TableHead,
+ TableRow,
+ TableCell,
+ TableSortLabel,
+} from '@material-ui/core';
+
+import HelpLink from '../../HelpLink';
+import useStyles from './styles';
+
+function desc(a, b, orderBy) {
+ const getA = get(orderBy)(a);
+ const getB = get(orderBy)(b);
+ if (getB < getA) {
+ return -1;
+ }
+ if (getB > getA) {
+ return 1;
+ }
+ return 0;
+}
+
+function stableSort(array, cmp) {
+ const stabilizedThis = map((el, index) => [el, index])(array);
+ stabilizedThis.sort((a, b) => {
+ const order = cmp(a[0], b[0]);
+ if (order !== 0) return order;
+ return a[1] - b[1];
+ });
+ return map(el => el[0])(stabilizedThis);
+}
+
+function getSorting(order, orderBy) {
+ return order === 'desc'
+ ? (a, b) => desc(a, b, orderBy)
+ : (a, b) => -desc(a, b, orderBy);
+}
+
+const EnhancedTableHead = props => {
+ const classes = useStyles();
+ const {fields, order, orderBy, onRequestSort, text, term} = props;
+
+ const createSortHandler = property => event => {
+ onRequestSort(event, property);
+ };
+
+ return (
+
+
+ {map(
+ headCell => (
+
+
+ {headCell.label}
+
+
+
+ ),
+ fields,
+ )}
+
+
+ );
+};
+
+const EnhancedTable = props => {
+ const classes = useStyles();
+ const {data = [], fields, renderRow, initialSort = 'name'} = props;
+ const [order, setOrder] = useState('asc');
+ const [orderBy, setOrderBy] = React.useState(initialSort);
+ const handleRequestSort = (event, property) => {
+ const isDesc = orderBy === property && order === 'desc';
+ setOrder(isDesc ? 'asc' : 'desc');
+ setOrderBy(property);
+ };
+
+ return (
+
+
+
+ {map(renderRow)(stableSort(data, getSorting(order, orderBy)))}
+
+
+ );
+};
+
+EnhancedTable.propTypes = {};
+
+export default EnhancedTable;
diff --git a/src/v2/components/UI/Table/styles.js b/src/v2/components/UI/Table/styles.js
new file mode 100644
index 00000000..4ff30c05
--- /dev/null
+++ b/src/v2/components/UI/Table/styles.js
@@ -0,0 +1,21 @@
+import {makeStyles} from '@material-ui/core';
+
+export default makeStyles(() => ({
+ head: {
+ border: '1px solid #979797',
+ '& th': {
+ textTransform: 'uppercase',
+ fontSize: 15,
+ letterSpacing: 2,
+ fontWeight: 'bold',
+ borderBottom: 'none',
+ },
+ },
+ root: {
+ '& td': {
+ maxWidth: 1,
+ overflow: 'hidden',
+ textOverflow: 'ellipsis',
+ },
+ },
+}));
diff --git a/src/v2/components/Validators/Table/index.jsx b/src/v2/components/Validators/Table/index.jsx
index 0be0d280..2796a568 100644
--- a/src/v2/components/Validators/Table/index.jsx
+++ b/src/v2/components/Validators/Table/index.jsx
@@ -1,31 +1,49 @@
// @flow
import React from 'react';
-import {
- Typography,
- Table,
- TableBody,
- TableCell,
- TableHead,
- TableRow,
- Grid,
-} from '@material-ui/core';
+import {Typography, TableCell, TableRow, Grid} from '@material-ui/core';
import cn from 'classnames';
import useMediaQuery from '@material-ui/core/useMediaQuery';
import {useTheme} from '@material-ui/core/styles';
import {observer} from 'mobx-react-lite';
import {Link} from 'react-router-dom';
-import {map} from 'lodash/fp';
+import {map, concat} from 'lodash/fp';
import NodesStore from 'v2/stores/nodes';
import getUptime from 'v2/utils/getUptime';
import Avatar from 'v2/components/UI/Avatar';
+import Table from 'v2/components/UI/Table';
+import {LAMPORT_SOL_RATIO} from 'v2/constants';
+import Socket from 'v2/stores/socket';
+import Loader from 'v2/components/UI/Loader';
-import {LAMPORT_SOL_RATIO} from '../../../constants';
-import Socket from '../../../stores/socket';
-import Loader from '../../UI/Loader';
-import HelpLink from '../../HelpLink';
import useStyles from './styles';
+const fields = [
+ {
+ id: 'identity.name',
+ label: 'Name/Moniker',
+ text: '',
+ term: '',
+ },
+ {
+ id: 'activatedStake',
+ label: 'Staked SOL',
+ text: '',
+ term: '',
+ },
+ {
+ id: 'commission',
+ label: 'Commission',
+ text: '',
+ term: '',
+ },
+ {
+ id: 'uptime.uptime.[0].percentage',
+ label: 'Uptime',
+ text: 'term',
+ },
+];
+
const ValidatorsTable = ({separate}: {separate: boolean}) => {
const classes = useStyles();
const theme = useTheme();
@@ -95,6 +113,9 @@ const ValidatorsTable = ({separate}: {separate: boolean}) => {
);
};
+
+ const allValidators = concat(activeValidators)(inactiveValidators);
+
return (
{!separate && (
@@ -103,39 +124,18 @@ const ValidatorsTable = ({separate}: {separate: boolean}) => {
{activeValidators.length + inactiveValidators.length}
-
See all >
)}
{showTable ? (
-
-
-
-
- Name/Moniker
-
-
- Staked SOL
-
-
- Commission
-
-
- Uptime
-
-
-
-
- {map(renderRow)(activeValidators)}
- {map(renderRow)(inactiveValidators)}
-
-
+
) : (
{map(renderCard)(activeValidators)}
diff --git a/src/v2/components/Validators/Table/styles.js b/src/v2/components/Validators/Table/styles.js
index 82bf0feb..8595c791 100644
--- a/src/v2/components/Validators/Table/styles.js
+++ b/src/v2/components/Validators/Table/styles.js
@@ -19,16 +19,6 @@ export default makeStyles(theme => ({
padding: 0,
background: 'transparent',
},
- head: {
- border: '1px solid #979797',
- '& th': {
- textTransform: 'uppercase',
- fontSize: 15,
- letterSpacing: 2,
- fontWeight: 'bold',
- borderBottom: 'none',
- },
- },
body: {
'& td': {
fontSize: 15,