mirror of
https://github.com/zadam/trilium.git
synced 2025-03-01 14:22:32 +01:00
import WIP
This commit is contained in:
parent
626af84f42
commit
ff5d3a5f0c
@ -75,6 +75,7 @@ import CodeButtonsWidget from "../widgets/floating_buttons/code_buttons.js";
|
||||
import ApiLogWidget from "../widgets/api_log.js";
|
||||
import HideFloatingButtonsButton from "../widgets/floating_buttons/hide_floating_buttons_button.js";
|
||||
import ScriptExecutorWidget from "../widgets/ribbon_widgets/script_executor.js";
|
||||
import UploadAttachmentsDialog from "../widgets/dialogs/upload_attachments.js";
|
||||
|
||||
export default class DesktopLayout {
|
||||
constructor(customWidgets) {
|
||||
@ -200,6 +201,7 @@ export default class DesktopLayout {
|
||||
.child(new MoveToDialog())
|
||||
.child(new ImportDialog())
|
||||
.child(new ExportDialog())
|
||||
.child(new UploadAttachmentsDialog())
|
||||
.child(new MarkdownImportDialog())
|
||||
.child(new ProtectedSessionPasswordDialog())
|
||||
.child(new NoteRevisionsDialog())
|
||||
|
@ -182,7 +182,7 @@ function makeToast(id, message) {
|
||||
}
|
||||
|
||||
ws.subscribeToMessages(async message => {
|
||||
if (message.taskType !== 'delete-notes') {
|
||||
if (message.taskType !== 'deleteNotes') {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -54,7 +54,7 @@ function makeToast(id, message) {
|
||||
}
|
||||
|
||||
ws.subscribeToMessages(async message => {
|
||||
if (message.taskType !== 'import') {
|
||||
if (message.taskType !== 'importNotes') {
|
||||
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 {
|
||||
uploadFiles
|
||||
};
|
||||
|
@ -21,7 +21,7 @@ const TPL = `
|
||||
|
||||
<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 class="form-group">
|
||||
|
@ -9,7 +9,7 @@ const TPL = `
|
||||
<div class="modal-dialog modal-lg" role="document">
|
||||
<div class="modal-content">
|
||||
<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">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
@ -21,7 +21,7 @@ const TPL = `
|
||||
|
||||
<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 class="form-group">
|
||||
|
@ -67,6 +67,8 @@ export default class AttachmentDetailTypeWidget extends TypeWidget {
|
||||
async entitiesReloadedEvent({loadResults}) {
|
||||
const attachmentChange = loadResults.getAttachments().find(att => att.attachmentId === this.attachmentId);
|
||||
|
||||
console.log(attachmentChange);
|
||||
|
||||
if (attachmentChange?.isDeleted) {
|
||||
this.refresh(); // all other updates are handled within AttachmentDetailWidget
|
||||
}
|
||||
|
@ -13,6 +13,8 @@ const TPL = `
|
||||
.attachment-list .links-wrapper {
|
||||
font-size: larger;
|
||||
margin-bottom: 15px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -36,9 +38,11 @@ export default class AttachmentListTypeWidget extends TypeWidget {
|
||||
|
||||
async doRefresh(note) {
|
||||
this.$linksWrapper.append(
|
||||
"Owning note: ",
|
||||
await linkService.createNoteLink(this.noteId),
|
||||
$('<button class="btn btn-sm">')
|
||||
$('<div>').append(
|
||||
"Owning note: ",
|
||||
await linkService.createNoteLink(this.noteId),
|
||||
),
|
||||
$('<button class="btn btn-xs">')
|
||||
.text("Upload attachments")
|
||||
.on('click', () => this.triggerCommand("showUploadAttachmentsDialog", {noteId: this.noteId}))
|
||||
);
|
||||
|
@ -185,7 +185,7 @@ function deleteBranch(req) {
|
||||
const eraseNotes = req.query.eraseNotes === 'true';
|
||||
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);
|
||||
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
|
||||
|
||||
const taskContext = TaskContext.getInstance(taskId, 'import', options);
|
||||
const taskContext = TaskContext.getInstance(taskId, 'importNotes', options);
|
||||
|
||||
try {
|
||||
if (extension === '.zip' && options.explodeArchives) {
|
||||
@ -95,22 +95,12 @@ async function importAttachmentsToNote(req) {
|
||||
}
|
||||
|
||||
const parentNote = becca.getNoteOrThrow(parentNoteId);
|
||||
const taskContext = TaskContext.getInstance(taskId, 'importAttachment', options);
|
||||
|
||||
// running all the event handlers on imported notes (and attributes) is slow
|
||||
// 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);
|
||||
// unlike in note import we let the events run, because a huge number of attachments is not likely
|
||||
|
||||
try {
|
||||
// FIXME
|
||||
|
||||
note = await singleImportService.importSingleFile(taskContext, file, parentNote);
|
||||
await singleImportService.importAttachment(taskContext, file, parentNote);
|
||||
}
|
||||
catch (e) {
|
||||
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") {
|
||||
// small timeout to avoid race condition (the message is received before the transaction is committed)
|
||||
setTimeout(() => taskContext.taskSucceeded({
|
||||
parentNoteId: parentNoteId,
|
||||
importedNoteId: note.noteId
|
||||
parentNoteId: parentNoteId
|
||||
}), 1000);
|
||||
}
|
||||
|
||||
// import has deactivated note events so becca is not updated, instead we force it to reload
|
||||
beccaLoader.load();
|
||||
|
||||
return note.getPojo();
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
|
@ -62,7 +62,7 @@ function deleteNote(req) {
|
||||
|
||||
const note = becca.getNote(noteId);
|
||||
|
||||
const taskContext = TaskContext.getInstance(taskId, 'delete-notes');
|
||||
const taskContext = TaskContext.getInstance(taskId, 'deleteNotes');
|
||||
|
||||
note.deleteNote(deleteId, taskContext);
|
||||
|
||||
|
@ -10,7 +10,7 @@ const cls = require('../services/cls');
|
||||
const sql = require('../services/sql');
|
||||
const entityChangesService = require('../services/entity_changes');
|
||||
const csurf = require('csurf');
|
||||
const {createPartialContentHandler} = require("express-partial-content");
|
||||
const { createPartialContentHandler } = require("express-partial-content");
|
||||
const rateLimit = require("express-rate-limit");
|
||||
const AbstractBeccaEntity = require("../becca/entities/abstract_becca_entity");
|
||||
const NotFoundError = require("../errors/not_found_error");
|
||||
@ -71,7 +71,7 @@ const etapiSpecRoute = require('../etapi/spec');
|
||||
|
||||
const csrfMiddleware = csurf({
|
||||
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;
|
||||
|
@ -178,6 +178,34 @@ function importHtml(taskContext, file, parentNote) {
|
||||
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 = {
|
||||
importSingleFile
|
||||
importSingleFile,
|
||||
importAttachment
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user