Improve compatibility for connections without processPath

This commit is contained in:
Peanuts 2022-11-11 10:50:40 +08:00 committed by Haishan
parent c33bc0b8b8
commit 4b657ba372
5 changed files with 52 additions and 13 deletions

View file

@ -1,7 +1,6 @@
.tr { .tr {
display: grid; display: grid;
/* grid-template-columns: repeat(11, minmax(max-content, 1fr)); */ grid-template-columns: repeat(var(--col-count, 11), minmax(max-content, auto));
grid-template-columns: repeat(12, minmax(max-content, auto));
} }
.th { .th {

View file

@ -6,10 +6,11 @@ import { useSortBy, useTable } from 'react-table';
import prettyBytes from '../misc/pretty-bytes'; import prettyBytes from '../misc/pretty-bytes';
import s from './ConnectionTable.module.scss'; import s from './ConnectionTable.module.scss';
import { MutableConnRefCtx } from './conns/ConnCtx';
const sortDescFirst = true; const sortDescFirst = true;
const columns = [ const fullColumns = [
{ accessor: 'id', show: false }, { accessor: 'id', show: false },
{ Header: 'Host', accessor: 'host' }, { Header: 'Host', accessor: 'host' },
{ Header: 'Process', accessor: 'process' }, { Header: 'Process', accessor: 'process' },
@ -25,6 +26,9 @@ const columns = [
{ Header: 'Type', accessor: 'type' }, { Header: 'Type', accessor: 'type' },
]; ];
const columns = fullColumns;
const columnsWithoutProcess = fullColumns.filter((item) => item.accessor !== 'process');
function renderCell(cell: { column: { id: string }; value: number }) { function renderCell(cell: { column: { id: string }; value: number }) {
switch (cell.column.id) { switch (cell.column.id) {
case 'start': case 'start':
@ -50,9 +54,10 @@ const tableState = {
}; };
function Table({ data }) { function Table({ data }) {
const connCtx = React.useContext(MutableConnRefCtx);
const { getTableProps, headerGroups, rows, prepareRow } = useTable( const { getTableProps, headerGroups, rows, prepareRow } = useTable(
{ {
columns, columns: connCtx.hasProcessPath ? columns : columnsWithoutProcess,
data, data,
initialState: tableState, initialState: tableState,
autoResetSortBy: false, autoResetSortBy: false,
@ -60,7 +65,13 @@ function Table({ data }) {
useSortBy useSortBy
); );
return ( return (
<div {...getTableProps()}> <div
{...getTableProps()}
style={{
// @ts-ignore
'--col-count': connCtx.hasProcessPath ? '12' : '11',
}}
>
{headerGroups.map((headerGroup) => { {headerGroups.map((headerGroup) => {
return ( return (
<div {...headerGroup.getHeaderGroupProps()} className={s.tr}> <div {...headerGroup.getHeaderGroupProps()} className={s.tr}>
@ -86,7 +97,13 @@ function Table({ data }) {
className={cx( className={cx(
s.td, s.td,
i % 2 === 0 ? s.odd : false, 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)} {renderCell(cell)}

View file

@ -17,6 +17,7 @@ import ModalCloseAllConnections from './ModalCloseAllConnections';
import { Action, Fab, position as fabPosition } from './shared/Fab'; import { Action, Fab, position as fabPosition } from './shared/Fab';
import { connect } from './StateProvider'; import { connect } from './StateProvider';
import SvgYacd from './SvgYacd'; import SvgYacd from './SvgYacd';
import { MutableConnRefCtx } from './conns/ConnCtx';
const { useEffect, useState, useRef, useCallback } = React; const { useEffect, useState, useRef, useCallback } = React;
@ -31,8 +32,8 @@ function arrayToIdKv<T extends { id: string }>(items: T[]) {
return o; return o;
} }
function basePath (path: string) { function basePath(path: string) {
return path.replace(/.*[/\\]/, '') return path?.replace(/.*[/\\]/, '');
} }
type FormattedConn = { type FormattedConn = {
@ -50,7 +51,7 @@ type FormattedConn = {
host: string; host: string;
type: string; type: string;
network: string; network: string;
processPath: string; processPath?: string;
downloadSpeedCurr?: number; downloadSpeedCurr?: number;
uploadSpeedCurr?: number; uploadSpeedCurr?: number;
}; };
@ -80,10 +81,16 @@ function filterConns(conns: FormattedConn[], keyword: string) {
function formatConnectionDataItem( function formatConnectionDataItem(
i: ConnectionItem, i: ConnectionItem,
prevKv: Record<string, { upload: number; download: number }>, prevKv: Record<string, { upload: number; download: number }>,
now: number now: number,
mutConnCtxRef: { hasProcessPath: boolean }
): FormattedConn { ): FormattedConn {
const { id, metadata, upload, download, start, chains, rule, rulePayload } = i; 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 // host could be an empty string if it's direct IP connection
let host2 = host; let host2 = host;
if (host2 === '') host2 = destinationIP; if (host2 === '') host2 = destinationIP;
@ -139,12 +146,13 @@ function Conn({ apiConfig }) {
closeCloseAllModal(); closeCloseAllModal();
}, [apiConfig, closeCloseAllModal]); }, [apiConfig, closeCloseAllModal]);
const prevConnsRef = useRef(conns); const prevConnsRef = useRef(conns);
const connCtx = React.useContext(MutableConnRefCtx);
const read = useCallback( const read = useCallback(
({ connections }) => { ({ connections }) => {
const prevConnsKv = arrayToIdKv(prevConnsRef.current); const prevConnsKv = arrayToIdKv(prevConnsRef.current);
const now = Date.now(); const now = Date.now();
const x = connections.map((c: ConnectionItem) => const x = connections.map((c: ConnectionItem) =>
formatConnectionDataItem(c, prevConnsKv, now) formatConnectionDataItem(c, prevConnsKv, now, connCtx)
); );
const closed = []; const closed = [];
for (const c of prevConnsRef.current) { for (const c of prevConnsRef.current) {

View file

@ -13,6 +13,7 @@ import { queryClient } from 'src/misc/query';
import { actions, initialState } from '../store'; import { actions, initialState } from '../store';
import APIConfig from './APIConfig'; import APIConfig from './APIConfig';
import APIDiscovery from './APIDiscovery'; import APIDiscovery from './APIDiscovery';
import { MutableConnRefCtx } from './conns/ConnCtx';
import ErrorBoundary from './ErrorBoundary'; import ErrorBoundary from './ErrorBoundary';
import Home from './Home'; import Home from './Home';
import Loading2 from './Loading2'; import Loading2 from './Loading2';
@ -31,7 +32,14 @@ const Rules = lazy(() => import('./Rules'));
const routes = [ const routes = [
{ path: '/', element: <Home /> }, { path: '/', element: <Home /> },
{ path: '/connections', element: <Connections /> }, {
path: '/connections',
element: (
<MutableConnRefCtx.Provider value={{ hasProcessPath: false }}>
<Connections />
</MutableConnRefCtx.Provider>
),
},
{ path: '/configs', element: <Config /> }, { path: '/configs', element: <Config /> },
{ path: '/logs', element: <Logs /> }, { path: '/logs', element: <Logs /> },
{ path: '/proxies', element: <Proxies /> }, { path: '/proxies', element: <Proxies /> },

View file

@ -0,0 +1,7 @@
import * as React from 'react';
const ref = {
hasProcessPath: false,
};
export const MutableConnRefCtx = React.createContext(ref);