1- import { App , Card , Table , Tag } from "antd" ;
1+ import { App , Card , Table , Tag , Dropdown , Button } from "antd" ;
22import type { ColumnsType } from "antd/es/table" ;
3+ import type { MenuProps } from "antd" ;
34import { SearchControls } from "@/components/SearchControls" ;
45import useFetchData from "@/hooks/useFetchData" ;
56import { queryDataXTemplatesUsingGet } from "../collection.apis" ;
67import { formatDateTime } from "@/utils/unit" ;
78import { useTranslation } from "react-i18next" ;
9+ import { SettingOutlined } from "@ant-design/icons" ;
10+ import { useState , useMemo } from "react" ;
811
912type CollectionTemplate = {
1013 id : string ;
@@ -19,9 +22,24 @@ type CollectionTemplate = {
1922 updatedAt ?: string ;
2023} ;
2124
25+ // 所有可用的列配置
26+ const ALL_COLUMNS = {
27+ name : 'dataCollection.templateManagement.columns.templateName' ,
28+ builtIn : 'dataCollection.templateManagement.columns.templateType' ,
29+ source : 'dataCollection.templateManagement.columns.source' ,
30+ target : 'dataCollection.templateManagement.columns.target' ,
31+ description : 'dataCollection.templateManagement.columns.description' ,
32+ createdAt : 'dataCollection.templateManagement.columns.createdAt' ,
33+ updatedAt : 'dataCollection.templateManagement.columns.updatedAt' ,
34+ } as const ;
35+
36+ // 默认隐藏的列
37+ const DEFAULT_HIDDEN_COLUMNS = [ 'createdAt' , 'updatedAt' ] ;
38+
2239export default function TemplateManagement ( ) {
2340 const { message } = App . useApp ( ) ;
2441 const { t } = useTranslation ( ) ;
42+ const [ hiddenColumns , setHiddenColumns ] = useState < Set < string > > ( new Set ( DEFAULT_HIDDEN_COLUMNS ) ) ;
2543
2644 const filters = [
2745 {
@@ -62,96 +80,149 @@ export default function TemplateManagement() {
6280 0
6381 ) ;
6482
65- const columns : ColumnsType < CollectionTemplate > = [
66- {
67- title : t ( "dataCollection.templateManagement.columns.templateName" ) ,
68- dataIndex : "name" ,
69- key : "name" ,
70- fixed : "left" ,
71- width : 200 ,
72- ellipsis : true ,
73- } ,
74- {
75- title : t ( "dataCollection.templateManagement.columns.templateType" ) ,
76- dataIndex : "builtIn" ,
77- key : "builtIn" ,
78- width : 120 ,
79- render : ( v ?: boolean ) => (
80- < Tag color = { v ? "blue" : "default" } >
81- { v
82- ? t ( "dataCollection.templateManagement.filters.builtIn" )
83- : t ( "dataCollection.templateManagement.filters.custom" ) }
84- </ Tag >
85- ) ,
86- } ,
87- {
88- title : t ( "dataCollection.templateManagement.columns.source" ) ,
89- key : "source" ,
90- width : 220 ,
91- ellipsis : true ,
92- render : ( _ : any , record : CollectionTemplate ) => (
93- < span > { `${ record . sourceType } / ${ record . sourceName } ` } </ span >
94- ) ,
95- } ,
96- {
97- title : t ( "dataCollection.templateManagement.columns.target" ) ,
98- key : "target" ,
99- width : 220 ,
100- ellipsis : true ,
101- render : ( _ : any , record : CollectionTemplate ) => (
102- < span > { `${ record . targetType } / ${ record . targetName } ` } </ span >
103- ) ,
104- } ,
105- {
106- title : t ( "dataCollection.templateManagement.columns.description" ) ,
107- dataIndex : "description" ,
108- key : "description" ,
109- width : 260 ,
110- ellipsis : true ,
111- render : ( v ?: string ) => v || t ( "common.placeholders.empty" ) ,
112- } ,
113- {
114- title : t ( "dataCollection.templateManagement.columns.createdAt" ) ,
115- dataIndex : "createdAt" ,
116- key : "createdAt" ,
117- width : 160 ,
118- } ,
119- {
120- title : t ( "dataCollection.templateManagement.columns.updatedAt" ) ,
121- dataIndex : "updatedAt" ,
122- key : "updatedAt" ,
123- width : 160 ,
124- } ,
125- ] ;
83+ // 根据隐藏列的状态动态生成 columns
84+ const columns : ColumnsType < CollectionTemplate > = useMemo ( ( ) => {
85+ const allColumns : ColumnsType < CollectionTemplate > = [
86+ {
87+ title : t ( "dataCollection.templateManagement.columns.templateName" ) ,
88+ dataIndex : "name" ,
89+ key : "name" ,
90+ fixed : "left" ,
91+ width : 200 ,
92+ ellipsis : true ,
93+ } ,
94+ {
95+ title : t ( "dataCollection.templateManagement.columns.templateType" ) ,
96+ dataIndex : "builtIn" ,
97+ key : "builtIn" ,
98+ width : 120 ,
99+ render : ( v ?: boolean ) => (
100+ < Tag color = { v ? "blue" : "default" } >
101+ { v
102+ ? t ( "dataCollection.templateManagement.filters.builtIn" )
103+ : t ( "dataCollection.templateManagement.filters.custom" ) }
104+ </ Tag >
105+ ) ,
106+ } ,
107+ {
108+ title : t ( "dataCollection.templateManagement.columns.source" ) ,
109+ key : "source" ,
110+ width : 220 ,
111+ ellipsis : true ,
112+ render : ( _ : any , record : CollectionTemplate ) => {
113+ // 如果 sourceType 和 sourceName 相同,只显示一个
114+ if ( record . sourceType === record . sourceName ) {
115+ return < span > { record . sourceType } </ span > ;
116+ }
117+ return < span > { `${ record . sourceType } / ${ record . sourceName } ` } </ span > ;
118+ } ,
119+ } ,
120+ {
121+ title : t ( "dataCollection.templateManagement.columns.target" ) ,
122+ key : "target" ,
123+ width : 220 ,
124+ ellipsis : true ,
125+ render : ( _ : any , record : CollectionTemplate ) => {
126+ // 如果 targetType 和 targetName 相同,只显示一个
127+ if ( record . targetType === record . targetName ) {
128+ return < span > { record . targetType } </ span > ;
129+ }
130+ return < span > { `${ record . targetType } / ${ record . targetName } ` } </ span > ;
131+ } ,
132+ } ,
133+ {
134+ title : t ( "dataCollection.templateManagement.columns.description" ) ,
135+ dataIndex : "description" ,
136+ key : "description" ,
137+ width : 260 ,
138+ ellipsis : true ,
139+ render : ( v ?: string ) => v || t ( "common.placeholders.empty" ) ,
140+ } ,
141+ {
142+ title : t ( "dataCollection.templateManagement.columns.createdAt" ) ,
143+ dataIndex : "createdAt" ,
144+ key : "createdAt" ,
145+ width : 160 ,
146+ } ,
147+ {
148+ title : t ( "dataCollection.templateManagement.columns.updatedAt" ) ,
149+ dataIndex : "updatedAt" ,
150+ key : "updatedAt" ,
151+ width : 160 ,
152+ } ,
153+ ] ;
154+
155+ // 过滤掉隐藏的列
156+ return allColumns . filter ( col => ! hiddenColumns . has ( col . key as string ) ) ;
157+ } , [ t , hiddenColumns ] ) ;
158+
159+ // 列显示切换处理
160+ const handleColumnToggle = ( columnKey : string ) => {
161+ setHiddenColumns ( prev => {
162+ const newHidden = new Set ( prev ) ;
163+ if ( newHidden . has ( columnKey ) ) {
164+ newHidden . delete ( columnKey ) ;
165+ } else {
166+ newHidden . add ( columnKey ) ;
167+ }
168+ return newHidden ;
169+ } ) ;
170+ } ;
171+
172+ // 列选择菜单
173+ const columnMenuItems : MenuProps [ 'items' ] = Object . entries ( ALL_COLUMNS ) . map ( ( [ key , label ] ) => ( {
174+ key,
175+ label : t ( label ) ,
176+ } ) ) ;
177+
178+ // 获取显示的列(非隐藏列)
179+ const visibleColumns = Object . keys ( ALL_COLUMNS ) . filter ( key => ! hiddenColumns . has ( key ) ) ;
126180
127181 return (
128182 < div className = "space-y-4" >
129- < SearchControls
130- searchTerm = { searchParams . keyword }
131- onSearchChange = { ( newSearchTerm ) =>
132- setSearchParams ( ( prev ) => ( {
133- ...prev ,
134- keyword : newSearchTerm ,
135- current : 1 ,
136- } ) )
137- }
138- searchPlaceholder = { t ( "dataCollection.templateManagement.filters.searchPlaceholder" ) }
139- filters = { filters }
140- selectedFilters = { searchParams . filter }
141- onFiltersChange = { handleFiltersChange }
142- showViewToggle = { false }
143- onClearFilters = { ( ) =>
144- setSearchParams ( ( prev ) => ( {
145- ...prev ,
146- filter : { ...prev . filter , builtIn : [ ] } ,
147- current : 1 ,
148- keyword : "" ,
149- } ) )
150- }
151- onReload = { ( ) => {
152- fetchData ( ) . catch ( ( ) => message . error ( t ( "dataCollection.templateManagement.messages.refreshFailed" ) ) ) ;
153- } }
154- />
183+ < div className = "flex items-center justify-between" >
184+ < SearchControls
185+ searchTerm = { searchParams . keyword }
186+ onSearchChange = { ( newSearchTerm ) =>
187+ setSearchParams ( ( prev ) => ( {
188+ ...prev ,
189+ keyword : newSearchTerm ,
190+ current : 1 ,
191+ } ) )
192+ }
193+ searchPlaceholder = { t ( "dataCollection.templateManagement.filters.searchPlaceholder" ) }
194+ filters = { filters }
195+ selectedFilters = { searchParams . filter }
196+ onFiltersChange = { handleFiltersChange }
197+ showViewToggle = { false }
198+ showReload = { true }
199+ onClearFilters = { ( ) =>
200+ setSearchParams ( ( prev ) => ( {
201+ ...prev ,
202+ filter : { ...prev . filter , builtIn : [ ] } ,
203+ current : 1 ,
204+ keyword : "" ,
205+ } ) )
206+ }
207+ onReload = { ( ) => {
208+ fetchData ( ) . catch ( ( ) => message . error ( t ( "dataCollection.templateManagement.messages.refreshFailed" ) ) ) ;
209+ } }
210+ className = "flex-1"
211+ />
212+ < Dropdown
213+ menu = { {
214+ items : columnMenuItems ,
215+ selectable : true ,
216+ multiple : true ,
217+ selectedKeys : visibleColumns ,
218+ onClick : ( { key } ) => handleColumnToggle ( key as string ) ,
219+ } }
220+ >
221+ < Button icon = { < SettingOutlined /> } >
222+ { t ( "dataCollection.templateManagement.columnSettings" ) }
223+ </ Button >
224+ </ Dropdown >
225+ </ div >
155226
156227 < Card >
157228 < Table
0 commit comments