Skip to content

Commit 7431e42

Browse files
committed
fix(webview): handle unsaved API config changes on unmount
- Move handleSave to useCallback for better performance - Add cleanup effect to save pending changes on unmount - Improve new config UX by setting default copy name - Fix code formatting
1 parent 5f3ace4 commit 7431e42

File tree

1 file changed

+28
-21
lines changed

1 file changed

+28
-21
lines changed

webview-ui/src/components/settings/ApiConfigManager.tsx

Lines changed: 28 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { VSCodeButton, VSCodeTextField } from "@vscode/webview-ui-toolkit/react"
2-
import { memo, useEffect, useRef, useState } from "react"
2+
import { memo, useCallback, useEffect, useRef, useState } from "react"
33
import { ApiConfigMeta } from "../../../../src/shared/ExtensionMessage"
44

55
interface ApiConfigManagerProps {
@@ -36,9 +36,30 @@ const ApiConfigManager = ({
3636
setInputValue("");
3737
}, [currentApiConfigName]);
3838

39+
const handleSave = useCallback(() => {
40+
const trimmedValue = inputValue.trim();
41+
if (!trimmedValue) return;
42+
43+
if (editState === 'new') {
44+
onUpsertConfig(trimmedValue);
45+
} else if (editState === 'rename' && currentApiConfigName) {
46+
onRenameConfig(currentApiConfigName, trimmedValue);
47+
}
48+
49+
setEditState(null);
50+
setInputValue("");
51+
}, [currentApiConfigName, editState, inputValue, onRenameConfig, onUpsertConfig]);
52+
53+
useEffect(() => {
54+
return () => {
55+
// handle hit done without save or cancel
56+
handleSave()
57+
}
58+
}, [handleSave, inputValue])
59+
3960
const handleStartNew = () => {
4061
setEditState('new');
41-
setInputValue("");
62+
setInputValue(currentApiConfigName + "(copy)");
4263
};
4364

4465
const handleStartRename = () => {
@@ -51,23 +72,9 @@ const ApiConfigManager = ({
5172
setInputValue("");
5273
};
5374

54-
const handleSave = () => {
55-
const trimmedValue = inputValue.trim();
56-
if (!trimmedValue) return;
57-
58-
if (editState === 'new') {
59-
onUpsertConfig(trimmedValue);
60-
} else if (editState === 'rename' && currentApiConfigName) {
61-
onRenameConfig(currentApiConfigName, trimmedValue);
62-
}
63-
64-
setEditState(null);
65-
setInputValue("");
66-
};
67-
6875
const handleDelete = () => {
6976
if (!currentApiConfigName || !listApiConfigMeta || listApiConfigMeta.length <= 1) return;
70-
77+
7178
// Let the extension handle both deletion and selection
7279
onDeleteConfig(currentApiConfigName);
7380
};
@@ -76,8 +83,8 @@ const ApiConfigManager = ({
7683

7784
return (
7885
<div style={{ marginBottom: 5 }}>
79-
<div style={{
80-
display: "flex",
86+
<div style={{
87+
display: "flex",
8188
flexDirection: "column",
8289
gap: "2px"
8390
}}>
@@ -152,8 +159,8 @@ const ApiConfigManager = ({
152159
}}
153160
>
154161
{listApiConfigMeta?.map((config) => (
155-
<option
156-
key={config.name}
162+
<option
163+
key={config.name}
157164
value={config.name}
158165
>
159166
{config.name}

0 commit comments

Comments
 (0)