mirror of
				https://github.com/zadam/trilium.git
				synced 2025-10-31 18:36:30 +01:00 
			
		
		
		
	chore(client/ts): port services/note_create
This commit is contained in:
		| @@ -56,6 +56,9 @@ export type TriggerData = { | |||||||
|     entityId: string; |     entityId: string; | ||||||
|     lastModifiedMs: number; |     lastModifiedMs: number; | ||||||
|     filePath: string; |     filePath: string; | ||||||
|  | } | { | ||||||
|  |     // For "focusAndSelectTitle" | ||||||
|  |     isNewNote: boolean; | ||||||
| } | } | ||||||
|     | PromptDialogOptions    // For "showPromptDialog" |     | PromptDialogOptions    // For "showPromptDialog" | ||||||
|     | ConfirmWithMessageOptions   // For "showConfirmDialog" |     | ConfirmWithMessageOptions   // For "showConfirmDialog" | ||||||
|   | |||||||
| @@ -6,8 +6,41 @@ import froca from "./froca.js"; | |||||||
| import treeService from "./tree.js"; | import treeService from "./tree.js"; | ||||||
| import toastService from "./toast.js"; | import toastService from "./toast.js"; | ||||||
| import { t } from "./i18n.js"; | import { t } from "./i18n.js"; | ||||||
|  | import FNote from "../entities/fnote.js"; | ||||||
|  | import FBranch from "../entities/fbranch.js"; | ||||||
|  | import { ChooseNoteTypeResponse } from "../widgets/dialogs/note_type_chooser.js"; | ||||||
| 
 | 
 | ||||||
