Entity export and stuff
This commit is contained in:
@@ -87,6 +87,7 @@ export default function Router({
|
||||
statuses={entity.config.statuses}
|
||||
setTags={setTags}
|
||||
setStatuses={setStatuses}
|
||||
entityName={entity.name}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -101,7 +102,12 @@ export default function Router({
|
||||
|
||||
return (
|
||||
<div className="h-full w-3xl mx-auto bg-card rounded-2xl p-6 border">
|
||||
<DocView key={entity.id} doc={entity.content} setDoc={setDoc} />
|
||||
<DocView
|
||||
key={entity.id}
|
||||
doc={entity.content}
|
||||
setDoc={setDoc}
|
||||
docName={entity.name}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"use client";
|
||||
|
||||
import { useEffect, useRef } from "react";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
|
||||
import Header from "@editorjs/header";
|
||||
import List from "@editorjs/list";
|
||||
@@ -11,6 +11,21 @@ import Delimiter from "@editorjs/delimiter";
|
||||
import Warning from "@editorjs/warning";
|
||||
import InlineCode from "@editorjs/inline-code";
|
||||
import { OutputData } from "@editorjs/editorjs";
|
||||
import {
|
||||
downloadFile,
|
||||
exportDocAsJson,
|
||||
exportDocAsMarkdown,
|
||||
exportDocAsHtml,
|
||||
} from "@/lib/export";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuTrigger,
|
||||
DropdownMenuSeparator,
|
||||
} from "@/components/ui/dropdown-menu";
|
||||
import { FileDown } from "lucide-react";
|
||||
|
||||
function toMarkdown(data: OutputData): string {
|
||||
return data.blocks
|
||||
@@ -55,11 +70,48 @@ function toMarkdown(data: OutputData): string {
|
||||
export default function DocView({
|
||||
doc,
|
||||
setDoc,
|
||||
docName = "Document",
|
||||
}: {
|
||||
doc: OutputData;
|
||||
setDoc: (data: OutputData) => void;
|
||||
docName?: string;
|
||||
}) {
|
||||
const holderRef = useRef<HTMLDivElement | null>(null);
|
||||
const [isExporting, setIsExporting] = useState(false);
|
||||
|
||||
const handleExport = (format: "json" | "markdown" | "html") => {
|
||||
const docEntity = {
|
||||
id: "",
|
||||
type: "doc" as const,
|
||||
name: docName,
|
||||
content: doc,
|
||||
createdAt: Date.now(),
|
||||
updatedAt: Date.now(),
|
||||
};
|
||||
let content = "";
|
||||
let filename = `${docName.replace(/\s+/g, "_")}_${Date.now()}`;
|
||||
|
||||
switch (format) {
|
||||
case "json":
|
||||
content = exportDocAsJson(docEntity);
|
||||
filename += ".json";
|
||||
break;
|
||||
case "markdown":
|
||||
content = exportDocAsMarkdown(docEntity);
|
||||
filename += ".md";
|
||||
break;
|
||||
case "html":
|
||||
content = exportDocAsHtml(docEntity);
|
||||
filename += ".html";
|
||||
break;
|
||||
}
|
||||
|
||||
downloadFile(
|
||||
content,
|
||||
filename,
|
||||
format === "html" ? "text/html" : "text/plain",
|
||||
);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
let editor: any;
|
||||
@@ -135,5 +187,31 @@ export default function DocView({
|
||||
};
|
||||
}, []);
|
||||
|
||||
return <div ref={holderRef} className="docs-view h-max w-full" />;
|
||||
return (
|
||||
<div className="flex flex-col gap-4">
|
||||
<div className="flex items-center justify-end gap-2">
|
||||
<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("markdown")}>
|
||||
Export as Markdown
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem onClick={() => handleExport("html")}>
|
||||
Export as HTML
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuSeparator />
|
||||
<DropdownMenuItem onClick={() => handleExport("json")}>
|
||||
Export as JSON
|
||||
</DropdownMenuItem>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
</div>
|
||||
<div ref={holderRef} className="docs-view h-max w-full" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -6,6 +6,22 @@ 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>;
|
||||
@@ -25,6 +41,9 @@ export type TaskViewProps = {
|
||||
|
||||
/** Create a new task with a status */
|
||||
createTask: (statusId: string) => void;
|
||||
|
||||
/** Entity name for export */
|
||||
entityName?: string;
|
||||
};
|
||||
|
||||
export default function TaskView({
|
||||
@@ -35,9 +54,66 @@ export default function TaskView({
|
||||
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">
|
||||
<div className="px-6 pt-4 flex flex-col gap-4">
|
||||
<div className="flex items-center justify-end">
|
||||
<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>
|
||||
<Tabs defaultValue="board" className="w-full">
|
||||
<TabsList className="mb-4">
|
||||
<TabsTrigger value="board">Board</TabsTrigger>
|
||||
|
||||
Reference in New Issue
Block a user