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 {
@@ -70,94 +88,147 @@ export default function TemplateManagement() {
7088 0
7189 ) ;
7290
73- const columns : ColumnsType < CollectionTemplate > = [
74- {
75- title : t ( "dataCollection.templateManagement.columns.templateName" ) ,
76- dataIndex : "name" ,
77- key : "name" ,
78- fixed : "left" ,
79- width : 200 ,
80- ellipsis : true ,
81- } ,
82- {
83- title : t ( "dataCollection.templateManagement.columns.templateType" ) ,
84- dataIndex : "builtIn" ,
85- key : "builtIn" ,
86- width : 120 ,
87- render : ( v ?: boolean ) => (
88- < Tag color = { v ? "blue" : "default" } >
89- { v
90- ? t ( "dataCollection.templateManagement.filters.builtIn" )
91- : t ( "dataCollection.templateManagement.filters.custom" ) }
92- </ Tag >
93- ) ,
94- } ,
95- {
96- title : t ( "dataCollection.templateManagement.columns.source" ) ,
97- key : "source" ,
98- width : 220 ,
99- ellipsis : true ,
100- render : ( _ : any , record : CollectionTemplate ) => (
101- < span > { `${ record . sourceType } / ${ record . sourceName } ` } </ span >
102- ) ,
103- } ,
104- {
105- title : t ( "dataCollection.templateManagement.columns.target" ) ,
106- key : "target" ,
107- width : 220 ,
108- ellipsis : true ,
109- render : ( _ : any , record : CollectionTemplate ) => (
110- < span > { `${ record . targetType } / ${ record . targetName } ` } </ span >
111- ) ,
112- } ,
113- {
114- title : t ( "dataCollection.templateManagement.columns.description" ) ,
115- dataIndex : "description" ,
116- key : "description" ,
117- width : 260 ,
118- ellipsis : true ,
119- render : ( v ?: string ) => v || t ( "common.placeholders.empty" ) ,
120- } ,
121- {
122- title : t ( "dataCollection.templateManagement.columns.createdAt" ) ,
123- dataIndex : "createdAt" ,
124- key : "createdAt" ,
125- width : 160 ,
126- } ,
127- {
128- title : t ( "dataCollection.templateManagement.columns.updatedAt" ) ,
129- dataIndex : "updatedAt" ,
130- key : "updatedAt" ,
131- width : 160 ,
132- } ,
133- ] ;
91+ // 根据隐藏列的状态动态生成 columns
92+ const columns : ColumnsType < CollectionTemplate > = useMemo ( ( ) => {
93+ const allColumns : ColumnsType < CollectionTemplate > = [
94+ {
95+ title : t ( "dataCollection.templateManagement.columns.templateName" ) ,
96+ dataIndex : "name" ,
97+ key : "name" ,
98+ fixed : "left" ,
99+ width : 200 ,
100+ ellipsis : true ,
101+ } ,
102+ {
103+ title : t ( "dataCollection.templateManagement.columns.templateType" ) ,
104+ dataIndex : "builtIn" ,
105+ key : "builtIn" ,
106+ width : 120 ,
107+ render : ( v ?: boolean ) => (
108+ < Tag color = { v ? "blue" : "default" } >
109+ { v
110+ ? t ( "dataCollection.templateManagement.filters.builtIn" )
111+ : t ( "dataCollection.templateManagement.filters.custom" ) }
112+ </ Tag >
113+ ) ,
114+ } ,
115+ {
116+ title : t ( "dataCollection.templateManagement.columns.source" ) ,
117+ key : "source" ,
118+ width : 220 ,
119+ ellipsis : true ,
120+ render : ( _ : any , record : CollectionTemplate ) => {
121+ // 如果 sourceType 和 sourceName 相同,只显示一个
122+ if ( record . sourceType === record . sourceName ) {
123+ return < span > { record . sourceType } </ span > ;
124+ }
125+ return < span > { `${ record . sourceType } / ${ record . sourceName } ` } </ span > ;
126+ } ,
127+ } ,
128+ {
129+ title : t ( "dataCollection.templateManagement.columns.target" ) ,
130+ key : "target" ,
131+ width : 220 ,
132+ ellipsis : true ,
133+ render : ( _ : any , record : CollectionTemplate ) => {
134+ // 如果 targetType 和 targetName 相同,只显示一个
135+ if ( record . targetType === record . targetName ) {
136+ return < span > { record . targetType } </ span > ;
137+ }
138+ return < span > { `${ record . targetType } / ${ record . targetName } ` } </ span > ;
139+ } ,
140+ } ,
141+ {
142+ title : t ( "dataCollection.templateManagement.columns.description" ) ,
143+ dataIndex : "description" ,
144+ key : "description" ,
145+ width : 260 ,
146+ ellipsis : true ,
147+ render : ( v ?: string ) => v || t ( "common.placeholders.empty" ) ,
148+ } ,
149+ {
150+ title : t ( "dataCollection.templateManagement.columns.createdAt" ) ,
151+ dataIndex : "createdAt" ,
152+ key : "createdAt" ,
153+ width : 160 ,
154+ } ,
155+ {
156+ title : t ( "dataCollection.templateManagement.columns.updatedAt" ) ,
157+ dataIndex : "updatedAt" ,
158+ key : "updatedAt" ,
159+ width : 160 ,
160+ } ,
161+ ] ;
162+
163+ // 过滤掉隐藏的列
164+ return allColumns . filter ( col => ! hiddenColumns . has ( col . key as string ) ) ;
165+ } , [ t , hiddenColumns ] ) ;
166+
167+ // 列显示切换处理
168+ const handleColumnToggle = ( columnKey : string ) => {
169+ setHiddenColumns ( prev => {
170+ const newHidden = new Set ( prev ) ;
171+ if ( newHidden . has ( columnKey ) ) {
172+ newHidden . delete ( columnKey ) ;
173+ } else {
174+ newHidden . add ( columnKey ) ;
175+ }
176+ return newHidden ;
177+ } ) ;
178+ } ;
179+
180+ // 列选择菜单
181+ const columnMenuItems : MenuProps [ 'items' ] = Object . entries ( ALL_COLUMNS ) . map ( ( [ key , label ] ) => ( {
182+ key,
183+ label : t ( label ) ,
184+ } ) ) ;
185+
186+ // 获取显示的列(非隐藏列)
187+ const visibleColumns = Object . keys ( ALL_COLUMNS ) . filter ( key => ! hiddenColumns . has ( key ) ) ;
134188
135189 return (
136190 < div className = "space-y-4" >
137- < SearchControls
138- searchTerm = { searchParams . keyword }
139- onSearchChange = { ( newSearchTerm ) =>
140- setSearchParams ( ( prev ) => ( {
141- ...prev ,
142- keyword : newSearchTerm ,
143- current : 1 ,
144- } ) )
145- }
146- searchPlaceholder = { t ( "dataCollection.templateManagement.filters.searchPlaceholder" ) }
147- filters = { filters }
148- onFiltersChange = { handleFiltersChange }
149- showViewToggle = { false }
150- onClearFilters = { ( ) =>
151- setSearchParams ( ( prev ) => ( {
152- ...prev ,
153- filter : { ...prev . filter , builtIn : [ ] } ,
154- current : 1 ,
155- } ) )
156- }
157- onReload = { ( ) => {
158- fetchData ( ) . catch ( ( ) => message . error ( t ( "dataCollection.templateManagement.messages.refreshFailed" ) ) ) ;
159- } }
160- />
191+ < div className = "flex items-center justify-between" >
192+ < SearchControls
193+ searchTerm = { searchParams . keyword }
194+ onSearchChange = { ( newSearchTerm ) =>
195+ setSearchParams ( ( prev ) => ( {
196+ ...prev ,
197+ keyword : newSearchTerm ,
198+ current : 1 ,
199+ } ) )
200+ }
201+ searchPlaceholder = { t ( "dataCollection.templateManagement.filters.searchPlaceholder" ) }
202+ filters = { filters }
203+ onFiltersChange = { handleFiltersChange }
204+ showViewToggle = { false }
205+ showReload = { true }
206+ onClearFilters = { ( ) =>
207+ setSearchParams ( ( prev ) => ( {
208+ ...prev ,
209+ filter : { ...prev . filter , builtIn : [ ] } ,
210+ current : 1 ,
211+ } ) )
212+ }
213+ onReload = { ( ) => {
214+ fetchData ( ) . catch ( ( ) => message . error ( t ( "dataCollection.templateManagement.messages.refreshFailed" ) ) ) ;
215+ } }
216+ className = "flex-1"
217+ />
218+ < Dropdown
219+ menu = { {
220+ items : columnMenuItems ,
221+ selectable : true ,
222+ multiple : true ,
223+ selectedKeys : visibleColumns ,
224+ onClick : ( { key } ) => handleColumnToggle ( key as string ) ,
225+ } }
226+ >
227+ < Button icon = { < SettingOutlined /> } >
228+ { t ( "dataCollection.templateManagement.columnSettings" ) }
229+ </ Button >
230+ </ Dropdown >
231+ </ div >
161232
162233 < Card >
163234 < Table
0 commit comments