Skip to content

Commit 11e5c8a

Browse files
committed
Fix advanced settings field mapping and remove query cache
- Fix image moderation and wallet settings to use prefixed fields directly - Add comprehensive field mapping for wallet, general, and image moderation settings - Remove query cache panel from advanced settings layout - Update general settings to read from both server and relay sections - Ensure proper bidirectional field mapping for all settings groups
1 parent 4884f1b commit 11e5c8a

6 files changed

Lines changed: 137 additions & 99 deletions

File tree

src/components/settings/ImageModerationSettings.tsx

Lines changed: 6 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -25,39 +25,15 @@ const ImageModerationSettings: React.FC = () => {
2525
if (settings && !isUserEditing) {
2626
console.log('ImageModerationSettings - Received settings:', settings);
2727

28-
// Transform property names to match form field names
29-
// The API returns properties without the prefix, but the form expects prefixed names
28+
// The useGenericSettings hook now returns properly prefixed field names
29+
// so we can use the settings directly without transformation
3030
const settingsObj = settings as Record<string, any>;
3131

32-
// Log the mode value specifically to debug
33-
console.log('Mode field from settings:', settingsObj.mode);
32+
console.log('ImageModerationSettings - Setting form values directly:', settingsObj);
3433

35-
const formValues = {
36-
image_moderation_api: settingsObj.api,
37-
image_moderation_check_interval: typeof settingsObj.check_interval === 'string'
38-
? parseFloat(settingsObj.check_interval)
39-
: settingsObj.check_interval,
40-
image_moderation_concurrency: typeof settingsObj.concurrency === 'string'
41-
? parseFloat(settingsObj.concurrency)
42-
: settingsObj.concurrency,
43-
image_moderation_enabled: settingsObj.enabled,
44-
image_moderation_mode: settingsObj.mode || 'basic', // Default to basic if mode is undefined
45-
image_moderation_temp_dir: settingsObj.temp_dir,
46-
image_moderation_threshold: typeof settingsObj.threshold === 'string'
47-
? parseFloat(settingsObj.threshold)
48-
: settingsObj.threshold,
49-
image_moderation_timeout: typeof settingsObj.timeout === 'string'
50-
? parseFloat(settingsObj.timeout)
51-
: settingsObj.timeout
52-
};
53-
54-
console.log('ImageModerationSettings - Transformed form values:', formValues);
55-
56-
// Set form values with a slight delay to ensure the form is ready
57-
setTimeout(() => {
58-
form.setFieldsValue(formValues);
59-
console.log('ImageModerationSettings - Form values after set:', form.getFieldsValue());
60-
}, 100);
34+
// Set form values directly since they're already properly prefixed
35+
form.setFieldsValue(settingsObj);
36+
console.log('ImageModerationSettings - Form values after set:', form.getFieldsValue());
6137
}
6238
}, [settings, form, isUserEditing]);
6339

src/components/settings/WalletSettings.tsx

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -23,22 +23,15 @@ const WalletSettings: React.FC = () => {
2323
if (settings && !isUserEditing) {
2424
console.log('WalletSettings - Received settings:', settings);
2525

26-
// Transform property names to match form field names
27-
// The API returns properties without the prefix, but the form expects prefixed names
26+
// The useGenericSettings hook now returns properly prefixed field names
27+
// so we can use the settings directly without transformation
2828
const settingsObj = settings as Record<string, any>;
2929

30-
const formValues = {
31-
wallet_name: settingsObj.name,
32-
wallet_api_key: settingsObj.api_key
33-
};
30+
console.log('WalletSettings - Setting form values directly:', settingsObj);
3431

35-
console.log('WalletSettings - Transformed form values:', formValues);
36-
37-
// Set form values with a slight delay to ensure the form is ready
38-
setTimeout(() => {
39-
form.setFieldsValue(formValues);
40-
console.log('WalletSettings - Form values after set:', form.getFieldsValue());
41-
}, 100);
32+
// Set form values directly since they're already properly prefixed
33+
form.setFieldsValue(settingsObj);
34+
console.log('WalletSettings - Form values after set:', form.getFieldsValue());
4235
}
4336
}, [settings, form, isUserEditing]);
4437

