import WIP

This commit is contained in:
zadam 2023-05-09 00:05:27 +02:00
parent 626af84f42
commit ff5d3a5f0c
12 changed files with 80 additions and 34 deletions

View File

@ -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())

View File

@ -182,7 +182,7 @@ function makeToast(id, message) {
}
ws.subscribeToMessages(async message => {
if (message.taskType !== 'delete-notes') {
if (message.taskType !== 'deleteNotes') {
return;
}

View File

@ -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
};

View File

@ -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">

View File

@ -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">&times;</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">

View File

@ -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
}

View File

@ -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}))
);

View File

@ -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;

View File

@ -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 = {

View File

@ -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);

View File

@ -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;

View File

@ -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
};