* Get detailed data for project drill-down
(projectName: string)
| 1600 | * Get detailed data for project drill-down |
| 1601 | */ |
| 1602 | private async getProjectDrilldownData(projectName: string): Promise<ProjectDrilldownData> { |
| 1603 | const allTasks = this.plugin.cacheManager.getAllTaskPaths(); |
| 1604 | const projectTasks: TaskInfo[] = []; |
| 1605 | |
| 1606 | // Get all tasks for this project |
| 1607 | for (const path of allTasks) { |
| 1608 | try { |
| 1609 | const task = await this.plugin.cacheManager.getTaskInfo(path); |
| 1610 | if (task && !task.archived) { |
| 1611 | const taskProjects = this.getTaskProjects(task); |
| 1612 | if (taskProjects.includes(projectName)) { |
| 1613 | projectTasks.push(task); |
| 1614 | } |
| 1615 | } |
| 1616 | } catch (error) { |
| 1617 | tasknotesLogger.error(`Failed to get task for drill-down: ${path}`, { |
| 1618 | category: "persistence", |
| 1619 | operation: "get-task-drill-down", |
| 1620 | error: error, |
| 1621 | }); |
| 1622 | } |
| 1623 | } |
| 1624 | |
| 1625 | // Calculate stats |
| 1626 | const totalTimeSpent = projectTasks.reduce( |
| 1627 | (sum, task) => sum + calculateTotalTimeSpent(task.timeEntries || []), |
| 1628 | 0 |
| 1629 | ); |
| 1630 | |
| 1631 | const totalTimeEstimate = projectTasks.reduce( |
| 1632 | (sum, task) => sum + (task.timeEstimate || 0), |
| 1633 | 0 |
| 1634 | ); |
| 1635 | |
| 1636 | const completedTasks = projectTasks.filter((task) => |
| 1637 | this.plugin.statusManager.isCompletedStatus(task.status) |
| 1638 | ).length; |
| 1639 | |
| 1640 | const completionRate = |
| 1641 | projectTasks.length > 0 ? (completedTasks / projectTasks.length) * 100 : 0; |
| 1642 | |
| 1643 | // Get recent activity (last 10 tasks with time entries or recent completion) |
| 1644 | const recentActivity = projectTasks |
| 1645 | .filter((task) => task.timeEntries?.length || task.completedDate) |
| 1646 | .sort((a, b) => { |
| 1647 | const aTime = a.timeEntries?.length |
| 1648 | ? Math.max(...a.timeEntries.map((e) => new Date(e.startTime).getTime())) |
| 1649 | : a.completedDate |
| 1650 | ? new Date(a.completedDate).getTime() |
| 1651 | : 0; |
| 1652 | const bTime = b.timeEntries?.length |
| 1653 | ? Math.max(...b.timeEntries.map((e) => new Date(e.startTime).getTime())) |
| 1654 | : b.completedDate |
| 1655 | ? new Date(b.completedDate).getTime() |
| 1656 | : 0; |
| 1657 | return bTime - aTime; |
| 1658 | }) |
| 1659 | .slice(0, 10); |
no test coverage detected