import { useMemo } from 'react'; import { useTranslation } from 'react-i18next'; import { Button, Dropdown, Tag, Tooltip } from 'antd'; import { RetweetOutlined, MoreOutlined, EditOutlined, DeleteOutlined, VerticalAlignTopOutlined, ThunderboltOutlined, LoadingOutlined, ArrowUpOutlined, ArrowDownOutlined, } from '@ant-design/icons'; import type { ColumnsType } from 'antd/es/table'; import { SizeFormatter } from '@/utils'; import { OutboundProtocols as Protocols } from '@/schemas/primitives'; import type { OutboundTestMode, OutboundTestState, OutboundTrafficRow } from '@/hooks/useXraySetting'; import type { OutboundRow } from './outbounds-tab-types'; import TestResultPopover from './TestResultPopover'; import { effectiveTestMode, isTesting, isUntestable, outboundAddresses, showSecurity, testModeLabel, testResult, trafficFor, } from './outbounds-tab-helpers'; interface OutboundColumnsParams { testMode: OutboundTestMode; rows: OutboundRow[]; outboundsTraffic: OutboundTrafficRow[]; outboundTestStates: Record; openEdit: (idx: number) => void; setFirst: (idx: number) => void; moveUp: (idx: number) => void; moveDown: (idx: number) => void; confirmDelete: (idx: number) => void; onResetTraffic: (tag: string) => void; onTest: (index: number, mode: string) => void; } export function useOutboundColumns({ testMode, rows, outboundsTraffic, outboundTestStates, openEdit, setFirst, moveUp, moveDown, confirmDelete, onResetTraffic, onTest, }: OutboundColumnsParams): ColumnsType { const { t } = useTranslation(); return useMemo( () => [ { title: '#', key: 'action', align: 'center', width: 100, render: (_v, _record, index) => (
{index + 1}
), }, { title: t('pages.xray.outbound.tag'), key: 'identity', align: 'left', render: (_v, record) => (
{record.tag}
{record.protocol} {[Protocols.VMess, Protocols.VLESS, Protocols.Trojan, Protocols.Shadowsocks].includes(record.protocol as never) && ( <> {record.streamSettings?.network} {showSecurity(record.streamSettings?.security) && {record.streamSettings?.security}} )}
), }, { title: t('pages.inbounds.address'), key: 'address', align: 'left', render: (_v, record) => { const addrs = outboundAddresses(record); return (
{addrs.length === 0 ? ( ) : ( addrs.map((addr) => ( {addr} )) )}
); }, }, { title: t('pages.inbounds.traffic'), key: 'traffic', align: 'left', width: 200, render: (_v, record) => { const tr = trafficFor(outboundsTraffic, record); return ( <> ↑ {SizeFormatter.sizeFormat(tr.up)} ↓ {SizeFormatter.sizeFormat(tr.down)} ); }, }, { title: t('pages.nodes.latency'), key: 'testResult', align: 'left', width: 140, render: (_v, _record, index) => { const r = testResult(outboundTestStates, index); if (!r) return isTesting(outboundTestStates, index) ? : ; return ; }, }, { title: t('check'), key: 'test', align: 'center', width: 80, render: (_v, record, index) => (