Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
phsl
/
new-api
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
d502ac20
authored
Jun 11, 2025
by
同語
Committed by
GitHub
Jun 11, 2025
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #1199 from feitianbubu/revert-column-visiblity-settting-channel
feat: add column visibility settings for channels
parents
d5222743
f49a797f
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
196 additions
and
3 deletions
+196
-3
web/src/components/table/ChannelsTable.js
+196
-3
No files found.
web/src/components/table/ChannelsTable.js
View file @
d502ac20
...
@@ -41,6 +41,7 @@ import {
...
@@ -41,6 +41,7 @@ import {
Tag
,
Tag
,
Tooltip
,
Tooltip
,
Typography
,
Typography
,
Checkbox
,
Card
,
Card
,
Form
Form
}
from
'@douyinfe/semi-ui'
;
}
from
'@douyinfe/semi-ui'
;
...
@@ -172,17 +173,108 @@ const ChannelsTable = () => {
...
@@ -172,17 +173,108 @@ const ChannelsTable = () => {
}
}
};
};
// Define all columns
// Define column keys for selection
const
columns
=
[
const
COLUMN_KEYS
=
{
ID
:
'id'
,
NAME
:
'name'
,
GROUP
:
'group'
,
TYPE
:
'type'
,
STATUS
:
'status'
,
RESPONSE_TIME
:
'response_time'
,
BALANCE
:
'balance'
,
PRIORITY
:
'priority'
,
WEIGHT
:
'weight'
,
OPERATE
:
'operate'
,
};
// State for column visibility
const
[
visibleColumns
,
setVisibleColumns
]
=
useState
({});
const
[
showColumnSelector
,
setShowColumnSelector
]
=
useState
(
false
);
// Load saved column preferences from localStorage
useEffect
(()
=>
{
const
savedColumns
=
localStorage
.
getItem
(
'channels-table-columns'
);
if
(
savedColumns
)
{
try
{
const
parsed
=
JSON
.
parse
(
savedColumns
);
// Make sure all columns are accounted for
const
defaults
=
getDefaultColumnVisibility
();
const
merged
=
{
...
defaults
,
...
parsed
};
setVisibleColumns
(
merged
);
}
catch
(
e
)
{
console
.
error
(
'Failed to parse saved column preferences'
,
e
);
initDefaultColumns
();
}
}
else
{
initDefaultColumns
();
}
},
[]);
// Update table when column visibility changes
useEffect
(()
=>
{
if
(
Object
.
keys
(
visibleColumns
).
length
>
0
)
{
// Save to localStorage
localStorage
.
setItem
(
'channels-table-columns'
,
JSON
.
stringify
(
visibleColumns
),
);
}
},
[
visibleColumns
]);
// Get default column visibility
const
getDefaultColumnVisibility
=
()
=>
{
return
{
[
COLUMN_KEYS
.
ID
]:
true
,
[
COLUMN_KEYS
.
NAME
]:
true
,
[
COLUMN_KEYS
.
GROUP
]:
true
,
[
COLUMN_KEYS
.
TYPE
]:
true
,
[
COLUMN_KEYS
.
STATUS
]:
true
,
[
COLUMN_KEYS
.
RESPONSE_TIME
]:
true
,
[
COLUMN_KEYS
.
BALANCE
]:
true
,
[
COLUMN_KEYS
.
PRIORITY
]:
true
,
[
COLUMN_KEYS
.
WEIGHT
]:
true
,
[
COLUMN_KEYS
.
OPERATE
]:
true
,
};
};
// Initialize default column visibility
const
initDefaultColumns
=
()
=>
{
const
defaults
=
getDefaultColumnVisibility
();
setVisibleColumns
(
defaults
);
};
// Handle column visibility change
const
handleColumnVisibilityChange
=
(
columnKey
,
checked
)
=>
{
const
updatedColumns
=
{
...
visibleColumns
,
[
columnKey
]:
checked
};
setVisibleColumns
(
updatedColumns
);
};
// Handle "Select All" checkbox
const
handleSelectAll
=
(
checked
)
=>
{
const
allKeys
=
Object
.
keys
(
COLUMN_KEYS
).
map
((
key
)
=>
COLUMN_KEYS
[
key
]);
const
updatedColumns
=
{};
allKeys
.
forEach
((
key
)
=>
{
updatedColumns
[
key
]
=
checked
;
});
setVisibleColumns
(
updatedColumns
);
};
// Define all columns with keys
const
allColumns
=
[
{
{
key
:
COLUMN_KEYS
.
ID
,
title
:
t
(
'ID'
),
title
:
t
(
'ID'
),
dataIndex
:
'id'
,
dataIndex
:
'id'
,
},
},
{
{
key
:
COLUMN_KEYS
.
NAME
,
title
:
t
(
'名称'
),
title
:
t
(
'名称'
),
dataIndex
:
'name'
,
dataIndex
:
'name'
,
},
},
{
{
key
:
COLUMN_KEYS
.
GROUP
,
title
:
t
(
'分组'
),
title
:
t
(
'分组'
),
dataIndex
:
'group'
,
dataIndex
:
'group'
,
render
:
(
text
,
record
,
index
)
=>
(
render
:
(
text
,
record
,
index
)
=>
(
...
@@ -201,6 +293,7 @@ const ChannelsTable = () => {
...
@@ -201,6 +293,7 @@ const ChannelsTable = () => {
),
),
},
},
{
{
key
:
COLUMN_KEYS
.
TYPE
,
title
:
t
(
'类型'
),
title
:
t
(
'类型'
),
dataIndex
:
'type'
,
dataIndex
:
'type'
,
render
:
(
text
,
record
,
index
)
=>
{
render
:
(
text
,
record
,
index
)
=>
{
...
@@ -212,6 +305,7 @@ const ChannelsTable = () => {
...
@@ -212,6 +305,7 @@ const ChannelsTable = () => {
},
},
},
},
{
{
key
:
COLUMN_KEYS
.
STATUS
,
title
:
t
(
'状态'
),
title
:
t
(
'状态'
),
dataIndex
:
'status'
,
dataIndex
:
'status'
,
render
:
(
text
,
record
,
index
)
=>
{
render
:
(
text
,
record
,
index
)
=>
{
...
@@ -237,6 +331,7 @@ const ChannelsTable = () => {
...
@@ -237,6 +331,7 @@ const ChannelsTable = () => {
},
},
},
},
{
{
key
:
COLUMN_KEYS
.
RESPONSE_TIME
,
title
:
t
(
'响应时间'
),
title
:
t
(
'响应时间'
),
dataIndex
:
'response_time'
,
dataIndex
:
'response_time'
,
render
:
(
text
,
record
,
index
)
=>
(
render
:
(
text
,
record
,
index
)
=>
(
...
@@ -244,6 +339,7 @@ const ChannelsTable = () => {
...
@@ -244,6 +339,7 @@ const ChannelsTable = () => {
),
),
},
},
{
{
key
:
COLUMN_KEYS
.
BALANCE
,
title
:
t
(
'已用/剩余'
),
title
:
t
(
'已用/剩余'
),
dataIndex
:
'expired_time'
,
dataIndex
:
'expired_time'
,
render
:
(
text
,
record
,
index
)
=>
{
render
:
(
text
,
record
,
index
)
=>
{
...
@@ -283,6 +379,7 @@ const ChannelsTable = () => {
...
@@ -283,6 +379,7 @@ const ChannelsTable = () => {
},
},
},
},
{
{
key
:
COLUMN_KEYS
.
PRIORITY
,
title
:
t
(
'优先级'
),
title
:
t
(
'优先级'
),
dataIndex
:
'priority'
,
dataIndex
:
'priority'
,
render
:
(
text
,
record
,
index
)
=>
{
render
:
(
text
,
record
,
index
)
=>
{
...
@@ -334,6 +431,7 @@ const ChannelsTable = () => {
...
@@ -334,6 +431,7 @@ const ChannelsTable = () => {
},
},
},
},
{
{
key
:
COLUMN_KEYS
.
WEIGHT
,
title
:
t
(
'权重'
),
title
:
t
(
'权重'
),
dataIndex
:
'weight'
,
dataIndex
:
'weight'
,
render
:
(
text
,
record
,
index
)
=>
{
render
:
(
text
,
record
,
index
)
=>
{
...
@@ -385,6 +483,7 @@ const ChannelsTable = () => {
...
@@ -385,6 +483,7 @@ const ChannelsTable = () => {
},
},
},
},
{
{
key
:
COLUMN_KEYS
.
OPERATE
,
title
:
''
,
title
:
''
,
dataIndex
:
'operate'
,
dataIndex
:
'operate'
,
fixed
:
'right'
,
fixed
:
'right'
,
...
@@ -595,6 +694,89 @@ const ChannelsTable = () => {
...
@@ -595,6 +694,89 @@ const ChannelsTable = () => {
searchModel
:
''
,
searchModel
:
''
,
};
};
// Filter columns based on visibility settings
const
getVisibleColumns
=
()
=>
{
return
allColumns
.
filter
((
column
)
=>
visibleColumns
[
column
.
key
]);
};
// Column selector modal
const
renderColumnSelector
=
()
=>
{
return
(
<
Modal
title
=
{
t
(
'列设置'
)}
visible
=
{
showColumnSelector
}
onCancel
=
{()
=>
setShowColumnSelector
(
false
)}
footer
=
{
<
div
className
=
"flex justify-end"
>
<
Button
theme
=
"light"
onClick
=
{()
=>
initDefaultColumns
()}
className
=
"!rounded-full"
>
{
t
(
'重置'
)}
<
/Button
>
<
Button
theme
=
"light"
onClick
=
{()
=>
setShowColumnSelector
(
false
)}
className
=
"!rounded-full"
>
{
t
(
'取消'
)}
<
/Button
>
<
Button
type
=
'primary'
onClick
=
{()
=>
setShowColumnSelector
(
false
)}
className
=
"!rounded-full"
>
{
t
(
'确定'
)}
<
/Button
>
<
/div
>
}
size
=
"middle"
centered
=
{
true
}
>
<
div
style
=
{{
marginBottom
:
20
}}
>
<
Checkbox
checked
=
{
Object
.
values
(
visibleColumns
).
every
((
v
)
=>
v
===
true
)}
indeterminate
=
{
Object
.
values
(
visibleColumns
).
some
((
v
)
=>
v
===
true
)
&&
!
Object
.
values
(
visibleColumns
).
every
((
v
)
=>
v
===
true
)
}
onChange
=
{(
e
)
=>
handleSelectAll
(
e
.
target
.
checked
)}
>
{
t
(
'全选'
)}
<
/Checkbox
>
<
/div
>
<
div
className
=
"flex flex-wrap max-h-96 overflow-y-auto rounded-lg p-4"
style
=
{{
border
:
'1px solid var(--semi-color-border)'
}}
>
{
allColumns
.
map
((
column
)
=>
{
// Skip columns without title
if
(
!
column
.
title
)
{
return
null
;
}
return
(
<
div
key
=
{
column
.
key
}
className
=
"w-1/2 mb-4 pr-2"
>
<
Checkbox
checked
=
{
!!
visibleColumns
[
column
.
key
]}
onChange
=
{(
e
)
=>
handleColumnVisibilityChange
(
column
.
key
,
e
.
target
.
checked
)
}
>
{
column
.
title
}
<
/Checkbox
>
<
/div
>
);
})}
<
/div
>
<
/Modal
>
);
};
const
removeRecord
=
(
record
)
=>
{
const
removeRecord
=
(
record
)
=>
{
let
newDataSource
=
[...
channels
];
let
newDataSource
=
[...
channels
];
if
(
record
.
id
!=
null
)
{
if
(
record
.
id
!=
null
)
{
...
@@ -1397,6 +1579,16 @@ const ChannelsTable = () => {
...
@@ -1397,6 +1579,16 @@ const ChannelsTable = () => {
>
>
{
t
(
'刷新'
)}
{
t
(
'刷新'
)}
<
/Button
>
<
/Button
>
<
Button
theme
=
'light'
type
=
'tertiary'
icon
=
{
<
IconSetting
/>
}
onClick
=
{()
=>
setShowColumnSelector
(
true
)}
className
=
"!rounded-full w-full md:w-auto"
>
{
t
(
'列设置'
)}
<
/Button
>
<
/div
>
<
/div
>
<
div
className
=
"flex flex-col md:flex-row items-center gap-4 w-full md:w-auto order-1 md:order-2"
>
<
div
className
=
"flex flex-col md:flex-row items-center gap-4 w-full md:w-auto order-1 md:order-2"
>
...
@@ -1481,6 +1673,7 @@ const ChannelsTable = () => {
...
@@ -1481,6 +1673,7 @@ const ChannelsTable = () => {
return
(
return
(
<>
<>
{
renderColumnSelector
()}
<
EditTagModal
<
EditTagModal
visible
=
{
showEditTag
}
visible
=
{
showEditTag
}
tag
=
{
editingTag
}
tag
=
{
editingTag
}
...
@@ -1501,7 +1694,7 @@ const ChannelsTable = () => {
...
@@ -1501,7 +1694,7 @@ const ChannelsTable = () => {
bordered
=
{
false
}
bordered
=
{
false
}
>
>
<
Table
<
Table
columns
=
{
columns
}
columns
=
{
getVisibleColumns
()
}
dataSource
=
{
pageData
}
dataSource
=
{
pageData
}
scroll
=
{{
x
:
'max-content'
}}
scroll
=
{{
x
:
'max-content'
}}
pagination
=
{{
pagination
=
{{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment