import { html } from 'lit'; import { LightElement } from '../lib/base.js'; function emptyIgForm() { return { provider_id: '', model_id: '', name: '', priority: 100 }; } export class ModelsImageSection extends LightElement { static properties = { onback: { attribute: false }, _models: { state: true }, _providers: { state: true }, _modal: { state: true }, _form: { state: true }, _saving: { state: true }, _error: { state: true }, _provider: { state: true }, }; constructor() { super(); this.onback = null; this._models = []; this._providers = []; this._modal = null; this._form = emptyIgForm(); this._saving = false; this._error = null; this._provider = null; } connectedCallback() { super.connectedCallback(); this._load(); } async _load() { try { const [modelsRes, providersRes] = await Promise.all([ fetch('/api/image-generate/models'), fetch('/api/llm/providers'), ]); if (!modelsRes.ok) throw new Error(`models: HTTP ${modelsRes.status}`); if (!providersRes.ok) throw new Error(`providers: HTTP ${providersRes.status}`); this._models = await modelsRes.json(); this._providers = await providersRes.json(); } catch (e) { this._error = e.message; } } // ── Add flow ───────────────────────────────────────────────────────────────── _openAdd() { this._error = null; this._provider = null; this._form = emptyIgForm(); this._modal = 'pick-provider'; } _pickProvider(provider) { this._provider = provider; this._form = { ...emptyIgForm(), provider_id: provider.id }; this._modal = 'add'; } // ── Edit flow ──────────────────────────────────────────────────────────────── async _openEdit(m) { this._error = null; try { const res = await fetch(`/api/image-generate/models/${m.id}`); if (!res.ok) throw new Error(`HTTP ${res.status}`); const r = await res.json(); this._provider = this._providers.find(p => p.id === r.provider_id) ?? null; this._form = { provider_id: r.provider_id, model_id: r.model_id, name: r.name, priority: r.priority, }; this._modal = { mode: 'edit', id: r.id, name: r.name }; } catch (e) { this._error = e.message; } } // ── Delete ─────────────────────────────────────────────────────────────────── async _delete(m) { if (!confirm(`Delete image model "${m.name}"?`)) return; try { const res = await fetch(`/api/image-generate/models/${m.id}`, { method: 'DELETE' }); if (!res.ok) throw new Error(await res.text()); await this._load(); } catch (e) { this._error = e.message; } } // ── Submit add ─────────────────────────────────────────────────────────────── async _submitAdd(e) { e.preventDefault(); if (this._saving) return; this._saving = true; this._error = null; const f = this._form; try { const res = await fetch('/api/image-generate/models', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ provider_id: Number(f.provider_id), model_id: f.model_id, name: f.name || f.model_id, priority: Number(f.priority) || 100, }), }); if (!res.ok) throw new Error(await res.text()); this._modal = null; await this._load(); } catch (err) { this._error = err.message; } finally { this._saving = false; } } // ── Submit edit ────────────────────────────────────────────────────────────── async _submitEdit(e) { e.preventDefault(); if (this._saving) return; this._saving = true; this._error = null; const f = this._form; const id = this._modal.id; try { const res = await fetch(`/api/image-generate/models/${id}`, { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ provider_id: Number(f.provider_id), model_id: f.model_id, name: f.name || f.model_id, priority: Number(f.priority) || 100, }), }); if (!res.ok) throw new Error(await res.text()); this._modal = null; await this._load(); } catch (err) { this._error = err.message; } finally { this._saving = false; } } _closeModal() { this._modal = null; this._error = null; } // ── Render card ────────────────────────────────────────────────────────────── _renderCard(m) { const isPlugin = m.from_plugin; return html`
No image generation models configured.
${canAdd ? html` ` : ''}