From e2465f1289246035d2af3a363bef6a8cb75e939b82b88d30c97dc712b61e16ea Mon Sep 17 00:00:00 2001 From: mstoeck3 Date: Mon, 19 Jan 2026 14:16:02 +0100 Subject: [PATCH] model grouping --- static/script.js | 54 ++++++++++++++++++++++++++++++++++++++-- static/style.css | 64 +++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 115 insertions(+), 3 deletions(-) diff --git a/static/script.js b/static/script.js index 0b7b441..4210cd3 100644 --- a/static/script.js +++ b/static/script.js @@ -254,7 +254,43 @@ function renderModels(models) { return; } - container.innerHTML = models.map(model => ` + // Group models by family (everything before the colon) + const grouped = {}; + models.forEach(model => { + const family = model.name.includes(':') ? model.name.split(':')[0] : 'other'; + if (!grouped[family]) { + grouped[family] = []; + } + grouped[family].push(model); + }); + + // Sort families alphabetically + const sortedFamilies = Object.keys(grouped).sort(); + + // Render grouped models + container.innerHTML = sortedFamilies.map(family => { + const familyModels = grouped[family]; + const familyId = `family-${family.replace(/[^a-zA-Z0-9]/g, '-')}`; + + return ` +
+
+
+ + ${escapeHtml(family)} + (${familyModels.length}) +
+
+
+ ${familyModels.map(model => renderModelCard(model)).join('')} +
+
+ `; + }).join(''); +} + +function renderModelCard(model) { + return `
@@ -338,7 +374,21 @@ function renderModels(models) { ${model.capabilities.map(cap => `${escapeHtml(cap)}`).join('')}
- `).join(''); + `; +} + +function toggleModelFamily(familyId) { + const content = document.getElementById(familyId); + const header = content.previousElementSibling; + const icon = header.querySelector('.model-family-icon'); + + if (content.classList.contains('collapsed')) { + content.classList.remove('collapsed'); + icon.textContent = '▼'; + } else { + content.classList.add('collapsed'); + icon.textContent = '▶'; + } } async function deleteModel(modelName) { diff --git a/static/style.css b/static/style.css index 3c35865..4284f66 100644 --- a/static/style.css +++ b/static/style.css @@ -296,12 +296,74 @@ body { /* Models List */ .models-list { + display: grid; + gap: 20px; +} + +/* Model Family Groups */ +.model-family-group { + background-color: var(--bg-secondary); + border: 1px solid var(--border); + border-radius: 6px; + overflow: hidden; +} + +.model-family-header { + padding: 12px 15px; + background-color: var(--bg-tertiary); + cursor: pointer; + user-select: none; + transition: background-color 0.2s; +} + +.model-family-header:hover { + background-color: #4a4a4a; +} + +.model-family-title { + display: flex; + align-items: center; + gap: 10px; + font-weight: 600; + font-size: 15px; + color: var(--text-primary); +} + +.model-family-icon { + color: var(--accent-primary); + font-size: 12px; + transition: transform 0.2s; + display: inline-block; + width: 16px; +} + +.model-family-name { + text-transform: capitalize; +} + +.model-family-count { + color: var(--text-secondary); + font-size: 13px; + font-weight: 400; +} + +.model-family-content { display: grid; gap: 15px; + padding: 15px; + max-height: 2000px; + overflow: hidden; + transition: max-height 0.3s ease-out, padding 0.3s ease-out; +} + +.model-family-content.collapsed { + max-height: 0; + padding-top: 0; + padding-bottom: 0; } .model-card { - background-color: var(--bg-secondary); + background-color: var(--bg-primary); border: 1px solid var(--border); border-radius: 6px; padding: 15px;