Skip to content

Commit 811fca7

Browse files
authored
fix(client): close confirmation before saved SQL naming
1 parent 50e6f3d commit 811fca7

2 files changed

Lines changed: 28 additions & 25 deletions

File tree

‎chat2db-community-client/src/utils/editorCloseConfirmation.tsx‎

Lines changed: 13 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import { useState } from 'react';
21
import { Button } from 'antd';
32
import { staticModal } from '@chat2db/ui';
43
import i18n from '@/i18n';
@@ -21,31 +20,24 @@ interface EditorCloseDialogFooterProps {
2120
const footerButtonStyle = { marginInlineStart: 0 };
2221

2322
function EditorCloseDialogFooter({ editor, onDecision }: EditorCloseDialogFooterProps) {
24-
const [saving, setSaving] = useState(false);
25-
26-
const handleSave = async () => {
27-
if (!editor.saveBeforeClose || saving) {
23+
const handleSave = () => {
24+
if (!editor.saveBeforeClose) {
2825
return;
2926
}
30-
setSaving(true);
31-
try {
32-
if (await editor.saveBeforeClose()) {
33-
onDecision('saved');
34-
}
35-
} finally {
36-
setSaving(false);
37-
}
27+
// Resolve the dialog before starting the save. An unnamed draft opens a
28+
// second modal to collect its name, which must be the only active layer.
29+
onDecision('save');
3830
};
3931

4032
return (
4133
<div style={{ display: 'grid', gap: 8, width: '100%' }}>
42-
<Button block type="primary" loading={saving} style={footerButtonStyle} onClick={handleSave}>
34+
<Button block type="primary" style={footerButtonStyle} onClick={handleSave}>
4335
{i18n('common.button.save')}
4436
</Button>
45-
<Button block disabled={saving} style={footerButtonStyle} onClick={() => onDecision('discard')}>
37+
<Button block style={footerButtonStyle} onClick={() => onDecision('discard')}>
4638
{i18n('workspace.editorClose.dontSave')}
4739
</Button>
48-
<Button block disabled={saving} style={footerButtonStyle} onClick={() => onDecision('cancel')}>
40+
<Button block style={footerButtonStyle} onClick={() => onDecision('cancel')}>
4941
{i18n('common.button.cancel')}
5042
</Button>
5143
</div>
@@ -54,14 +46,13 @@ function EditorCloseDialogFooter({ editor, onDecision }: EditorCloseDialogFooter
5446

5547
function requestEditorCloseDecision(tab: IWorkspaceTab, editor: EditorCloseGuardRef) {
5648
return new Promise<EditorCloseDecision>((resolve) => {
57-
let settled = false;
58-
const finish = (decision: EditorCloseDecision) => {
59-
if (settled) {
49+
let selectedDecision: EditorCloseDecision | undefined;
50+
const finish = (nextDecision: EditorCloseDecision) => {
51+
if (selectedDecision !== undefined) {
6052
return;
6153
}
62-
settled = true;
54+
selectedDecision = nextDecision;
6355
modal.destroy();
64-
resolve(decision);
6556
};
6657
const modal = staticModal.confirm({
6758
icon: null,
@@ -75,10 +66,7 @@ function requestEditorCloseDecision(tab: IWorkspaceTab, editor: EditorCloseGuard
7566
footer: () => <EditorCloseDialogFooter editor={editor} onDecision={finish} />,
7667
onCancel: () => finish('cancel'),
7768
afterClose: () => {
78-
if (!settled) {
79-
settled = true;
80-
resolve('cancel');
81-
}
69+
resolve(selectedDecision ?? 'cancel');
8270
},
8371
});
8472
});

‎chat2db-community-client/src/utils/editorCloseGuard.test.ts‎

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,21 @@ async function run() {
129129
3,
130130
'all close-dialog actions share the same horizontal alignment',
131131
);
132+
assert.match(
133+
confirmationSource,
134+
/const handleSave = \(\) => \{[\s\S]*?onDecision\('save'\)/,
135+
'the save action resolves the close dialog before the guard starts saving',
136+
);
137+
assert.doesNotMatch(
138+
confirmationSource,
139+
/await editor\.saveBeforeClose\(\)/,
140+
'the close dialog must not keep a second save modal blocked behind it',
141+
);
142+
assert.match(
143+
confirmationSource,
144+
/afterClose: \(\) => \{[\s\S]*?resolve\(selectedDecision \?\? 'cancel'\)/,
145+
'the guard waits for the close mask to finish its exit lifecycle',
146+
);
132147

133148
console.log('Editor close guard tests passed');
134149
}

0 commit comments

Comments
 (0)