🐛 fix(model-test-modal): keep Modal mounted to restore body overflow correctly

Previously the component unmounted the Modal as soon as `showModelTestModal` became
false, preventing Semi UI from running its cleanup routine. This left `body`
stuck with `overflow: hidden`, disabling page scroll after the dialog closed.

Changes made
– Removed the early `return null` and always keep the Modal mounted; visibility
  is now controlled solely via the `visible` prop.
– Introduced a `hasChannel` guard to safely skip data processing/rendering when
  no channel is selected.
– Added defensive checks for table data, footer and title to avoid undefined
  access when the Modal is hidden.

This fix ensures that closing the test-model dialog correctly restores the
page’s scroll behaviour on both desktop and mobile.
This commit is contained in:
t0ng7u
2025-07-19 11:34:34 +08:00
parent 635bfd4aba
commit f3bcf570f4
3 changed files with 16 additions and 16 deletions

View File

@@ -139,7 +139,6 @@ const CardPro = ({
</div>
)}
</div>
</div>
);
};

View File

@@ -440,7 +440,7 @@ const SiderBar = ({ onNavigate = () => { } }) => {
/>
}
onClick={toggleCollapsed}
iconOnly={collapsed}
icononly={collapsed}
style={collapsed ? { padding: '4px', width: '100%' } : { padding: '4px 12px', width: '100%' }}
>
{!collapsed ? t('收起侧边栏') : null}

View File

@@ -49,15 +49,15 @@ const ModelTestModal = ({
isMobile,
t
}) => {
if (!showModelTestModal || !currentTestChannel) {
return null;
}
const hasChannel = Boolean(currentTestChannel);
const filteredModels = currentTestChannel.models
.split(',')
.filter((model) =>
model.toLowerCase().includes(modelSearchKeyword.toLowerCase())
);
const filteredModels = hasChannel
? currentTestChannel.models
.split(',')
.filter((model) =>
model.toLowerCase().includes(modelSearchKeyword.toLowerCase())
)
: [];
const handleCopySelected = () => {
if (selectedModelKeys.length === 0) {
@@ -158,6 +158,7 @@ const ModelTestModal = ({
];
const dataSource = (() => {
if (!hasChannel) return [];
const start = (modelTablePage - 1) * MODEL_TABLE_PAGE_SIZE;
const end = start + MODEL_TABLE_PAGE_SIZE;
return filteredModels.slice(start, end).map((model) => ({
@@ -168,7 +169,7 @@ const ModelTestModal = ({
return (
<Modal
title={
title={hasChannel ? (
<div className="flex flex-col gap-2 w-full">
<div className="flex items-center gap-2">
<Typography.Text strong className="!text-[var(--semi-color-text-0)] !text-base">
@@ -179,10 +180,10 @@ const ModelTestModal = ({
</Typography.Text>
</div>
</div>
}
) : null}
visible={showModelTestModal}
onCancel={handleCloseModal}
footer={
footer={hasChannel ? (
<div className="flex justify-end">
{isBatchTesting ? (
<Button
@@ -210,12 +211,12 @@ const ModelTestModal = ({
)}
</Button>
</div>
}
) : null}
maskClosable={!isBatchTesting}
className="!rounded-lg"
size={isMobile ? 'full-width' : 'large'}
>
<div className="model-test-scroll">
{hasChannel && (<div className="model-test-scroll">
{/* 搜索与操作按钮 */}
<div className="flex items-center justify-end gap-2 w-full mb-2">
<Input
@@ -267,7 +268,7 @@ const ModelTestModal = ({
onPageChange: (page) => setModelTablePage(page),
}}
/>
</div>
</div>)}
</Modal>
);
};