Group tool libraries by model and component role
This commit is contained in:
+6
-1
@@ -32,7 +32,12 @@ window.CatalogUI = (() => {
|
||||
}
|
||||
function renderLibrary() {
|
||||
const openRows=new Set([...root.querySelectorAll('.detail-row[open]')].map(x=>x.dataset.rowId));
|
||||
el('hub-results').innerHTML = state.entries.filter(x => x.kind === kind).map(x => `<details class="detail-row" data-row-id="${escape(x.id)}" ${openRows.has(x.id)?'open':''}><summary class="detail-summary"><strong class="hub-filename">${escape(x.file)}</strong><span>${escape(x.role_label)}</span><span>${size(x.size)}</span><span>${x.used_by_profiles?.length?`${x.used_by_profiles.length} Profil(e)`:'Nicht zugeordnet'}</span></summary><div class="detail-body"><p class="hub-filename">Quelle: ${escape(x.repo)}</p><p>${x.profile_eligible?'Modelldatei · über ein Profil verwenden':'Zusatzdatei · wird einem Modellprofil unter Komponenten zugeordnet'}</p><details><summary>Version und Integrität</summary><p class="hub-filename">Revision ${escape(x.revision)}</p><p>${x.upstream_hash_verified ? 'SHA-256 mit Quelle geprüft' : 'SHA-256 lokal erfasst; Größe mit Quelle geprüft'}</p></details>${executionHTML(x.execution)}${x.used_by_profiles?.length?`<p class="warning">Verwendet von Profil: ${x.used_by_profiles.map(p=>escape(p.name)).join(", ")}. Bitte zuerst das Profil löschen.</p>`:""}<div class="card-actions">${x.profile_eligible===true?`<button data-profile-model="${x.id}">${kind==='video'?'Als Videomodell verwenden':'Profil anlegen'}</button>`:""}<button type="button" class="secondary" data-delete-model="${x.id}" ${x.used_by_profiles?.length?"disabled":""}>Datei löschen</button></div></div></details>`).join('') || '<div class="empty wide"><h3>Deine Bibliothek ist noch leer</h3><p>Unter „Entdecken“ kannst du Dateien für diesen Bereich auswählen und herunterladen.</p></div>';
|
||||
const entries = state.entries.filter(x => x.kind === kind);
|
||||
const groups = [['model', kind==='chat'?'Sprachmodelle · Hauptgewichte':'Modelle · Hauptgewichte'],['vision_projector','Vision-Projektoren'],['audio_projector','Audio-Projektoren'],['text_encoder','Textencoder'],['vae','VAE · Decoder'],['configuration','Konfigurationen'],['auxiliary','Tokenizer und weitere Zusatzkomponenten']];
|
||||
const row = x => `<details class="detail-row" data-row-id="${escape(x.id)}" ${openRows.has(x.id)?'open':''}><summary class="detail-summary"><strong class="hub-filename">${escape(x.file)}</strong><span>${escape(x.role_label)}</span><span>${size(x.size)}</span><span>${x.used_by_profiles?.length?`${x.used_by_profiles.length} Profil(e)`:'Nicht zugeordnet'}</span></summary><div class="detail-body"><p class="hub-filename">Quelle: ${escape(x.repo)}</p><p>${x.profile_eligible?'Modelldatei · über ein Profil verwenden':'Zusatzdatei · wird einem Modellprofil unter Komponenten zugeordnet'}</p><details><summary>Version und Integrität</summary><p class="hub-filename">Revision ${escape(x.revision)}</p><p>${x.upstream_hash_verified ? 'SHA-256 mit Quelle geprüft' : 'SHA-256 lokal erfasst; Größe mit Quelle geprüft'}</p></details>${executionHTML(x.execution)}${x.used_by_profiles?.length?`<p class="warning">Verwendet von Profil: ${x.used_by_profiles.map(p=>escape(p.name)).join(", ")}. Bitte zuerst das Profil löschen.</p>`:""}<div class="card-actions">${x.profile_eligible===true?`<button data-profile-model="${x.id}">${kind==='video'?'Als Videomodell verwenden':'Profil anlegen'}</button>`:""}<button type="button" class="secondary" data-delete-model="${x.id}" ${x.used_by_profiles?.length?"disabled":""}>Datei löschen</button></div></div></details>`;
|
||||
const known = new Set(groups.map(([role])=>role));
|
||||
const sections = [...groups, ['other','Weitere Dateien · Zuordnung unbekannt']];
|
||||
el('hub-results').innerHTML = sections.map(([role,label])=>{const files=entries.filter(x=>role==='other'?!known.has(x.role):x.role===role);return files.length?`<section class="library-group" aria-label="${escape(label)}"><h3>${escape(label)} <span class="small muted">(${files.length})</span></h3><div class="detail-list">${files.map(row).join('')}</div></section>`:'';}).join('') || '<div class="empty wide"><h3>Deine Bibliothek ist noch leer</h3><p>Unter „Entdecken“ kannst du Dateien für diesen Bereich auswählen und herunterladen.</p></div>';
|
||||
root.querySelectorAll('[data-delete-model]').forEach(b=>b.onclick=async()=>{const entry=state.entries.find(x=>x.id===b.dataset.deleteModel);if(!entry||!confirm(`Datei „${entry.file}“ (${size(entry.size)}) dauerhaft von Athena löschen?`))return;b.disabled=true;try{await api('/delete',{id:entry.id});message('Datei aus der Bibliothek gelöscht.');await refresh();}catch(error){message(error.message);b.disabled=false;}});
|
||||
}
|
||||
function renderJob() {
|
||||
|
||||
Reference in New Issue
Block a user