summaryrefslogtreecommitdiff
path: root/src/components
diff options
context:
space:
mode:
authorHaishan <[email protected]>2020-02-23 18:02:03 +0800
committerHaishan <[email protected]>2020-03-01 14:48:15 +0800
commit2ff62bb0b90176b51058c3858ab9c5b2bc4a603f (patch)
treee4da1de8dad90bfcba36457ec1e9ca41a2be4eb5 /src/components
parent7441c50f6a2564bd18f7e8b5c78ebff091c90841 (diff)
feat(conns): show download upload speed
Diffstat (limited to 'src/components')
-rw-r--r--src/components/ConnectionTable.js79
-rw-r--r--src/components/ConnectionTable.module.css2
-rw-r--r--src/components/Connections.js20
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);