diff --git a/src/v2/components/Accounts/Table/index.jsx b/src/v2/components/Accounts/Table/index.jsx index 64832cff..d7ea461e 100644 --- a/src/v2/components/Accounts/Table/index.jsx +++ b/src/v2/components/Accounts/Table/index.jsx @@ -12,6 +12,7 @@ import TypeLabel from 'v2/components/UI/TypeLabel'; import Table from 'v2/components/UI/Table'; import type {TableHeadProps} from 'v2/@types/table'; import formatDistanceToNow from 'date-fns/formatDistanceToNow'; +import TableCard from 'v2/components/UI/TableCard'; import useStyles from './styles'; @@ -70,26 +71,22 @@ const AccountsTable = ({ }; const renderCard = account => { - return ( -
- -
- ); + const {programId, timestamp, pubkey} = account; + const data = [ + { + label: 'Account id', + value: programId, + }, + { + label: 'Type', + value: , + }, + { + label: 'Time', + value: asTime(timestamp), + }, + ]; + return ; }; return ( diff --git a/src/v2/components/Blocks/Table/index.jsx b/src/v2/components/Blocks/Table/index.jsx index 5fa27cce..52555cf2 100644 --- a/src/v2/components/Blocks/Table/index.jsx +++ b/src/v2/components/Blocks/Table/index.jsx @@ -12,6 +12,8 @@ import {map} from 'lodash/fp'; import Table from 'v2/components/UI/Table'; import type {TableHeadProps} from 'v2/@types/table'; import ValidatorName from 'v2/components/UI/ValidatorName'; +import TableCard from 'v2/components/UI/TableCard'; + import useStyles from './styles'; const fields: TableHeadProps[] = [ @@ -86,40 +88,34 @@ const BlocksTable = ({ }; const renderCard = block => { - return ( -
-
    -
  • -
    Block
    -
    {block.id}
    -
  • -
  • -
    Slot
    -
    {block.slot}
    -
  • -
  • -
    Time
    -
    {asTime(block.timestamp)}
    -
  • -
  • -
    Transactions
    -
    TODO
    -
  • -
  • -
    Confidence
    -
    TODO
    -
  • -
  • -
    Leader
    - -
  • -
-
- ); + const {id, slot, timestamp, leader} = block; + const data = [ + { + label: 'Block', + value: id, + }, + { + label: 'Slot', + value: slot, + }, + { + label: 'Time', + value: asTime(timestamp), + }, + { + label: 'Transactions', + value: 'TODO', + }, + { + label: 'Confidence', + value: 'TODO', + }, + { + label: 'Leader', + value: , + }, + ]; + return ; }; return ( diff --git a/src/v2/components/Blocks/Table/styles.js b/src/v2/components/Blocks/Table/styles.js index 94176fd9..4129f8e8 100644 --- a/src/v2/components/Blocks/Table/styles.js +++ b/src/v2/components/Blocks/Table/styles.js @@ -1,5 +1,4 @@ import {makeStyles} from '@material-ui/core'; -import getColor from 'v2/utils/getColor'; export default makeStyles(theme => ({ root: { @@ -18,40 +17,4 @@ export default makeStyles(theme => ({ flexDirection: 'column', }, }, - card: { - padding: 7, - background: getColor('grey2')(theme), - '& ul': { - padding: 0, - margin: 0, - display: 'flex', - flexWrap: 'wrap', - '& li': { - padding: 10, - width: '33.33%', - [theme.breakpoints.down('xs')]: { - width: '50%', - }, - '& div:last-child': { - whiteSpace: 'nowrap', - textOverflow: 'ellipsis', - overflow: 'hidden', - }, - }, - }, - }, - cardVertical: { - [theme.breakpoints.down('sm')]: { - marginBottom: 2, - marginRight: 0, - maxWidth: '100%', - }, - }, - cardTitle: { - fontSize: 12, - textTransform: 'uppercase', - color: '#C4C4C4', - letterSpacing: 2, - fontWeight: 'bold', - }, })); diff --git a/src/v2/components/HelpLink/index.jsx b/src/v2/components/HelpLink/index.jsx index a1e12ac9..7e3592ef 100644 --- a/src/v2/components/HelpLink/index.jsx +++ b/src/v2/components/HelpLink/index.jsx @@ -1,5 +1,5 @@ // @flow -import React from 'react'; +import React, {forwardRef} from 'react'; import {Link, Tooltip} from '@material-ui/core'; import {testnetDefaultChannel} from '@solana/web3.js/package.json'; @@ -7,19 +7,26 @@ import useStyles from './styles'; const BOOK_VERSION = testnetDefaultChannel === 'edge' ? 'book-edge' : 'book'; -const HelpLink = ({text, term}: {text: string, term: string}) => { - const classes = useStyles(); - return ( - - { + const classes = useStyles(); + return ( + - ? - - - ); -}; + + ? + + + ); + }, +); export default HelpLink; diff --git a/src/v2/components/Programs/Table/index.jsx b/src/v2/components/Programs/Table/index.jsx index 6633f5a7..ea93816a 100644 --- a/src/v2/components/Programs/Table/index.jsx +++ b/src/v2/components/Programs/Table/index.jsx @@ -12,6 +12,7 @@ import TypeLabel from 'v2/components/UI/TypeLabel'; import Table from 'v2/components/UI/Table'; import type {TableHeadProps} from 'v2/@types/table'; import formatDistanceToNow from 'date-fns/formatDistanceToNow'; +import TableCard from 'v2/components/UI/TableCard'; import useStyles from './styles'; @@ -70,26 +71,26 @@ const ProgramsTable = ({ }; const renderCard = program => { - return ( -
-
    -
  • -
    Program id
    -
    {program.programId}
    -
  • -
  • -
    Type
    -
    - TODO -
    -
  • -
  • -
    Time
    -
    {asTime(program.timestamp)}
    -
  • -
-
- ); + const {programId, timestamp} = program; + const data = [ + { + label: 'Program id', + value: programId, + }, + { + label: 'Type', + value: ( +
+ TODO +
+ ), + }, + { + label: 'Time', + value: asTime(timestamp), + }, + ]; + return ; }; return ( diff --git a/src/v2/components/Programs/Table/styles.js b/src/v2/components/Programs/Table/styles.js index 6eed4eb0..4129f8e8 100644 --- a/src/v2/components/Programs/Table/styles.js +++ b/src/v2/components/Programs/Table/styles.js @@ -1,5 +1,4 @@ import {makeStyles} from '@material-ui/core'; -import getColor from 'v2/utils/getColor'; export default makeStyles(theme => ({ root: { @@ -10,52 +9,6 @@ export default makeStyles(theme => ({ marginBottom: 50, }, }, - head: { - border: '1px solid #979797', - '& th': { - textTransform: 'uppercase', - fontSize: 15, - letterSpacing: 2, - fontWeight: 'bold', - borderBottom: 'none', - paddingRight: 16, - '&:first-child': { - paddingLeft: 40, - }, - }, - }, - body: { - '& td': { - fontSize: 15, - paddingTop: 18, - paddingBottom: 18, - maxWidth: 0, - whiteSpace: 'nowrap', - textOverflow: 'ellipsis', - overflow: 'hidden', - paddingRight: 16, - '&:first-child': { - paddingLeft: 40, - }, - }, - }, - name: { - display: 'flex', - alignItems: 'center', - color: getColor('main')(theme), - textDecoration: 'none', - '& div': { - '&:first-child': { - marginRight: 15, - }, - whiteSpace: 'nowrap', - textOverflow: 'ellipsis', - overflow: 'hidden', - }, - [theme.breakpoints.down('sm')]: { - marginBottom: 22, - }, - }, list: { width: '100%', }, @@ -64,43 +17,4 @@ export default makeStyles(theme => ({ flexDirection: 'column', }, }, - card: { - padding: 7, - background: getColor('grey2')(theme), - '& ul': { - padding: 0, - margin: 0, - display: 'flex', - flexWrap: 'wrap', - '& li': { - padding: 10, - width: '33.33%', - [theme.breakpoints.down('xs')]: { - width: '50%', - }, - }, - }, - }, - cardVertical: { - [theme.breakpoints.down('sm')]: { - marginBottom: 2, - marginRight: 0, - maxWidth: '100%', - }, - }, - cardTitle: { - fontSize: 12, - textTransform: 'uppercase', - color: '#C4C4C4', - letterSpacing: 2, - fontWeight: 'bold', - }, - miner: { - display: 'flex', - alignItems: 'center', - color: getColor('main')(theme), - '& div': { - marginLeft: 5, - }, - }, })); diff --git a/src/v2/components/Transactions/Table/index.jsx b/src/v2/components/Transactions/Table/index.jsx index 30feda1e..93ffdd12 100644 --- a/src/v2/components/Transactions/Table/index.jsx +++ b/src/v2/components/Transactions/Table/index.jsx @@ -12,6 +12,7 @@ import TypeLabel from 'v2/components/UI/TypeLabel'; import Table from 'v2/components/UI/Table'; import type {TableHeadProps} from 'v2/@types/table'; import formatDistanceToNow from 'date-fns/formatDistanceToNow'; +import TableCard from 'v2/components/UI/TableCard'; import useStyles from './styles'; @@ -100,53 +101,46 @@ const TransactionsTable = ({ }; const renderCard = transaction => { - return ( -
-
    -
  • -
    Hash
    - -
    {transaction.id}
    - -
  • -
  • -
    Block
    - - {transaction.blockId} - -
  • -
  • -
    Time
    -
    - {asTime(transaction.timestamp)} -
    -
  • -
  • -
    Program ID
    - -
    {transaction.instructions[0].programId}
    - -
  • -
  • -
    Type
    - TODO -
  • -
  • -
    Confirmations
    -
    TODO
    -
  • -
-
- ); + const {id, blockId, timestamp, instructions} = transaction; + const data = [ + { + label: 'Hash', + value: ( + +
{id}
+ + ), + }, + { + label: 'Block', + value: ( + +
{blockId}
+ + ), + }, + { + label: 'Time', + value: asTime(timestamp), + }, + { + label: 'Program ID', + value: ( + +
{instructions[0].programId}
+ + ), + }, + { + label: 'Type', + value: , + }, + { + label: 'Confirmations', + value: 'TODO', + }, + ]; + return ; }; return ( diff --git a/src/v2/components/UI/TabNav/index.jsx b/src/v2/components/UI/TabNav/index.jsx index 3d9fa090..3c38ca58 100644 --- a/src/v2/components/UI/TabNav/index.jsx +++ b/src/v2/components/UI/TabNav/index.jsx @@ -1,6 +1,6 @@ // @flow import {Tab} from '@material-ui/core'; -import React from 'react'; +import React, {forwardRef} from 'react'; import arrowDarkIcon from 'v2/assets/icons/arrow-right-dark.png'; import arrowIcon from 'v2/assets/icons/arrow-right-green.png'; @@ -15,14 +15,20 @@ const TabNav = ({label, ...rest}: {label: string}) => { root: classes.tab, selected: classes.tabSelected, }} - component={({className, 'aria-selected': selected, onClick}) => { - return ( -
- {label} - -
- ); - }} + component={forwardRef( + ({className, 'aria-selected': selected, onClick}, ref) => { + return ( +
+ {label} + +
+ ); + }, + )} /> ); }; diff --git a/src/v2/components/UI/TableCard/index.jsx b/src/v2/components/UI/TableCard/index.jsx new file mode 100644 index 00000000..2666b7a3 --- /dev/null +++ b/src/v2/components/UI/TableCard/index.jsx @@ -0,0 +1,22 @@ +import React from 'react'; +import cn from 'classnames'; +import {map} from 'lodash/fp'; + +import useStyles from './styles'; + +const TableCard = ({data, vertical = false}) => { + const classes = useStyles(); + const renderItem = ({label, value}) => ( +
  • +
    {label}
    +
    {value}
    +
  • + ); + return ( +
    +
      {map(renderItem)(data)}
    +
    + ); +}; + +export default TableCard; diff --git a/src/v2/components/UI/TableCard/styles.js b/src/v2/components/UI/TableCard/styles.js new file mode 100644 index 00000000..a079f98d --- /dev/null +++ b/src/v2/components/UI/TableCard/styles.js @@ -0,0 +1,43 @@ +import {makeStyles} from '@material-ui/core'; +import getColor from 'v2/utils/getColor'; + +export default makeStyles(theme => ({ + card: { + padding: 7, + background: getColor('grey2')(theme), + marginBottom: 1, + borderRight: `1px solid ${getColor('dark')(theme)}`, + '& ul': { + padding: 0, + margin: 0, + display: 'flex', + flexWrap: 'wrap', + '& li': { + padding: 10, + width: '33.33%', + [theme.breakpoints.down('xs')]: { + width: '50%', + }, + '& div:last-child': { + whiteSpace: 'nowrap', + textOverflow: 'ellipsis', + overflow: 'hidden', + }, + }, + }, + }, + vertical: { + [theme.breakpoints.down('sm')]: { + marginBottom: 2, + marginRight: 0, + maxWidth: '100%', + }, + }, + cardTitle: { + fontSize: 12, + textTransform: 'uppercase', + color: '#C4C4C4', + letterSpacing: 2, + fontWeight: 'bold', + }, +})); diff --git a/src/v2/components/Validators/Detail/index.jsx b/src/v2/components/Validators/Detail/index.jsx index 43837147..61161c34 100644 --- a/src/v2/components/Validators/Detail/index.jsx +++ b/src/v2/components/Validators/Detail/index.jsx @@ -13,13 +13,12 @@ import Button from 'v2/components/UI/Button'; import Mixpanel from 'v2/mixpanel'; import CopyBtn from 'v2/components/UI/CopyBtn'; import ValidatorName from 'v2/components/UI/ValidatorName'; -import {LAMPORT_SOL_RATIO} from 'v2/constants'; import ValidatorsMap from 'v2/components/ValidatorsMap'; import useStyles from './styles'; const ValidatorsDetail = ({match}: {match: Match}) => { - const {validators, inactiveValidators, totalStaked} = NodesStore; + const {validators, inactiveValidators} = NodesStore; const classes = useStyles(); const theme = useTheme(); @@ -43,11 +42,13 @@ const ValidatorsDetail = ({match}: {match: Match}) => { const { nodePubkey, gossip, - activatedStake, commission, identity = {}, coordinates, + stakedSol, + stakedSolPercent, } = node; + const markers = [{gossip, coordinates, name: nodePubkey}]; const specs = [ { @@ -65,10 +66,7 @@ const ValidatorsDetail = ({match}: {match: Match}) => { { label: 'Staked SOL', hint: '', - value: `${(activatedStake * LAMPORT_SOL_RATIO).toFixed(8)} (${( - 100 * - (activatedStake / totalStaked) - ).toFixed(3)}%)`, + value: `${stakedSol} (${stakedSolPercent}%)`, }, { label: 'Website', diff --git a/src/v2/components/Validators/Table/index.jsx b/src/v2/components/Validators/Table/index.jsx index 75aa5c78..752d6f6d 100644 --- a/src/v2/components/Validators/Table/index.jsx +++ b/src/v2/components/Validators/Table/index.jsx @@ -5,7 +5,6 @@ import { Typography, TableCell, TableRow, - Grid, Select, MenuItem, } from '@material-ui/core'; @@ -18,11 +17,11 @@ import {eq, map, concat} from 'lodash/fp'; import NodesStore from 'v2/stores/nodes'; import getUptime from 'v2/utils/getUptime'; 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 HelpLink from 'v2/components/HelpLink'; import ValidatorName from 'v2/components/UI/ValidatorName'; +import TableCard from 'v2/components/UI/TableCard'; import useStyles from './styles'; @@ -57,7 +56,8 @@ const ValidatorsTable = ({separate}: {separate: boolean}) => { const classes = useStyles(); const theme = useTheme(); const showTable = useMediaQuery(theme.breakpoints.up('md')); - const {activeValidators, inactiveValidators, totalStaked} = NodesStore; + const {activeValidators, inactiveValidators} = NodesStore; + const {isLoading} = Socket; const isActiveTab = eq(tab); const switchTab = tab => () => setTab(tab); @@ -72,7 +72,13 @@ const ValidatorsTable = ({separate}: {separate: boolean}) => { const renderRow = ({data: row}) => { const uptime = row.uptime && getUptime(row); - const {identity = {}, nodePubkey, activatedStake, commission} = row; + const { + identity = {}, + nodePubkey, + stakedSol, + stakedSolPercent, + commission, + } = row; return ( @@ -83,12 +89,9 @@ const ValidatorsTable = ({separate}: {separate: boolean}) => { /> - {activatedStake && ( -
    - {(activatedStake * LAMPORT_SOL_RATIO).toFixed(8) || 'N/A'} ( - {(100 * (activatedStake / totalStaked)).toFixed(3)}%) -
    - )} +
    + {stakedSol || 'N/A'} ({stakedSolPercent}%) +
    {commission || 'N/A'} @@ -101,40 +104,44 @@ const ValidatorsTable = ({separate}: {separate: boolean}) => { }; const renderCard = card => { const uptime = card.uptime && getUptime(card); - const {identity = {}, nodePubkey, activatedStake, commission} = card; - return ( -
    - - - -
    Stake
    -
    - {(activatedStake * LAMPORT_SOL_RATIO).toFixed(8) || 'N/A'} ( - {(100 * (activatedStake / totalStaked)).toFixed(3)}%) -
    -
    - -
    Commission
    -
    - {commission || 'N/A'} - {Boolean(commission) && - ` (${(100 * (commission / 0xff)).toFixed(3)}%)`} -
    -
    - -
    Uptime
    -
    {(uptime && uptime + '%') || 'Unavailable'}
    -
    -
    -
    - ); + const { + identity = {}, + nodePubkey, + stakedSol, + stakedSolPercent, + commission, + } = card; + const data = [ + { + label: 'Name', + value: ( + + ), + }, + { + label: 'Stake', + value: `${stakedSol || 'N/A'} (${stakedSolPercent}%)`, + }, + { + label: 'Commission', + value: ( +
    + {commission || 'N/A'} + {Boolean(commission) && + ` (${(100 * (commission / 0xff)).toFixed(3)}%)`} +
    + ), + }, + { + label: 'Uptime', + value: (uptime && uptime + '%') || 'Unavailable', + }, + ]; + return ; }; const allValidators = concat(activeValidators)(inactiveValidators); diff --git a/src/v2/stores/nodes.js b/src/v2/stores/nodes.js index 465c0a3b..394482b2 100644 --- a/src/v2/stores/nodes.js +++ b/src/v2/stores/nodes.js @@ -2,11 +2,20 @@ import {compose, filter, map} from 'lodash/fp'; import {action, computed, decorate, observable, flow} from 'mobx'; import * as API from 'v2/api/stats'; +import {LAMPORT_SOL_RATIO} from '../constants'; + +const addNetworkSolInfo = totalStaked => node => ({ + ...node, + stakedSol: (node.activatedStake * LAMPORT_SOL_RATIO).toFixed(8), + stakedSolPercent: (100 * (node.activatedStake / totalStaked)).toFixed(3), +}); + class Store { cluster = { network: {}, }; clusterChanges = {}; + network = []; // constructor() { // observe(this, 'network', ({oldValue, newValue}) => { @@ -27,7 +36,9 @@ class Store { updateClusterInfo = data => { data = JSON.parse(data); - this.network = data.network || {}; + this.network = data.network + ? map(addNetworkSolInfo(data.totalStaked))(data.network) + : []; this.totalStaked = data.totalStaked; this.supply = data.supply; this.networkInflationRate = data.networkInflationRate; @@ -37,7 +48,9 @@ class Store { try { const res = yield API.getClusterInfo(); const data = res.data; - this.network = data.network; + this.network = data.network + ? map(addNetworkSolInfo(data.totalStaked))(data.network) + : []; this.totalStaked = data.totalStaked; this.supply = data.supply; this.networkInflationRate = data.networkInflationRate; @@ -48,7 +61,7 @@ class Store { }); get mapMarkers() { - if (!this.network) { + if (!this.network.length) { return []; }