feat(revisions): add a shortcut to save named revisions

This commit is contained in:
Elian Doran
2026-04-18 19:04:22 +03:00
parent 9d953ea700
commit e01d835709
11 changed files with 85 additions and 11 deletions

View File

@@ -281,6 +281,7 @@ export type CommandMappings = {
backInNoteHistory: CommandData;
forwardInNoteHistory: CommandData;
forceSaveRevision: CommandData;
saveNamedRevision: CommandData;
scrollToActiveNote: CommandData;
quickSearch: CommandData;
collapseTree: CommandData;

View File

@@ -1,6 +1,7 @@
import { CreateChildrenResponse, SqlExecuteResponse } from "@triliumnext/commons";
import bundleService from "../services/bundle.js";
import dialog from "../services/dialog.js";
import dateNoteService from "../services/date_notes.js";
import froca from "../services/froca.js";
import { t } from "../services/i18n.js";
@@ -216,4 +217,21 @@ export default class Entrypoints extends Component {
toastService.showMessage(t("entrypoints.note-revision-created"));
}
async saveNamedRevisionCommand() {
const noteId = appContext.tabManager.getActiveContextNoteId();
if (!noteId) return;
const name = await dialog.prompt({
title: t("entrypoints.save-named-revision-title"),
message: t("entrypoints.save-named-revision-message"),
defaultValue: ""
});
// null means the user cancelled
if (name === null) return;
await server.post(`notes/${noteId}/revision`, { description: name || undefined });
toastService.showMessage(t("entrypoints.note-revision-created"));
}
}

View File

@@ -302,6 +302,7 @@
"snapshot_interval": "Note Revision Snapshot Interval: {{seconds}}s.",
"maximum_revisions": "Note Revision Snapshot Limit: {{number}}.",
"save_revision_now": "Save a revision now",
"save_named_revision": "Save named revision...",
"snapshot_header": "Note revision snapshot",
"snapshot_interval_value": "Interval: {{seconds}}s",
"snapshot_limit_value": "Limit: {{number}}",
@@ -746,6 +747,7 @@
"print_note": "Print note",
"view_revisions": "Note revisions...",
"save_revision": "Save revision",
"save_named_revision": "Save named revision...",
"advanced": "Advanced",
"convert_into_attachment_failed": "Converting note '{{title}}' failed.",
"convert_into_attachment_successful": "Note '{{title}}' has been converted to attachment.",
@@ -1925,6 +1927,8 @@
},
"entrypoints": {
"note-revision-created": "Note revision has been created.",
"save-named-revision-title": "Save named revision",
"save-named-revision-message": "Enter a name for this revision (leave empty for no name):",
"note-executed": "Note executed.",
"sql-error": "Error occurred while executing SQL query: {{message}}"
},

View File

