feat: note line management
This commit is contained in:
parent
32b33ae4c4
commit
753fb225e1
@ -1,23 +1,27 @@
|
|||||||
"use server";
|
"use server";
|
||||||
|
|
||||||
import { revalidatePath } from "next/cache";
|
import { revalidatePath } from "next/cache";
|
||||||
import { eq } from "drizzle-orm";
|
import { eq, asc } from "drizzle-orm";
|
||||||
import { db } from "@/lib/db";
|
import { db } from "@/lib/db";
|
||||||
import { blocksTable, IBlock } from "@/lib/db/schema";
|
import { blocksTable, IBlock } from "@/lib/db/schema";
|
||||||
|
|
||||||
export async function createBlock(formData: FormData) {
|
export async function createBlock(formData: FormData) {
|
||||||
const noteId = formData.get("noteId") as string;
|
const noteId = formData.get("noteId") as string;
|
||||||
|
const blocks = await getBlocks(noteId);
|
||||||
|
const lastBlock = blocks.pop();
|
||||||
|
const order = lastBlock === undefined ? 1 : lastBlock.order + 1;
|
||||||
await db
|
await db
|
||||||
.insert(blocksTable)
|
.insert(blocksTable)
|
||||||
.values({ noteId });
|
.values({ noteId, order });
|
||||||
revalidatePath("/notes/[id]");
|
revalidatePath("/notes/[id]", "page");
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getBlocks(noteId: string): Promise<IBlock[]> {
|
export async function getBlocks(noteId: string): Promise<IBlock[]> {
|
||||||
return db
|
return db
|
||||||
.select()
|
.select()
|
||||||
.from(blocksTable)
|
.from(blocksTable)
|
||||||
.where(eq(blocksTable.noteId, noteId));
|
.where(eq(blocksTable.noteId, noteId))
|
||||||
|
.orderBy(asc(blocksTable.order));
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function deleteBlock(formData: FormData) {
|
export async function deleteBlock(formData: FormData) {
|
||||||
@ -25,7 +29,7 @@ export async function deleteBlock(formData: FormData) {
|
|||||||
await db
|
await db
|
||||||
.delete(blocksTable)
|
.delete(blocksTable)
|
||||||
.where(eq(blocksTable.id, blockId));
|
.where(eq(blocksTable.id, blockId));
|
||||||
revalidatePath("/notes/[id]");
|
revalidatePath("/notes/[id]", "page");
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function changeLock(formData: FormData) {
|
export async function changeLock(formData: FormData) {
|
||||||
@ -35,5 +39,39 @@ export async function changeLock(formData: FormData) {
|
|||||||
.update(blocksTable)
|
.update(blocksTable)
|
||||||
.set({ isLocked })
|
.set({ isLocked })
|
||||||
.where(eq(blocksTable.id, blockId));
|
.where(eq(blocksTable.id, blockId));
|
||||||
revalidatePath("/notes/[id]");
|
revalidatePath("/notes/[id]", "page");
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function addLine(formData: FormData) {
|
||||||
|
const blockId = formData.get("blockId") as string;
|
||||||
|
const blocks = await db
|
||||||
|
.select()
|
||||||
|
.from(blocksTable)
|
||||||
|
.where(eq(blocksTable.id, blockId));
|
||||||
|
if (blocks.length === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const block = blocks[0];
|
||||||
|
await db
|
||||||
|
.update(blocksTable)
|
||||||
|
.set({ lines: [...block.lines, ""] })
|
||||||
|
.where(eq(blocksTable.id, blockId));
|
||||||
|
revalidatePath("/notes/[id]", "page");
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function deleteLine(formData: FormData) {
|
||||||
|
const blockId = formData.get("blockId") as string;
|
||||||
|
const blocks = await db
|
||||||
|
.select()
|
||||||
|
.from(blocksTable)
|
||||||
|
.where(eq(blocksTable.id, blockId));
|
||||||
|
if (blocks.length === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const block = blocks[0];
|
||||||
|
await db
|
||||||
|
.update(blocksTable)
|
||||||
|
.set({ lines: block.lines.slice(0, -1) })
|
||||||
|
.where(eq(blocksTable.id, blockId));
|
||||||
|
revalidatePath("/notes/[id]", "page");
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { ArrowDown, ArrowUp, LockOpen, Lock, Minus, Plus, X } from "lucide-react";
|
import { ArrowDown, ArrowUp, LockOpen, Lock, Minus, Plus, X } from "lucide-react";
|
||||||
import { changeLock, deleteBlock } from "@/app/actions/blocks";
|
import { addLine, changeLock, deleteBlock, deleteLine } from "@/app/actions/blocks";
|
||||||
import { IBlock } from "@/lib/db/schema";
|
import { IBlock } from "@/lib/db/schema";
|
||||||
import IconOnlyButton from "../ui/IconOnlyButton";
|
import IconOnlyButton from "../ui/IconOnlyButton";
|
||||||
import LineInput from "./LineInput";
|
import LineInput from "./LineInput";
|
||||||
@ -20,26 +20,33 @@ export default function Block({ block }: { block: IBlock }) {
|
|||||||
))}
|
))}
|
||||||
<div className="flex items-center mx-2 mt-2">
|
<div className="flex items-center mx-2 mt-2">
|
||||||
<div className="flex gap-1 mr-4">
|
<div className="flex gap-1 mr-4">
|
||||||
<IconOnlyButton icon={<Plus size={18} />} disabled={block.isLocked} />
|
<form action={addLine}>
|
||||||
<IconOnlyButton icon={<Minus size={18} />} disabled={block.isLocked} />
|
<input type="hidden" name="blockId" value={block.id} />
|
||||||
|
<IconOnlyButton type="submit" icon={<Plus size={18} />} disabled={block.isLocked} />
|
||||||
|
</form>
|
||||||
|
<form action={deleteLine}>
|
||||||
|
<input type="hidden" name="blockId" value={block.id} />
|
||||||
|
<IconOnlyButton type="submit" icon={<Minus size={18} />} disabled={block.isLocked} />
|
||||||
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex gap-1">
|
<div className="flex gap-1">
|
||||||
<IconOnlyButton icon={<ArrowUp size={18} />} />
|
<IconOnlyButton icon={<ArrowUp size={18} />} />
|
||||||
<IconOnlyButton icon={<ArrowDown size={18} />} />
|
<IconOnlyButton icon={<ArrowDown size={18} />} />
|
||||||
</div>
|
</div>
|
||||||
<div className="flex gap-2 ml-auto">
|
<div className="flex gap-2 ml-auto">
|
||||||
<form action={deleteBlock}>
|
|
||||||
<input type="hidden" name="blockId" value={block.id} />
|
|
||||||
<IconOnlyButton icon={<X size={18} />} type="submit" />
|
|
||||||
</form>
|
|
||||||
<form action={changeLock}>
|
<form action={changeLock}>
|
||||||
<input type="hidden" name="blockId" value={block.id} />
|
<input type="hidden" name="blockId" value={block.id} />
|
||||||
{!block.isLocked && <input type="hidden" name="isLocked" />}
|
{!block.isLocked && <input type="hidden" name="isLocked" />}
|
||||||
<IconOnlyButton
|
<IconOnlyButton
|
||||||
|
type="submit"
|
||||||
alwaysOn={block.isLocked}
|
alwaysOn={block.isLocked}
|
||||||
icon={block.isLocked ? <Lock size={18} /> : <LockOpen size={18} />}
|
icon={block.isLocked ? <Lock size={18} /> : <LockOpen size={18} />}
|
||||||
/>
|
/>
|
||||||
</form>
|
</form>
|
||||||
|
<form action={deleteBlock}>
|
||||||
|
<input type="hidden" name="blockId" value={block.id} />
|
||||||
|
<IconOnlyButton type="submit" icon={<X size={18} />} />
|
||||||
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user