From 765db90570fd92a706cade6acdedde99819c106a Mon Sep 17 00:00:00 2001 From: Henry Date: Sun, 12 Jan 2025 09:32:31 +0000 Subject: [PATCH] fix: generate board slug for new boards --- .../views/boards/components/NewBoardForm.tsx | 12 +++++------ packages/api/src/routers/board.ts | 12 +++++++++++ packages/db/src/repository/board.repo.ts | 21 ++++++++++++++++++- packages/utils/src/generateSlug.ts | 8 +++++++ packages/utils/src/index.ts | 1 + 5 files changed, 46 insertions(+), 8 deletions(-) create mode 100644 packages/utils/src/generateSlug.ts diff --git a/apps/web/src/views/boards/components/NewBoardForm.tsx b/apps/web/src/views/boards/components/NewBoardForm.tsx index 76b2e60e..ba85a452 100644 --- a/apps/web/src/views/boards/components/NewBoardForm.tsx +++ b/apps/web/src/views/boards/components/NewBoardForm.tsx @@ -1,8 +1,9 @@ import { useForm } from "react-hook-form"; import { HiXMark } from "react-icons/hi2"; -import { type NewBoardInput } from "@kan/api/types"; +import type { NewBoardInput } from "@kan/api/types"; +import Button from "~/components/Button"; import { useModal } from "~/providers/modal"; import { useWorkspace } from "~/providers/workspace"; import { api } from "~/utils/api"; @@ -15,7 +16,7 @@ export function NewBoardForm() { const { register, handleSubmit } = useForm({ defaultValues: { name: "", - workspacePublicId: workspace?.publicId || "", + workspacePublicId: workspace.publicId || "", }, }); @@ -57,12 +58,9 @@ export function NewBoardForm() {
- +
diff --git a/packages/api/src/routers/board.ts b/packages/api/src/routers/board.ts index 10ca53a2..eca7402f 100644 --- a/packages/api/src/routers/board.ts +++ b/packages/api/src/routers/board.ts @@ -6,6 +6,7 @@ import * as cardRepo from "@kan/db/repository/card.repo"; import * as activityRepo from "@kan/db/repository/cardActivity.repo"; import * as listRepo from "@kan/db/repository/list.repo"; import * as workspaceRepo from "@kan/db/repository/workspace.repo"; +import { generateSlug, generateUID } from "@kan/utils"; import { createTRPCRouter, protectedProcedure, publicProcedure } from "../trpc"; @@ -141,7 +142,18 @@ export const boardRouter = createTRPCRouter({ code: "NOT_FOUND", }); + let slug = generateSlug(input.name); + + const isSlugUnique = await boardRepo.isSlugUnique(ctx.db, { + slug, + workspaceId: workspace.id, + }); + + if (!isSlugUnique) slug = `${slug}-${generateUID()}`; + const result = await boardRepo.create(ctx.db, { + publicId: generateUID(), + slug, name: input.name, createdBy: userId, workspaceId: workspace.id, diff --git a/packages/db/src/repository/board.repo.ts b/packages/db/src/repository/board.repo.ts index 2a9968d7..55b9fbe7 100644 --- a/packages/db/src/repository/board.repo.ts +++ b/packages/db/src/repository/board.repo.ts @@ -210,20 +210,23 @@ export const getWithLatestListIndexByPublicId = async ( export const create = async ( db: SupabaseClient, boardInput: { + publicId?: string; name: string; createdBy: string; workspaceId: number; importId?: number; + slug: string; }, ) => { const { data } = await db .from("board") .insert({ - publicId: generateUID(), + publicId: boardInput.publicId ?? generateUID(), name: boardInput.name, createdBy: boardInput.createdBy, workspaceId: boardInput.workspaceId, importId: boardInput.importId, + slug: boardInput.slug, }) .select(`id, publicId, name`) .limit(1) @@ -277,3 +280,19 @@ export const hardDelete = async ( return result; }; + +export const isSlugUnique = async ( + db: SupabaseClient, + args: { slug: string; workspaceId: number }, +) => { + const { data } = await db + .from("board") + .select("slug") + .eq("slug", args.slug) + .eq("workspaceId", args.workspaceId) + .is("deletedAt", null) + .limit(1) + .single(); + + return !data; +}; diff --git a/packages/utils/src/generateSlug.ts b/packages/utils/src/generateSlug.ts new file mode 100644 index 00000000..f06241be --- /dev/null +++ b/packages/utils/src/generateSlug.ts @@ -0,0 +1,8 @@ +export function generateSlug(text: string): string { + return text + .toLowerCase() + .trim() + .replace(/[^\w\s-]/g, "") // Remove special characters + .replace(/\s+/g, "-") // Replace spaces with hyphens + .replace(/-+/g, "-"); // Remove consecutive hyphens +} diff --git a/packages/utils/src/index.ts b/packages/utils/src/index.ts index 476c9d3c..bb2edd45 100644 --- a/packages/utils/src/index.ts +++ b/packages/utils/src/index.ts @@ -1,3 +1,4 @@ export const name = "utils"; export { generateUID } from "./generateUID"; +export { generateSlug } from "./generateSlug";