@@ -199,6 +199,22 @@ function RevisionsMenu({ note, onRevisionSaved, onAllDeleted, hasRevisions }: {
>
{t("revisions.save_revision_now")}
</FormListItem>
<FormListItem
icon="bx bx-purchase-tag"
onClick={async () => {
const name = await dialog.prompt({
title: t("entrypoints.save-named-revision-title"),
message: t("entrypoints.save-named-revision-message"),
defaultValue: ""
});
if (name === null) return;
await server.post(`notes/${note.noteId}/revision`, { description: name || undefined });
toast.showMessage(t("revisions.revision_saved"));
onRevisionSaved();
}}
>
{t("revisions.save_named_revision")}
</FormListItem>
<FormDropdownDivider />
<FormListItem disabled className="revision-menu-header">
{t("revisions.snapshot_header")}

View File

@@ -153,6 +153,7 @@ export function NoteContextMenu({ note, noteContext, itemsAtStart, itemsNearNote
<CommandItem command="showRevisions" icon="bx bx-history" text={t("note_actions.view_revisions")} />
<CommandItem command="forceSaveRevision" icon="bx bx-save" disabled={isInOptionsOrHelp} text={t("note_actions.save_revision")} />
<CommandItem command="saveNamedRevision" icon="bx bx-purchase-tag" disabled={isInOptionsOrHelp} text={t("note_actions.save_named_revision")} />
<FormDropdownDivider />

View File

@@ -62,16 +62,24 @@
<h2>Named revisions</h2>
<p>Named revisions are a new feature of Trilium v0.103.0 which allows adding
a short description of what the changes in the snapshot contain.</p>
<p>In the list of note revisions:</p>
<ul>
<li>
<p>The name of the revision is displayed underneath the time of the revision
in the sidebar, as well as at the top of the dialog where it is displayed
in full.</p>
</li>
<li>
<p>Clicking on the edit button near the name of the revision allows it to
be changed.</p>
</li>
<li>The name of the revision is displayed underneath the time of the revision
in the sidebar, as well as at the top of the dialog where it is displayed
in full.</li>
<li>Clicking on the edit button near the name of the revision allows it to
be changed.</li>
</ul>
<p>To create a named revision, either:</p>
<ul>
<li>Go to the&nbsp;<a class="reference-link" href="#root/pOsGYCXsbNQG/gh7bpGYxajRS/Vc8PjrjAGuOp/_help_8YBEPzcpUgxw">Note buttons</a>,
select <em>Save named revision…</em>, enter the name of revision and confirm.</li>
<li
>Use the corresponding <a href="#root/pOsGYCXsbNQG/gh7bpGYxajRS/_help_A9Oc6YKKc65v">keyboard shortcut</a> or
the&nbsp;<a class="reference-link" href="#root/pOsGYCXsbNQG/gh7bpGYxajRS/wArbEsdSae6g/_help_F1r9QtzQLZqm">Jump to...</a>&nbsp;command
with the same name.</li>
<li>Save a revision normally, and adjust the name afterwards from the note
revision list.</li>
</ul>
<h2>When revisions are saved</h2>
<p>Revisions are saved:</p>

View File

@@ -100,6 +100,7 @@
"reset-zoom-level": "Reset zoom level",
"copy-without-formatting": "Copy selected text without formatting",
"force-save-revision": "Force creating / saving new note revision of the active note",
"save-named-revision": "Save a named revision of the active note",
"toggle-book-properties": "Toggle Collection Properties",
"toggle-classic-editor-toolbar": "Toggle the Formatting tab for the editor with fixed toolbar",
"export-as-pdf": "Export the current note as a PDF",
@@ -200,7 +201,8 @@
"zoom-in": "Zoom In",
"reset-zoom-level": "Reset Zoom Level",
"copy-without-formatting": "Copy Without Formatting",
"force-save-revision": "Force Save Revision"
"force-save-revision": "Force Save Revision",
"save-named-revision": "Save Named Revision"
},
"login": {
"title": "Login",

View File

@@ -828,6 +828,14 @@ function getDefaultKeyboardActions() {
defaultShortcuts: [],
description: t("keyboard_actions.force-save-revision"),
scope: "window"
},
{
actionName: "saveNamedRevision",
friendlyName: t("keyboard_action_names.save-named-revision"),
iconClass: "bx bx-purchase-tag",
defaultShortcuts: [],
description: t("keyboard_actions.save-named-revision"),
scope: "window"
}
];

View File

@@ -4574,6 +4574,13 @@
"value": "A9Oc6YKKc65v",
"isInheritable": false,
"position": 90
},
{
"type": "relation",
"name": "internalLink",
"value": "F1r9QtzQLZqm",
"isInheritable": false,
"position": 100
}
],
"format": "markdown",

View File

@@ -32,9 +32,17 @@ Trilium supports seamless versioning of notes by storing snapshots ("revisions")
Named revisions are a new feature of Trilium v0.103.0 which allows adding a short description of what the changes in the snapshot contain.
In the list of note revisions:
* The name of the revision is displayed underneath the time of the revision in the sidebar, as well as at the top of the dialog where it is displayed in full.
* Clicking on the edit button near the name of the revision allows it to be changed.
To create a named revision, either:
* Go to the <a class="reference-link" href="../UI%20Elements/Note%20buttons.md">Note buttons</a>, select _Save named revision…_, enter the name of revision and confirm.
* Use the corresponding [keyboard shortcut](../Keyboard%20Shortcuts.md) or the <a class="reference-link" href="../Navigation/Jump%20to.md">Jump to...</a> command with the same name.
* Save a revision normally, and adjust the name afterwards from the note revision list.
## When revisions are saved
Revisions are saved:

View File

@@ -94,7 +94,8 @@ const enum KeyboardActionNamesEnum {
zoomIn,
zoomReset,
copyWithoutFormatting,
forceSaveRevision
forceSaveRevision,
saveNamedRevision
}
export type KeyboardActionNames = keyof typeof KeyboardActionNamesEnum;