mirror of
				https://github.com/TriliumNext/Notes.git
				synced 2025-10-31 21:11:30 +08:00 
			
		
		
		
	chore(client/ts): port menus/launcher_context_menu
This commit is contained in:
		
							parent
							
								
									a14d112a5c
								
							
						
					
					
						commit
						6140bb5d99
					
				| @ -24,7 +24,7 @@ interface Layout { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| interface RootWidget extends Component { | interface RootWidget extends Component { | ||||||
|     render: () => JQuery<HTMLElement>;     |     render: () => JQuery<HTMLElement>; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| interface BeforeUploadListener extends Component { | interface BeforeUploadListener extends Component { | ||||||
| @ -61,7 +61,7 @@ type CommandMappings = { | |||||||
|     showConfirmDialog: ConfirmWithMessageOptions; |     showConfirmDialog: ConfirmWithMessageOptions; | ||||||
|     openNewNoteSplit: CommandData & { |     openNewNoteSplit: CommandData & { | ||||||
|         ntxId: string; |         ntxId: string; | ||||||
|         notePath: string;    |         notePath: string; | ||||||
|     }; |     }; | ||||||
|     executeInActiveNoteDetailWidget: CommandData & { |     executeInActiveNoteDetailWidget: CommandData & { | ||||||
|         callback: (value: NoteDetailWidget | PromiseLike<NoteDetailWidget>) => void |         callback: (value: NoteDetailWidget | PromiseLike<NoteDetailWidget>) => void | ||||||
| @ -69,11 +69,12 @@ type CommandMappings = { | |||||||
|     addTextToActiveEditor: CommandData & { |     addTextToActiveEditor: CommandData & { | ||||||
|         text: string; |         text: string; | ||||||
|     }; |     }; | ||||||
|      | 
 | ||||||
|     importMarkdownInline: CommandData; |     importMarkdownInline: CommandData; | ||||||
|     showPasswordNotSet: CommandData; |     showPasswordNotSet: CommandData; | ||||||
|     showProtectedSessionPasswordDialog: CommandData; |     showProtectedSessionPasswordDialog: CommandData; | ||||||
|     closeProtectedSessionPasswordDialog: CommandData; |     closeProtectedSessionPasswordDialog: CommandData; | ||||||
|  |     resetLauncher: CommandData; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| type EventMappings = { | type EventMappings = { | ||||||
|  | |||||||
							
								
								
									
										7
									
								
								src/public/app/components/events.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								src/public/app/components/events.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,7 @@ | |||||||
|  | import { MenuCommandItem } from "../menus/context_menu.js"; | ||||||
|  | 
 | ||||||
|  | type ListenerReturnType = void | Promise<void>; | ||||||
|  | 
 | ||||||
|  | export interface SelectMenuItemEventListener { | ||||||
|  |     selectMenuItemHandler(item: MenuCommandItem): ListenerReturnType; | ||||||
|  | } | ||||||
| @ -1,21 +1,28 @@ | |||||||
| import treeService from '../services/tree.js'; | import treeService, { Node } from '../services/tree.js'; | ||||||
| import froca from "../services/froca.js"; | import froca from "../services/froca.js"; | ||||||
| import contextMenu from "./context_menu.js"; | import contextMenu, { MenuCommandItem, MenuItem } from "./context_menu.js"; | ||||||
| import dialogService from "../services/dialog.js"; | import dialogService from "../services/dialog.js"; | ||||||
| import server from "../services/server.js"; | import server from "../services/server.js"; | ||||||
| import { t } from '../services/i18n.js'; | import { t } from '../services/i18n.js'; | ||||||
|  | import type { SelectMenuItemEventListener } from '../components/events.js'; | ||||||
|  | import NoteTreeWidget from '../widgets/note_tree.js'; | ||||||
| 
 | 
 | ||||||
| export default class LauncherContextMenu { | interface ShowContext { | ||||||
|     /** |     pageX: number; | ||||||
|      * @param {NoteTreeWidget} treeWidget |     pageY: number; | ||||||
|      * @param {FancytreeNode} node | } | ||||||
|      */ | 
 | ||||||
|     constructor(treeWidget, node) { | export default class LauncherContextMenu implements SelectMenuItemEventListener { | ||||||
|  | 
 | ||||||
|  |     private treeWidget: NoteTreeWidget; | ||||||
|  |     private node: Node; | ||||||
|  | 
 | ||||||
|  |     constructor(treeWidget: NoteTreeWidget, node: Node) { | ||||||
|         this.treeWidget = treeWidget; |         this.treeWidget = treeWidget; | ||||||
|         this.node = node; |         this.node = node; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     async show(e) { |     async show(e: ShowContext) { | ||||||
|         contextMenu.show({ |         contextMenu.show({ | ||||||
|             x: e.pageX, |             x: e.pageX, | ||||||
|             y: e.pageY, |             y: e.pageY, | ||||||
| @ -24,17 +31,17 @@ export default class LauncherContextMenu { | |||||||
|         }) |         }) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     async getMenuItems() { |     async getMenuItems(): Promise<MenuItem[]> { | ||||||
|         const note = await froca.getNote(this.node.data.noteId); |         const note = this.node.data.noteId ? await froca.getNote(this.node.data.noteId) : null; | ||||||
|         const parentNoteId = this.node.getParent().data.noteId; |         const parentNoteId = this.node.getParent().data.noteId; | ||||||
| 
 | 
 | ||||||
|         const isVisibleRoot = note.noteId === '_lbVisibleLaunchers'; |         const isVisibleRoot = note?.noteId === '_lbVisibleLaunchers'; | ||||||
|         const isAvailableRoot = note.noteId === '_lbAvailableLaunchers'; |         const isAvailableRoot = note?.noteId === '_lbAvailableLaunchers'; | ||||||
|         const isVisibleItem = parentNoteId === '_lbVisibleLaunchers'; |         const isVisibleItem = parentNoteId === '_lbVisibleLaunchers'; | ||||||
|         const isAvailableItem = parentNoteId === '_lbAvailableLaunchers'; |         const isAvailableItem = parentNoteId === '_lbAvailableLaunchers'; | ||||||
|         const isItem = isVisibleItem || isAvailableItem; |         const isItem = isVisibleItem || isAvailableItem; | ||||||
|         const canBeDeleted = !note.noteId.startsWith("_"); // fixed notes can't be deleted
 |         const canBeDeleted = !note?.noteId.startsWith("_"); // fixed notes can't be deleted
 | ||||||
|         const canBeReset = !canBeDeleted && note.isLaunchBarConfig(); |         const canBeReset = !canBeDeleted && note?.isLaunchBarConfig(); | ||||||
| 
 | 
 | ||||||
|         return [ |         return [ | ||||||
|             (isVisibleRoot || isAvailableRoot) ? { title: t("launcher_context_menu.add-note-launcher"), command: 'addNoteLauncher', uiIcon: "bx bx-note" } : null, |             (isVisibleRoot || isAvailableRoot) ? { title: t("launcher_context_menu.add-note-launcher"), command: 'addNoteLauncher', uiIcon: "bx bx-note" } : null, | ||||||
| @ -49,14 +56,18 @@ export default class LauncherContextMenu { | |||||||
| 
 | 
 | ||||||
|             { title: `${t("launcher_context_menu.duplicate-launcher")} <kbd data-command="duplicateSubtree">`, command: "duplicateSubtree", uiIcon: "bx bx-outline", enabled: isItem }, |             { title: `${t("launcher_context_menu.duplicate-launcher")} <kbd data-command="duplicateSubtree">`, command: "duplicateSubtree", uiIcon: "bx bx-outline", enabled: isItem }, | ||||||
|             { title: `${t("launcher_context_menu.delete")} <kbd data-command="deleteNotes"></kbd>`, command: "deleteNotes", uiIcon: "bx bx-trash destructive-action-icon", enabled: canBeDeleted }, |             { title: `${t("launcher_context_menu.delete")} <kbd data-command="deleteNotes"></kbd>`, command: "deleteNotes", uiIcon: "bx bx-trash destructive-action-icon", enabled: canBeDeleted }, | ||||||
|             | 
 | ||||||
|             { title: "----" }, |             { title: "----" }, | ||||||
|             | 
 | ||||||
|             { title: t("launcher_context_menu.reset"), command: "resetLauncher", uiIcon: "bx bx-reset destructive-action-icon", enabled: canBeReset} |             { title: t("launcher_context_menu.reset"), command: "resetLauncher", uiIcon: "bx bx-reset destructive-action-icon", enabled: canBeReset} | ||||||
|         ].filter(row => row !== null); |         ].filter(row => row !== null); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     async selectMenuItemHandler({command}) { |     async selectMenuItemHandler({command}: MenuCommandItem) { | ||||||
|  |         if (!command) { | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|         if (command === 'resetLauncher') { |         if (command === 'resetLauncher') { | ||||||
|             const confirmed = await dialogService.confirm(t("launcher_context_menu.reset_launcher_confirm", { title: this.node.title })); |             const confirmed = await dialogService.confirm(t("launcher_context_menu.reset_launcher_confirm", { title: this.node.title })); | ||||||
| 
 | 
 | ||||||
| @ -5,6 +5,7 @@ import hoistedNoteService from '../services/hoisted_note.js'; | |||||||
| import appContext from "../components/app_context.js"; | import appContext from "../components/app_context.js"; | ||||||
| 
 | 
 | ||||||
| export interface Node { | export interface Node { | ||||||
|  |     title: string; | ||||||
|     getParent(): Node; |     getParent(): Node; | ||||||
|     getChildren(): Node[]; |     getChildren(): Node[]; | ||||||
|     folder: boolean; |     folder: boolean; | ||||||
| @ -85,8 +86,8 @@ async function resolveNotePathToSegments(notePath: string, hoistedNoteId = 'root | |||||||
|                 if (logErrors) { |                 if (logErrors) { | ||||||
|                     const parent = froca.getNoteFromCache(parentNoteId); |                     const parent = froca.getNoteFromCache(parentNoteId); | ||||||
| 
 | 
 | ||||||
|                     console.debug(utils.now(), `Did not find parent ${parentNoteId} (${parent ? parent.title : 'n/a'}) 
 |                     console.debug(utils.now(), `Did not find parent ${parentNoteId} (${parent ? parent.title : 'n/a'})
 | ||||||
|                         for child ${childNoteId} (${child.title}), available parents: ${parents.map(p => `${p.noteId} (${p.title})`)}.  |                         for child ${childNoteId} (${child.title}), available parents: ${parents.map(p => `${p.noteId} (${p.title})`)}. | ||||||
|                         You can ignore this message as it is mostly harmless.`);
 |                         You can ignore this message as it is mostly harmless.`);
 | ||||||
|                 } |                 } | ||||||
| 
 | 
 | ||||||
| @ -294,7 +295,7 @@ async function getNoteTitleWithPathAsSuffix(notePath: string) { | |||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|     $titleWithPath.append(formatNotePath(path)); |     $titleWithPath.append(formatNotePath(path)); | ||||||
|      | 
 | ||||||
|     return $titleWithPath; |     return $titleWithPath; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -302,12 +303,12 @@ function formatNotePath(path: string[]) { | |||||||
|     const $notePath = $('<span class="note-path">'); |     const $notePath = $('<span class="note-path">'); | ||||||
| 
 | 
 | ||||||
|     if (path.length > 0) { |     if (path.length > 0) { | ||||||
|          | 
 | ||||||
|         $notePath.append($(`<span class="path-bracket"> (</span>)`)); |         $notePath.append($(`<span class="path-bracket"> (</span>)`)); | ||||||
| 
 | 
 | ||||||
|         for (let segmentIndex = 0; segmentIndex < path.length; segmentIndex++) { |         for (let segmentIndex = 0; segmentIndex < path.length; segmentIndex++) { | ||||||
|             $notePath.append($(`<span>`).text(path[segmentIndex])); |             $notePath.append($(`<span>`).text(path[segmentIndex])); | ||||||
|              | 
 | ||||||
|             if (segmentIndex < path.length - 1) { |             if (segmentIndex < path.length - 1) { | ||||||
|                 $notePath.append($(`<span class="path-delimiter">`).text(" / ")); |                 $notePath.append($(`<span class="path-delimiter">`).text(" / ")); | ||||||
|             } |             } | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Elian Doran
						Elian Doran