mirror of
https://github.com/comfyanonymous/ComfyUI.git
synced 2026-04-15 04:52:31 +08:00
feat: add Asset Library panel with papers list and drag-to-canvas
This commit is contained in:
parent
62956a16e8
commit
efecc78f54
@ -108,3 +108,42 @@ body {
|
||||
|
||||
.empty-state { color: #858585; font-style: italic; padding: 1rem; }
|
||||
.error { color: #f48771; padding: 1rem; }
|
||||
|
||||
/* Asset Panel */
|
||||
.asset-panel { max-width: 1200px; margin: 0 auto; }
|
||||
.asset-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 1.5rem; }
|
||||
.asset-header h2 { color: #fff; }
|
||||
.asset-tabs { display: flex; gap: 0.25rem; }
|
||||
.tab-btn {
|
||||
background: transparent; border: none; color: #d4d4d4;
|
||||
padding: 0.5rem 1rem; cursor: pointer; border-radius: 4px;
|
||||
}
|
||||
.tab-btn:hover { background: #3c3c3c; }
|
||||
.tab-btn.active { background: #37373d; color: #fff; }
|
||||
|
||||
.asset-list { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 1rem; }
|
||||
|
||||
.asset-card {
|
||||
background: #252526; border-radius: 6px; padding: 1rem;
|
||||
cursor: grab;
|
||||
}
|
||||
.asset-card:active { cursor: grabbing; }
|
||||
.asset-card h4 { color: #fff; margin-bottom: 0.5rem; }
|
||||
.asset-meta { color: #858585; font-size: 0.85rem; }
|
||||
.asset-badges { display: flex; gap: 0.5rem; margin: 0.5rem 0; }
|
||||
.badge {
|
||||
font-size: 0.7rem; padding: 0.2rem 0.4rem;
|
||||
border-radius: 3px; background: #37373d; color: #d4d4d4;
|
||||
}
|
||||
.badge.unread { background: #d29922; color: #000; }
|
||||
.badge.library { background: #2ea043; color: #fff; }
|
||||
.badge.pending { background: #6c6c6c; color: #fff; }
|
||||
.badge.enabled { background: #2ea043; color: #fff; }
|
||||
.badge.disabled { background: #6c6c6c; color: #fff; }
|
||||
|
||||
.asset-actions { display: flex; gap: 0.5rem; margin-top: 0.75rem; }
|
||||
.btn-quick-read, .btn-drag {
|
||||
background: #37373d; border: none; color: #d4d4d4;
|
||||
padding: 0.4rem 0.8rem; border-radius: 4px; cursor: pointer; font-size: 0.8rem;
|
||||
}
|
||||
.btn-quick-read:hover, .btn-drag:hover { background: #4f4f4f; }
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
/** Main Research Workbench app - Home and Project Workspace panels. */
|
||||
import * as api from "./api_client.js";
|
||||
import { renderAssetPanel } from "./panels/AssetPanel.js";
|
||||
|
||||
const mainContent = document.getElementById("main-content");
|
||||
const navButtons = document.querySelectorAll(".nav-btn");
|
||||
@ -38,6 +39,9 @@ async function render() {
|
||||
}
|
||||
} else if (currentPanel === "canvas") {
|
||||
window.location.href = "/";
|
||||
} else if (currentPanel === "assets") {
|
||||
mainContent.innerHTML = "";
|
||||
renderAssetPanel(mainContent, api);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
97
research_web/js/panels/AssetPanel.js
Normal file
97
research_web/js/panels/AssetPanel.js
Normal file
@ -0,0 +1,97 @@
|
||||
// research_web/js/panels/AssetPanel.js
|
||||
/**Asset Library panel - browse and manage paper assets.*/
|
||||
|
||||
export function renderAssetPanel(container, api) {
|
||||
container.innerHTML = `
|
||||
<div class="asset-panel">
|
||||
<div class="asset-header">
|
||||
<h2>Asset Library</h2>
|
||||
<div class="asset-tabs">
|
||||
<button class="tab-btn active" data-tab="papers">Papers</button>
|
||||
<button class="tab-btn" data-tab="claims">Claims</button>
|
||||
<button class="tab-btn" data-tab="sources">Sources</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="asset-content">
|
||||
<div class="asset-list" id="asset-list">
|
||||
<p class="loading">Loading...</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
// Tab switching
|
||||
container.querySelectorAll('.tab-btn').forEach(btn => {
|
||||
btn.addEventListener('click', () => {
|
||||
container.querySelectorAll('.tab-btn').forEach(b => b.classList.remove('active'));
|
||||
btn.classList.add('active');
|
||||
loadAssets(btn.dataset.tab);
|
||||
});
|
||||
});
|
||||
|
||||
// Initial load
|
||||
loadAssets('papers');
|
||||
|
||||
function loadAssets(type) {
|
||||
const list = container.querySelector('#asset-list');
|
||||
if (type === 'papers') {
|
||||
list.innerHTML = '<p class="loading">Loading papers...</p>';
|
||||
api.listPapers().then(papers => {
|
||||
if (!papers || papers.length === 0) {
|
||||
list.innerHTML = '<p class="empty-state">No papers in library. Search papers in ComfyUI canvas to add them.</p>';
|
||||
return;
|
||||
}
|
||||
list.innerHTML = papers.map(p => `
|
||||
<div class="asset-card paper-card" data-id="${p.id}" draggable="true">
|
||||
<h4>${p.title || 'Untitled'}</h4>
|
||||
<p class="asset-meta">${p.authors_text || 'Unknown authors'}</p>
|
||||
<p class="asset-meta">${p.journal_or_source || ''} ${p.published_at || ''}</p>
|
||||
<div class="asset-badges">
|
||||
<span class="badge ${p.read_status}">${p.read_status || 'unread'}</span>
|
||||
<span class="badge ${p.library_status}">${p.library_status || 'pending'}</span>
|
||||
</div>
|
||||
<div class="asset-actions">
|
||||
<button class="btn-quick-read" data-id="${p.id}">Quick Read</button>
|
||||
<button class="btn-drag" data-id="${p.id}" title="Drag to canvas">Drag to Canvas</button>
|
||||
</div>
|
||||
</div>
|
||||
`).join('');
|
||||
|
||||
// Make cards draggable for canvas
|
||||
list.querySelectorAll('.asset-card').forEach(card => {
|
||||
card.addEventListener('dragstart', (e) => {
|
||||
e.dataTransfer.setData('application/json', JSON.stringify({
|
||||
type: 'paper_asset',
|
||||
id: card.dataset.id,
|
||||
title: card.querySelector('h4').textContent
|
||||
}));
|
||||
e.dataTransfer.effectAllowed = 'copy';
|
||||
});
|
||||
});
|
||||
}).catch(err => {
|
||||
list.innerHTML = `<p class="error">Failed to load: ${err.message}</p>`;
|
||||
});
|
||||
} else if (type === 'claims') {
|
||||
list.innerHTML = '<p class="empty-state">Claims panel coming in Phase 3.</p>';
|
||||
} else if (type === 'sources') {
|
||||
list.innerHTML = '<p class="loading">Loading sources...</p>';
|
||||
api.listSources().then(sources => {
|
||||
if (!sources || sources.length === 0) {
|
||||
list.innerHTML = '<p class="empty-state">No sources configured. Add sources to start your feed.</p>';
|
||||
return;
|
||||
}
|
||||
list.innerHTML = sources.map(s => `
|
||||
<div class="asset-card source-card" data-id="${s.id}">
|
||||
<h4>${s.name}</h4>
|
||||
<p class="asset-meta">${s.category || ''} - ${s.intake_type}</p>
|
||||
<div class="asset-badges">
|
||||
<span class="badge ${s.enabled ? 'enabled' : 'disabled'}">${s.enabled ? 'enabled' : 'disabled'}</span>
|
||||
</div>
|
||||
</div>
|
||||
`).join('');
|
||||
}).catch(err => {
|
||||
list.innerHTML = `<p class="error">Failed to load: ${err.message}</p>`;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user