feat: add global tasks folder
This commit is contained in:
@@ -1,7 +1,14 @@
|
||||
import * as vscode from "vscode";
|
||||
import { listLocatedTasks } from "@/commands/listLocatedTasks";
|
||||
import { resolveTaskLocations } from "@/commands/resolveTaskLocations";
|
||||
import { Task, TaskStatus } from "@/model/task";
|
||||
import { LocatedTask, TaskLocation } from "@/model/taskLocation";
|
||||
import { IConfigProvider, ITaskRepository } from "@/ports";
|
||||
import { TASK_STATUS_LABELS, TASK_STATUS_ORDER } from "@/ui/taskLabels";
|
||||
import {
|
||||
TASK_SCOPE_LABELS,
|
||||
TASK_STATUS_LABELS,
|
||||
TASK_STATUS_ORDER,
|
||||
} from "@/ui/taskLabels";
|
||||
import { TaskTreeItem } from "./taskTreeItem";
|
||||
|
||||
const STATUS_ICONS: Record<TaskStatus, vscode.ThemeIcon> = {
|
||||
@@ -11,19 +18,42 @@ const STATUS_ICONS: Record<TaskStatus, vscode.ThemeIcon> = {
|
||||
cancelled: new vscode.ThemeIcon("close"),
|
||||
};
|
||||
|
||||
class ScopeTreeItem extends vscode.TreeItem {
|
||||
readonly location: TaskLocation;
|
||||
readonly locatedTasks: LocatedTask[];
|
||||
|
||||
constructor(location: TaskLocation, locatedTasks: LocatedTask[]) {
|
||||
super(
|
||||
TASK_SCOPE_LABELS[location.scope],
|
||||
vscode.TreeItemCollapsibleState.Expanded,
|
||||
);
|
||||
this.location = location;
|
||||
this.locatedTasks = locatedTasks;
|
||||
this.id = `scope-${location.scope}`;
|
||||
this.contextValue = "taskScope";
|
||||
this.description = `(${locatedTasks.length})`;
|
||||
this.iconPath =
|
||||
location.scope === "project"
|
||||
? new vscode.ThemeIcon("root-folder")
|
||||
: new vscode.ThemeIcon("globe");
|
||||
}
|
||||
}
|
||||
|
||||
class TaskGroupTreeItem extends vscode.TreeItem {
|
||||
readonly location: TaskLocation;
|
||||
readonly tasks: Task[];
|
||||
|
||||
constructor(status: TaskStatus, tasks: Task[]) {
|
||||
constructor(status: TaskStatus, location: TaskLocation, tasks: Task[]) {
|
||||
super(
|
||||
TASK_STATUS_LABELS[status],
|
||||
vscode.TreeItemCollapsibleState.Collapsed,
|
||||
);
|
||||
this.iconPath = STATUS_ICONS[status];
|
||||
this.location = location;
|
||||
this.tasks = tasks;
|
||||
this.description = `(${tasks.length})`;
|
||||
this.id = `group-${status}`;
|
||||
this.id = `group-${location.scope}-${status}`;
|
||||
this.contextValue = "taskGroup";
|
||||
this.iconPath = STATUS_ICONS[status];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,23 +83,51 @@ export class TaskTreeProvider implements vscode.TreeDataProvider<vscode.TreeItem
|
||||
if (!element) {
|
||||
return this.getRootChildren();
|
||||
}
|
||||
if (element instanceof ScopeTreeItem) {
|
||||
return this.getStatusGroups(element);
|
||||
}
|
||||
if (element instanceof TaskGroupTreeItem) {
|
||||
return element.tasks.map((task) => new TaskTreeItem(task));
|
||||
return element.tasks.map(
|
||||
(task) => new TaskTreeItem(task, element.location),
|
||||
);
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
private async getRootChildren(): Promise<vscode.TreeItem[]> {
|
||||
const projectPath = this.#configStore.getProjectTaskPath();
|
||||
if (!projectPath) {
|
||||
return [new vscode.TreeItem("Open a workspace folder to start")];
|
||||
const locations = resolveTaskLocations(this.#configStore);
|
||||
if (locations.length === 0) {
|
||||
return [
|
||||
new vscode.TreeItem(
|
||||
"Configure project or global task path in settings",
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
const tasks = await this.#taskStore.list(projectPath);
|
||||
const result = await listLocatedTasks(this.#taskStore, locations);
|
||||
if (result.isErr()) {
|
||||
return [new vscode.TreeItem(result.error.message)];
|
||||
}
|
||||
|
||||
const byScope = new Map<string, LocatedTask[]>();
|
||||
for (const location of locations) {
|
||||
byScope.set(location.scope, []);
|
||||
}
|
||||
for (const located of result.value) {
|
||||
byScope.get(located.location.scope)?.push(located);
|
||||
}
|
||||
|
||||
return locations.map((location) => {
|
||||
const tasks = byScope.get(location.scope) ?? [];
|
||||
return new ScopeTreeItem(location, tasks);
|
||||
});
|
||||
}
|
||||
|
||||
private getStatusGroups(scope: ScopeTreeItem): vscode.TreeItem[] {
|
||||
const tasks = scope.locatedTasks.map((item) => item.task);
|
||||
return TASK_STATUS_ORDER.map((status) => {
|
||||
const groupTasks = tasks.filter((t) => t.status === status);
|
||||
return new TaskGroupTreeItem(status, groupTasks);
|
||||
return new TaskGroupTreeItem(status, scope.location, groupTasks);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user