From 99ad456adfd0143a53dbf4ef73a283642c1436e7 Mon Sep 17 00:00:00 2001 From: Daniel Grzelak <59827851+pan-daniel@users.noreply.github.com> Date: Mon, 1 Jun 2026 04:50:50 +0200 Subject: [PATCH] fix: group cookbook dependencies into Odysseus and Server sections (#144) * fix: group cookbook dependencies into Odysseus and Server sections * refactor: tidy dependency render with guard clauses and a section-header class --- static/js/cookbook.js | 67 ++++++++++++++++++++++--------------------- static/style.css | 15 ++++++++++ 2 files changed, 50 insertions(+), 32 deletions(-) diff --git a/static/js/cookbook.js b/static/js/cookbook.js index b4802fc..ce299c7 100644 --- a/static/js/cookbook.js +++ b/static/js/cookbook.js @@ -523,39 +523,42 @@ async function _fetchDependencies() { const pkgs = data.packages || []; if (!pkgs.length) { list.innerHTML = '
No packages found
'; return; } const _winUnsupported = new Set(['diffusers', 'hf_transfer', 'vllm', 'rembg', 'gfpgan']); - // When a non-local server is selected, the Local-only packages aren't - // relevant to it — hide them so the list shows just that server's packages. - const _viewingRemote = !!(_dsel && _dsel.value && _dsel.value !== 'local'); - let html = ''; - for (const pkg of pkgs) { + + const _statusTag = (pkg, isLocal, isSystemDep, winBlocked) => { + if (winBlocked) return `N/A`; + if (pkg.installed && isSystemDep) return `Installed`; + if (pkg.installed) return ``; + if (isSystemDep) return `Missing`; + return ``; + }; + + const _depRow = (pkg) => { const isLocal = pkg.target === 'local'; - if (_viewingRemote && isLocal) continue; - const winBlocked = !isLocal && _isWindows() && _winUnsupported.has(pkg.name); - const targetLabel = isLocal ? 'Local' : 'GPU server'; const isSystemDep = pkg.kind === 'system'; - html += `
`; - html += `
`; - html += `
${esc(pkg.name)}
`; - html += `
${esc(pkg.desc)}
`; - html += `
`; - html += `${targetLabel}`; - html += `${esc(pkg.category)}`; - if (winBlocked) { - html += `N/A`; - } else if (pkg.installed) { - if (isSystemDep) { - html += `Installed`; - } else { - html += ``; - } - } else if (isSystemDep) { - html += `Missing`; - } else { - html += ``; - } - html += `
`; - } - list.innerHTML = html; + const winBlocked = !isLocal && _isWindows() && _winUnsupported.has(pkg.name); + return `
` + + `
` + + `
${esc(pkg.name)}
` + + `
${esc(pkg.desc)}
` + + `
` + + `${esc(pkg.category)}` + + _statusTag(pkg, isLocal, isSystemDep, winBlocked) + + `
`; + }; + + const _section = (title, note, items) => + items.length + ? `
${title}${note}
` + items.map(_depRow).join('') + : ''; + + const _viewingRemote = !!(_dsel && _dsel.value && _dsel.value !== 'local'); + const _appDeps = pkgs.filter(p => p.target === 'local'); + const _serverDeps = pkgs.filter(p => p.target !== 'local'); + + list.innerHTML = [ + _viewingRemote ? '' : _section('Odysseus app', 'Run inside the Odysseus app itself.', _appDeps), + _section('Server', 'Run on the server chosen above (Local, or a remote box over SSH).', _serverDeps), + ].join(''); // Shared install/update routine — used by the Install button and the // "Update" item in an installed package's ⋮ menu. `upgrade` adds pip -U; @@ -1475,7 +1478,7 @@ function _renderRecipes() { html += _buildServerOpts(false); html += ''; html += ''; - html += '

Optional packages that extend Odysseus capabilities. Install on local or remote servers.

'; + html += '

Optional packages that extend Odysseus capabilities.

'; html += '
'; html += ''; diff --git a/static/style.css b/static/style.css index 3ab47fb..60f9f46 100644 --- a/static/style.css +++ b/static/style.css @@ -18007,6 +18007,21 @@ body.gallery-selecting .gallery-dl-btn, .cookbook-settings-stack.hidden { display: none; } .cookbook-dep-row.cookbook-dep-blocked { opacity: 0.4; } .cookbook-dep-info { flex: 1; min-width: 0; } +.cookbook-dep-section { + display: flex; + align-items: baseline; + gap: 8px; + margin: 12px 2px 4px; +} +.cookbook-dep-section-title { + font-size: 11px; + font-weight: 600; + letter-spacing: 0.03em; +} +.cookbook-dep-section-note { + font-size: 10px; + color: color-mix(in srgb, var(--fg) 50%, transparent); +} .cookbook-dep-tag { font-size: 9px; padding: 0 8px;