added "delete note revisions" search action

This commit is contained in:
zadam 2021-02-14 21:35:13 +01:00
parent 66c5606d46
commit cc4d04416b
6 changed files with 51 additions and 13 deletions

20
package-lock.json generated
View file

@ -1,6 +1,6 @@
{ {
"name": "trilium", "name": "trilium",
"version": "0.45.9", "version": "0.45.10",
"lockfileVersion": 1, "lockfileVersion": 1,
"requires": true, "requires": true,
"dependencies": { "dependencies": {
@ -2712,9 +2712,9 @@
} }
}, },
"electron-dl": { "electron-dl": {
"version": "3.0.2", "version": "3.0.3",
"resolved": "https://registry.npmjs.org/electron-dl/-/electron-dl-3.0.2.tgz", "resolved": "https://registry.npmjs.org/electron-dl/-/electron-dl-3.0.3.tgz",
"integrity": "sha512-pRgE9Jbhoo5z6Vk3qi+vIrfpMDlCp2oB1UeR96SMnsfz073jj0AZGQwp69EdIcEvlUlwBSGyJK8Jt6OB6JLn+g==", "integrity": "sha512-eh1zDc+cffWQ0wVjZj7YGSq5qSYsD2vxIeojJt2hoV0/2fOlLv57pqeRkVfrDrocVYRwAytphctunTXRKj1GmA==",
"requires": { "requires": {
"ext-name": "^5.0.0", "ext-name": "^5.0.0",
"pupa": "^2.0.1", "pupa": "^2.0.1",
@ -5180,9 +5180,9 @@
"integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg=="
}, },
"mime-db": { "mime-db": {
"version": "1.44.0", "version": "1.46.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.46.0.tgz",
"integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==" "integrity": "sha512-svXaP8UQRZ5K7or+ZmfNhg2xX3yKDMUzqadsSqi4NCH/KomcH75MAMYAGVlvXn4+b/xOPhS3I2uHKRUzvjY7BQ=="
}, },
"mime-types": { "mime-types": {
"version": "2.1.28", "version": "2.1.28",
@ -5656,9 +5656,9 @@
} }
}, },
"open": { "open": {
"version": "7.4.0", "version": "7.4.1",
"resolved": "https://registry.npmjs.org/open/-/open-7.4.0.tgz", "resolved": "https://registry.npmjs.org/open/-/open-7.4.1.tgz",
"integrity": "sha512-PGoBCX/lclIWlpS/R2PQuIR4NJoXh6X5AwVzE7WXnWRGvHg7+4TBCgsujUgiPpm0K1y4qvQeWnCWVTpTKZBtvA==", "integrity": "sha512-Pxv+fKRsd/Ozflgn2Gjev1HZveJJeKR6hKKmdaImJMuEZ6htAvCTbcMABJo+qevlAelTLCrEK3YTKZ9fVTcSPw==",
"requires": { "requires": {
"is-docker": "^2.0.0", "is-docker": "^2.0.0",
"is-wsl": "^2.1.1" "is-wsl": "^2.1.1"

View file

@ -35,7 +35,7 @@
"dayjs": "1.10.4", "dayjs": "1.10.4",
"ejs": "3.1.6", "ejs": "3.1.6",
"electron-debug": "3.2.0", "electron-debug": "3.2.0",
"electron-dl": "3.0.2", "electron-dl": "3.0.3",
"electron-find": "1.0.6", "electron-find": "1.0.6",
"electron-window-state": "5.0.3", "electron-window-state": "5.0.3",
"express": "4.17.1", "express": "4.17.1",
@ -55,7 +55,7 @@
"mime-types": "2.1.28", "mime-types": "2.1.28",
"multer": "1.4.2", "multer": "1.4.2",
"node-abi": "2.19.3", "node-abi": "2.19.3",
"open": "7.4.0", "open": "7.4.1",
"portscanner": "2.2.0", "portscanner": "2.2.0",
"rand-token": "1.0.1", "rand-token": "1.0.1",
"request": "^2.88.2", "request": "^2.88.2",

View file

@ -0,0 +1,28 @@
import AbstractSearchAction from "./abstract_search_action.js";
const TPL = `
<tr>
<td colspan="2">
<span class="bx bx-trash"></span>
Delete note revisions
</td>
<td class="button-column">
<div class="dropdown help-dropdown">
<span class="bx bx-help-circle icon-action" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"></span>
<div class="dropdown-menu dropdown-menu-right p-4">
All past note revisions of matched notes will be deleted. Note itself will be fully preserved. In other terms, note's history will be removed.
</div>
</div>
<span class="bx bx-x icon-action action-conf-del"></span>
</td>
</tr>`;
export default class DeleteNoteRevisionsSearchAction extends AbstractSearchAction {
static get actionName() { return "deleteNoteRevisions"; }
doRender() {
return $(TPL);
}
}

View file

@ -19,6 +19,7 @@ import IncludeArchivedNotes from "../search_options/include_archived_notes.js";
import OrderBy from "../search_options/order_by.js"; import OrderBy from "../search_options/order_by.js";
import SearchScript from "../search_options/search_script.js"; import SearchScript from "../search_options/search_script.js";
import Limit from "../search_options/limit.js"; import Limit from "../search_options/limit.js";
import DeleteNoteRevisionsSearchAction from "../search_actions/delete_note_revisions.js";
const TPL = ` const TPL = `
<div class="search-definition-widget"> <div class="search-definition-widget">
@ -120,6 +121,8 @@ const TPL = `
<div class="dropdown-menu"> <div class="dropdown-menu">
<a class="dropdown-item" href="#" data-action-add="deleteNote"> <a class="dropdown-item" href="#" data-action-add="deleteNote">
Delete note</a> Delete note</a>
<a class="dropdown-item" href="#" data-action-add="deleteNoteRevisions">
Delete note revisions</a>
<a class="dropdown-item" href="#" data-action-add="deleteLabel"> <a class="dropdown-item" href="#" data-action-add="deleteLabel">
Delete label</a> Delete label</a>
<a class="dropdown-item" href="#" data-action-add="deleteRelation"> <a class="dropdown-item" href="#" data-action-add="deleteRelation">
@ -177,6 +180,7 @@ const ACTION_CLASSES = {};
for (const clazz of [ for (const clazz of [
DeleteNoteSearchAction, DeleteNoteSearchAction,
DeleteNoteRevisionsSearchAction,
DeleteLabelSearchAction, DeleteLabelSearchAction,
DeleteRelationSearchAction, DeleteRelationSearchAction,
RenameLabelSearchAction, RenameLabelSearchAction,

View file

@ -5,6 +5,7 @@ const SearchContext = require('../../services/search/search_context.js');
const log = require('../../services/log'); const log = require('../../services/log');
const scriptService = require('../../services/script'); const scriptService = require('../../services/script');
const searchService = require('../../services/search/services/search'); const searchService = require('../../services/search/services/search');
const noteRevisionService = require("../../services/note_revisions.js");
async function search(note) { async function search(note) {
let searchResultNoteIds; let searchResultNoteIds;
@ -56,9 +57,12 @@ async function searchFromNote(req) {
const ACTION_HANDLERS = { const ACTION_HANDLERS = {
deleteNote: (action, note) => { deleteNote: (action, note) => {
note.isDeleted; note.isDeleted = true;
note.save(); note.save();
}, },
deleteNoteRevisions: (action, note) => {
noteRevisionService.eraseNoteRevisions(note.getRevisions().map(rev => rev.noteRevisionId));
},
deleteLabel: (action, note) => { deleteLabel: (action, note) => {
for (const label of note.getOwnedLabels(action.labelName)) { for (const label of note.getOwnedLabels(action.labelName)) {
label.isDeleted = true; label.isDeleted = true;

View file

@ -75,6 +75,8 @@ function eraseNoteRevisions(noteRevisionIdsToErase) {
return; return;
} }
log.info(`Removing note revisions: ${JSON.stringify(noteRevisionIdsToErase)}`);
sql.executeMany(`DELETE FROM note_revisions WHERE noteRevisionId IN (???)`, noteRevisionIdsToErase); sql.executeMany(`DELETE FROM note_revisions WHERE noteRevisionId IN (???)`, noteRevisionIdsToErase);
sql.executeMany(`UPDATE entity_changes SET isErased = 1 WHERE entityName = 'note_revisions' AND entityId IN (???)`, noteRevisionIdsToErase); sql.executeMany(`UPDATE entity_changes SET isErased = 1 WHERE entityName = 'note_revisions' AND entityId IN (???)`, noteRevisionIdsToErase);