feat: jump between section on channel edit page
This commit is contained in:
parent
d77aa81f4f
commit
a23955a025
@ -66,6 +66,8 @@ import {
|
|||||||
IconCode,
|
IconCode,
|
||||||
IconGlobe,
|
IconGlobe,
|
||||||
IconBolt,
|
IconBolt,
|
||||||
|
IconChevronUp,
|
||||||
|
IconChevronDown,
|
||||||
} from '@douyinfe/semi-icons';
|
} from '@douyinfe/semi-icons';
|
||||||
|
|
||||||
const { Text, Title } = Typography;
|
const { Text, Title } = Typography;
|
||||||
@ -184,6 +186,18 @@ const EditChannelModal = (props) => {
|
|||||||
const [verifyCode, setVerifyCode] = useState('');
|
const [verifyCode, setVerifyCode] = useState('');
|
||||||
const [verifyLoading, setVerifyLoading] = useState(false);
|
const [verifyLoading, setVerifyLoading] = useState(false);
|
||||||
|
|
||||||
|
// 表单块导航相关状态
|
||||||
|
const formSectionRefs = useRef({
|
||||||
|
basicInfo: null,
|
||||||
|
apiConfig: null,
|
||||||
|
modelConfig: null,
|
||||||
|
advancedSettings: null,
|
||||||
|
channelExtraSettings: null,
|
||||||
|
});
|
||||||
|
const [currentSectionIndex, setCurrentSectionIndex] = useState(0);
|
||||||
|
const formSections = ['basicInfo', 'apiConfig', 'modelConfig', 'advancedSettings', 'channelExtraSettings'];
|
||||||
|
const formContainerRef = useRef(null);
|
||||||
|
|
||||||
// 2FA状态更新辅助函数
|
// 2FA状态更新辅助函数
|
||||||
const updateTwoFAState = (updates) => {
|
const updateTwoFAState = (updates) => {
|
||||||
setTwoFAState((prev) => ({ ...prev, ...updates }));
|
setTwoFAState((prev) => ({ ...prev, ...updates }));
|
||||||
@ -207,6 +221,37 @@ const EditChannelModal = (props) => {
|
|||||||
setVerifyLoading(false);
|
setVerifyLoading(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 表单导航功能
|
||||||
|
const scrollToSection = (sectionKey) => {
|
||||||
|
const sectionElement = formSectionRefs.current[sectionKey];
|
||||||
|
if (sectionElement) {
|
||||||
|
sectionElement.scrollIntoView({
|
||||||
|
behavior: 'smooth',
|
||||||
|
block: 'start',
|
||||||
|
inline: 'nearest'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const navigateToSection = (direction) => {
|
||||||
|
const availableSections = formSections.filter(section => {
|
||||||
|
if (section === 'apiConfig') {
|
||||||
|
return showApiConfigCard;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
let newIndex;
|
||||||
|
if (direction === 'up') {
|
||||||
|
newIndex = currentSectionIndex > 0 ? currentSectionIndex - 1 : availableSections.length - 1;
|
||||||
|
} else {
|
||||||
|
newIndex = currentSectionIndex < availableSections.length - 1 ? currentSectionIndex + 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
setCurrentSectionIndex(newIndex);
|
||||||
|
scrollToSection(availableSections[newIndex]);
|
||||||
|
};
|
||||||
|
|
||||||
// 渠道额外设置状态
|
// 渠道额外设置状态
|
||||||
const [channelSettings, setChannelSettings] = useState({
|
const [channelSettings, setChannelSettings] = useState({
|
||||||
force_format: false,
|
force_format: false,
|
||||||
@ -672,6 +717,8 @@ const EditChannelModal = (props) => {
|
|||||||
fetchModelGroups();
|
fetchModelGroups();
|
||||||
// 重置手动输入模式状态
|
// 重置手动输入模式状态
|
||||||
setUseManualInput(false);
|
setUseManualInput(false);
|
||||||
|
// 重置导航状态
|
||||||
|
setCurrentSectionIndex(0);
|
||||||
} else {
|
} else {
|
||||||
// 统一的模态框关闭重置逻辑
|
// 统一的模态框关闭重置逻辑
|
||||||
resetModalState();
|
resetModalState();
|
||||||
@ -1108,7 +1155,41 @@ const EditChannelModal = (props) => {
|
|||||||
visible={props.visible}
|
visible={props.visible}
|
||||||
width={isMobile ? '100%' : 600}
|
width={isMobile ? '100%' : 600}
|
||||||
footer={
|
footer={
|
||||||
<div className='flex justify-end bg-white'>
|
<div className='flex justify-between items-center bg-white'>
|
||||||
|
<div className='flex gap-2'>
|
||||||
|
<Button
|
||||||
|
size='small'
|
||||||
|
type='tertiary'
|
||||||
|
icon={<IconChevronUp />}
|
||||||
|
onClick={() => navigateToSection('up')}
|
||||||
|
style={{
|
||||||
|
borderRadius: '50%',
|
||||||
|
width: '32px',
|
||||||
|
height: '32px',
|
||||||
|
padding: 0,
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center'
|
||||||
|
}}
|
||||||
|
title={t('上一个表单块')}
|
||||||
|
/>
|
||||||
|
<Button
|
||||||
|
size='small'
|
||||||
|
type='tertiary'
|
||||||
|
icon={<IconChevronDown />}
|
||||||
|
onClick={() => navigateToSection('down')}
|
||||||
|
style={{
|
||||||
|
borderRadius: '50%',
|
||||||
|
width: '32px',
|
||||||
|
height: '32px',
|
||||||
|
padding: 0,
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center'
|
||||||
|
}}
|
||||||
|
title={t('下一个表单块')}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
<Space>
|
<Space>
|
||||||
<Button
|
<Button
|
||||||
theme='solid'
|
theme='solid'
|
||||||
@ -1139,10 +1220,14 @@ const EditChannelModal = (props) => {
|
|||||||
>
|
>
|
||||||
{() => (
|
{() => (
|
||||||
<Spin spinning={loading}>
|
<Spin spinning={loading}>
|
||||||
<div className='p-2'>
|
<div
|
||||||
<Card className='!rounded-2xl shadow-sm border-0 mb-6'>
|
className='p-2'
|
||||||
{/* Header: Basic Info */}
|
ref={formContainerRef}
|
||||||
<div className='flex items-center mb-2'>
|
>
|
||||||
|
<div ref={el => formSectionRefs.current.basicInfo = el}>
|
||||||
|
<Card className='!rounded-2xl shadow-sm border-0 mb-6'>
|
||||||
|
{/* Header: Basic Info */}
|
||||||
|
<div className='flex items-center mb-2'>
|
||||||
<Avatar
|
<Avatar
|
||||||
size='small'
|
size='small'
|
||||||
color='blue'
|
color='blue'
|
||||||
@ -1596,13 +1681,15 @@ const EditChannelModal = (props) => {
|
|||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</Card>
|
</Card>
|
||||||
|
</div>
|
||||||
|
|
||||||
{/* API Configuration Card */}
|
{/* API Configuration Card */}
|
||||||
{showApiConfigCard && (
|
{showApiConfigCard && (
|
||||||
<Card className='!rounded-2xl shadow-sm border-0 mb-6'>
|
<div ref={el => formSectionRefs.current.apiConfig = el}>
|
||||||
{/* Header: API Config */}
|
<Card className='!rounded-2xl shadow-sm border-0 mb-6'>
|
||||||
<div className='flex items-center mb-2'>
|
{/* Header: API Config */}
|
||||||
|
<div className='flex items-center mb-2'>
|
||||||
<Avatar
|
<Avatar
|
||||||
size='small'
|
size='small'
|
||||||
color='green'
|
color='green'
|
||||||
@ -1789,13 +1876,15 @@ const EditChannelModal = (props) => {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</Card>
|
</Card>
|
||||||
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Model Configuration Card */}
|
{/* Model Configuration Card */}
|
||||||
<Card className='!rounded-2xl shadow-sm border-0 mb-6'>
|
<div ref={el => formSectionRefs.current.modelConfig = el}>
|
||||||
{/* Header: Model Config */}
|
<Card className='!rounded-2xl shadow-sm border-0 mb-6'>
|
||||||
<div className='flex items-center mb-2'>
|
{/* Header: Model Config */}
|
||||||
|
<div className='flex items-center mb-2'>
|
||||||
<Avatar
|
<Avatar
|
||||||
size='small'
|
size='small'
|
||||||
color='purple'
|
color='purple'
|
||||||
@ -1988,12 +2077,14 @@ const EditChannelModal = (props) => {
|
|||||||
formApi={formApiRef.current}
|
formApi={formApiRef.current}
|
||||||
extraText={t('键为请求中的模型名称,值为要替换的模型名称')}
|
extraText={t('键为请求中的模型名称,值为要替换的模型名称')}
|
||||||
/>
|
/>
|
||||||
</Card>
|
</Card>
|
||||||
|
</div>
|
||||||
|
|
||||||
{/* Advanced Settings Card */}
|
{/* Advanced Settings Card */}
|
||||||
<Card className='!rounded-2xl shadow-sm border-0 mb-6'>
|
<div ref={el => formSectionRefs.current.advancedSettings = el}>
|
||||||
{/* Header: Advanced Settings */}
|
<Card className='!rounded-2xl shadow-sm border-0 mb-6'>
|
||||||
<div className='flex items-center mb-2'>
|
{/* Header: Advanced Settings */}
|
||||||
|
<div className='flex items-center mb-2'>
|
||||||
<Avatar
|
<Avatar
|
||||||
size='small'
|
size='small'
|
||||||
color='orange'
|
color='orange'
|
||||||
@ -2206,12 +2297,14 @@ const EditChannelModal = (props) => {
|
|||||||
'键为原状态码,值为要复写的状态码,仅影响本地判断',
|
'键为原状态码,值为要复写的状态码,仅影响本地判断',
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
</Card>
|
</Card>
|
||||||
|
</div>
|
||||||
|
|
||||||
{/* Channel Extra Settings Card */}
|
{/* Channel Extra Settings Card */}
|
||||||
<Card className='!rounded-2xl shadow-sm border-0 mb-6'>
|
<div ref={el => formSectionRefs.current.channelExtraSettings = el}>
|
||||||
{/* Header: Channel Extra Settings */}
|
<Card className='!rounded-2xl shadow-sm border-0 mb-6'>
|
||||||
<div className='flex items-center mb-2'>
|
{/* Header: Channel Extra Settings */}
|
||||||
|
<div className='flex items-center mb-2'>
|
||||||
<Avatar
|
<Avatar
|
||||||
size='small'
|
size='small'
|
||||||
color='violet'
|
color='violet'
|
||||||
@ -2309,7 +2402,8 @@ const EditChannelModal = (props) => {
|
|||||||
'如果用户请求中包含系统提示词,则使用此设置拼接到用户的系统提示词前面',
|
'如果用户请求中包含系统提示词,则使用此设置拼接到用户的系统提示词前面',
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
</Card>
|
</Card>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Spin>
|
</Spin>
|
||||||
)}
|
)}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user