diff --git a/src/fgai/dashboard.py b/src/fgai/dashboard.py index 4a43cbe..b564668 100644 --- a/src/fgai/dashboard.py +++ b/src/fgai/dashboard.py @@ -184,6 +184,7 @@ async function loadSettings() { } const token = form.elements.namedItem('graylog_mcp_token'); token.placeholder = config.graylog_mcp_token_configured ? 'Token configured; leave blank to keep it' : 'Paste a read-only token'; + window.streamProfiles = config.graylog_stream_profiles || []; if (config.graylog_mcp_token_configured && config.graylog_mcp_url) loadStreams(); } async function loadStreams() { @@ -197,7 +198,9 @@ document.getElementById('loadFields').addEventListener('click', async () => { const selected = document.querySelector('.graylog-stream:checked'); if (!selected) { document.getElementById('fieldPicker').textContent = 'Load streams, tick one stream, then load its fields.'; return; } const payload = await (await fetch(`/api/graylog/fields?stream_id=${encodeURIComponent(selected.dataset.id)}`)).json(); - document.getElementById('fieldPicker').innerHTML = (payload.fields || []).map(field => `
${esc(field.name || field.field)} ${esc((field.type || {}).type || field.type || '')} ${esc(((field.type || {}).properties || field.capabilities || []).join(', '))}
`).join('') || esc(payload.error || 'No fields found.'); + const profile = (window.streamProfiles || []).find(item => item.stream_id === selected.dataset.id) || {}; + document.getElementById('fieldPicker').innerHTML = (payload.fields || []).map(field => { const name=field.name||field.field, props=(field.type||{}).properties||[]; return `
${esc(name)} ${props.includes('enumerable')?``:''} ${props.includes('numeric')?``:''}
`; }).join('') || esc(payload.error || 'No fields found.'); + window.activeProfileStream = selected.dataset.id; }); document.getElementById('settingsForm').addEventListener('submit', async event => { event.preventDefault(); @@ -206,6 +209,7 @@ document.getElementById('settingsForm').addEventListener('submit', async event = values.llm_enabled = form.elements.llm_enabled.checked; values.threat_intel_enabled = form.elements.threat_intel_enabled.checked; values.graylog_streams = [...document.querySelectorAll('.graylog-stream')].map(item => ({id:item.dataset.id, title:item.dataset.title, enabled:item.checked})); + if (window.activeProfileStream) { const profile={stream_id:window.activeProfileStream,entity_field:form.querySelector('[name="profile_entity"]:checked')?.value||'',timestamp_field:form.querySelector('[name="profile_timestamp"]:checked')?.value||'timestamp',categorical_fields:[...form.querySelectorAll('.profile-categorical:checked')].map(item=>item.value),numeric_fields:[...form.querySelectorAll('.profile-numeric:checked')].map(item=>item.value)}; values.graylog_stream_profiles=[...(window.streamProfiles||[]).filter(item=>item.stream_id!==profile.stream_id),profile]; } const response = await fetch('/api/config', {method:'POST', headers:{'Content-Type':'application/json'}, body:JSON.stringify(values)}); document.getElementById('settingsResult').textContent = response.ok ? 'Saved. Monitor applies supported settings on its next cycle.' : 'Could not save configuration.'; if (response.ok) loadSettings();