mirror of
				https://github.com/zadam/trilium.git
				synced 2025-10-31 10:26:08 +01:00 
			
		
		
		
	import WIP
This commit is contained in:
		| @@ -75,6 +75,7 @@ import CodeButtonsWidget from "../widgets/floating_buttons/code_buttons.js"; | |||||||
| import ApiLogWidget from "../widgets/api_log.js"; | import ApiLogWidget from "../widgets/api_log.js"; | ||||||
| import HideFloatingButtonsButton from "../widgets/floating_buttons/hide_floating_buttons_button.js"; | import HideFloatingButtonsButton from "../widgets/floating_buttons/hide_floating_buttons_button.js"; | ||||||
| import ScriptExecutorWidget from "../widgets/ribbon_widgets/script_executor.js"; | import ScriptExecutorWidget from "../widgets/ribbon_widgets/script_executor.js"; | ||||||
|  | import UploadAttachmentsDialog from "../widgets/dialogs/upload_attachments.js"; | ||||||
|  |  | ||||||
| export default class DesktopLayout { | export default class DesktopLayout { | ||||||
|     constructor(customWidgets) { |     constructor(customWidgets) { | ||||||
| @@ -200,6 +201,7 @@ export default class DesktopLayout { | |||||||
|             .child(new MoveToDialog()) |             .child(new MoveToDialog()) | ||||||
|             .child(new ImportDialog()) |             .child(new ImportDialog()) | ||||||
|             .child(new ExportDialog()) |             .child(new ExportDialog()) | ||||||
|  |             .child(new UploadAttachmentsDialog()) | ||||||
|             .child(new MarkdownImportDialog()) |             .child(new MarkdownImportDialog()) | ||||||
|             .child(new ProtectedSessionPasswordDialog()) |             .child(new ProtectedSessionPasswordDialog()) | ||||||
|             .child(new NoteRevisionsDialog()) |             .child(new NoteRevisionsDialog()) | ||||||
|   | |||||||
| @@ -182,7 +182,7 @@ function makeToast(id, message) { | |||||||
| } | } | ||||||
|  |  | ||||||
| ws.subscribeToMessages(async message => { | ws.subscribeToMessages(async message => { | ||||||
|     if (message.taskType !== 'delete-notes') { |     if (message.taskType !== 'deleteNotes') { | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -54,7 +54,7 @@ function makeToast(id, message) { | |||||||
| } | } | ||||||
|  |  | ||||||
| ws.subscribeToMessages(async message => { | ws.subscribeToMessages(async message => { | ||||||
|     if (message.taskType !== 'import') { |     if (message.taskType !== 'importNotes') { | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -75,6 +75,32 @@ ws.subscribeToMessages(async message => { | |||||||
|     } |     } | ||||||
| }); | }); | ||||||
|  |  | ||||||
|  | ws.subscribeToMessages(async message => { | ||||||
|  |     if (message.taskType !== 'importAttachments') { | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     if (message.type === 'taskError') { | ||||||
|  |         toastService.closePersistent(message.taskId); | ||||||
|  |         toastService.showError(message.message); | ||||||
|  |     } else if (message.type === 'taskProgressCount') { | ||||||
|  |         toastService.showPersistent(makeToast(message.taskId, `Import in progress: ${message.progressCount}`)); | ||||||
|  |     } else if (message.type === 'taskSucceeded') { | ||||||
|  |         const toast = makeToast(message.taskId, "Import finished successfully."); | ||||||
|  |         toast.closeAfter = 5000; | ||||||
|  |  | ||||||
|  |         toastService.showPersistent(toast); | ||||||
|  |  | ||||||
|  |         if (message.result.parentNoteId) { | ||||||
|  |             await appContext.tabManager.getActiveContext().setNote(message.result.importedNoteId, { | ||||||
|  |                 viewScope: { | ||||||
|  |                     viewMode: 'attachments' | ||||||
|  |                 } | ||||||
|  |             }); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | }); | ||||||
|  |  | ||||||
| export default { | export default { | ||||||
|     uploadFiles |     uploadFiles | ||||||
| }; | }; | ||||||
|   | |||||||
| @@ -21,7 +21,7 @@ const TPL = ` | |||||||
|  |  | ||||||
|                         <input type="file" class="import-file-upload-input form-control-file" multiple /> |                         <input type="file" class="import-file-upload-input form-control-file" multiple /> | ||||||
|  |  | ||||||
|                         <p>Content of the file will be imported as child note(s) into <strong class="import-note-title"></strong>. |                         <p>Content of the selected file(s) will be imported as child note(s) into <strong class="import-note-title"></strong>. | ||||||
|                     </div> |                     </div> | ||||||
|  |  | ||||||
|                     <div class="form-group"> |                     <div class="form-group"> | ||||||
|   | |||||||
| @@ -9,7 +9,7 @@ const TPL = ` | |||||||
|     <div class="modal-dialog modal-lg" role="document"> |     <div class="modal-dialog modal-lg" role="document"> | ||||||
|         <div class="modal-content"> |         <div class="modal-content"> | ||||||
|             <div class="modal-header"> |             <div class="modal-header"> | ||||||
|                 <h5 class="modal-title">Import into note</h5> |                 <h5 class="modal-title">Upload attachments to note</h5> | ||||||
|                 <button type="button" class="close" data-dismiss="modal" aria-label="Close"> |                 <button type="button" class="close" data-dismiss="modal" aria-label="Close"> | ||||||
|                     <span aria-hidden="true">×</span> |                     <span aria-hidden="true">×</span> | ||||||
|                 </button> |                 </button> | ||||||
| @@ -21,7 +21,7 @@ const TPL = ` | |||||||
|  |  | ||||||
|                         <input type="file" class="upload-attachment-file-upload-input form-control-file" multiple /> |                         <input type="file" class="upload-attachment-file-upload-input form-control-file" multiple /> | ||||||
|  |  | ||||||
|                         <p>Content of the file will be imported as child note(s) into <strong class="upload-attachment-note-title"></strong>. |                         <p>Files will be uploaded as attachments into <strong class="upload-attachment-note-title"></strong>. | ||||||
|                     </div> |                     </div> | ||||||
|  |  | ||||||
|                     <div class="form-group"> |                     <div class="form-group"> | ||||||
|   | |||||||
| @@ -67,6 +67,8 @@ export default class AttachmentDetailTypeWidget extends TypeWidget { | |||||||
|     async entitiesReloadedEvent({loadResults}) { |     async entitiesReloadedEvent({loadResults}) { | ||||||
|         const attachmentChange = loadResults.getAttachments().find(att => att.attachmentId === this.attachmentId); |         const attachmentChange = loadResults.getAttachments().find(att => att.attachmentId === this.attachmentId); | ||||||
|  |  | ||||||
|  |         console.log(attachmentChange); | ||||||
|  |  | ||||||
|         if (attachmentChange?.isDeleted) { |         if (attachmentChange?.isDeleted) { | ||||||
|             this.refresh(); // all other updates are handled within AttachmentDetailWidget |             this.refresh(); // all other updates are handled within AttachmentDetailWidget | ||||||
|         } |         } | ||||||
|   | |||||||
| @@ -13,6 +13,8 @@ const TPL = ` | |||||||
|         .attachment-list .links-wrapper { |         .attachment-list .links-wrapper { | ||||||
|             font-size: larger; |             font-size: larger; | ||||||
|             margin-bottom: 15px; |             margin-bottom: 15px; | ||||||
|  |             display: flex; | ||||||
|  |             justify-content: space-between; | ||||||
|         } |         } | ||||||
|     </style> |     </style> | ||||||
|      |      | ||||||
| @@ -36,9 +38,11 @@ export default class AttachmentListTypeWidget extends TypeWidget { | |||||||
|  |  | ||||||
|     async doRefresh(note) { |     async doRefresh(note) { | ||||||
|         this.$linksWrapper.append( |         this.$linksWrapper.append( | ||||||
|  |             $('<div>').append( | ||||||
|                 "Owning note: ", |                 "Owning note: ", | ||||||
|                 await linkService.createNoteLink(this.noteId), |                 await linkService.createNoteLink(this.noteId), | ||||||
|             $('<button class="btn btn-sm">') |             ), | ||||||
|  |             $('<button class="btn btn-xs">') | ||||||
|                 .text("Upload attachments") |                 .text("Upload attachments") | ||||||
|                 .on('click', () => this.triggerCommand("showUploadAttachmentsDialog", {noteId: this.noteId})) |                 .on('click', () => this.triggerCommand("showUploadAttachmentsDialog", {noteId: this.noteId})) | ||||||
|         ); |         ); | ||||||
|   | |||||||
| @@ -185,7 +185,7 @@ function deleteBranch(req) { | |||||||
|     const eraseNotes = req.query.eraseNotes === 'true'; |     const eraseNotes = req.query.eraseNotes === 'true'; | ||||||
|     const branch = becca.getBranchOrThrow(req.params.branchId); |     const branch = becca.getBranchOrThrow(req.params.branchId); | ||||||
|  |  | ||||||
|     const taskContext = TaskContext.getInstance(req.query.taskId, 'delete-notes'); |     const taskContext = TaskContext.getInstance(req.query.taskId, 'deleteNotes'); | ||||||
|  |  | ||||||
|     const deleteId = utils.randomString(10); |     const deleteId = utils.randomString(10); | ||||||
|     let noteDeleted; |     let noteDeleted; | ||||||
|   | |||||||
| @@ -44,7 +44,7 @@ async function importNotesToBranch(req) { | |||||||
|  |  | ||||||
|     let note; // typically root of the import - client can show it after finishing the import |     let note; // typically root of the import - client can show it after finishing the import | ||||||
|  |  | ||||||
|     const taskContext = TaskContext.getInstance(taskId, 'import', options); |     const taskContext = TaskContext.getInstance(taskId, 'importNotes', options); | ||||||
|  |  | ||||||
|     try { |     try { | ||||||
|         if (extension === '.zip' && options.explodeArchives) { |         if (extension === '.zip' && options.explodeArchives) { | ||||||
| @@ -95,22 +95,12 @@ async function importAttachmentsToNote(req) { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     const parentNote = becca.getNoteOrThrow(parentNoteId); |     const parentNote = becca.getNoteOrThrow(parentNoteId); | ||||||
|  |     const taskContext = TaskContext.getInstance(taskId, 'importAttachment', options); | ||||||
|  |  | ||||||
|     // running all the event handlers on imported notes (and attributes) is slow |     // unlike in note import we let the events run, because a huge number of attachments is not likely | ||||||
|     // and may produce unintended consequences |  | ||||||
|     cls.disableEntityEvents(); |  | ||||||
|  |  | ||||||
|     // eliminate flickering during import |  | ||||||
|     cls.ignoreEntityChangeIds(); |  | ||||||
|  |  | ||||||
|     let note; // typically root of the import - client can show it after finishing the import |  | ||||||
|  |  | ||||||
|     const taskContext = TaskContext.getInstance(taskId, 'import', options); |  | ||||||
|  |  | ||||||
|     try { |     try { | ||||||
|         // FIXME |         await singleImportService.importAttachment(taskContext, file, parentNote); | ||||||
|  |  | ||||||
|         note = await singleImportService.importSingleFile(taskContext, file, parentNote); |  | ||||||
|     } |     } | ||||||
|     catch (e) { |     catch (e) { | ||||||
|         const message = `Import failed with following error: '${e.message}'. More details might be in the logs.`; |         const message = `Import failed with following error: '${e.message}'. More details might be in the logs.`; | ||||||
| @@ -124,15 +114,9 @@ async function importAttachmentsToNote(req) { | |||||||
|     if (last === "true") { |     if (last === "true") { | ||||||
|         // small timeout to avoid race condition (the message is received before the transaction is committed) |         // small timeout to avoid race condition (the message is received before the transaction is committed) | ||||||
|         setTimeout(() => taskContext.taskSucceeded({ |         setTimeout(() => taskContext.taskSucceeded({ | ||||||
|             parentNoteId: parentNoteId, |             parentNoteId: parentNoteId | ||||||
|             importedNoteId: note.noteId |  | ||||||
|         }), 1000); |         }), 1000); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     // import has deactivated note events so becca is not updated, instead we force it to reload |  | ||||||
|     beccaLoader.load(); |  | ||||||
|  |  | ||||||
|     return note.getPojo(); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| module.exports = { | module.exports = { | ||||||
|   | |||||||
| @@ -62,7 +62,7 @@ function deleteNote(req) { | |||||||
|  |  | ||||||
|     const note = becca.getNote(noteId); |     const note = becca.getNote(noteId); | ||||||
|  |  | ||||||
|     const taskContext = TaskContext.getInstance(taskId, 'delete-notes'); |     const taskContext = TaskContext.getInstance(taskId, 'deleteNotes'); | ||||||
|  |  | ||||||
|     note.deleteNote(deleteId, taskContext); |     note.deleteNote(deleteId, taskContext); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -71,7 +71,7 @@ const etapiSpecRoute = require('../etapi/spec'); | |||||||
|  |  | ||||||
| const csrfMiddleware = csurf({ | const csrfMiddleware = csurf({ | ||||||
|     cookie: true, |     cookie: true, | ||||||
|     path: '' // nothing so cookie is valid only for current path |     path: '' // empty, so cookie is valid only for the current path | ||||||
| }); | }); | ||||||
|  |  | ||||||
| const MAX_ALLOWED_FILE_SIZE_MB = 250; | const MAX_ALLOWED_FILE_SIZE_MB = 250; | ||||||
|   | |||||||
| @@ -178,6 +178,34 @@ function importHtml(taskContext, file, parentNote) { | |||||||
|     return note; |     return note; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * @param {TaskContext} taskContext | ||||||
|  |  * @param file | ||||||
|  |  * @param {BNote} parentNote | ||||||
|  |  * @returns {BNote} | ||||||
|  |  */ | ||||||
|  | function importAttachment(taskContext, file, parentNote) { | ||||||
|  |     const mime = mimeService.getMime(file.originalname) || file.mimetype; | ||||||
|  |  | ||||||
|  |     console.log("mime", mime); | ||||||
|  |  | ||||||
|  |     if (mime.startsWith("image/")) { | ||||||
|  |         imageService.saveImageToAttachment(parentNote.noteId, file.buffer, file.originalname, taskContext.data.shrinkImages); | ||||||
|  |  | ||||||
|  |         taskContext.increaseProgressCount(); | ||||||
|  |     } else { | ||||||
|  |         parentNote.saveAttachment({ | ||||||
|  |             title: file.originalname, | ||||||
|  |             content: file.buffer, | ||||||
|  |             role: 'file', | ||||||
|  |             mime: mime | ||||||
|  |         }); | ||||||
|  |  | ||||||
|  |         taskContext.increaseProgressCount(); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
| module.exports = { | module.exports = { | ||||||
|     importSingleFile |     importSingleFile, | ||||||
|  |     importAttachment | ||||||
| }; | }; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user