| async function createNote(parentNotePath, options = {}) { | interface CreateNoteOpts { | ||||||
|  |     isProtected?: boolean; | ||||||
|  |     saveSelection?: boolean; | ||||||
|  |     title?: string | null; | ||||||
|  |     content?: string | null; | ||||||
|  |     type?: string; | ||||||
|  |     mime?: string; | ||||||
|  |     templateNoteId?: string; | ||||||
|  |     activate?: boolean; | ||||||
|  |     focus?: "title" | "content"; | ||||||
|  |     target?: string; | ||||||
|  |     targetBranchId?: string; | ||||||
|  |     textEditor?: { | ||||||
|  |         // TODO: Replace with interface once note_context.js is converted.
 | ||||||
|  |         getSelectedHtml(): string; | ||||||
|  |         removeSelection(): void; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | interface Response { | ||||||
|  |     // TODO: Deduplicate with server once we have client/server architecture.
 | ||||||
|  |     note: FNote; | ||||||
|  |     branch: FBranch; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | interface DuplicateResponse { | ||||||
|  |     // TODO: Deduplicate with server once we have client/server architecture.
 | ||||||
|  |     note: FNote; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | async function createNote(parentNotePath: string, options: CreateNoteOpts = {}) { | ||||||
|     options = Object.assign({ |     options = Object.assign({ | ||||||
|         activate: true, |         activate: true, | ||||||
|         focus: 'title', |         focus: 'title', | ||||||
| @@ -24,7 +57,7 @@ async function createNote(parentNotePath, options = {}) { | |||||||
|         options.saveSelection = false; |         options.saveSelection = false; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if (options.saveSelection) { |     if (options.saveSelection && options.textEditor) {         | ||||||
|         [options.title, options.content] = parseSelectedHtml(options.textEditor.getSelectedHtml()); |         [options.title, options.content] = parseSelectedHtml(options.textEditor.getSelectedHtml()); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @@ -38,7 +71,7 @@ async function createNote(parentNotePath, options = {}) { | |||||||
|     C-->D;` |     C-->D;` | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     const {note, branch} = await server.post(`notes/${parentNoteId}/children?target=${options.target}&targetBranchId=${options.targetBranchId || ""}`, { |     const {note, branch} = await server.post<Response>(`notes/${parentNoteId}/children?target=${options.target}&targetBranchId=${options.targetBranchId || ""}`, { | ||||||
|         title: options.title, |         title: options.title, | ||||||
|         content: options.content || "", |         content: options.content || "", | ||||||
|         isProtected: options.isProtected, |         isProtected: options.isProtected, | ||||||
| @@ -49,7 +82,7 @@ async function createNote(parentNotePath, options = {}) { | |||||||
| 
 | 
 | ||||||
|     if (options.saveSelection) { |     if (options.saveSelection) { | ||||||
|         // we remove the selection only after it was saved to server to make sure we don't lose anything
 |         // we remove the selection only after it was saved to server to make sure we don't lose anything
 | ||||||
|         options.textEditor.removeSelection(); |         options.textEditor?.removeSelection(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     await ws.waitForMaxKnownEntityChangeId(); |     await ws.waitForMaxKnownEntityChangeId(); | ||||||
| @@ -76,12 +109,14 @@ async function createNote(parentNotePath, options = {}) { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| async function chooseNoteType() { | async function chooseNoteType() { | ||||||
|     return new Promise(res => { |     return new Promise<ChooseNoteTypeResponse>(res => { | ||||||
|  |         // TODO: Remove ignore after callback for chooseNoteType is defined in app_context.ts
 | ||||||
|  |         //@ts-ignore
 | ||||||
|         appContext.triggerCommand("chooseNoteType", {callback: res}); |         appContext.triggerCommand("chooseNoteType", {callback: res}); | ||||||
|     }); |     }); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| async function createNoteWithTypePrompt(parentNotePath, options = {}) { | async function createNoteWithTypePrompt(parentNotePath: string, options: CreateNoteOpts = {}) { | ||||||
|     const {success, noteType, templateNoteId} = await chooseNoteType(); |     const {success, noteType, templateNoteId} = await chooseNoteType(); | ||||||
| 
 | 
 | ||||||
|     if (!success) { |     if (!success) { | ||||||
| @@ -95,12 +130,16 @@ async function createNoteWithTypePrompt(parentNotePath, options = {}) { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* If the first element is heading, parse it out and use it as a new heading. */ | /* If the first element is heading, parse it out and use it as a new heading. */ | ||||||
| function parseSelectedHtml(selectedHtml) { | function parseSelectedHtml(selectedHtml: string) { | ||||||
|     const dom = $.parseHTML(selectedHtml); |     const dom = $.parseHTML(selectedHtml); | ||||||
| 
 | 
 | ||||||
|  |     // TODO: tagName and outerHTML appear to be missing.
 | ||||||
|  |     //@ts-ignore
 | ||||||
|     if (dom.length > 0 && dom[0].tagName && dom[0].tagName.match(/h[1-6]/i)) { |     if (dom.length > 0 && dom[0].tagName && dom[0].tagName.match(/h[1-6]/i)) { | ||||||
|         const title = $(dom[0]).text(); |         const title = $(dom[0]).text(); | ||||||
|         // remove the title from content (only first occurrence)
 |         // remove the title from content (only first occurrence)
 | ||||||
|  |         // TODO: tagName and outerHTML appear to be missing.
 | ||||||
|  |         //@ts-ignore
 | ||||||
|         const content = selectedHtml.replace(dom[0].outerHTML, ""); |         const content = selectedHtml.replace(dom[0].outerHTML, ""); | ||||||
| 
 | 
 | ||||||
|         return [title, content]; |         return [title, content]; | ||||||
| @@ -110,9 +149,9 @@ function parseSelectedHtml(selectedHtml) { | |||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| async function duplicateSubtree(noteId, parentNotePath) { | async function duplicateSubtree(noteId: string, parentNotePath: string) { | ||||||
|     const parentNoteId = treeService.getNoteIdFromUrl(parentNotePath); |     const parentNoteId = treeService.getNoteIdFromUrl(parentNotePath); | ||||||
|     const {note} = await server.post(`notes/${noteId}/duplicate/${parentNoteId}`); |     const {note} = await server.post<DuplicateResponse>(`notes/${noteId}/duplicate/${parentNoteId}`); | ||||||
| 
 | 
 | ||||||
|     await ws.waitForMaxKnownEntityChangeId(); |     await ws.waitForMaxKnownEntityChangeId(); | ||||||
| 
 | 
 | ||||||
| @@ -120,7 +159,7 @@ async function duplicateSubtree(noteId, parentNotePath) { | |||||||
|     activeNoteContext.setNote(`${parentNotePath}/${note.noteId}`); |     activeNoteContext.setNote(`${parentNotePath}/${note.noteId}`); | ||||||
| 
 | 
 | ||||||
|     const origNote = await froca.getNote(noteId); |     const origNote = await froca.getNote(noteId); | ||||||
|     toastService.showMessage(t("note_create.duplicated", { title: origNote.title })); |     toastService.showMessage(t("note_create.duplicated", { title: origNote?.title })); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export default { | export default { | ||||||
| @@ -41,13 +41,13 @@ const TPL = ` | |||||||
|     </div> |     </div> | ||||||
| </div>`; | </div>`; | ||||||
|  |  | ||||||
| interface CallbackData { | export interface ChooseNoteTypeResponse { | ||||||
|     success: boolean; |     success: boolean; | ||||||
|     noteType?: string; |     noteType?: string; | ||||||
|     templateNoteId?: string; |     templateNoteId?: string; | ||||||
| } | } | ||||||
|  |  | ||||||
| type Callback = (data: CallbackData) => void; | type Callback = (data: ChooseNoteTypeResponse) => void; | ||||||
|  |  | ||||||
| export default class NoteTypeChooserDialog extends BasicWidget { | export default class NoteTypeChooserDialog extends BasicWidget { | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user