src/components/settings/layouts/AdvancedSettingsLayout.tsx

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import ContentFilterPanel from '../panels/ContentFilterPanel';
99
import NestFeederPanel from '../panels/NestFeederPanel';
1010
import OllamaPanel from '../panels/OllamaPanel';
1111
import WalletPanel from '../panels/WalletPanel';
12-
import QueryCachePanel from '../panels/QueryCachePanel';
1312
import useGenericSettings from '@app/hooks/useGenericSettings';
1413

1514
const { Panel } = Collapse;
@@ -155,10 +154,6 @@ const AdvancedSettingsLayout: React.FC<AdvancedSettingsLayoutProps> = ({
155154
<Panel header="Wallet" key="wallet">
156155
<WalletPanel />
157156
</Panel>
158-
159-
<Panel header="Query Cache" key="query-cache">
160-
<QueryCachePanel />
161-
</Panel>
162157
</Collapse>
163158
</SettingsContainer>
164159

src/components/settings/panels/ImageModerationPanel.tsx

Lines changed: 6 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -26,39 +26,15 @@ const ImageModerationPanel: React.FC = () => {
2626
if (settings && !isUserEditing) {
2727
console.log('ImageModerationPanel - Received settings:', settings);
2828

29-
// Transform property names to match form field names
30-
// The API returns properties without the prefix, but the form expects prefixed names
29+
// The useGenericSettings hook now returns properly prefixed field names
30+
// so we can use the settings directly without transformation
3131
const settingsObj = settings as Record<string, any>;
3232

33-
// Log the mode value specifically to debug
34-
console.log('Mode field from settings:', settingsObj.mode);
33+
console.log('ImageModerationPanel - Setting form values directly:', settingsObj);
3534

36-
const formValues = {
37-
image_moderation_api: settingsObj.api,
38-
image_moderation_check_interval: typeof settingsObj.check_interval === 'string'
39-
? parseFloat(settingsObj.check_interval)
40-
: settingsObj.check_interval,
41-
image_moderation_concurrency: typeof settingsObj.concurrency === 'string'
42-
? parseFloat(settingsObj.concurrency)
43-
: settingsObj.concurrency,
44-
image_moderation_enabled: settingsObj.enabled,
45-
image_moderation_mode: settingsObj.mode || 'basic', // Default to basic if mode is undefined
46-
image_moderation_temp_dir: settingsObj.temp_dir,
47-
image_moderation_threshold: typeof settingsObj.threshold === 'string'
48-
? parseFloat(settingsObj.threshold)
49-
: settingsObj.threshold,
50-
image_moderation_timeout: typeof settingsObj.timeout === 'string'
51-
? parseFloat(settingsObj.timeout)
52-
: settingsObj.timeout
53-
};
54-
55-
console.log('ImageModerationPanel - Transformed form values:', formValues);
56-
57-
// Set form values with a slight delay to ensure the form is ready
58-
setTimeout(() => {
59-
form.setFieldsValue(formValues);
60-
console.log('ImageModerationPanel - Form values after set:', form.getFieldsValue());
61-
}, 100);
35+
// Set form values directly since they're already properly prefixed
36+
form.setFieldsValue(settingsObj);
37+
console.log('ImageModerationPanel - Form values after set:', form.getFieldsValue());
6238
}
6339
}, [settings, form, isUserEditing]);
6440

src/components/settings/panels/WalletPanel.tsx

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -37,22 +37,15 @@ const WalletPanel: React.FC = () => {
3737
if (settings && !isUserEditing) {
3838
console.log('WalletPanel - Received settings:', settings);
3939

40-
// Transform property names to match form field names
41-
// The API returns properties without the prefix, but the form expects prefixed names
40+
// The useGenericSettings hook now returns properly prefixed field names
41+
// so we can use the settings directly without transformation
4242
const settingsObj = settings as Record<string, any>;
4343

44-
const formValues = {
45-
wallet_name: settingsObj.name,
46-
wallet_api_key: settingsObj.api_key
47-
};
44+
console.log('WalletPanel - Setting form values directly:', settingsObj);
4845

49-
console.log('WalletPanel - Transformed form values:', formValues);
50-
51-
// Set form values with a slight delay to ensure the form is ready
52-
setTimeout(() => {
53-
form.setFieldsValue(formValues);
54-
console.log('WalletPanel - Form values after set:', form.getFieldsValue());
55-
}, 100);
46+
// Set form values directly since they're already properly prefixed
47+
form.setFieldsValue(settingsObj);
48+
console.log('WalletPanel - Form values after set:', form.getFieldsValue());
5649
}
5750
}, [settings, form, isUserEditing]);
5851

