140 lines
5.4 KiB
JavaScript
140 lines
5.4 KiB
JavaScript
class TodoTree {
|
|
static buildProjectTree(todos) {
|
|
const tree = {};
|
|
todos.forEach(todo => {
|
|
const project = todo.project || '其它';
|
|
const subproject = todo.subproject || '其它';
|
|
|
|
if (!tree[project]) {
|
|
tree[project] = {
|
|
name: project,
|
|
subprojects: {}
|
|
};
|
|
}
|
|
if (!tree[project].subprojects[subproject]) {
|
|
tree[project].subprojects[subproject] = {
|
|
name: subproject,
|
|
todos: []
|
|
};
|
|
}
|
|
tree[project].subprojects[subproject].todos.push(todo);
|
|
});
|
|
return tree;
|
|
}
|
|
|
|
static renderProjectTree(tree, {
|
|
expandedProjects,
|
|
selectedProject,
|
|
selectedSubproject,
|
|
showCompleted,
|
|
onProjectSelect,
|
|
onSubprojectSelect,
|
|
onExpandToggle,
|
|
onShowCompletedChange,
|
|
onShowAll,
|
|
onAddTodo
|
|
}) {
|
|
const treeContainer = document.createElement('div');
|
|
treeContainer.className = 'project-tree';
|
|
|
|
// 创建树内容容器
|
|
const treeContent = document.createElement('div');
|
|
treeContent.className = 'tree-content';
|
|
|
|
// 添加新增待办按钮
|
|
const addTodoButton = document.createElement('button');
|
|
addTodoButton.className = 'add-todo-button';
|
|
addTodoButton.textContent = '新增待办';
|
|
addTodoButton.addEventListener('click', onAddTodo);
|
|
treeContent.appendChild(addTodoButton);
|
|
|
|
Object.values(tree).forEach(project => {
|
|
const projectNode = document.createElement('div');
|
|
projectNode.className = 'project-node';
|
|
|
|
const projectHeader = document.createElement('div');
|
|
projectHeader.className = 'project-header';
|
|
projectHeader.innerHTML = `
|
|
<div class="project-header-content">
|
|
<span class="expand-icon ${expandedProjects.has(project.name) ? 'expanded' : ''}">▶</span>
|
|
<span class="project-name">${project.name}</span>
|
|
<span class="todo-count">(${Object.values(project.subprojects).reduce((sum, sub) =>
|
|
sum + sub.todos.length, 0)})</span>
|
|
</div>
|
|
`;
|
|
|
|
projectHeader.addEventListener('click', () => {
|
|
onProjectSelect(project.name);
|
|
});
|
|
|
|
const expandButton = projectHeader.querySelector('.expand-icon');
|
|
expandButton.addEventListener('click', (e) => {
|
|
e.stopPropagation();
|
|
onExpandToggle(project.name);
|
|
});
|
|
|
|
const subprojectsContainer = document.createElement('div');
|
|
subprojectsContainer.className = 'subprojects-container';
|
|
subprojectsContainer.style.display = expandedProjects.has(project.name) ? 'block' : 'none';
|
|
|
|
Object.values(project.subprojects).forEach(subproject => {
|
|
const subprojectNode = document.createElement('div');
|
|
subprojectNode.className = 'subproject-node';
|
|
if (selectedProject === project.name && selectedSubproject === subproject.name) {
|
|
subprojectNode.classList.add('selected');
|
|
}
|
|
subprojectNode.innerHTML = `
|
|
<span class="subproject-name">${subproject.name}</span>
|
|
<span class="todo-count">(${subproject.todos.length})</span>
|
|
`;
|
|
|
|
subprojectNode.addEventListener('click', (e) => {
|
|
e.stopPropagation();
|
|
onSubprojectSelect(project.name, subproject.name);
|
|
});
|
|
|
|
subprojectsContainer.appendChild(subprojectNode);
|
|
});
|
|
|
|
projectNode.appendChild(projectHeader);
|
|
projectNode.appendChild(subprojectsContainer);
|
|
treeContent.appendChild(projectNode);
|
|
});
|
|
|
|
// 创建底部控制区域
|
|
const bottomControls = document.createElement('div');
|
|
bottomControls.className = 'bottom-controls';
|
|
|
|
// 添加显示已完成复选框
|
|
const showCompletedContainer = document.createElement('div');
|
|
showCompletedContainer.className = 'show-completed-container';
|
|
showCompletedContainer.innerHTML = `
|
|
<input type="checkbox" id="show-completed" ${showCompleted ? 'checked' : ''}>
|
|
<label for="show-completed">显示已完成</label>
|
|
`;
|
|
|
|
// 添加复选框事件监听
|
|
const checkbox = showCompletedContainer.querySelector('input');
|
|
checkbox.addEventListener('change', (e) => {
|
|
onShowCompletedChange(e.target.checked);
|
|
});
|
|
|
|
bottomControls.appendChild(showCompletedContainer);
|
|
|
|
// 添加显示全部按钮
|
|
const showAllButton = document.createElement('button');
|
|
showAllButton.className = 'show-all-button';
|
|
showAllButton.textContent = '显示全部';
|
|
showAllButton.addEventListener('click', onShowAll);
|
|
bottomControls.appendChild(showAllButton);
|
|
|
|
// 将树内容和底部控制区域添加到树容器
|
|
treeContainer.appendChild(treeContent);
|
|
treeContainer.appendChild(bottomControls);
|
|
|
|
return treeContainer;
|
|
}
|
|
}
|
|
|
|
export default TodoTree;
|