diff --git a/webui/src/pages/Config.tsx b/webui/src/pages/Config.tsx index 3d7bcfb..98a707e 100644 --- a/webui/src/pages/Config.tsx +++ b/webui/src/pages/Config.tsx @@ -1,26 +1,30 @@ -import React, { useState } from 'react'; +import React, { useMemo, useState } from 'react'; import { RefreshCw, Save } from 'lucide-react'; import { useTranslation } from 'react-i18next'; import { useAppContext } from '../context/AppContext'; import RecursiveConfig from '../components/RecursiveConfig'; function setPath(obj: any, path: string, value: any) { - const keys = path.split('.') - const next = JSON.parse(JSON.stringify(obj || {})) - let cur = next + const keys = path.split('.'); + const next = JSON.parse(JSON.stringify(obj || {})); + let cur = next; for (let i = 0; i < keys.length - 1; i++) { - const k = keys[i] - if (typeof cur[k] !== 'object' || cur[k] === null) cur[k] = {} - cur = cur[k] + const k = keys[i]; + if (typeof cur[k] !== 'object' || cur[k] === null) cur[k] = {}; + cur = cur[k]; } - cur[keys[keys.length - 1]] = value - return next + cur[keys[keys.length - 1]] = value; + return next; } const Config: React.FC = () => { const { t } = useTranslation(); const { cfg, setCfg, cfgRaw, setCfgRaw, loadConfig, hotReloadFieldDetails, q } = useAppContext(); const [showRaw, setShowRaw] = useState(false); + const topKeys = useMemo(() => Object.keys(cfg || {}).filter(k => typeof (cfg as any)?.[k] === 'object' && (cfg as any)?.[k] !== null), [cfg]); + const [selectedTop, setSelectedTop] = useState(''); + + const activeTop = selectedTop || topKeys[0] || ''; async function saveConfig() { try { @@ -35,8 +39,8 @@ const Config: React.FC = () => { } return ( -
-
+
+

{t('configuration')}

@@ -65,19 +69,41 @@ const Config: React.FC = () => {
-
+
{!showRaw ? ( -
- } - onChange={(path, val) => setCfg(v => setPath(v, path, val))} - /> +
+ + +
+ {activeTop ? ( + } + path={activeTop} + onChange={(path, val) => setCfg(v => setPath(v, path, val))} + /> + ) : ( +
No config groups found.
+ )} +
) : ( -