fix(hidden_subtree): clean up LLM launch item

This commit is contained in:
Elian Doran 2026-02-22 11:13:37 +02:00
parent 7310d8af30
commit 82cae8ffbf
No known key found for this signature in database
4 changed files with 49 additions and 14 deletions

View File

@ -6,6 +6,7 @@ import branches from "./branches.js";
import cls from "./cls.js";
import hiddenSubtreeService from "./hidden_subtree.js";
import { changeLanguage } from "./i18n.js";
import notes from "./notes.js";
import sql_init from "./sql_init.js";
describe("Hidden Subtree", () => {
@ -158,5 +159,26 @@ describe("Hidden Subtree", () => {
cls.init(() => hiddenSubtreeService.checkHiddenSubtree());
expect(hiddenSubtree.hasLabel("excludeFromNoteMap")).toBeFalsy();
});
it("cleans up item to be deleted", async () => {
const noteId = "_lbLlmChat";
let llmNote = becca.getNote(noteId);
if (!llmNote) {
llmNote = notes.createNewNote({
parentNoteId: "_lbVisibleLaunchers",
noteId,
title: "LLM chat",
type: "launcher",
content: ""
}).note;
}
cls.init(() => hiddenSubtreeService.checkHiddenSubtree());
expect(llmNote.isDeleted).toBeTruthy();
// Check twice for idempotency.
cls.init(() => hiddenSubtreeService.checkHiddenSubtree());
expect(llmNote.isDeleted).toBeTruthy();
});
});
});

View File

@ -1,15 +1,15 @@
import BAttribute from "../becca/entities/battribute.js";
import BBranch from "../becca/entities/bbranch.js";
import type { HiddenSubtreeItem } from "@triliumnext/commons";
import { t } from "i18next";
import becca from "../becca/becca.js";
import noteService from "./notes.js";
import log from "./log.js";
import migrationService from "./migration.js";
import { t } from "i18next";
import { cleanUpHelp, getHelpHiddenSubtreeData } from "./in_app_help.js";
import BAttribute from "../becca/entities/battribute.js";
import BBranch from "../becca/entities/bbranch.js";
import buildLaunchBarConfig from "./hidden_subtree_launcherbar.js";
import buildHiddenSubtreeTemplates from "./hidden_subtree_templates.js";
import { cleanUpHelp, getHelpHiddenSubtreeData } from "./in_app_help.js";
import log from "./log.js";
import migrationService from "./migration.js";
import noteService from "./notes.js";
export const LBTPL_ROOT = "_lbTplRoot";
export const LBTPL_BASE = "_lbTplBase";
@ -350,7 +350,7 @@ function checkHiddenSubtreeRecursively(parentNoteId: string, item: HiddenSubtree
noteId: item.id,
title: item.title,
type: item.type,
parentNoteId: parentNoteId,
parentNoteId,
content: item.content ?? "",
ignoreForbiddenParents: true
}));
@ -363,16 +363,19 @@ function checkHiddenSubtreeRecursively(parentNoteId: string, item: HiddenSubtree
note.setContent(item.content);
}
// Clean up any branches that shouldn't exist according to the meta definition
// For hidden subtree notes, we want to ensure they only exist in their designated locations
if (item.enforceBranches || item.id.startsWith("_help")) {
if (item.enforceDeleted) {
note.deleteNote();
} else if (item.enforceBranches || item.id.startsWith("_help")) {
// Clean up any branches that shouldn't exist according to the meta definition
// For hidden subtree notes, we want to ensure they only exist in their designated locations
// If the note exists but doesn't have a branch in the expected parent,
// create the missing branch to ensure it's in the correct location
if (!branch) {
log.info(`Creating missing branch for note ${item.id} under parent ${parentNoteId}.`);
branch = new BBranch({
noteId: item.id,
parentNoteId: parentNoteId,
parentNoteId,
notePosition: item.notePosition !== undefined ? item.notePosition : undefined,
isExpanded: item.isExpanded !== undefined ? item.isExpanded : false
}).save();
@ -417,7 +420,7 @@ function checkHiddenSubtreeRecursively(parentNoteId: string, item: HiddenSubtree
} else if (item.targetNoteId) {
attrs.push({ type: "relation", name: "template", value: LBTPL_NOTE_LAUNCHER });
attrs.push({ type: "relation", name: "target", value: item.targetNoteId });
} else {
} else if (!item.enforceDeleted) {
throw new Error(`No action defined for launcher ${JSON.stringify(item)}`);
}
}
@ -466,7 +469,7 @@ function checkHiddenSubtreeRecursively(parentNoteId: string, item: HiddenSubtree
}
for (const attr of attrs) {
const attrId = note.noteId + "_" + attr.type.charAt(0) + attr.name;
const attrId = `${note.noteId}_${attr.type.charAt(0)}${attr.name}`;
const existingAttribute = note.getAttributes().find((attr) => attr.attributeId === attrId);

View File

@ -104,6 +104,12 @@ export default function buildLaunchBarConfig() {
targetNoteId: "_globalNoteMap",
icon: "bx bxs-network-chart"
},
{
id: "_lbLlmChat",
title: t("hidden-subtree.llm-chat-title"),
type: "launcher",
enforceDeleted: true
},
{
id: "_lbCalendar",
...sharedLaunchers.calendar

View File

@ -57,6 +57,10 @@ export interface HiddenSubtreeItem {
* definitions will be removed.
*/
enforceAttributes?: boolean;
/**
* If set to true, if a note with the same ID is found, it will be deleted. This is useful to deactivate features in future versions, for example the launch bar.
*/
enforceDeleted?: boolean;
/**
* Optionally, a content to be set in the hidden note. If undefined, an empty string will be set instead.
*