🔧 fix(ui): 清理控制台 Form 与 Modal 弃用警告

- 关闭消息发送弹窗时不再对已卸载 Form 调用 resetFields
- 缩放修复路径中 ResetWebViewZoom 不可用时最多告警一次
- 将 Drawer/Modal 的 destroyOnClose 统一迁移为 destroyOnHidden
This commit is contained in:
Syngnat
2026-07-24 22:31:33 +08:00
parent 4400fd67c0
commit 4c0f0a8fdd
10 changed files with 39 additions and 26 deletions

View File

@@ -1797,6 +1797,29 @@ function App() {
let hiddenSeen = document.visibilityState === 'hidden';
const wait = (ms: number) => new Promise<void>((resolve) => window.setTimeout(resolve, ms));
// Automatic scale-fix may call ResetWebViewZoom multiple times on startup.
// The backend path depends on Wails unexported fields and can fail harmlessly;
// log at most once so the console is not flooded with expected unavailability.
let resetWebViewZoomUnavailableLogged = false;
const tryResetWebViewZoomQuietly = async () => {
try {
const res = await (window as any).go?.app?.App?.ResetWebViewZoom?.();
if (res?.success) {
return true;
}
if (!resetWebViewZoomUnavailableLogged) {
resetWebViewZoomUnavailableLogged = true;
console.warn('ResetWebViewZoom unavailable in fixWindowScaleIfNeeded:', res?.message);
}
return false;
} catch (e) {
if (!resetWebViewZoomUnavailableLogged) {
resetWebViewZoomUnavailableLogged = true;
console.warn('ResetWebViewZoom call failed in fixWindowScaleIfNeeded', e);
}
return false;
}
};
const fixWindowScaleIfNeeded = async (reason: WindowScaleFixReason) => {
if (cancelled || inFlight) return;
@@ -1828,14 +1851,7 @@ function App() {
const shouldResetWebViewZoom = shouldResetWebViewZoomForScaleFix(reason, hasViewportScaleDrift);
if (shouldResetWebViewZoom && !isMaximised) {
try {
const res = await (window as any).go?.app?.App?.ResetWebViewZoom?.();
if (!res?.success) {
console.warn('ResetWebViewZoom unavailable in fixWindowScaleIfNeeded:', res?.message);
}
} catch (e) {
console.warn('ResetWebViewZoom call failed in fixWindowScaleIfNeeded', e);
}
await tryResetWebViewZoomQuietly();
}
if (isMaximised) {
@@ -1847,14 +1863,7 @@ function App() {
// backend 失败wails 升级破坏反射 / 非 Windows时回退到 dispatch resize 兜底;
// 用户仍可按 Ctrl+Shift+0 手动 toggle 修复。
if (shouldResetWebViewZoom) {
try {
const res = await (window as any).go?.app?.App?.ResetWebViewZoom?.();
if (!res?.success) {
console.warn('ResetWebViewZoom unavailable in fixWindowScaleIfNeeded:', res?.message);
}
} catch (e) {
console.warn('ResetWebViewZoom call failed in fixWindowScaleIfNeeded', e);
}
await tryResetWebViewZoomQuietly();
}
window.dispatchEvent(new Event('resize'));
lastFixAt = Date.now();

View File

@@ -19,6 +19,9 @@ describe('MessagePublishModal i18n shell guards', () => {
expect(modalSource).toContain('connectionName: connection.name');
expect(modalSource).toContain('detail: res?.message');
expect(modalSource).toContain('detail: error?.message || String(error)');
expect(modalSource).toContain('destroyOnHidden');
// Closed modals unmount Form; never call form APIs while open === false.
expect(modalSource).not.toContain('form.resetFields()');
expect(modalSource).not.toContain('测试发送消息');
expect(modalSource).not.toContain('okText="发送"');
expect(modalSource).not.toContain('发送失败:');

View File

@@ -63,6 +63,8 @@ const MessagePublishModal: React.FC<MessagePublishModalProps> = ({
);
useEffect(() => {
// destroyOnHidden unmounts the Form while closed. Only touch the form
// instance when the modal is open so useForm stays connected.
if (!open || !connection) return;
form.setFieldsValue(
createDefaultMessagePublishDraft(
@@ -74,9 +76,8 @@ const MessagePublishModal: React.FC<MessagePublishModalProps> = ({
useEffect(() => {
if (open) return;
form.resetFields();
setSubmitting(false);
}, [form, open]);
}, [open]);
const handleSubmit = async () => {
if (!connection) return;

View File

@@ -146,7 +146,7 @@ export default function SqlAuditDetailDrawer({
onClose={onClose}
width="min(760px, calc(100vw - 24px))"
title={t('sql_audit.detail.title')}
destroyOnClose
destroyOnHidden
styles={{
body: {
padding: 20,

View File

@@ -82,7 +82,7 @@ export default function SqlAuditSettingsDrawer({
onClose={onClose}
width={440}
title={t('sql_audit.settings.title')}
destroyOnClose
destroyOnHidden
extra={(
<Space>
<Button onClick={onClose}>{t('common.cancel')}</Button>

View File

@@ -262,7 +262,7 @@ export default function ExplainWorkbench({ open, onClose, config, dbName, sql }:
width="90%"
style={{ top: 20 }}
title={<Title level={5} style={{ margin: 0 }}>{t('sql_analysis.workbench.title')}</Title>}
destroyOnClose
destroyOnHidden
>
<div style={{ minHeight: 480, height: '70vh' }}>
<ExplainReportView

View File

@@ -318,7 +318,7 @@ export default function SlowQueryPanel({ open, onClose, config, dbName, onPickQu
<Text type="secondary">{dbName || t('sql_analysis.slow_query.current_connection')}</Text>
</div>
}
destroyOnClose
destroyOnHidden
>
<div className="gn-slow-query-modal-body">
<SlowQueryPanelContent
@@ -454,7 +454,7 @@ function SlowQueryCard({
{t('common.close')}
</Button>,
]}
destroyOnClose
destroyOnHidden
>
<pre
className="gn-slow-query-full-sql"

View File

@@ -840,7 +840,7 @@ const ResultDiffPanel: React.FC<ResultDiffPanelProps> = ({
onClose={handleClose}
maskClosable={false}
width="min(1100px, 96vw)"
destroyOnClose={false}
destroyOnHidden={false}
extra={actionButtons}
>
{body}

View File

@@ -184,7 +184,7 @@ const ResultDiffWizard: React.FC<ResultDiffWizardProps> = ({
onOk={handleStart}
okText={t('result_diff.wizard.start')}
confirmLoading={loading}
destroyOnClose
destroyOnHidden
width={640}
maskClosable={!loading}
>

View File

@@ -510,7 +510,7 @@ const ViewDataVerifyWizard: React.FC<ViewDataVerifyWizardProps> = ({
onOk={handleStart}
okText={t('result_diff.view_verify.start')}
confirmLoading={running || probing}
destroyOnClose
destroyOnHidden
width={680}
maskClosable={!running}
>