diff --git a/apps/client/src/widgets/collections/board/data.spec.ts b/apps/client/src/widgets/collections/board/data.spec.ts new file mode 100644 index 000000000..357aea616 --- /dev/null +++ b/apps/client/src/widgets/collections/board/data.spec.ts @@ -0,0 +1,32 @@ +import { it, describe, expect } from "vitest"; +import { buildNote } from "../../../test/easy-froca"; +import { getBoardData } from "./data"; +import FBranch from "../../../entities/fbranch"; +import froca from "../../../services/froca"; + +describe("Board data", () => { + it("deduplicates cloned notes", async () => { + const parentNote = buildNote({ + title: "Board", + "#collection": "", + "#viewType": "board", + children: [ + { id: "note1", title: "First note", "#status": "To Do" }, + { id: "note2", title: "Second note", "#status": "In progress" }, + { id: "note3", title: "Third note", "#status": "Done" } + ] + }); + const branch = new FBranch(froca, { + branchId: "note1_note2", + notePosition: 10, + fromSearchNote: false, + noteId: "note2", + parentNoteId: "note1" + }); + froca.branches["note1_note2"] = branch; + froca.getNoteFromCache("note1").addChild("note2", "note1_note2", false); + const data = await getBoardData(parentNote, "status", {}, false); + const noteIds = Array.from(data.byColumn.values()).flat().map(item => item.note.noteId); + expect(noteIds.length).toBe(3); + }); +}); diff --git a/apps/client/src/widgets/collections/board/data.ts b/apps/client/src/widgets/collections/board/data.ts index db315564a..f283e2dc7 100644 --- a/apps/client/src/widgets/collections/board/data.ts +++ b/apps/client/src/widgets/collections/board/data.ts @@ -11,7 +11,7 @@ export async function getBoardData(parentNote: FNote, groupByColumn: string, per const byColumn: ColumnMap = new Map(); // First, scan all notes to find what columns actually exist - await recursiveGroupBy(parentNote.getChildBranches(), byColumn, groupByColumn, includeArchived); + await recursiveGroupBy(parentNote.getChildBranches(), byColumn, groupByColumn, includeArchived, new Set()); // Get all columns that exist in the notes const columnsFromNotes = [...byColumn.keys()]; @@ -61,26 +61,28 @@ export async function getBoardData(parentNote: FNote, groupByColumn: string, per }; } -async function recursiveGroupBy(branches: FBranch[], byColumn: ColumnMap, groupByColumn: string, includeArchived: boolean) { +async function recursiveGroupBy(branches: FBranch[], byColumn: ColumnMap, groupByColumn: string, includeArchived: boolean, seenNoteIds: Set) { for (const branch of branches) { const note = await branch.getNote(); if (!note || (!includeArchived && note.isArchived)) continue; if (note.type !== "search" && note.hasChildren()) { - await recursiveGroupBy(note.getChildBranches(), byColumn, groupByColumn, includeArchived); + await recursiveGroupBy(note.getChildBranches(), byColumn, groupByColumn, includeArchived, seenNoteIds); } const group = note.getLabelValue(groupByColumn); - if (!group) { + if (!group || seenNoteIds.has(note.noteId)) { continue; } if (!byColumn.has(group)) { byColumn.set(group, []); } + byColumn.get(group)!.push({ branch, note }); + seenNoteIds.add(note.noteId); } }