import { escapeHtml, inferEnhancementClass, inferEnhancementLabel } from '../common.js';
// 侧栏数据源树。数据源当作"盘符",可展开显示一层根目录快捷入口。
// 事件通过回调向编排器上报:onOpenSource / onOpenPath / onContextMenu。
export function createSidebar(rootElement, { onOpenSource, onContextMenu }) {
let sources = [];
let activeSourceId = null;
function statusDotClass(source) {
// 复用增强状态的语义色:ready/busy/error/idle
switch (inferEnhancementClass(source)) {
case 'status-ready':
return 'ready';
case 'status-busy':
return 'busy';
case 'status-error':
return 'error';
default:
return 'idle';
}
}
function render() {
if (sources.length === 0) {
rootElement.innerHTML = '
暂无数据源,请从「上传任务库」添加。
';
return;
}
rootElement.innerHTML = sources
.map((source) => {
const active = source.id === activeSourceId;
const label = source.displayName || source.originalFilename || source.id;
const dot = statusDotClass(source);
const title = `${label} · ${inferEnhancementLabel(source)}`;
return `
💽
${escapeHtml(label)}
`;
})
.join('');
}
function findSource(sourceId) {
return sources.find((source) => source.id === sourceId) ?? null;
}
rootElement.addEventListener('click', (event) => {
const item = event.target.closest('.explorer-tree-item');
if (!(item instanceof HTMLElement)) {
return;
}
onOpenSource?.(item.dataset.sourceId);
});
rootElement.addEventListener('keydown', (event) => {
if (event.key !== 'Enter' && event.key !== ' ') {
return;
}
const item = event.target.closest('.explorer-tree-item');
if (!(item instanceof HTMLElement)) {
return;
}
event.preventDefault();
onOpenSource?.(item.dataset.sourceId);
});
rootElement.addEventListener('contextmenu', (event) => {
const item = event.target.closest('.explorer-tree-item');
if (!(item instanceof HTMLElement)) {
return;
}
event.preventDefault();
onContextMenu?.(item.dataset.sourceId, { x: event.clientX, y: event.clientY });
});
return {
setSources(nextSources) {
sources = Array.isArray(nextSources) ? nextSources : [];
render();
},
setActive(sourceId) {
activeSourceId = sourceId;
render();
},
getSource: findSource,
getSources() {
return sources;
}
};
}