mirror of
https://github.com/laurent22/joplin.git
synced 2025-04-01 21:24:45 +02:00
Desktop: Allow restoring a delete note from note history using command palette
This commit is contained in:
parent
00dc1d881b
commit
5fd6571bf1
@ -140,6 +140,9 @@ packages/app-desktop/commands/openProfileDirectory.js.map
|
|||||||
packages/app-desktop/commands/replaceMisspelling.d.ts
|
packages/app-desktop/commands/replaceMisspelling.d.ts
|
||||||
packages/app-desktop/commands/replaceMisspelling.js
|
packages/app-desktop/commands/replaceMisspelling.js
|
||||||
packages/app-desktop/commands/replaceMisspelling.js.map
|
packages/app-desktop/commands/replaceMisspelling.js.map
|
||||||
|
packages/app-desktop/commands/restoreNoteRevision.d.ts
|
||||||
|
packages/app-desktop/commands/restoreNoteRevision.js
|
||||||
|
packages/app-desktop/commands/restoreNoteRevision.js.map
|
||||||
packages/app-desktop/commands/startExternalEditing.d.ts
|
packages/app-desktop/commands/startExternalEditing.d.ts
|
||||||
packages/app-desktop/commands/startExternalEditing.js
|
packages/app-desktop/commands/startExternalEditing.js
|
||||||
packages/app-desktop/commands/startExternalEditing.js.map
|
packages/app-desktop/commands/startExternalEditing.js.map
|
||||||
|
3
.gitignore
vendored
3
.gitignore
vendored
@ -126,6 +126,9 @@ packages/app-desktop/commands/openProfileDirectory.js.map
|
|||||||
packages/app-desktop/commands/replaceMisspelling.d.ts
|
packages/app-desktop/commands/replaceMisspelling.d.ts
|
||||||
packages/app-desktop/commands/replaceMisspelling.js
|
packages/app-desktop/commands/replaceMisspelling.js
|
||||||
packages/app-desktop/commands/replaceMisspelling.js.map
|
packages/app-desktop/commands/replaceMisspelling.js.map
|
||||||
|
packages/app-desktop/commands/restoreNoteRevision.d.ts
|
||||||
|
packages/app-desktop/commands/restoreNoteRevision.js
|
||||||
|
packages/app-desktop/commands/restoreNoteRevision.js.map
|
||||||
packages/app-desktop/commands/startExternalEditing.d.ts
|
packages/app-desktop/commands/startExternalEditing.d.ts
|
||||||
packages/app-desktop/commands/startExternalEditing.js
|
packages/app-desktop/commands/startExternalEditing.js
|
||||||
packages/app-desktop/commands/startExternalEditing.js.map
|
packages/app-desktop/commands/startExternalEditing.js.map
|
||||||
|
@ -96,6 +96,7 @@ const globalCommands = [
|
|||||||
require('./commands/stopExternalEditing'),
|
require('./commands/stopExternalEditing'),
|
||||||
require('./commands/toggleExternalEditing'),
|
require('./commands/toggleExternalEditing'),
|
||||||
require('./commands/toggleSafeMode'),
|
require('./commands/toggleSafeMode'),
|
||||||
|
require('./commands/restoreNoteRevision'),
|
||||||
require('@joplin/lib/commands/historyBackward'),
|
require('@joplin/lib/commands/historyBackward'),
|
||||||
require('@joplin/lib/commands/historyForward'),
|
require('@joplin/lib/commands/historyForward'),
|
||||||
require('@joplin/lib/commands/synchronize'),
|
require('@joplin/lib/commands/synchronize'),
|
||||||
|
20
packages/app-desktop/commands/restoreNoteRevision.ts
Normal file
20
packages/app-desktop/commands/restoreNoteRevision.ts
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
import { CommandRuntime, CommandDeclaration, CommandContext } from '@joplin/lib/services/CommandService';
|
||||||
|
import RevisionService from '@joplin/lib/services/RevisionService';
|
||||||
|
|
||||||
|
export const declaration: CommandDeclaration = {
|
||||||
|
name: 'restoreNoteRevision',
|
||||||
|
label: 'Restore a note from history',
|
||||||
|
};
|
||||||
|
|
||||||
|
export const runtime = (): CommandRuntime => {
|
||||||
|
return {
|
||||||
|
execute: async (_context: CommandContext, noteId: string, reverseRevIndex: number = 0) => {
|
||||||
|
try {
|
||||||
|
const note = await RevisionService.instance().restoreNoteById(noteId, reverseRevIndex);
|
||||||
|
alert(RevisionService.instance().restoreSuccessMessage(note));
|
||||||
|
} catch (error) {
|
||||||
|
alert(error.message);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
};
|
@ -13,7 +13,7 @@ const shared = require('@joplin/lib/components/shared/note-screen-shared.js');
|
|||||||
const { MarkupToHtml } = require('@joplin/renderer');
|
const { MarkupToHtml } = require('@joplin/renderer');
|
||||||
const time = require('@joplin/lib/time').default;
|
const time = require('@joplin/lib/time').default;
|
||||||
const ReactTooltip = require('react-tooltip');
|
const ReactTooltip = require('react-tooltip');
|
||||||
const { urlDecode, substrWithEllipsis } = require('@joplin/lib/string-utils');
|
const { urlDecode } = require('@joplin/lib/string-utils');
|
||||||
const bridge = require('electron').remote.require('./bridge').default;
|
const bridge = require('electron').remote.require('./bridge').default;
|
||||||
const markupLanguageUtils = require('../utils/markupLanguageUtils').default;
|
const markupLanguageUtils = require('../utils/markupLanguageUtils').default;
|
||||||
|
|
||||||
@ -75,7 +75,7 @@ class NoteRevisionViewerComponent extends React.PureComponent {
|
|||||||
this.setState({ restoring: true });
|
this.setState({ restoring: true });
|
||||||
await RevisionService.instance().importRevisionNote(this.state.note);
|
await RevisionService.instance().importRevisionNote(this.state.note);
|
||||||
this.setState({ restoring: false });
|
this.setState({ restoring: false });
|
||||||
alert(_('The note "%s" has been successfully restored to the notebook "%s".', substrWithEllipsis(this.state.note.title, 0, 32), RevisionService.instance().restoreFolderTitle()));
|
alert(RevisionService.instance().restoreSuccessMessage(this.state.note));
|
||||||
}
|
}
|
||||||
|
|
||||||
backButton_click() {
|
backButton_click() {
|
||||||
|
@ -9,6 +9,7 @@ import shim from '../shim';
|
|||||||
import BaseService from './BaseService';
|
import BaseService from './BaseService';
|
||||||
import { _ } from '../locale';
|
import { _ } from '../locale';
|
||||||
import { ItemChangeEntity, NoteEntity, RevisionEntity } from './database/types';
|
import { ItemChangeEntity, NoteEntity, RevisionEntity } from './database/types';
|
||||||
|
const { substrWithEllipsis } = require('../string-utils');
|
||||||
const { sprintf } = require('sprintf-js');
|
const { sprintf } = require('sprintf-js');
|
||||||
const { wrapError } = require('../errorUtils');
|
const { wrapError } = require('../errorUtils');
|
||||||
|
|
||||||
@ -230,7 +231,23 @@ export default class RevisionService extends BaseService {
|
|||||||
return folder;
|
return folder;
|
||||||
}
|
}
|
||||||
|
|
||||||
async importRevisionNote(note: NoteEntity) {
|
// reverseRevIndex = 0 means restoring the latest version. reverseRevIndex =
|
||||||
|
// 1 means the version before that, etc.
|
||||||
|
public async restoreNoteById(noteId: string, reverseRevIndex: number): Promise<NoteEntity> {
|
||||||
|
const revisions = await Revision.allByType(BaseModel.TYPE_NOTE, noteId);
|
||||||
|
if (!revisions.length) throw new Error(`No revision for note "${noteId}"`);
|
||||||
|
|
||||||
|
const revIndex = revisions.length - 1 - reverseRevIndex;
|
||||||
|
|
||||||
|
const note = await this.revisionNote(revisions, revIndex);
|
||||||
|
return this.importRevisionNote(note);
|
||||||
|
}
|
||||||
|
|
||||||
|
public restoreSuccessMessage(note: NoteEntity): string {
|
||||||
|
return _('The note "%s" has been successfully restored to the notebook "%s".', substrWithEllipsis(note.title, 0, 32), this.restoreFolderTitle());
|
||||||
|
}
|
||||||
|
|
||||||
|
async importRevisionNote(note: NoteEntity): Promise<NoteEntity> {
|
||||||
const toImport = Object.assign({}, note);
|
const toImport = Object.assign({}, note);
|
||||||
delete toImport.id;
|
delete toImport.id;
|
||||||
delete toImport.updated_time;
|
delete toImport.updated_time;
|
||||||
@ -242,7 +259,7 @@ export default class RevisionService extends BaseService {
|
|||||||
|
|
||||||
toImport.parent_id = folder.id;
|
toImport.parent_id = folder.id;
|
||||||
|
|
||||||
await Note.save(toImport);
|
return Note.save(toImport);
|
||||||
}
|
}
|
||||||
|
|
||||||
async maintenance() {
|
async maintenance() {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user