Skip to content

Commit 5a671e3

Browse files
committed
🐛 Changes to app settings on the configuration page need to be saved in real time #1748
1 parent 8636859 commit 5a671e3

File tree

1 file changed

+19
-44
lines changed

1 file changed

+19
-44
lines changed

frontend/app/[locale]/models/components/appConfig.tsx

Lines changed: 19 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { useRef, useState, useEffect } from 'react';
1+
import React, { useRef, useState, useEffect, useCallback } from 'react';
22
import dynamic from 'next/dynamic';
33
import { useTranslation } from 'react-i18next';
44

@@ -39,8 +39,6 @@ export const AppConfigSection: React.FC = () => {
3939
// Add user input state tracking
4040
const isUserTypingAppName = useRef(false);
4141
const isUserTypingDescription = useRef(false);
42-
const appNameUpdateTimer = useRef<NodeJS.Timeout | null>(null);
43-
const descriptionUpdateTimer = useRef<NodeJS.Timeout | null>(null);
4442

4543
// Avatar-related state
4644
const [isAvatarModalOpen, setIsAvatarModalOpen] = useState(false);
@@ -67,6 +65,22 @@ export const AppConfigSection: React.FC = () => {
6765

6866
const fileInputRef = useRef<HTMLInputElement>(null);
6967

68+
const triggerAutoSave = useCallback(() => {
69+
const runSave = async () => {
70+
try {
71+
const ok = await configService.saveConfigToBackend(getConfig() as any);
72+
if (!ok) {
73+
message.error(t("setup.page.error.saveConfig"));
74+
}
75+
} catch (error) {
76+
message.error(t("setup.page.error.saveConfig"));
77+
log.error("Failed to auto save app configuration", error);
78+
}
79+
};
80+
81+
void runSave();
82+
}, [getConfig, message, t]);
83+
7084
// Add configuration change listener, synchronize local state when config is loaded from backend
7185
useEffect(() => {
7286
const handleConfigChanged = (event: any) => {
@@ -139,18 +153,6 @@ export const AppConfigSection: React.FC = () => {
139153
};
140154
}, []);
141155

142-
// Clean up timers
143-
useEffect(() => {
144-
return () => {
145-
if (appNameUpdateTimer.current) {
146-
clearTimeout(appNameUpdateTimer.current);
147-
}
148-
if (descriptionUpdateTimer.current) {
149-
clearTimeout(descriptionUpdateTimer.current);
150-
}
151-
};
152-
}, []);
153-
154156
// Handle basic app config changes
155157
const handleAppNameChange = (e: React.ChangeEvent<HTMLInputElement>) => {
156158
const newAppName = e.target.value;
@@ -162,25 +164,12 @@ export const AppConfigSection: React.FC = () => {
162164
setAppNameError(false);
163165
}
164166

165-
// Clear previous timer
166-
if (appNameUpdateTimer.current) {
167-
clearTimeout(appNameUpdateTimer.current);
168-
}
169-
170-
// Set debounced update
171-
appNameUpdateTimer.current = setTimeout(() => {
172-
updateAppConfig({ appName: newAppName });
173-
isUserTypingAppName.current = false;
174-
}, 500);
175167
};
176168

177169
const handleAppNameBlur = () => {
178-
// Clear timer, update immediately
179-
if (appNameUpdateTimer.current) {
180-
clearTimeout(appNameUpdateTimer.current);
181-
}
182170
updateAppConfig({ appName: localAppName });
183171
isUserTypingAppName.current = false;
172+
triggerAutoSave();
184173
};
185174

186175
const handleDescriptionChange = (
@@ -189,26 +178,12 @@ export const AppConfigSection: React.FC = () => {
189178
const newDescription = e.target.value;
190179
isUserTypingDescription.current = true;
191180
setLocalAppDescription(newDescription);
192-
193-
// Clear previous timer
194-
if (descriptionUpdateTimer.current) {
195-
clearTimeout(descriptionUpdateTimer.current);
196-
}
197-
198-
// Set debounced update
199-
descriptionUpdateTimer.current = setTimeout(() => {
200-
updateAppConfig({ appDescription: newDescription });
201-
isUserTypingDescription.current = false;
202-
}, 500);
203181
};
204182

205183
const handleDescriptionBlur = () => {
206-
// Clear timer, update immediately
207-
if (descriptionUpdateTimer.current) {
208-
clearTimeout(descriptionUpdateTimer.current);
209-
}
210184
updateAppConfig({ appDescription: localAppDescription });
211185
isUserTypingDescription.current = false;
186+
triggerAutoSave();
212187
};
213188

214189
// Open avatar selection modal

0 commit comments

Comments
 (0)