diff options
| author | Haishan <[email protected]> | 2020-02-23 18:02:03 +0800 |
|---|---|---|
| committer | Haishan <[email protected]> | 2020-03-01 14:48:15 +0800 |
| commit | 2ff62bb0b90176b51058c3858ab9c5b2bc4a603f (patch) | |
| tree | e4da1de8dad90bfcba36457ec1e9ca41a2be4eb5 /src | |
| parent | 7441c50f6a2564bd18f7e8b5c78ebff091c90841 (diff) | |
feat(conns): show download upload speed
Diffstat (limited to 'src')
| -rw-r--r-- | src/components/ConnectionTable.js | 79 | ||||
| -rw-r--r-- | src/components/ConnectionTable.module.css | 2 | ||||
| -rw-r--r-- | src/components/Connections.js | 20 |
3 files changed, 61 insertions, 40 deletions
diff --git a/src/components/ConnectionTable.js b/src/components/ConnectionTable.js index d2afd22..52fd1d6 100644 --- a/src/components/ConnectionTable.js +++ b/src/components/ConnectionTable.js @@ -12,6 +12,8 @@ const columns = [ { Header: 'Host', accessor: 'host' }, { Header: 'Download', accessor: 'download' }, { Header: 'Upload', accessor: 'upload' }, + { Header: 'Download Speed', accessor: 'downloadSpeedCurr' }, + { Header: 'Upload Speed', accessor: 'uploadSpeedCurr' }, { Header: 'Network', accessor: 'network' }, { Header: 'Type', accessor: 'type' }, { Header: 'Chains', accessor: 'chains' }, @@ -29,6 +31,9 @@ function renderCell(cell, now) { case 'download': case 'upload': return prettyBytes(cell.value); + case 'downloadSpeedCurr': + case 'uploadSpeedCurr': + return prettyBytes(cell.value) + '/s'; default: return cell.value; } @@ -57,43 +62,45 @@ function Table({ data }) { return ( <div {...getTableProps()}> <div className={s.thead}> - {headerGroups.map(headerGroup => ( - <div {...headerGroup.getHeaderGroupProps()} className={s.tr}> - {headerGroup.headers.map(column => ( - <div - {...column.getHeaderProps(column.getSortByToggleProps())} - className={s.th} - > - <span>{column.render('Header')}</span> - <span className={s.sortIconContainer}> - {column.isSorted ? ( - <span className={column.isSortedDesc ? '' : s.rotate180}> - <ChevronDown size={16} /> - </span> - ) : null} - </span> - </div> - ))} + {headerGroups.map(headerGroup => { + return ( + <div {...headerGroup.getHeaderGroupProps()} className={s.tr}> + {headerGroup.headers.map(column => ( + <div + {...column.getHeaderProps(column.getSortByToggleProps())} + className={s.th} + > + <span>{column.render('Header')}</span> + <span className={s.sortIconContainer}> + {column.isSorted ? ( + <span className={column.isSortedDesc ? '' : s.rotate180}> + <ChevronDown size={16} /> + </span> + ) : null} + </span> + </div> + ))} - {rows.map((row, i) => { - prepareRow(row); - return row.cells.map((cell, j) => { - return ( - <div - {...cell.getCellProps()} - className={cx( - s.td, - i % 2 === 0 ? s.odd : false, - j === 1 || j === 2 ? s.du : false - )} - > - {renderCell(cell, now)} - </div> - ); - }); - })} - </div> - ))} + {rows.map((row, i) => { + prepareRow(row); + return row.cells.map((cell, j) => { + return ( + <div + {...cell.getCellProps()} + className={cx( + s.td, + i % 2 === 0 ? s.odd : false, + j >= 1 && j <= 4 ? s.du : false + )} + > + {renderCell(cell, now)} + </div> + ); + }); + })} + </div> + ); + })} </div> </div> ); diff --git a/src/components/ConnectionTable.module.css b/src/components/ConnectionTable.module.css index 467904c..6697b58 100644 --- a/src/components/ConnectionTable.module.css +++ b/src/components/ConnectionTable.module.css @@ -1,6 +1,6 @@ .thead .tr { display: grid; - grid-template-columns: repeat(11, max-content); + grid-template-columns: repeat(13, max-content); } .th { diff --git a/src/components/Connections.js b/src/components/Connections.js index aa26478..bb58c5a 100644 --- a/src/components/Connections.js +++ b/src/components/Connections.js @@ -18,7 +18,16 @@ const { useEffect, useState, useRef, useCallback, useMemo } = React; const paddingBottom = 30; -function formatConnectionDataItem(i) { +function arrayToIdKv(items) { + const o = {}; + for (let i = 0; i < items.length; i++) { + const item = items[i]; + o[item.id] = item; + } + return o; +} + +function formatConnectionDataItem(i, prevKv) { const { id, metadata, upload, download, start, chains, rule } = i; let { host, destinationPort, destinationIP } = metadata; // host could be an empty string if it's direct IP connection @@ -29,7 +38,7 @@ function formatConnectionDataItem(i) { host: host + ':' + destinationPort }; // const started = formatDistance(new Date(start), now); - return { + const ret = { id, upload, download, @@ -38,6 +47,10 @@ function formatConnectionDataItem(i) { rule, ...metadataNext }; + const prev = prevKv[id]; + ret.downloadSpeedCurr = download - (prev ? prev.download : 0); + ret.uploadSpeedCurr = upload - (prev ? prev.upload : 0); + return ret; } function renderTableOrPlaceholder(conns) { @@ -72,7 +85,8 @@ function Conn({ apiConfig }) { const prevConnsRef = useRef(conns); const read = useCallback( ({ connections }) => { - const x = connections.map(c => formatConnectionDataItem(c)); + const prevConnsKv = arrayToIdKv(prevConnsRef.current); + const x = connections.map(c => formatConnectionDataItem(c, prevConnsKv)); const closed = []; for (const c of prevConnsRef.current) { const idx = x.findIndex(conn => conn.id === c.id); |
