mirror of
https://github.com/streetwriters/notesnook.git
synced 2026-02-23 19:49:56 +01:00
core: restoring note history with title
This commit is contained in:
committed by
Abdullah Atta
parent
1e023500be
commit
e6eb71a484
@@ -214,28 +214,90 @@ test("note history item can be created by setting note title", () =>
|
||||
));
|
||||
|
||||
test("note history item can be created by setting note title and content both", () =>
|
||||
noteTest({ title: "Test note", ...TEST_NOTE, sessionId: "notesession" }).then(
|
||||
noteTest({
|
||||
...TEST_NOTE,
|
||||
title: "Test note",
|
||||
sessionId: "notesession"
|
||||
}).then(async ({ db, id }) => {
|
||||
expect(await db.noteHistory.get(id).count()).toBe(1);
|
||||
const history = db.noteHistory.get(id);
|
||||
const items = await history.items();
|
||||
const content = await db.noteHistory.sessionContent.get(
|
||||
items[0].sessionContentId
|
||||
);
|
||||
expect(await db.noteHistory.collection.count()).toBe(1);
|
||||
expect(content.data).toBe(TEST_NOTE.content.data);
|
||||
expect(content.title).toBe("Test note");
|
||||
await db.notes.add({
|
||||
id: id,
|
||||
content: TEST_NOTE.content,
|
||||
sessionId: "notesession"
|
||||
});
|
||||
expect(content.data).toBe(TEST_NOTE.content.data);
|
||||
expect(content.title).toBe("Test note");
|
||||
await db.notes.add({
|
||||
id: id,
|
||||
title: "Test note",
|
||||
sessionId: "notesession"
|
||||
});
|
||||
expect(content.data).toBe(TEST_NOTE.content.data);
|
||||
expect(content.title).toBe("Test note");
|
||||
}));
|
||||
|
||||
test("restoring an old session should replace note's content title", () =>
|
||||
noteTest({ title: "Test note", sessionId: Date.now() }).then(
|
||||
async ({ db, id }) => {
|
||||
expect(await db.noteHistory.get(id).count()).toBe(1);
|
||||
const history = db.noteHistory.get(id);
|
||||
const items = await history.items();
|
||||
const content = await db.noteHistory.sessionContent.get(
|
||||
items[0].sessionContentId
|
||||
);
|
||||
expect(await db.noteHistory.sessionContent.collection.count()).toBe(1);
|
||||
expect(content.data).toBe(TEST_NOTE.content.data);
|
||||
expect(content.title).toBe("Test note");
|
||||
await delay(1000);
|
||||
let newTitle = "Test note (edited)";
|
||||
|
||||
const sessionId = `${Date.now() + 10000}`;
|
||||
await db.notes.add({
|
||||
id: id,
|
||||
content: TEST_NOTE.content
|
||||
title: newTitle,
|
||||
sessionId
|
||||
});
|
||||
expect(content.data).toBe(TEST_NOTE.content.data);
|
||||
expect(content.title).toBe("Test note");
|
||||
await db.notes.add({
|
||||
id: id,
|
||||
title: "Test note"
|
||||
});
|
||||
expect(content.data).toBe(TEST_NOTE.content.data);
|
||||
expect(content.title).toBe("Test note");
|
||||
|
||||
const [, firstVersion] = await db.noteHistory
|
||||
.get(id)
|
||||
.items(undefined, { sortBy: "dateModified", sortDirection: "desc" });
|
||||
expect(firstVersion.id).not.toBe(`${id}_${sessionId}`);
|
||||
await db.noteHistory.restore(firstVersion.id);
|
||||
|
||||
const title = (await db.notes.note(id)).title;
|
||||
expect(title).toBe("Test note");
|
||||
}
|
||||
));
|
||||
|
||||
test("restoring an old session should replace note's content and title", () =>
|
||||
noteTest({ ...TEST_NOTE, title: "Test note", sessionId: Date.now() }).then(
|
||||
async ({ db, id }) => {
|
||||
await delay(1000);
|
||||
let newTitle = "Test note (edited)";
|
||||
let editedContent = {
|
||||
data: TEST_NOTE.content.data + "<p>Some new content</p>",
|
||||
type: "tiptap"
|
||||
};
|
||||
|
||||
const sessionId = `${Date.now() + 10000}`;
|
||||
await db.notes.add({
|
||||
id: id,
|
||||
title: newTitle,
|
||||
sessionId,
|
||||
content: editedContent
|
||||
});
|
||||
|
||||
const [, firstVersion] = await db.noteHistory
|
||||
.get(id)
|
||||
.items(undefined, { sortBy: "dateModified", sortDirection: "desc" });
|
||||
expect(firstVersion.id).not.toBe(`${id}_${sessionId}`);
|
||||
await db.noteHistory.restore(firstVersion.id);
|
||||
|
||||
const title = (await db.notes.note(id)).title;
|
||||
expect(title).toBe("Test note");
|
||||
|
||||
const contentId = (await db.notes.note(id)).contentId;
|
||||
expect((await db.content.get(contentId)).data).toBe(
|
||||
TEST_NOTE.content.data
|
||||
);
|
||||
}
|
||||
));
|
||||
|
||||
@@ -20,7 +20,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
import Database from "../api/index.js";
|
||||
import { isCipher } from "../utils/crypto.js";
|
||||
import { FilteredSelector, SQLCollection } from "../database/sql-collection.js";
|
||||
import { HistorySession, isDeleted, NoteContent } from "../types.js";
|
||||
import { HistorySession, isDeleted, Note, NoteContent } from "../types.js";
|
||||
import { makeSessionContentId } from "../utils/id.js";
|
||||
import { ICollection } from "./collection.js";
|
||||
import { SessionContent } from "./session-content.js";
|
||||
@@ -190,22 +190,48 @@ export class NoteHistory implements ICollection {
|
||||
if (!note || !content) return;
|
||||
|
||||
if (session.locked && isCipher(content.data)) {
|
||||
const sessionId = `${Date.now()}`;
|
||||
await this.db.content.add({
|
||||
id: note.contentId,
|
||||
noteId: session.noteId,
|
||||
sessionId: `${Date.now()}`,
|
||||
sessionId: sessionId,
|
||||
data: content.data,
|
||||
type: content.type
|
||||
});
|
||||
} else if (content.data && content.type && !isCipher(content.data)) {
|
||||
await this.db.notes.add({
|
||||
|
||||
if (content.title) {
|
||||
await this.db.notes.add({
|
||||
id: session.noteId,
|
||||
sessionId: sessionId,
|
||||
title: content.title
|
||||
});
|
||||
}
|
||||
} else if (
|
||||
(content.data && content.type && !isCipher(content.data)) ||
|
||||
content.title
|
||||
) {
|
||||
const note: Partial<
|
||||
Note & {
|
||||
content: NoteContent<false>;
|
||||
sessionId: string;
|
||||
}
|
||||
> = {
|
||||
id: session.noteId,
|
||||
sessionId: `${Date.now()}`,
|
||||
content: {
|
||||
sessionId: `${Date.now()}`
|
||||
};
|
||||
|
||||
if (content.data && content.type && !isCipher(content.data)) {
|
||||
note.content = {
|
||||
data: content.data,
|
||||
type: content.type
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
if (content.title) {
|
||||
note.title = content.title;
|
||||
}
|
||||
|
||||
await this.db.notes.add(note);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6552,6 +6552,10 @@ msgstr "This may take a while"
|
||||
msgid "This must only be used for troubleshooting. Using it regularly for sync is not recommended and will lead to unexpected data loss and other issues. If you are having persistent issues with sync, please report them to us at support@streetwriters.co."
|
||||
msgstr "This must only be used for troubleshooting. Using it regularly for sync is not recommended and will lead to unexpected data loss and other issues. If you are having persistent issues with sync, please report them to us at support@streetwriters.co."
|
||||
|
||||
#: src/strings.ts:2623
|
||||
msgid "This note is empty"
|
||||
msgstr "This note is empty"
|
||||
|
||||
#: src/strings.ts:1594
|
||||
msgid "This note is locked"
|
||||
msgstr "This note is locked"
|
||||
|
||||
@@ -6511,6 +6511,10 @@ msgstr ""
|
||||
msgid "This must only be used for troubleshooting. Using it regularly for sync is not recommended and will lead to unexpected data loss and other issues. If you are having persistent issues with sync, please report them to us at support@streetwriters.co."
|
||||
msgstr ""
|
||||
|
||||
#: src/strings.ts:2623
|
||||
msgid "This note is empty"
|
||||
msgstr ""
|
||||
|
||||
#: src/strings.ts:1594
|
||||
msgid "This note is locked"
|
||||
msgstr ""
|
||||
|
||||
@@ -2631,5 +2631,6 @@ Use this if changes from other devices are not appearing on this device. This wi
|
||||
unsetExpiry: () => t`Unset expiry`,
|
||||
expiryDate: () => t`Expiry date`,
|
||||
exportCsv: () => t`Export CSV`,
|
||||
importCsv: () => t`Import CSV`
|
||||
importCsv: () => t`Import CSV`,
|
||||
noContent: () => t`This note is empty`
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user