feat: add wirings - view and ui
This commit is contained in:
@@ -0,0 +1,169 @@
|
||||
import * as vscode from "vscode";
|
||||
import { changeStatus } from "@/commands/changeStatus";
|
||||
import { createTask } from "@/commands/createTask";
|
||||
import { deleteTask } from "@/commands/deleteTask";
|
||||
import { openTask } from "@/commands/openTask";
|
||||
import { appError, AppErrorVariant } from "@/error";
|
||||
import { TaskStatus } from "@/model/task";
|
||||
import { IConfigProvider, ITaskRepository } from "@/ports";
|
||||
import { TaskTreeProvider } from "@/views/taskTreeProvider";
|
||||
import { presentError } from "./presentError";
|
||||
import { resolveTaskId } from "./resolveTaskId";
|
||||
import { TASK_STATUS_LABELS, TASK_STATUS_ORDER } from "./taskLabels";
|
||||
|
||||
export type TaskCommandDeps = {
|
||||
repo: ITaskRepository;
|
||||
config: IConfigProvider;
|
||||
tree: TaskTreeProvider;
|
||||
};
|
||||
|
||||
export async function runCreateTask(deps: TaskCommandDeps): Promise<void> {
|
||||
const title = await vscode.window.showInputBox({
|
||||
prompt: "Task title",
|
||||
placeHolder: "Enter task title...",
|
||||
});
|
||||
// InputBox cancel is not an application error.
|
||||
if (title === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
const result = await createTask(deps.repo, {
|
||||
folderPath: deps.config.getProjectTaskPath(),
|
||||
title,
|
||||
});
|
||||
|
||||
if (result.isErr()) {
|
||||
presentError(result.error);
|
||||
return;
|
||||
}
|
||||
|
||||
deps.tree.refresh();
|
||||
void vscode.window.showInformationMessage(
|
||||
`Task created: ${result.value.title}`,
|
||||
);
|
||||
}
|
||||
|
||||
export async function runOpenTask(
|
||||
deps: TaskCommandDeps,
|
||||
item?: unknown,
|
||||
): Promise<void> {
|
||||
const folderPath = deps.config.getProjectTaskPath();
|
||||
if (folderPath === undefined) {
|
||||
presentError(appError(AppErrorVariant.NO_FOLDER));
|
||||
return;
|
||||
}
|
||||
|
||||
const id = await resolveTaskId(deps.repo, folderPath, item);
|
||||
if (id === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
const result = await openTask(deps.repo, { folderPath, id });
|
||||
if (result.isErr()) {
|
||||
presentError(result.error);
|
||||
return;
|
||||
}
|
||||
|
||||
const uri = vscode.Uri.file(result.value.path);
|
||||
await vscode.window.showTextDocument(uri);
|
||||
}
|
||||
|
||||
export async function runDeleteTask(
|
||||
deps: TaskCommandDeps,
|
||||
item?: unknown,
|
||||
): Promise<void> {
|
||||
const folderPath = deps.config.getProjectTaskPath();
|
||||
if (folderPath === undefined) {
|
||||
presentError(appError(AppErrorVariant.NO_FOLDER));
|
||||
return;
|
||||
}
|
||||
|
||||
const id = await resolveTaskId(deps.repo, folderPath, item);
|
||||
if (id === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
const confirm = await vscode.window.showWarningMessage(
|
||||
"Delete this task?",
|
||||
{ modal: true },
|
||||
"Delete",
|
||||
);
|
||||
if (confirm !== "Delete") {
|
||||
return;
|
||||
}
|
||||
|
||||
const result = await deleteTask(deps.repo, { folderPath, id });
|
||||
if (result.isErr()) {
|
||||
presentError(result.error);
|
||||
return;
|
||||
}
|
||||
|
||||
deps.tree.refresh();
|
||||
void vscode.window.showInformationMessage("Task deleted");
|
||||
}
|
||||
|
||||
export async function runChangeStatus(
|
||||
deps: TaskCommandDeps,
|
||||
item?: unknown,
|
||||
): Promise<void> {
|
||||
const folderPath = deps.config.getProjectTaskPath();
|
||||
if (folderPath === undefined) {
|
||||
presentError(appError(AppErrorVariant.NO_FOLDER));
|
||||
return;
|
||||
}
|
||||
|
||||
const id = await resolveTaskId(deps.repo, folderPath, item);
|
||||
if (id === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
const picked = await vscode.window.showQuickPick(
|
||||
TASK_STATUS_ORDER.map((value) => ({
|
||||
label: TASK_STATUS_LABELS[value],
|
||||
status: value as TaskStatus,
|
||||
})),
|
||||
{ placeHolder: "New status" },
|
||||
);
|
||||
if (!picked) {
|
||||
return;
|
||||
}
|
||||
|
||||
const result = await changeStatus(deps.repo, {
|
||||
folderPath,
|
||||
id,
|
||||
status: picked.status,
|
||||
});
|
||||
if (result.isErr()) {
|
||||
presentError(result.error);
|
||||
return;
|
||||
}
|
||||
|
||||
deps.tree.refresh();
|
||||
void vscode.window.showInformationMessage(
|
||||
`Status: ${TASK_STATUS_LABELS[result.value.status]}`,
|
||||
);
|
||||
}
|
||||
|
||||
/** Register all task command adapters on the extension host. */
|
||||
export function registerTaskCommands(
|
||||
context: vscode.ExtensionContext,
|
||||
deps: TaskCommandDeps,
|
||||
): void {
|
||||
context.subscriptions.push(
|
||||
vscode.commands.registerCommand("projectTasks.createTask", () =>
|
||||
runCreateTask(deps),
|
||||
),
|
||||
vscode.commands.registerCommand(
|
||||
"projectTasks.openTask",
|
||||
(item?: unknown) => runOpenTask(deps, item),
|
||||
),
|
||||
vscode.commands.registerCommand(
|
||||
"projectTasks.deleteTask",
|
||||
(item?: unknown) => runDeleteTask(deps, item),
|
||||
),
|
||||
vscode.commands.registerCommand(
|
||||
"projectTasks.changeStatus",
|
||||
(item?: unknown) => runChangeStatus(deps, item),
|
||||
),
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user