fix(collections/board): cloned notes appearing twice (closes #6786)
Some checks are pending
Checks / main (push) Waiting to run
CodeQL Advanced / Analyze (actions) (push) Waiting to run
CodeQL Advanced / Analyze (javascript-typescript) (push) Waiting to run
Dev / Test development (push) Waiting to run
Dev / Build Docker image (push) Blocked by required conditions
Dev / Check Docker build (Dockerfile) (push) Blocked by required conditions
Dev / Check Docker build (Dockerfile.alpine) (push) Blocked by required conditions
/ Check Docker build (Dockerfile) (push) Waiting to run
/ Check Docker build (Dockerfile.alpine) (push) Waiting to run
/ Build Docker images (Dockerfile, ubuntu-24.04-arm, linux/arm64) (push) Blocked by required conditions
/ Build Docker images (Dockerfile.alpine, ubuntu-latest, linux/amd64) (push) Blocked by required conditions
/ Build Docker images (Dockerfile.legacy, ubuntu-24.04-arm, linux/arm/v7) (push) Blocked by required conditions
/ Build Docker images (Dockerfile.legacy, ubuntu-24.04-arm, linux/arm/v8) (push) Blocked by required conditions
/ Merge manifest lists (push) Blocked by required conditions
playwright / main (push) Waiting to run

This commit is contained in:
Elian Doran 2025-11-08 20:17:56 +02:00
parent b0bd60b9a4
commit 3463cb83a0
No known key found for this signature in database
2 changed files with 38 additions and 4 deletions

View File

@ -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);
});
});

View File

@ -11,7 +11,7 @@ export async function getBoardData(parentNote: FNote, groupByColumn: string, per
const byColumn: ColumnMap = new Map(); const byColumn: ColumnMap = new Map();
// First, scan all notes to find what columns actually exist // 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<string>());
// Get all columns that exist in the notes // Get all columns that exist in the notes
const columnsFromNotes = [...byColumn.keys()]; 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<string>) {
for (const branch of branches) { for (const branch of branches) {
const note = await branch.getNote(); const note = await branch.getNote();
if (!note || (!includeArchived && note.isArchived)) continue; if (!note || (!includeArchived && note.isArchived)) continue;
if (note.type !== "search" && note.hasChildren()) { 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); const group = note.getLabelValue(groupByColumn);
if (!group) { if (!group || seenNoteIds.has(note.noteId)) {
continue; continue;
} }
if (!byColumn.has(group)) { if (!byColumn.has(group)) {
byColumn.set(group, []); byColumn.set(group, []);
} }
byColumn.get(group)!.push({ byColumn.get(group)!.push({
branch, branch,
note note
}); });
seenNoteIds.add(note.noteId);
} }
} }