63 lines
4.1 KiB
JavaScript
63 lines
4.1 KiB
JavaScript
// One image model per workflow: Clinical Assistant and Learning, each a dropdown of discovered models.
|
|
import { imageJson } from '../generatedImages.js';
|
|
let loading = false;
|
|
let loaded = false;
|
|
let clinicalSelect; let learningSelect; let clinicalBudget; let learningBudget; let save; let status;
|
|
|
|
async function load() {
|
|
const root = document.getElementById('workflow-image-settings');
|
|
if (root && !root.children.length) loaded = false; // fresh DOM (test/re-import) re-renders
|
|
if (!root || loaded || loading) return;
|
|
loading = true;
|
|
try {
|
|
const [settings, models] = await Promise.all([
|
|
imageJson('/api/admin/image-settings'),
|
|
imageJson('/api/admin/config/image-models/discover').catch(() => ({ success: false }))
|
|
]);
|
|
root.textContent = '';
|
|
const form = document.createElement('form');
|
|
const heading = document.createElement('h4'); heading.textContent = 'Image models';
|
|
clinicalSelect = makeSelect([settings.workflows.clinical_assistant.model], models.models);
|
|
learningSelect = makeSelect([settings.workflows.learning_hub.model], models.models);
|
|
clinicalBudget = makeBudget(settings.workflows.clinical_assistant.budget);
|
|
learningBudget = makeBudget(settings.workflows.learning_hub.budget);
|
|
save = document.createElement('button'); save.type = 'submit'; save.className = 'btn-sm btn-primary'; save.textContent = 'Save image settings';
|
|
status = document.createElement('p'); status.setAttribute('role', 'status');
|
|
const row1 = document.createElement('div'); row1.className = 'admin-row';
|
|
const l1 = document.createElement('label'); l1.className = 'admin-row-label'; l1.textContent = 'Clinical Assistant image model'; row1.append(l1, clinicalSelect);
|
|
const row2 = document.createElement('div'); row2.className = 'admin-row';
|
|
const l2 = document.createElement('label'); l2.className = 'admin-row-label'; l2.textContent = 'Clinical image input budget'; row2.append(l2, clinicalBudget);
|
|
const row3 = document.createElement('div'); row3.className = 'admin-row';
|
|
const l3 = document.createElement('label'); l3.className = 'admin-row-label'; l3.textContent = 'Learning image model'; row3.append(l3, learningSelect);
|
|
const row4 = document.createElement('div'); row4.className = 'admin-row';
|
|
const l4 = document.createElement('label'); l4.className = 'admin-row-label'; l4.textContent = 'Learning image input budget'; row4.append(l4, learningBudget);
|
|
form.append(heading, row1, row2, row3, row4, save, status);
|
|
form.onsubmit = async e => {
|
|
e.preventDefault(); if (save.disabled) return; save.disabled = true;
|
|
try {
|
|
await imageJson('/api/admin/image-settings/clinical_assistant', { method: 'PUT', body: JSON.stringify({ model: clinicalSelect.value, budget: Number(clinicalBudget.value) }) });
|
|
await imageJson('/api/admin/image-settings/learning_hub', { method: 'PUT', body: JSON.stringify({ model: learningSelect.value, budget: Number(learningBudget.value) }) });
|
|
status.textContent = 'Saved. New jobs use these settings; existing jobs are unchanged.';
|
|
} catch (error) { status.textContent = error.message + ' Nothing was saved.'; } finally { save.disabled = false; }
|
|
};
|
|
root.append(form);
|
|
loaded = true;
|
|
} catch (_) { /* Next tab entry retries; no drafts are touched. */ }
|
|
finally { loading = false; }
|
|
}
|
|
function makeSelect(knownIds, models) {
|
|
const select = document.createElement('select'); select.className = 'admin-control';
|
|
const ids = new Set([...(Array.isArray(knownIds) ? knownIds : []), ...((Array.isArray(models) ? models : []).map(m => m && m.id).filter(Boolean))]);
|
|
[...ids].sort().forEach(id => { const o = document.createElement('option'); o.value = id; o.textContent = id; select.appendChild(o); });
|
|
if (knownIds[0]) select.value = knownIds[0];
|
|
return select;
|
|
}
|
|
function makeBudget(value) {
|
|
const input = document.createElement('input'); input.className = 'admin-control';
|
|
input.type = 'number'; input.min = '1000'; input.max = '32000'; input.required = true; input.value = value;
|
|
return input;
|
|
}
|
|
export function initImageSettings() {
|
|
document.addEventListener('tabChanged', e => { if (e.detail?.tab === 'admin') load(); });
|
|
}
|
|
|