mirror of
https://github.com/zadam/trilium.git
synced 2026-01-14 18:44:25 +01:00
fix(client/tree): toast displayed when doing operations outside of tree
This commit is contained in:
parent
8ad779be66
commit
3354bd669f
@ -1,12 +1,12 @@
|
||||
import utils from "./utils.js";
|
||||
import server from "./server.js";
|
||||
import toastService, { type ToastOptionsWithRequiredId } from "./toast.js";
|
||||
import appContext from "../components/app_context.js";
|
||||
import type { ResolveOptions } from "../widgets/dialogs/delete_notes.js";
|
||||
import froca from "./froca.js";
|
||||
import hoistedNoteService from "./hoisted_note.js";
|
||||
import ws from "./ws.js";
|
||||
import appContext from "../components/app_context.js";
|
||||
import { t } from "./i18n.js";
|
||||
import type { ResolveOptions } from "../widgets/dialogs/delete_notes.js";
|
||||
import server from "./server.js";
|
||||
import toastService, { type ToastOptionsWithRequiredId } from "./toast.js";
|
||||
import utils from "./utils.js";
|
||||
import ws from "./ws.js";
|
||||
|
||||
// TODO: Deduplicate type with server
|
||||
interface Response {
|
||||
@ -66,7 +66,7 @@ async function moveAfterBranch(branchIdsToMove: string[], afterBranchId: string)
|
||||
}
|
||||
}
|
||||
|
||||
async function moveToParentNote(branchIdsToMove: string[], newParentBranchId: string) {
|
||||
async function moveToParentNote(branchIdsToMove: string[], newParentBranchId: string, componentId?: string) {
|
||||
const newParentBranch = froca.getBranch(newParentBranchId);
|
||||
if (!newParentBranch) {
|
||||
return;
|
||||
@ -86,7 +86,7 @@ async function moveToParentNote(branchIdsToMove: string[], newParentBranchId: st
|
||||
continue;
|
||||
}
|
||||
|
||||
const resp = await server.put<Response>(`branches/${branchIdToMove}/move-to/${newParentBranchId}`);
|
||||
const resp = await server.put<Response>(`branches/${branchIdToMove}/move-to/${newParentBranchId}`, undefined, componentId);
|
||||
|
||||
if (!resp.success) {
|
||||
toastService.showError(resp.message);
|
||||
|
||||
@ -132,7 +132,6 @@ export default class LoadResults {
|
||||
}
|
||||
|
||||
addBranch(branchId: string, componentId: string) {
|
||||
console.log("Got branch with ", branchId, componentId);
|
||||
this.branchRows.push({ branchId, componentId });
|
||||
}
|
||||
|
||||
|
||||
21
apps/client/src/types-fancytree.d.ts
vendored
21
apps/client/src/types-fancytree.d.ts
vendored
@ -69,7 +69,7 @@ declare namespace Fancytree {
|
||||
debug(msg: any): void;
|
||||
|
||||
/** Expand (or collapse) all parent nodes. */
|
||||
expandAll(flag?: boolean, options?: Object): void;
|
||||
expandAll(flag?: boolean, options?: object): void;
|
||||
|
||||
/** [ext-filter] Dimm or hide whole branches.
|
||||
* @returns {integer} count
|
||||
@ -221,6 +221,7 @@ declare namespace Fancytree {
|
||||
branchId: string;
|
||||
isProtected: boolean;
|
||||
noteType: NoteType;
|
||||
subtreeHidden: boolean;
|
||||
}
|
||||
|
||||
interface FancytreeNewNode extends FancytreeNodeData {
|
||||
@ -369,7 +370,7 @@ declare namespace Fancytree {
|
||||
* @param mode 'before', 'after', or 'child' (default='child')
|
||||
* @param init NodeData (or simple title string)
|
||||
*/
|
||||
editCreateNode(mode?: string, init?: Object): void;
|
||||
editCreateNode(mode?: string, init?: object): void;
|
||||
|
||||
/** [ext-edit] Stop inline editing.
|
||||
*
|
||||
@ -526,7 +527,7 @@ declare namespace Fancytree {
|
||||
*
|
||||
* @param opts passed to `setExpanded()`. Defaults to {noAnimation: false, noEvents: false, scrollIntoView: true}
|
||||
*/
|
||||
makeVisible(opts?: Object): JQueryPromise<any>;
|
||||
makeVisible(opts?: object): JQueryPromise<any>;
|
||||
|
||||
/** Move this node to targetNode.
|
||||
*
|
||||
@ -589,25 +590,25 @@ declare namespace Fancytree {
|
||||
* @param effects animation options.
|
||||
* @param options {topNode: null, effects: ..., parent: ...} this node will remain visible in any case, even if `this` is outside the scroll pane.
|
||||
*/
|
||||
scrollIntoView(effects?: boolean, options?: Object): JQueryPromise<any>;
|
||||
scrollIntoView(effects?: boolean, options?: object): JQueryPromise<any>;
|
||||
|
||||
/**
|
||||
* @param effects animation options.
|
||||
* @param options {topNode: null, effects: ..., parent: ...} this node will remain visible in any case, even if `this` is outside the scroll pane.
|
||||
*/
|
||||
scrollIntoView(effects?: Object, options?: Object): JQueryPromise<any>;
|
||||
scrollIntoView(effects?: object, options?: object): JQueryPromise<any>;
|
||||
|
||||
/**
|
||||
* @param flag pass false to deactivate
|
||||
* @param opts additional options. Defaults to {noEvents: false}
|
||||
*/
|
||||
setActive(flag?: boolean, opts?: Object): JQueryPromise<any>;
|
||||
setActive(flag?: boolean, opts?: object): JQueryPromise<any>;
|
||||
|
||||
/**
|
||||
* @param flag pass false to collapse.
|
||||
* @param opts additional options. Defaults to {noAnimation:false, noEvents:false}
|
||||
*/
|
||||
setExpanded(flag?: boolean, opts?: Object): JQueryPromise<any>;
|
||||
setExpanded(flag?: boolean, opts?: object): JQueryPromise<any>;
|
||||
|
||||
/**
|
||||
* Set keyboard focus to this node.
|
||||
@ -1109,7 +1110,7 @@ declare namespace Fancytree {
|
||||
/** class names added to the node markup (separate with space) */
|
||||
extraClasses?: string | undefined;
|
||||
/** all properties from will be copied to `node.data` */
|
||||
data?: Object | undefined;
|
||||
data?: object | undefined;
|
||||
|
||||
/** Will be added as title attribute of the node's icon span,thus enabling a tooltip. */
|
||||
iconTooltip?: string | undefined;
|
||||
@ -1160,7 +1161,7 @@ declare namespace Fancytree {
|
||||
|
||||
escapeHtml(s: string): string;
|
||||
|
||||
getEventTarget(event: Event): Object;
|
||||
getEventTarget(event: Event): object;
|
||||
|
||||
getEventTargetType(event: Event): string;
|
||||
|
||||
@ -1179,7 +1180,7 @@ declare namespace Fancytree {
|
||||
parseHtml($ul: JQuery): NodeData[];
|
||||
|
||||
/** Add Fancytree extension definition to the list of globally available extensions. */
|
||||
registerExtension(definition: Object): void;
|
||||
registerExtension(definition: object): void;
|
||||
|
||||
unescapeHtml(s: string): string;
|
||||
|
||||
|
||||
@ -555,7 +555,7 @@ export default class NoteTreeWidget extends NoteContextAwareWidget {
|
||||
} else if (data.hitMode === "after") {
|
||||
branchService.moveAfterBranch(selectedBranchIds, node.data.branchId);
|
||||
} else if (data.hitMode === "over") {
|
||||
branchService.moveToParentNote(selectedBranchIds, node.data.branchId);
|
||||
branchService.moveToParentNote(selectedBranchIds, node.data.branchId, this.componentId);
|
||||
} else {
|
||||
throw new Error(`Unknown hitMode '${data.hitMode}'`);
|
||||
}
|
||||
@ -758,12 +758,6 @@ export default class NoteTreeWidget extends NoteContextAwareWidget {
|
||||
return;
|
||||
}
|
||||
|
||||
const parentNote = froca.getNoteFromCache(branch.parentNoteId);
|
||||
if (parentNote?.isLabelTruthy("subtreeHidden")) {
|
||||
node.remove();
|
||||
return "removed-due-to-subtree-hidden";
|
||||
}
|
||||
|
||||
const title = `${branch.prefix ? `${branch.prefix} - ` : ""}${note.title}`;
|
||||
|
||||
node.data.isProtected = note.isProtected;
|
||||
@ -805,6 +799,7 @@ export default class NoteTreeWidget extends NoteContextAwareWidget {
|
||||
lazy: true,
|
||||
folder: isFolder,
|
||||
expanded: !!branch.isExpanded && note.type !== "search",
|
||||
subtreeHidden: note.isLabelTruthy("subtreeHidden"),
|
||||
key: utils.randomString(12) // this should prevent some "duplicate key" errors
|
||||
};
|
||||
|
||||
@ -1339,18 +1334,34 @@ export default class NoteTreeWidget extends NoteContextAwareWidget {
|
||||
} else if (frocaBranch) {
|
||||
// make sure it's loaded
|
||||
// we're forcing lazy since it's not clear if the whole required subtree is in froca
|
||||
const newNode = this.prepareNode(frocaBranch, true);
|
||||
if (newNode) {
|
||||
parentNode.addChildren([newNode]);
|
||||
}
|
||||
if (!parentNode.data.subtreeHidden) {
|
||||
const newNode = this.prepareNode(frocaBranch, true);
|
||||
if (newNode) {
|
||||
parentNode.addChildren([newNode]);
|
||||
}
|
||||
|
||||
if (frocaBranch?.isExpanded && note && note.hasChildren()) {
|
||||
refreshCtx.noteIdsToReload.add(frocaBranch.noteId);
|
||||
}
|
||||
if (frocaBranch?.isExpanded && note && note.hasChildren()) {
|
||||
refreshCtx.noteIdsToReload.add(frocaBranch.noteId);
|
||||
}
|
||||
|
||||
this.sortChildren(parentNode);
|
||||
this.sortChildren(parentNode);
|
||||
} else if (branchRow.componentId === this.componentId) {
|
||||
// Display the toast and focus to parent note only if we know for sure that the operation comes from the tree.
|
||||
const parentNote = froca.getNoteFromCache(parentNode.data.noteId || "");
|
||||
toastService.showPersistent({
|
||||
id: `subtree-hidden-moved`,
|
||||
title: t("note_tree.subtree-hidden-moved-title", { title: parentNote?.title }),
|
||||
message: parentNote?.type === "book"
|
||||
? t("note_tree.subtree-hidden-moved-description-collection")
|
||||
: t("note_tree.subtree-hidden-moved-description-other"),
|
||||
icon: "bx bx-hide",
|
||||
timeout: 5_000,
|
||||
});
|
||||
parentNode.setActive(true);
|
||||
}
|
||||
|
||||
// this might be a first child which would force an icon change
|
||||
// also update the count if the subtree is hidden.
|
||||
if (branchRow.parentNoteId) {
|
||||
refreshCtx.noteIdsToUpdate.add(branchRow.parentNoteId);
|
||||
}
|
||||
@ -1385,30 +1396,11 @@ export default class NoteTreeWidget extends NoteContextAwareWidget {
|
||||
});
|
||||
|
||||
// for some reason, node update cannot be in the batchUpdate() block (node is not re-rendered)
|
||||
let removedFromSubtreeParent: Fancytree.FancytreeNode | null = null;
|
||||
for (const noteId of refreshCtx.noteIdsToUpdate) {
|
||||
for (const node of this.getNodesByNoteId(noteId)) {
|
||||
const parent = node.parent;
|
||||
const result = await this.updateNode(node);
|
||||
if (result === "removed-due-to-subtree-hidden") {
|
||||
removedFromSubtreeParent = parent;
|
||||
}
|
||||
await this.updateNode(node);
|
||||
}
|
||||
}
|
||||
|
||||
if (removedFromSubtreeParent) {
|
||||
removedFromSubtreeParent.setActive(true, { noEvents: true });
|
||||
const targetNote = froca.getNoteFromCache(removedFromSubtreeParent.data.noteId || "");
|
||||
toastService.showPersistent({
|
||||
id: `subtree-hidden-moved`,
|
||||
title: t("note_tree.subtree-hidden-moved-title", { title: targetNote?.title }),
|
||||
message: targetNote?.type === "book"
|
||||
? t("note_tree.subtree-hidden-moved-description-collection")
|
||||
: t("note_tree.subtree-hidden-moved-description-other"),
|
||||
icon: "bx bx-hide",
|
||||
timeout: 5_000,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
async #setActiveNode(activeNotePath: string | null, activeNodeFocused: boolean, movedActiveNode: Fancytree.FancytreeNode | null, parentsOfAddedNodes: Fancytree.FancytreeNode[]) {
|
||||
@ -1665,7 +1657,7 @@ export default class NoteTreeWidget extends NoteContextAwareWidget {
|
||||
const toNode = node.getPrevSibling();
|
||||
|
||||
if (toNode !== null) {
|
||||
branchService.moveToParentNote([node.data.branchId], toNode.data.branchId);
|
||||
branchService.moveToParentNote([node.data.branchId], toNode.data.branchId, this.componentId);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1802,12 +1794,12 @@ export default class NoteTreeWidget extends NoteContextAwareWidget {
|
||||
#moveLaunchers(selectedOrActiveBranchIds: string[], desktopParent: string, mobileParent: string) {
|
||||
const desktopLaunchersToMove = selectedOrActiveBranchIds.filter((branchId) => !branchId.startsWith("_lbMobile"));
|
||||
if (desktopLaunchersToMove) {
|
||||
branchService.moveToParentNote(desktopLaunchersToMove, `_lbRoot_${ desktopParent}`);
|
||||
branchService.moveToParentNote(desktopLaunchersToMove, `_lbRoot_${ desktopParent}`, this.componentId);
|
||||
}
|
||||
|
||||
const mobileLaunchersToMove = selectedOrActiveBranchIds.filter((branchId) => branchId.startsWith("_lbMobile"));
|
||||
if (mobileLaunchersToMove) {
|
||||
branchService.moveToParentNote(mobileLaunchersToMove, `_lbMobileRoot_${ mobileParent}`);
|
||||
branchService.moveToParentNote(mobileLaunchersToMove, `_lbMobileRoot_${mobileParent}`, this.componentId);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user