src/hooks/useGenericSettings.ts

Lines changed: 113 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -49,14 +49,15 @@ const extractSettingsForGroup = (settings: any, groupName: string) => {
4949
if (groupName === 'image_moderation' && rawData) {
5050
const processedData: any = {};
5151

52-
// Map unprefixed fields to prefixed ones that the form expects
52+
// Map backend fields to prefixed ones that the form expects
53+
// Based on the actual backend response, backend sends both prefixed and unprefixed versions
5354
const imageModerationMappings: Record<string, string[]> = {
54-
'image_moderation_api': ['image_moderation_api', 'api'],
55+
'image_moderation_api': ['image_moderation_api'],
5556
'image_moderation_check_interval': ['image_moderation_check_interval_seconds', 'check_interval_seconds'],
5657
'image_moderation_concurrency': ['image_moderation_concurrency', 'concurrency'],
5758
'image_moderation_enabled': ['image_moderation_enabled', 'enabled'],
5859
'image_moderation_mode': ['image_moderation_mode', 'mode'],
59-
'image_moderation_temp_dir': ['image_moderation_temp_dir', 'temp_dir'],
60+
'image_moderation_temp_dir': ['image_moderation_temp_dir'],
6061
'image_moderation_threshold': ['image_moderation_threshold', 'threshold'],
6162
'image_moderation_timeout': ['image_moderation_timeout_seconds', 'timeout_seconds']
6263
};
@@ -131,6 +132,66 @@ const extractSettingsForGroup = (settings: any, groupName: string) => {
131132
return processedData;
132133
}
133134

135+
// Handle wallet field name mapping
136+
if (groupName === 'wallet' && rawData) {
137+
const processedData: any = {};
138+
139+
// Map backend field names to frontend field names
140+
const walletMappings: Record<string, string> = {
141+
'wallet_name': 'name',
142+
'wallet_api_key': 'key' // Backend sends 'key', frontend expects 'wallet_api_key'
143+
};
144+
145+
// Apply field mappings
146+
Object.entries(walletMappings).forEach(([frontendKey, backendKey]) => {
147+
if (rawData[backendKey] !== undefined) {
148+
processedData[frontendKey] = rawData[backendKey];
149+
}
150+
});
151+
152+
console.log(`Processed ${groupName} data:`, processedData);
153+
return processedData;
154+
}
155+
156+
// Handle general settings field name mapping
157+
if (groupName === 'general' && rawData) {
158+
const processedData: any = {};
159+
160+
// General settings come from both server and relay sections
161+
// We need to access both sections from the root settings
162+
const relayData = settings?.relay || {};
163+
164+
// Map backend field names to frontend field names
165+
// Some fields come from server section, others from relay section
166+
const generalMappings: Record<string, { section: string; field: string }> = {
167+
'port': { section: 'server', field: 'port' },
168+
'private_key': { section: 'relay', field: 'private_key' },
169+
'service_tag': { section: 'relay', field: 'service_tag' },
170+
'relay_stats_db': { section: 'server', field: 'stats_db' },
171+
'proxy': { section: 'server', field: 'proxy' }, // May not exist
172+
'demo_mode': { section: 'server', field: 'demo' },
173+
'web': { section: 'server', field: 'web' }
174+
};
175+
176+
// Apply field mappings
177+
Object.entries(generalMappings).forEach(([frontendKey, mapping]) => {
178+
const sourceData = mapping.section === 'relay' ? relayData : rawData;
179+
if (sourceData[mapping.field] !== undefined) {
180+
processedData[frontendKey] = sourceData[mapping.field];
181+
} else {
182+
// Set default values for missing fields
183+
if (frontendKey === 'relay_stats_db') {
184+
processedData[frontendKey] = ''; // Default empty
185+
} else if (frontendKey === 'proxy') {
186+
processedData[frontendKey] = false; // Default false
187+
}
188+
}
189+
});
190+
191+
console.log(`Processed ${groupName} data:`, processedData);
192+
return processedData;
193+
}
194+
134195
// Handle relay info field name mapping
135196
if (groupName === 'relay_info' && rawData) {
136197
const processedData: any = {};
@@ -208,10 +269,23 @@ const buildNestedUpdate = (groupName: string, data: any) => {
208269
};
209270

210271
case 'wallet':
272+
// Reverse the field mapping for saving
273+
const backendWalletData: any = {};
274+
const walletFieldMappings: Record<string, string> = {
275+
'name': 'wallet_name',
276+
'key': 'wallet_api_key'
277+
};
278+
279+
Object.entries(walletFieldMappings).forEach(([backendKey, frontendKey]) => {
280+
if (data[frontendKey] !== undefined) {
281+
backendWalletData[backendKey] = data[frontendKey];
282+
}
283+
});
284+
211285
return {
212286
settings: {
213287
external_services: {
214-
wallet: data
288+
wallet: backendWalletData
215289
}
216290
}
217291
};
@@ -253,11 +327,42 @@ const buildNestedUpdate = (groupName: string, data: any) => {
253327
};
254328

255329
case 'general':
256-
return {
257-
settings: {
258-
server: data
259-
}
330+
// Reverse the field mapping for saving
331+
// General settings need to be split between server and relay sections
332+
const serverData: any = {};
333+
const relayData: any = {};
334+
335+
const generalFieldMappings: Record<string, { section: string; field: string }> = {
336+
'port': { section: 'server', field: 'port' },
337+
'private_key': { section: 'relay', field: 'private_key' },
338+
'service_tag': { section: 'relay', field: 'service_tag' },
339+
'stats_db': { section: 'server', field: 'relay_stats_db' },
340+
'proxy': { section: 'server', field: 'proxy' },
341+
'demo': { section: 'server', field: 'demo_mode' }, // Frontend 'demo_mode' -> backend 'demo'
342+
'web': { section: 'server', field: 'web' }
260343
};
344+
345+
Object.entries(generalFieldMappings).forEach(([backendField, mapping]) => {
346+
const frontendField = mapping.field;
347+
if (data[frontendField] !== undefined) {
348+
if (mapping.section === 'server') {
349+
serverData[backendField] = data[frontendField];
350+
} else {
351+
relayData[backendField] = data[frontendField];
352+
}
353+
}
354+
});
355+
356+
// Return nested structure with both server and relay sections
357+
const result: any = { settings: {} };
358+
if (Object.keys(serverData).length > 0) {
359+
result.settings.server = serverData;
360+
}
361+
if (Object.keys(relayData).length > 0) {
362+
result.settings.relay = relayData;
363+
}
364+
365+
return result;
261366

262367
default:
263368
console.warn(`Unknown settings group for save: ${groupName}`);

0 commit comments

Comments
 (0)