import { Eye, EyeOff, Save } from 'lucide-react';
import { useEffect, useMemo, useState } from 'react';
import { api, errorMessage } from '../api.js';
export function Settings({ nodes, onChanged }) {
const [fields, setFields] = useState([]);
const [values, setValues] = useState({});
const [nodeId, setNodeId] = useState(nodes[0]?.id || '');
const [visibleSecrets, setVisibleSecrets] = useState({});
const [saving, setSaving] = useState(false);
const [message, setMessage] = useState('');
const [error, setError] = useState('');
const requiredMissing = useMemo(
() => fields.filter((field) => field.required && !String(values[field.key] || '').trim()),
[fields, values],
);
async function loadSettings() {
if (!nodeId) return;
setError('');
try {
const result = await api.get(`/settings/${encodeURIComponent(nodeId)}`);
setFields(result.data.fields || []);
setValues(Object.fromEntries((result.data.fields || []).map((field) => [field.key, field.value || ''])));
} catch (requestError) {
setError(errorMessage(requestError));
}
}
useEffect(() => {
loadSettings();
}, [nodeId]);
useEffect(() => {
if (!nodeId && nodes[0]?.id) setNodeId(nodes[0].id);
}, [nodeId, nodes]);
async function saveSettings(event) {
event.preventDefault();
setSaving(true);
setMessage('');
setError('');
try {
const result = await api.put(`/settings/${encodeURIComponent(nodeId)}`, { values });
setFields(result.data.fields || []);
setValues(Object.fromEntries((result.data.fields || []).map((field) => [field.key, field.value || ''])));
setMessage('Settings saved. Running jobs use the updated values; a changed PORT still needs a backend restart.');
await onChanged?.();
} catch (requestError) {
setError(errorMessage(requestError));
} finally {
setSaving(false);
}
}
return (
Values are written to the selected node agent. Keep access to this UI restricted because secrets are editable here.
Settings