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 = `
${project.name} (${Object.values(project.subprojects).reduce((sum, sub) => sum + sub.todos.length, 0)})
`; 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 = ` ${subproject.name} (${subproject.todos.length}) `; 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 = ` `; // 添加复选框事件监听 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;