"use client"
import React from "react"
import { ColumnDef } from "@tanstack/react-table"
import { Button } from "@/components/ui/button"
import { Badge } from "@/components/ui/badge"
import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip"
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuSeparator,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu"
import {
MoreHorizontal,
Trash2,
ChevronsUpDown,
ChevronUp,
ChevronDown,
Check,
Edit,
X as XIcon,
} from "lucide-react"
import {
IconTarget,
IconBolt,
IconSettings,
} from "@tabler/icons-react"
import * as yaml from "js-yaml"
import type { ScanEngine } from "@/types/engine.types"
/**
* 解析引擎的 YAML 配置并检测功能是否启用
*
* 判断逻辑:
* - 如果 YAML 中存在该配置项(即使是空对象 {}),则认为启用了该功能
* - 空对象表示使用默认配置启用该功能
*/
function parseEngineFeatures(engine: ScanEngine) {
// 如果引擎有 configuration 字段,解析 YAML
if (engine.configuration) {
try {
const config = yaml.load(engine.configuration) as any
return {
subdomain_discovery: !!config?.subdomain_discovery,
port_scan: !!config?.port_scan,
site_scan: !!config?.site_scan,
directory_scan: !!config?.directory_scan,
url_fetch: !!config?.url_fetch || !!config?.fetch_url, // 兼容 fetch_url
osint: !!config?.osint,
vulnerability_scan: !!config?.vulnerability_scan,
waf_detection: !!config?.waf_detection,
screenshot: !!config?.screenshot,
}
} catch (error) {
console.error("Failed to parse YAML configuration:", error)
}
}
// 无配置时,所有功能默认为禁用
return {
subdomain_discovery: false,
port_scan: false,
site_scan: false,
directory_scan: false,
url_fetch: false,
osint: false,
vulnerability_scan: false,
waf_detection: false,
screenshot: false,
}
}
/**
* 功能支持状态组件
*/
function FeatureStatus({ enabled }: { enabled?: boolean }) {
if (enabled) {
return (
)
}
return (
)
}
/**
* 数据表格列头组件
*/
function DataTableColumnHeader({
column,
title,
}: {
column: {
getCanSort: () => boolean
getIsSorted: () => false | "asc" | "desc"
toggleSorting: (desc?: boolean) => void
}
title: string
}) {
if (!column.getCanSort()) {
return {title}
}
const isSorted = column.getIsSorted()
return (
)
}
// 列创建函数的参数类型
interface CreateColumnsProps {
formatDate: (dateString: string) => string
handleEdit: (engine: ScanEngine) => void
handleDelete: (engine: ScanEngine) => void
}
/**
* 引擎行操作组件
*/
function EngineRowActions({
engine,
onEdit,
onDelete,
}: {
engine: ScanEngine
onEdit: () => void
onDelete: () => void
}) {
return (
编辑引擎
删除
)
}
/**
* 创建引擎表格列定义
*/
export const createEngineColumns = ({
formatDate,
handleEdit,
handleDelete,
}: CreateColumnsProps): ColumnDef[] => [
// 引擎名称列 - 可点击编辑
{
accessorKey: "name",
size: 200,
minSize: 150,
maxSize: 350,
header: ({ column }) => (
),
cell: ({ row }) => {
const name = row.getValue("name") as string
return (
编辑引擎
)
},
},
// Subdomain Discovery
{
id: "subdomain_discovery",
header: "Subdomain Discovery",
size: 80,
minSize: 60,
maxSize: 100,
cell: ({ row }) => {
const features = parseEngineFeatures(row.original)
return
},
enableSorting: false,
},
// Port Scan
{
id: "port_scan",
header: "Port Scan",
size: 80,
minSize: 60,
maxSize: 100,
cell: ({ row }) => {
const features = parseEngineFeatures(row.original)
return
},
enableSorting: false,
},
// Site Scan (原 HTTP Crawl)
{
id: "site_scan",
header: "Site Scan",
size: 80,
minSize: 60,
maxSize: 100,
cell: ({ row }) => {
const features = parseEngineFeatures(row.original)
return
},
enableSorting: false,
},
// Directory Scan
{
id: "directory_scan",
header: "Directory Scan",
size: 80,
minSize: 60,
maxSize: 100,
cell: ({ row }) => {
const features = parseEngineFeatures(row.original)
return
},
enableSorting: false,
},
// URL Fetch
{
id: "url_fetch",
header: "URL Fetch",
size: 80,
minSize: 60,
maxSize: 100,
cell: ({ row }) => {
const features = parseEngineFeatures(row.original)
return
},
enableSorting: false,
},
// OSINT
{
id: "osint",
header: "OSINT",
size: 80,
minSize: 60,
maxSize: 100,
cell: ({ row }) => {
const features = parseEngineFeatures(row.original)
return
},
enableSorting: false,
},
// Vulnerability Scan
{
id: "vulnerability_scan",
header: "Vulnerability Scan",
size: 80,
minSize: 60,
maxSize: 100,
cell: ({ row }) => {
const features = parseEngineFeatures(row.original)
return
},
enableSorting: false,
},
// WAF Detection
{
id: "waf_detection",
header: "WAF Detection",
size: 80,
minSize: 60,
maxSize: 100,
cell: ({ row }) => {
const features = parseEngineFeatures(row.original)
return
},
enableSorting: false,
},
// Screenshot
{
id: "screenshot",
header: "Screenshot",
size: 80,
minSize: 60,
maxSize: 100,
cell: ({ row }) => {
const features = parseEngineFeatures(row.original)
return
},
enableSorting: false,
},
// 操作列
{
id: "actions",
size: 60,
minSize: 60,
maxSize: 60,
enableResizing: false,
cell: ({ row }) => (
handleEdit(row.original)}
onDelete={() => handleDelete(row.original)}
/>
),
enableSorting: false,
enableHiding: false,
},
]