Files
drift/src/components/view/TaskView.tsx
T
2026-02-27 23:31:58 +01:00

162 lines
4.3 KiB
TypeScript

"use client";
import { Tag, TagId, Task, TaskId, Status } from "@/lib/types";
import { Color } from "@/lib/ui/color";
import BoardView from "./board/BoardView";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "../ui/tabs";
import { TableView } from "./table/TableView";
import EditView from "./edit/EditView";
import { Button } from "@/components/ui/button";
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
DropdownMenuSeparator,
} from "@/components/ui/dropdown-menu";
import { FileDown } from "lucide-react";
import {
downloadFile,
exportTodoAsJson,
exportTodoAsCsv,
exportTodoAsMarkdown,
} from "@/lib/export";
import { useEffect, useState } from "react";
export type TaskViewProps = {
tags: Record<TagId, Tag>;
tasks: Record<TaskId, Task>;
statuses: Status[];
/** Update entire tasks record */
setTasks: (tasks: Record<TaskId, Task>) => void;
/** Update tags */
setTags: (tags: Record<TagId, Tag>) => void;
/** Update statuses */
setStatuses: (statuses: Status[]) => void;
/** Create a new task with a status */
createTask: (statusId: string) => void;
/** Entity name for export */
entityName?: string;
};
export default function TaskView({
tags,
tasks,
statuses,
setTasks,
setTags,
setStatuses,
createTask,
entityName = "Tasks",
}: TaskViewProps) {
const [isExporting, setIsExporting] = useState(false);
const handleExport = (format: "json" | "csv" | "markdown") => {
const todoEntity = {
id: "",
type: "todo" as const,
name: entityName,
config: { statuses },
tags,
tasks,
createdAt: Date.now(),
updatedAt: Date.now(),
};
let content = "";
let filename = `${entityName.replace(/\s+/g, "_")}_${Date.now()}`;
switch (format) {
case "json":
content = exportTodoAsJson(todoEntity);
filename += ".json";
break;
case "csv":
content = exportTodoAsCsv(todoEntity);
filename += ".csv";
break;
case "markdown":
content = exportTodoAsMarkdown(todoEntity);
filename += ".md";
break;
}
downloadFile(content, filename, "text/plain");
};
return (
<div className="px-6 pt-4 flex flex-col gap-4">
<div className="flex items-center justify-end"></div>
<Tabs defaultValue="board" className="w-full">
<div className="flex justify-between">
<TabsList className="mb-4">
<TabsTrigger value="board">Board</TabsTrigger>
<TabsTrigger value="table">Table</TabsTrigger>
<TabsTrigger value="edit">Edit</TabsTrigger>
</TabsList>
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="outline" size="sm" disabled={isExporting}>
<FileDown className="h-4 w-4 mr-2" />
Export
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
<DropdownMenuItem onClick={() => handleExport("csv")}>
Export as CSV
</DropdownMenuItem>
<DropdownMenuItem onClick={() => handleExport("markdown")}>
Export as Markdown
</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem onClick={() => handleExport("json")}>
Export as JSON
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</div>
<TabsContent value="board" className="mt-0">
<BoardView
tasks={tasks}
setTasks={setTasks}
createTask={createTask}
tags={tags}
setTags={setTags}
setStatuses={setStatuses}
statuses={statuses}
/>
</TabsContent>
<TabsContent value="table" className="mt-0">
<TableView
tasks={tasks}
setTasks={setTasks}
createTask={createTask}
tags={tags}
setTags={setTags}
setStatuses={setStatuses}
statuses={statuses}
/>
</TabsContent>
<TabsContent value="edit" className="mt-0">
<EditView
tags={tags}
statuses={statuses}
setTags={setTags}
setStatuses={setStatuses}
/>
</TabsContent>
</Tabs>
</div>
);
}