From a89bd835d0eb47c2304ce2362f540c8563b7ec3c Mon Sep 17 00:00:00 2001 From: Henry Date: Sun, 10 Aug 2025 23:08:52 +0100 Subject: [PATCH] feat: update checklist name --- apps/web/src/components/Editor.tsx | 11 ++- .../card/components/ChecklistItemRow.tsx | 49 +++++------ .../card/components/ChecklistNameInput.tsx | 81 +++++++++++++++++ apps/web/src/views/card/index.tsx | 13 ++- packages/api/src/routers/checklist.ts | 87 ++++++++++--------- packages/db/src/repository/card.repo.ts | 2 + packages/db/src/repository/checklist.repo.ts | 12 +++ 7 files changed, 180 insertions(+), 75 deletions(-) create mode 100644 apps/web/src/views/card/components/ChecklistNameInput.tsx diff --git a/apps/web/src/components/Editor.tsx b/apps/web/src/components/Editor.tsx index e4abc1c3..92046ad8 100644 --- a/apps/web/src/components/Editor.tsx +++ b/apps/web/src/components/Editor.tsx @@ -15,10 +15,15 @@ import { ReactRenderer, useEditor, } from "@tiptap/react"; -import { useEffect } from "react"; import StarterKit from "@tiptap/starter-kit"; import Suggestion from "@tiptap/suggestion"; -import { forwardRef, useImperativeHandle, useRef, useState } from "react"; +import { + forwardRef, + useEffect, + useImperativeHandle, + useRef, + useState, +} from "react"; import { HiH1, HiH2, @@ -373,7 +378,7 @@ export default function Editor({ {!readOnly && editor && } ); diff --git a/apps/web/src/views/card/components/ChecklistItemRow.tsx b/apps/web/src/views/card/components/ChecklistItemRow.tsx index e29132a0..0ee7da32 100644 --- a/apps/web/src/views/card/components/ChecklistItemRow.tsx +++ b/apps/web/src/views/card/components/ChecklistItemRow.tsx @@ -91,10 +91,20 @@ export default function ChecklistItemRow({ const [title, setTitle] = useState(item.title); const [completed, setCompleted] = useState(item.completed); + // Only resync from props when switching items to avoid clobbering edits useEffect(() => { setTitle(item.title); setCompleted(item.completed); - }, [item.publicId, item.title, item.completed]); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [item.publicId]); + + const sanitizeHtmlToPlainText = (html: string): string => + html + .replace(/(\n)?/gi, "\n") + .replace(/
<\/div>/gi, "") + .replace(/<[^>]*>/g, "") + .replace(/ /g, " ") + .trim(); const handleToggleCompleted = () => { setCompleted((prev) => !prev); @@ -104,12 +114,13 @@ export default function ChecklistItemRow({ }); }; - const commitTitle = async () => { - const trimmed = title.trim(); - if (!trimmed || trimmed === item.title) return; + const commitTitle = (rawHtml: string) => { + const plain = sanitizeHtmlToPlainText(rawHtml); + if (!plain || plain === item.title) return; + setTitle(plain); updateItem.mutate({ checklistItemPublicId: item.publicId, - title: trimmed, + title: plain, }); }; @@ -118,40 +129,26 @@ export default function ChecklistItemRow({ }; return ( -
-