import { useMemo } from 'react'; import { useTranslation } from 'react-i18next'; import { Button, Dropdown, Switch, Tag } from 'antd'; import { MoreOutlined, EditOutlined, DeleteOutlined, ExportOutlined, ClusterOutlined, ArrowUpOutlined, ArrowDownOutlined, HolderOutlined, } from '@ant-design/icons'; import type { ColumnsType } from 'antd/es/table'; import { useInboundOptions } from '@/api/queries/useInboundOptions'; import CriterionRow from './CriterionRow'; import { buildRemarkByTag, formatInboundTagList, inboundTagsDisplayTitle, isApiRule } from './helpers'; import type { RuleRow } from './types'; interface RoutingColumnsParams { isMobile: boolean; rowsLength: number; showSource: boolean; showBalancer: boolean; onHandlePointerDown: (idx: number, ev: React.PointerEvent) => void; openEdit: (idx: number) => void; moveUp: (idx: number) => void; moveDown: (idx: number) => void; confirmDelete: (idx: number) => void; toggleRule: (idx: number, enabled: boolean) => void; } export function useRoutingColumns({ isMobile, rowsLength, showSource, showBalancer, onHandlePointerDown, openEdit, moveUp, moveDown, confirmDelete, toggleRule, }: RoutingColumnsParams): ColumnsType { const { t } = useTranslation(); const { data: inboundOptions } = useInboundOptions(); const remarkByTag = useMemo(() => buildRemarkByTag(inboundOptions || []), [inboundOptions]); return useMemo( () => [ { title: '#', align: 'center', width: 60, key: 'index', render: (_v, _r, index) => (
onHandlePointerDown(index, ev)} /> {index + 1}
), }, { title: t('pages.clients.actions'), align: 'center', width: 80, key: 'action', render: (_v, _r, index) => (
{!isMobile && (
), }, { title: t('enable'), align: 'center', width: 80, key: 'enabled', render: (_v, _r, index) => ( toggleRule(index, checked)} disabled={isApiRule(_r)} /> ), }, { title: t('pages.xray.rules.source'), align: 'left', width: 180, key: 'source', hidden: !showSource, render: (_v, record) => (
{record.sourceIP && } {record.sourcePort && } {record.vlessRoute && } {!record.sourceIP && !record.sourcePort && !record.vlessRoute && }
), }, { title: t('pages.inbounds.network'), align: 'left', width: 180, key: 'network', render: (_v, record) => (
{record.network && } {record.protocol && } {record.attrs && } {!record.network && !record.protocol && !record.attrs && }
), }, { title: t('pages.xray.rules.dest'), align: 'left', width: 200, key: 'destination', render: (_v, record) => (
{record.ip && } {record.domain && } {record.port && } {!record.ip && !record.domain && !record.port && }
), }, { title: t('pages.xray.Inbounds'), align: 'left', width: 180, key: 'inbound', render: (_v, record) => { const inboundParts = formatInboundTagList(record.inboundTag, remarkByTag); return (
{inboundParts.length > 0 && ( )} {record.user && } {inboundParts.length === 0 && !record.user && }
); }, }, { title: t('pages.xray.Outbounds'), align: 'left', width: 170, key: 'outbound', render: (_v, record) => record.outboundTag ? (
{record.outboundTag}
) : ( ), }, { title: t('pages.xray.Balancers'), align: 'left', width: 150, key: 'balancer', hidden: !showBalancer, render: (_v, record) => record.balancerTag ? (
{record.balancerTag}
) : ( ), }, ], [t, isMobile, rowsLength, showSource, showBalancer, remarkByTag, onHandlePointerDown, openEdit, moveUp, moveDown, confirmDelete, toggleRule], ); }