You've already forked DataMate
feat(dataset): 添加子数据集展示功能
- 在 DatasetDetail 页面引入 Table 和 Tag 组件用于子数据集展示 - 新增 queryDatasetsUsingGet 接口调用方法用于获取子数据集列表 - 添加 childDatasets 和 childDatasetsLoading 状态管理 - 实现 tabList 动态渲染,父数据集显示子数据集选项卡 - 添加 fetchChildDatasets 方法异步获取子数据集数据 - 实现子数据集表格列定义,包含名称、类型、状态、文件数等信息 - 在子数据集选项卡中展示表格并添加加载状态和空数据提示 - 添加子数据集数量统计显示 - 优化标签颜色显示和数据映射逻辑
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
import { useEffect, useMemo, useState } from "react";
|
import { useEffect, useMemo, useState } from "react";
|
||||||
import { Breadcrumb, App, Tabs } from "antd";
|
import { Breadcrumb, App, Tabs, Table, Tag } from "antd";
|
||||||
import {
|
import {
|
||||||
ReloadOutlined,
|
ReloadOutlined,
|
||||||
DownloadOutlined,
|
DownloadOutlined,
|
||||||
@@ -13,14 +13,15 @@ import { mapDataset, datasetTypeMap } from "../dataset.const";
|
|||||||
import type { Dataset } from "@/pages/DataManagement/dataset.model";
|
import type { Dataset } from "@/pages/DataManagement/dataset.model";
|
||||||
import { Link, useNavigate, useParams } from "react-router";
|
import { Link, useNavigate, useParams } from "react-router";
|
||||||
import { useFilesOperation } from "./useFilesOperation";
|
import { useFilesOperation } from "./useFilesOperation";
|
||||||
import {
|
import {
|
||||||
createDatasetTagUsingPost,
|
createDatasetTagUsingPost,
|
||||||
deleteDatasetByIdUsingDelete,
|
deleteDatasetByIdUsingDelete,
|
||||||
downloadDatasetUsingGet,
|
downloadDatasetUsingGet,
|
||||||
queryDatasetByIdUsingGet,
|
queryDatasetByIdUsingGet,
|
||||||
queryDatasetTagsUsingGet,
|
queryDatasetsUsingGet,
|
||||||
updateDatasetByIdUsingPut,
|
queryDatasetTagsUsingGet,
|
||||||
} from "../dataset.api";
|
updateDatasetByIdUsingPut,
|
||||||
|
} from "../dataset.api";
|
||||||
import DataQuality from "./components/DataQuality";
|
import DataQuality from "./components/DataQuality";
|
||||||
import DataLineageFlow from "./components/DataLineageFlow";
|
import DataLineageFlow from "./components/DataLineageFlow";
|
||||||
import Overview from "./components/Overview";
|
import Overview from "./components/Overview";
|
||||||
@@ -28,22 +29,17 @@ import { Activity, Clock, File, FileType } from "lucide-react";
|
|||||||
import EditDataset from "../Create/EditDataset";
|
import EditDataset from "../Create/EditDataset";
|
||||||
import ImportConfiguration from "./components/ImportConfiguration";
|
import ImportConfiguration from "./components/ImportConfiguration";
|
||||||
|
|
||||||
const tabList = [
|
export default function DatasetDetail() {
|
||||||
{
|
const { id } = useParams(); // 获取动态路由参数
|
||||||
key: "overview",
|
const navigate = useNavigate();
|
||||||
label: "概览",
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
export default function DatasetDetail() {
|
|
||||||
const { id } = useParams(); // 获取动态路由参数
|
|
||||||
const navigate = useNavigate();
|
|
||||||
const [activeTab, setActiveTab] = useState("overview");
|
const [activeTab, setActiveTab] = useState("overview");
|
||||||
const { message } = App.useApp();
|
const { message } = App.useApp();
|
||||||
const [showEditDialog, setShowEditDialog] = useState(false);
|
const [showEditDialog, setShowEditDialog] = useState(false);
|
||||||
|
|
||||||
const [dataset, setDataset] = useState<Dataset>({} as Dataset);
|
const [dataset, setDataset] = useState<Dataset>({} as Dataset);
|
||||||
const [parentDataset, setParentDataset] = useState<Dataset | null>(null);
|
const [parentDataset, setParentDataset] = useState<Dataset | null>(null);
|
||||||
|
const [childDatasets, setChildDatasets] = useState<Dataset[]>([]);
|
||||||
|
const [childDatasetsLoading, setChildDatasetsLoading] = useState(false);
|
||||||
const filesOperation = useFilesOperation(dataset);
|
const filesOperation = useFilesOperation(dataset);
|
||||||
|
|
||||||
const [showUploadDialog, setShowUploadDialog] = useState(false);
|
const [showUploadDialog, setShowUploadDialog] = useState(false);
|
||||||
@@ -67,6 +63,21 @@ export default function DatasetDetail() {
|
|||||||
});
|
});
|
||||||
return items;
|
return items;
|
||||||
}, [dataset, parentDataset]);
|
}, [dataset, parentDataset]);
|
||||||
|
const tabList = useMemo(() => {
|
||||||
|
const items = [
|
||||||
|
{
|
||||||
|
key: "overview",
|
||||||
|
label: "概览",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
if (!dataset?.parentDatasetId) {
|
||||||
|
items.push({
|
||||||
|
key: "children",
|
||||||
|
label: "子数据集",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return items;
|
||||||
|
}, [dataset?.parentDatasetId]);
|
||||||
const handleCreateChildDataset = () => {
|
const handleCreateChildDataset = () => {
|
||||||
if (!dataset?.id) {
|
if (!dataset?.id) {
|
||||||
return;
|
return;
|
||||||
@@ -75,6 +86,24 @@ export default function DatasetDetail() {
|
|||||||
state: { parentDatasetId: dataset.id },
|
state: { parentDatasetId: dataset.id },
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
const fetchChildDatasets = async (parentId?: string) => {
|
||||||
|
if (!parentId) {
|
||||||
|
setChildDatasets([]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setChildDatasetsLoading(true);
|
||||||
|
try {
|
||||||
|
const { data: res } = await queryDatasetsUsingGet({
|
||||||
|
parentDatasetId: parentId,
|
||||||
|
page: 1,
|
||||||
|
size: 1000,
|
||||||
|
});
|
||||||
|
const list = res?.content || res?.data || [];
|
||||||
|
setChildDatasets(list.map((item) => mapDataset(item)));
|
||||||
|
} finally {
|
||||||
|
setChildDatasetsLoading(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
const fetchDataset = async () => {
|
const fetchDataset = async () => {
|
||||||
if (!id) {
|
if (!id) {
|
||||||
return;
|
return;
|
||||||
@@ -87,15 +116,22 @@ export default function DatasetDetail() {
|
|||||||
data.parentDatasetId
|
data.parentDatasetId
|
||||||
);
|
);
|
||||||
setParentDataset(mapDataset(parentData));
|
setParentDataset(mapDataset(parentData));
|
||||||
|
setChildDatasets([]);
|
||||||
} else {
|
} else {
|
||||||
setParentDataset(null);
|
setParentDataset(null);
|
||||||
|
await fetchChildDatasets(data?.id);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
fetchDataset();
|
fetchDataset();
|
||||||
filesOperation.fetchFiles('', 1, 10); // 从根目录开始,第一页
|
filesOperation.fetchFiles('', 1, 10); // 从根目录开始,第一页
|
||||||
}, []);
|
}, []);
|
||||||
|
useEffect(() => {
|
||||||
|
if (dataset?.parentDatasetId && activeTab === "children") {
|
||||||
|
setActiveTab("overview");
|
||||||
|
}
|
||||||
|
}, [activeTab, dataset?.parentDatasetId]);
|
||||||
|
|
||||||
const handleRefresh = async (showMessage = true, prefixOverride?: string) => {
|
const handleRefresh = async (showMessage = true, prefixOverride?: string) => {
|
||||||
fetchDataset();
|
fetchDataset();
|
||||||
@@ -226,7 +262,52 @@ export default function DatasetDetail() {
|
|||||||
icon: <DeleteOutlined />,
|
icon: <DeleteOutlined />,
|
||||||
onClick: handleDeleteDataset,
|
onClick: handleDeleteDataset,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
const childColumns = [
|
||||||
|
{
|
||||||
|
title: "名称",
|
||||||
|
dataIndex: "name",
|
||||||
|
key: "name",
|
||||||
|
render: (_: string, record: Dataset) => (
|
||||||
|
<Link to={`/data/management/detail/${record.id}`}>{record.name}</Link>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "类型",
|
||||||
|
dataIndex: "datasetType",
|
||||||
|
key: "datasetType",
|
||||||
|
width: 120,
|
||||||
|
render: (value: string) => datasetTypeMap[value]?.label || "未知",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "状态",
|
||||||
|
dataIndex: "status",
|
||||||
|
key: "status",
|
||||||
|
width: 120,
|
||||||
|
render: (status) =>
|
||||||
|
status ? <Tag color={status.color}>{status.label}</Tag> : "-",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "文件数",
|
||||||
|
dataIndex: "fileCount",
|
||||||
|
key: "fileCount",
|
||||||
|
width: 120,
|
||||||
|
render: (value?: number) => value ?? 0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "大小",
|
||||||
|
dataIndex: "size",
|
||||||
|
key: "size",
|
||||||
|
width: 140,
|
||||||
|
render: (value?: string) => value || "0 B",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "更新时间",
|
||||||
|
dataIndex: "updatedAt",
|
||||||
|
key: "updatedAt",
|
||||||
|
width: 180,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="h-full flex flex-col gap-4">
|
<div className="h-full flex flex-col gap-4">
|
||||||
@@ -266,15 +347,33 @@ export default function DatasetDetail() {
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<div className="flex-overflow-auto p-6 pt-2 bg-white rounded-md shadow">
|
<div className="flex-overflow-auto p-6 pt-2 bg-white rounded-md shadow">
|
||||||
<Tabs activeKey={activeTab} items={tabList} onChange={setActiveTab} />
|
<Tabs activeKey={activeTab} items={tabList} onChange={setActiveTab} />
|
||||||
<div className="h-full overflow-auto">
|
<div className="h-full overflow-auto">
|
||||||
{activeTab === "overview" && (
|
{activeTab === "overview" && (
|
||||||
<Overview dataset={dataset} filesOperation={filesOperation} fetchDataset={fetchDataset}/>
|
<Overview dataset={dataset} filesOperation={filesOperation} fetchDataset={fetchDataset}/>
|
||||||
)}
|
)}
|
||||||
{activeTab === "lineage" && <DataLineageFlow dataset={dataset} />}
|
{activeTab === "children" && (
|
||||||
{activeTab === "quality" && <DataQuality />}
|
<div className="pt-4">
|
||||||
</div>
|
<div className="flex items-center justify-between mb-3">
|
||||||
</div>
|
<h2 className="text-base font-semibold">子数据集</h2>
|
||||||
|
<span className="text-xs text-gray-500">
|
||||||
|
共 {childDatasets.length} 个
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<Table
|
||||||
|
rowKey="id"
|
||||||
|
columns={childColumns}
|
||||||
|
dataSource={childDatasets}
|
||||||
|
loading={childDatasetsLoading}
|
||||||
|
pagination={false}
|
||||||
|
locale={{ emptyText: "暂无子数据集" }}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{activeTab === "lineage" && <DataLineageFlow dataset={dataset} />}
|
||||||
|
{activeTab === "quality" && <DataQuality />}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<ImportConfiguration
|
<ImportConfiguration
|
||||||
data={dataset}
|
data={dataset}
|
||||||
open={showUploadDialog}
|
open={showUploadDialog}
|
||||||
|
|||||||
Reference in New Issue
Block a user