diff --git a/src/components/ConnectionTable.module.scss b/src/components/ConnectionTable.module.scss index a14904f..6e453ad 100644 --- a/src/components/ConnectionTable.module.scss +++ b/src/components/ConnectionTable.module.scss @@ -1,7 +1,6 @@ .tr { display: grid; - /* grid-template-columns: repeat(11, minmax(max-content, 1fr)); */ - grid-template-columns: repeat(12, minmax(max-content, auto)); + grid-template-columns: repeat(var(--col-count, 11), minmax(max-content, auto)); } .th { diff --git a/src/components/ConnectionTable.tsx b/src/components/ConnectionTable.tsx index a5361a0..c84f3a0 100644 --- a/src/components/ConnectionTable.tsx +++ b/src/components/ConnectionTable.tsx @@ -6,10 +6,11 @@ import { useSortBy, useTable } from 'react-table'; import prettyBytes from '../misc/pretty-bytes'; import s from './ConnectionTable.module.scss'; +import { MutableConnRefCtx } from './conns/ConnCtx'; const sortDescFirst = true; -const columns = [ +const fullColumns = [ { accessor: 'id', show: false }, { Header: 'Host', accessor: 'host' }, { Header: 'Process', accessor: 'process' }, @@ -25,6 +26,9 @@ const columns = [ { Header: 'Type', accessor: 'type' }, ]; +const columns = fullColumns; +const columnsWithoutProcess = fullColumns.filter((item) => item.accessor !== 'process'); + function renderCell(cell: { column: { id: string }; value: number }) { switch (cell.column.id) { case 'start': @@ -50,9 +54,10 @@ const tableState = { }; function Table({ data }) { + const connCtx = React.useContext(MutableConnRefCtx); const { getTableProps, headerGroups, rows, prepareRow } = useTable( { - columns, + columns: connCtx.hasProcessPath ? columns : columnsWithoutProcess, data, initialState: tableState, autoResetSortBy: false, @@ -60,7 +65,13 @@ function Table({ data }) { useSortBy ); return ( -
+
{headerGroups.map((headerGroup) => { return (
@@ -86,7 +97,13 @@ function Table({ data }) { className={cx( s.td, i % 2 === 0 ? s.odd : false, - j >= 2 && j <= 5 ? s.du : false + connCtx.hasProcessPath + ? j >= 2 && j <= 5 + ? s.du + : false + : j >= 1 && j <= 4 + ? s.du + : false )} > {renderCell(cell)} diff --git a/src/components/Connections.tsx b/src/components/Connections.tsx index 5b5e990..25d557a 100644 --- a/src/components/Connections.tsx +++ b/src/components/Connections.tsx @@ -17,6 +17,7 @@ import ModalCloseAllConnections from './ModalCloseAllConnections'; import { Action, Fab, position as fabPosition } from './shared/Fab'; import { connect } from './StateProvider'; import SvgYacd from './SvgYacd'; +import { MutableConnRefCtx } from './conns/ConnCtx'; const { useEffect, useState, useRef, useCallback } = React; @@ -31,8 +32,8 @@ function arrayToIdKv(items: T[]) { return o; } -function basePath (path: string) { - return path.replace(/.*[/\\]/, '') +function basePath(path: string) { + return path?.replace(/.*[/\\]/, ''); } type FormattedConn = { @@ -50,7 +51,7 @@ type FormattedConn = { host: string; type: string; network: string; - processPath: string; + processPath?: string; downloadSpeedCurr?: number; uploadSpeedCurr?: number; }; @@ -80,10 +81,16 @@ function filterConns(conns: FormattedConn[], keyword: string) { function formatConnectionDataItem( i: ConnectionItem, prevKv: Record, - now: number + now: number, + mutConnCtxRef: { hasProcessPath: boolean } ): FormattedConn { const { id, metadata, upload, download, start, chains, rule, rulePayload } = i; - const { host, destinationPort, destinationIP, network, type, sourceIP, sourcePort, processPath } = metadata; + const { host, destinationPort, destinationIP, network, type, sourceIP, sourcePort } = metadata; + const processPath = metadata.processPath; + if (mutConnCtxRef.hasProcessPath === false && typeof processPath !== 'undefined') { + mutConnCtxRef.hasProcessPath = true; + } + // host could be an empty string if it's direct IP connection let host2 = host; if (host2 === '') host2 = destinationIP; @@ -139,12 +146,13 @@ function Conn({ apiConfig }) { closeCloseAllModal(); }, [apiConfig, closeCloseAllModal]); const prevConnsRef = useRef(conns); + const connCtx = React.useContext(MutableConnRefCtx); const read = useCallback( ({ connections }) => { const prevConnsKv = arrayToIdKv(prevConnsRef.current); const now = Date.now(); const x = connections.map((c: ConnectionItem) => - formatConnectionDataItem(c, prevConnsKv, now) + formatConnectionDataItem(c, prevConnsKv, now, connCtx) ); const closed = []; for (const c of prevConnsRef.current) { diff --git a/src/components/Root.tsx b/src/components/Root.tsx index 3e0a339..b439ba6 100644 --- a/src/components/Root.tsx +++ b/src/components/Root.tsx @@ -13,6 +13,7 @@ import { queryClient } from 'src/misc/query'; import { actions, initialState } from '../store'; import APIConfig from './APIConfig'; import APIDiscovery from './APIDiscovery'; +import { MutableConnRefCtx } from './conns/ConnCtx'; import ErrorBoundary from './ErrorBoundary'; import Home from './Home'; import Loading2 from './Loading2'; @@ -31,7 +32,14 @@ const Rules = lazy(() => import('./Rules')); const routes = [ { path: '/', element: }, - { path: '/connections', element: }, + { + path: '/connections', + element: ( + + + + ), + }, { path: '/configs', element: }, { path: '/logs', element: }, { path: '/proxies', element: }, diff --git a/src/components/conns/ConnCtx.tsx b/src/components/conns/ConnCtx.tsx new file mode 100644 index 0000000..0f08395 --- /dev/null +++ b/src/components/conns/ConnCtx.tsx @@ -0,0 +1,7 @@ +import * as React from 'react'; + +const ref = { + hasProcessPath: false, +}; + +export const MutableConnRefCtx = React.createContext(ref);