diff --git a/frontend/src/i18n/locales/en/common.json b/frontend/src/i18n/locales/en/common.json index 218a5fc1..3b03a243 100644 --- a/frontend/src/i18n/locales/en/common.json +++ b/frontend/src/i18n/locales/en/common.json @@ -111,6 +111,7 @@ "createdAt": "Created At", "updatedAt": "Updated At" }, + "columnSettings": "Column Settings", "messages": { "refreshFailed": "Refresh failed" } diff --git a/frontend/src/i18n/locales/zh/common.json b/frontend/src/i18n/locales/zh/common.json index 3de37d94..d507fbf4 100644 --- a/frontend/src/i18n/locales/zh/common.json +++ b/frontend/src/i18n/locales/zh/common.json @@ -111,6 +111,7 @@ "createdAt": "创建时间", "updatedAt": "更新时间" }, + "columnSettings": "列设置", "messages": { "refreshFailed": "刷新失败" } diff --git a/frontend/src/pages/DataCollection/Home/TemplateManagement.tsx b/frontend/src/pages/DataCollection/Home/TemplateManagement.tsx index ae2320af..31f37668 100644 --- a/frontend/src/pages/DataCollection/Home/TemplateManagement.tsx +++ b/frontend/src/pages/DataCollection/Home/TemplateManagement.tsx @@ -1,10 +1,13 @@ -import { App, Card, Table, Tag } from "antd"; +import { App, Card, Table, Tag, Dropdown, Button } from "antd"; import type { ColumnsType } from "antd/es/table"; +import type { MenuProps } from "antd"; import { SearchControls } from "@/components/SearchControls"; import useFetchData from "@/hooks/useFetchData"; import { queryDataXTemplatesUsingGet } from "../collection.apis"; import { formatDateTime } from "@/utils/unit"; import { useTranslation } from "react-i18next"; +import { SettingOutlined } from "@ant-design/icons"; +import { useState, useMemo } from "react"; type CollectionTemplate = { id: string; @@ -19,9 +22,24 @@ type CollectionTemplate = { updatedAt?: string; }; +// 所有可用的列配置 +const ALL_COLUMNS = { + name: 'dataCollection.templateManagement.columns.templateName', + builtIn: 'dataCollection.templateManagement.columns.templateType', + source: 'dataCollection.templateManagement.columns.source', + target: 'dataCollection.templateManagement.columns.target', + description: 'dataCollection.templateManagement.columns.description', + createdAt: 'dataCollection.templateManagement.columns.createdAt', + updatedAt: 'dataCollection.templateManagement.columns.updatedAt', +} as const; + +// 默认隐藏的列 +const DEFAULT_HIDDEN_COLUMNS = ['createdAt', 'updatedAt']; + export default function TemplateManagement() { const { message } = App.useApp(); const { t } = useTranslation(); + const [hiddenColumns, setHiddenColumns] = useState>(new Set(DEFAULT_HIDDEN_COLUMNS)); const filters = [ { @@ -62,96 +80,149 @@ export default function TemplateManagement() { 0 ); - const columns: ColumnsType = [ - { - title: t("dataCollection.templateManagement.columns.templateName"), - dataIndex: "name", - key: "name", - fixed: "left", - width: 200, - ellipsis: true, - }, - { - title: t("dataCollection.templateManagement.columns.templateType"), - dataIndex: "builtIn", - key: "builtIn", - width: 120, - render: (v?: boolean) => ( - - {v - ? t("dataCollection.templateManagement.filters.builtIn") - : t("dataCollection.templateManagement.filters.custom")} - - ), - }, - { - title: t("dataCollection.templateManagement.columns.source"), - key: "source", - width: 220, - ellipsis: true, - render: (_: any, record: CollectionTemplate) => ( - {`${record.sourceType} / ${record.sourceName}`} - ), - }, - { - title: t("dataCollection.templateManagement.columns.target"), - key: "target", - width: 220, - ellipsis: true, - render: (_: any, record: CollectionTemplate) => ( - {`${record.targetType} / ${record.targetName}`} - ), - }, - { - title: t("dataCollection.templateManagement.columns.description"), - dataIndex: "description", - key: "description", - width: 260, - ellipsis: true, - render: (v?: string) => v || t("common.placeholders.empty"), - }, - { - title: t("dataCollection.templateManagement.columns.createdAt"), - dataIndex: "createdAt", - key: "createdAt", - width: 160, - }, - { - title: t("dataCollection.templateManagement.columns.updatedAt"), - dataIndex: "updatedAt", - key: "updatedAt", - width: 160, - }, - ]; + // 根据隐藏列的状态动态生成 columns + const columns: ColumnsType = useMemo(() => { + const allColumns: ColumnsType = [ + { + title: t("dataCollection.templateManagement.columns.templateName"), + dataIndex: "name", + key: "name", + fixed: "left", + width: 200, + ellipsis: true, + }, + { + title: t("dataCollection.templateManagement.columns.templateType"), + dataIndex: "builtIn", + key: "builtIn", + width: 120, + render: (v?: boolean) => ( + + {v + ? t("dataCollection.templateManagement.filters.builtIn") + : t("dataCollection.templateManagement.filters.custom")} + + ), + }, + { + title: t("dataCollection.templateManagement.columns.source"), + key: "source", + width: 220, + ellipsis: true, + render: (_: any, record: CollectionTemplate) => { + // 如果 sourceType 和 sourceName 相同,只显示一个 + if (record.sourceType === record.sourceName) { + return {record.sourceType}; + } + return {`${record.sourceType} / ${record.sourceName}`}; + }, + }, + { + title: t("dataCollection.templateManagement.columns.target"), + key: "target", + width: 220, + ellipsis: true, + render: (_: any, record: CollectionTemplate) => { + // 如果 targetType 和 targetName 相同,只显示一个 + if (record.targetType === record.targetName) { + return {record.targetType}; + } + return {`${record.targetType} / ${record.targetName}`}; + }, + }, + { + title: t("dataCollection.templateManagement.columns.description"), + dataIndex: "description", + key: "description", + width: 260, + ellipsis: true, + render: (v?: string) => v || t("common.placeholders.empty"), + }, + { + title: t("dataCollection.templateManagement.columns.createdAt"), + dataIndex: "createdAt", + key: "createdAt", + width: 160, + }, + { + title: t("dataCollection.templateManagement.columns.updatedAt"), + dataIndex: "updatedAt", + key: "updatedAt", + width: 160, + }, + ]; + + // 过滤掉隐藏的列 + return allColumns.filter(col => !hiddenColumns.has(col.key as string)); + }, [t, hiddenColumns]); + + // 列显示切换处理 + const handleColumnToggle = (columnKey: string) => { + setHiddenColumns(prev => { + const newHidden = new Set(prev); + if (newHidden.has(columnKey)) { + newHidden.delete(columnKey); + } else { + newHidden.add(columnKey); + } + return newHidden; + }); + }; + + // 列选择菜单 + const columnMenuItems: MenuProps['items'] = Object.entries(ALL_COLUMNS).map(([key, label]) => ({ + key, + label: t(label), + })); + + // 获取显示的列(非隐藏列) + const visibleColumns = Object.keys(ALL_COLUMNS).filter(key => !hiddenColumns.has(key)); return (
- - setSearchParams((prev) => ({ - ...prev, - keyword: newSearchTerm, - current: 1, - })) - } - searchPlaceholder={t("dataCollection.templateManagement.filters.searchPlaceholder")} - filters={filters} - selectedFilters={searchParams.filter} - onFiltersChange={handleFiltersChange} - showViewToggle={false} - onClearFilters={() => - setSearchParams((prev) => ({ - ...prev, - filter: { ...prev.filter, builtIn: [] }, - current: 1, - keyword: "", - })) - } - onReload={() => { - fetchData().catch(() => message.error(t("dataCollection.templateManagement.messages.refreshFailed"))); - }} - /> +
+ + setSearchParams((prev) => ({ + ...prev, + keyword: newSearchTerm, + current: 1, + })) + } + searchPlaceholder={t("dataCollection.templateManagement.filters.searchPlaceholder")} + filters={filters} + selectedFilters={searchParams.filter} + onFiltersChange={handleFiltersChange} + showViewToggle={false} + showReload={true} + onClearFilters={() => + setSearchParams((prev) => ({ + ...prev, + filter: { ...prev.filter, builtIn: [] }, + current: 1, + keyword: "", + })) + } + onReload={() => { + fetchData().catch(() => message.error(t("dataCollection.templateManagement.messages.refreshFailed"))); + }} + className="flex-1" + /> + handleColumnToggle(key as string), + }} + > + + +