mirror of
https://github.com/zadam/trilium.git
synced 2025-06-06 18:08:33 +02:00
undelete note WIP
This commit is contained in:
parent
1d3608b7bf
commit
c1d0a1e07b
81
db/migrations/0156__add_deleteId.sql
Normal file
81
db/migrations/0156__add_deleteId.sql
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
CREATE TABLE IF NOT EXISTS "notes_mig" (
|
||||||
|
`noteId` TEXT NOT NULL,
|
||||||
|
`title` TEXT NOT NULL DEFAULT "note",
|
||||||
|
`contentLength` INT NOT NULL,
|
||||||
|
`isProtected` INT NOT NULL DEFAULT 0,
|
||||||
|
`type` TEXT NOT NULL DEFAULT 'text',
|
||||||
|
`mime` TEXT NOT NULL DEFAULT 'text/html',
|
||||||
|
`hash` TEXT DEFAULT "" NOT NULL,
|
||||||
|
`isDeleted` INT NOT NULL DEFAULT 0,
|
||||||
|
`deleteId` TEXT DEFAULT NULL,
|
||||||
|
`isErased` INT NOT NULL DEFAULT 0,
|
||||||
|
`dateCreated` TEXT NOT NULL,
|
||||||
|
`dateModified` TEXT NOT NULL,
|
||||||
|
`utcDateCreated` TEXT NOT NULL,
|
||||||
|
`utcDateModified` TEXT NOT NULL,
|
||||||
|
PRIMARY KEY(`noteId`));
|
||||||
|
|
||||||
|
INSERT INTO notes_mig (noteId, title, contentLength, isProtected, type, mime, hash, isDeleted, isErased, dateCreated, dateModified, utcDateCreated, utcDateModified)
|
||||||
|
SELECT noteId, title, -1, isProtected, type, mime, hash, isDeleted, isErased, dateCreated, dateModified, utcDateCreated, utcDateModified FROM notes;
|
||||||
|
|
||||||
|
DROP TABLE notes;
|
||||||
|
ALTER TABLE notes_mig RENAME TO notes;
|
||||||
|
|
||||||
|
CREATE INDEX `IDX_notes_isDeleted` ON `notes` (`isDeleted`);
|
||||||
|
CREATE INDEX `IDX_notes_title` ON `notes` (`title`);
|
||||||
|
CREATE INDEX `IDX_notes_type` ON `notes` (`type`);
|
||||||
|
CREATE INDEX `IDX_notes_dateCreated` ON `notes` (`dateCreated`);
|
||||||
|
CREATE INDEX `IDX_notes_dateModified` ON `notes` (`dateModified`);
|
||||||
|
CREATE INDEX `IDX_notes_utcDateModified` ON `notes` (`utcDateModified`);
|
||||||
|
CREATE INDEX `IDX_notes_utcDateCreated` ON `notes` (`utcDateCreated`);
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS "branches_mig" (
|
||||||
|
`branchId` TEXT NOT NULL,
|
||||||
|
`noteId` TEXT NOT NULL,
|
||||||
|
`parentNoteId` TEXT NOT NULL,
|
||||||
|
`notePosition` INTEGER NOT NULL,
|
||||||
|
`prefix` TEXT,
|
||||||
|
`isExpanded` INTEGER NOT NULL DEFAULT 0,
|
||||||
|
`isDeleted` INTEGER NOT NULL DEFAULT 0,
|
||||||
|
`deleteId` TEXT DEFAULT NULL,
|
||||||
|
`utcDateModified` TEXT NOT NULL,
|
||||||
|
utcDateCreated TEXT NOT NULL,
|
||||||
|
hash TEXT DEFAULT "" NOT NULL,
|
||||||
|
PRIMARY KEY(`branchId`));
|
||||||
|
|
||||||
|
INSERT INTO branches_mig (branchId, noteId, parentNoteId, notePosition, prefix, isExpanded, isDeleted, utcDateModified, utcDateCreated, hash)
|
||||||
|
SELECT branchId, noteId, parentNoteId, notePosition, prefix, isExpanded, isDeleted, utcDateModified, utcDateCreated, hash FROM branches;
|
||||||
|
|
||||||
|
DROP TABLE branches;
|
||||||
|
ALTER TABLE branches_mig RENAME TO branches;
|
||||||
|
|
||||||
|
CREATE INDEX `IDX_branches_noteId_parentNoteId` ON `branches` (`noteId`,`parentNoteId`);
|
||||||
|
CREATE INDEX IDX_branches_parentNoteId ON branches (parentNoteId);
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS "attributes_mig"
|
||||||
|
(
|
||||||
|
attributeId TEXT not null primary key,
|
||||||
|
noteId TEXT not null,
|
||||||
|
type TEXT not null,
|
||||||
|
name TEXT not null,
|
||||||
|
value TEXT default '' not null,
|
||||||
|
position INT default 0 not null,
|
||||||
|
utcDateCreated TEXT not null,
|
||||||
|
utcDateModified TEXT not null,
|
||||||
|
isDeleted INT not null,
|
||||||
|
`deleteId` TEXT DEFAULT NULL,
|
||||||
|
hash TEXT default "" not null,
|
||||||
|
isInheritable int DEFAULT 0 NULL);
|
||||||
|
|
||||||
|
INSERT INTO attributes_mig (attributeId, noteId, type, name, value, position, utcDateCreated, utcDateModified, isDeleted, hash, isInheritable)
|
||||||
|
SELECT attributeId, noteId, type, name, value, position, utcDateCreated, utcDateModified, isDeleted, hash, isInheritable FROM attributes;
|
||||||
|
|
||||||
|
DROP TABLE attributes;
|
||||||
|
ALTER TABLE attributes_mig RENAME TO attributes;
|
||||||
|
|
||||||
|
CREATE INDEX IDX_attributes_name_value
|
||||||
|
on attributes (name, value);
|
||||||
|
CREATE INDEX IDX_attributes_noteId_index
|
||||||
|
on attributes (noteId);
|
||||||
|
CREATE INDEX IDX_attributes_value_index
|
||||||
|
on attributes (value);
|
113
db/schema.sql
113
db/schema.sql
@ -27,19 +27,6 @@ CREATE TABLE IF NOT EXISTS "options"
|
|||||||
utcDateCreated TEXT not null,
|
utcDateCreated TEXT not null,
|
||||||
utcDateModified TEXT NOT NULL
|
utcDateModified TEXT NOT NULL
|
||||||
);
|
);
|
||||||
CREATE TABLE IF NOT EXISTS "attributes"
|
|
||||||
(
|
|
||||||
attributeId TEXT not null primary key,
|
|
||||||
noteId TEXT not null,
|
|
||||||
type TEXT not null,
|
|
||||||
name TEXT not null,
|
|
||||||
value TEXT default '' not null,
|
|
||||||
position INT default 0 not null,
|
|
||||||
utcDateCreated TEXT not null,
|
|
||||||
utcDateModified TEXT not null,
|
|
||||||
isDeleted INT not null,
|
|
||||||
hash TEXT default "" not null,
|
|
||||||
isInheritable int DEFAULT 0 NULL);
|
|
||||||
CREATE UNIQUE INDEX `IDX_sync_entityName_entityId` ON `sync` (
|
CREATE UNIQUE INDEX `IDX_sync_entityName_entityId` ON `sync` (
|
||||||
`entityName`,
|
`entityName`,
|
||||||
`entityId`
|
`entityId`
|
||||||
@ -47,12 +34,6 @@ CREATE UNIQUE INDEX `IDX_sync_entityName_entityId` ON `sync` (
|
|||||||
CREATE INDEX `IDX_sync_utcSyncDate` ON `sync` (
|
CREATE INDEX `IDX_sync_utcSyncDate` ON `sync` (
|
||||||
`utcSyncDate`
|
`utcSyncDate`
|
||||||
);
|
);
|
||||||
CREATE INDEX IDX_attributes_name_value
|
|
||||||
on attributes (name, value);
|
|
||||||
CREATE INDEX IDX_attributes_noteId_index
|
|
||||||
on attributes (noteId);
|
|
||||||
CREATE INDEX IDX_attributes_value_index
|
|
||||||
on attributes (value);
|
|
||||||
CREATE TABLE IF NOT EXISTS "note_contents" (
|
CREATE TABLE IF NOT EXISTS "note_contents" (
|
||||||
`noteId` TEXT NOT NULL,
|
`noteId` TEXT NOT NULL,
|
||||||
`content` TEXT NULL DEFAULT NULL,
|
`content` TEXT NULL DEFAULT NULL,
|
||||||
@ -68,46 +49,10 @@ CREATE TABLE recent_notes
|
|||||||
utcDateCreated TEXT not null,
|
utcDateCreated TEXT not null,
|
||||||
isDeleted INT
|
isDeleted INT
|
||||||
);
|
);
|
||||||
CREATE TABLE IF NOT EXISTS "branches" (
|
|
||||||
`branchId` TEXT NOT NULL,
|
|
||||||
`noteId` TEXT NOT NULL,
|
|
||||||
`parentNoteId` TEXT NOT NULL,
|
|
||||||
`notePosition` INTEGER NOT NULL,
|
|
||||||
`prefix` TEXT,
|
|
||||||
`isExpanded` INTEGER NOT NULL DEFAULT 0,
|
|
||||||
`isDeleted` INTEGER NOT NULL DEFAULT 0,
|
|
||||||
`utcDateModified` TEXT NOT NULL,
|
|
||||||
utcDateCreated TEXT NOT NULL,
|
|
||||||
hash TEXT DEFAULT "" NOT NULL,
|
|
||||||
PRIMARY KEY(`branchId`));
|
|
||||||
CREATE INDEX `IDX_branches_noteId_parentNoteId` ON `branches` (`noteId`,`parentNoteId`);
|
|
||||||
CREATE INDEX IDX_branches_parentNoteId ON branches (parentNoteId);
|
|
||||||
CREATE TABLE IF NOT EXISTS "note_revision_contents" (`noteRevisionId` TEXT NOT NULL PRIMARY KEY,
|
CREATE TABLE IF NOT EXISTS "note_revision_contents" (`noteRevisionId` TEXT NOT NULL PRIMARY KEY,
|
||||||
`content` TEXT,
|
`content` TEXT,
|
||||||
hash TEXT DEFAULT '' NOT NULL,
|
hash TEXT DEFAULT '' NOT NULL,
|
||||||
`utcDateModified` TEXT NOT NULL);
|
`utcDateModified` TEXT NOT NULL);
|
||||||
CREATE TABLE IF NOT EXISTS "notes" (
|
|
||||||
`noteId` TEXT NOT NULL,
|
|
||||||
`title` TEXT NOT NULL DEFAULT "note",
|
|
||||||
`contentLength` INT NOT NULL,
|
|
||||||
`isProtected` INT NOT NULL DEFAULT 0,
|
|
||||||
`type` TEXT NOT NULL DEFAULT 'text',
|
|
||||||
`mime` TEXT NOT NULL DEFAULT 'text/html',
|
|
||||||
`hash` TEXT DEFAULT "" NOT NULL,
|
|
||||||
`isDeleted` INT NOT NULL DEFAULT 0,
|
|
||||||
`isErased` INT NOT NULL DEFAULT 0,
|
|
||||||
`dateCreated` TEXT NOT NULL,
|
|
||||||
`dateModified` TEXT NOT NULL,
|
|
||||||
`utcDateCreated` TEXT NOT NULL,
|
|
||||||
`utcDateModified` TEXT NOT NULL,
|
|
||||||
PRIMARY KEY(`noteId`));
|
|
||||||
CREATE INDEX `IDX_notes_isDeleted` ON `notes` (`isDeleted`);
|
|
||||||
CREATE INDEX `IDX_notes_title` ON `notes` (`title`);
|
|
||||||
CREATE INDEX `IDX_notes_type` ON `notes` (`type`);
|
|
||||||
CREATE INDEX `IDX_notes_dateCreated` ON `notes` (`dateCreated`);
|
|
||||||
CREATE INDEX `IDX_notes_dateModified` ON `notes` (`dateModified`);
|
|
||||||
CREATE INDEX `IDX_notes_utcDateModified` ON `notes` (`utcDateModified`);
|
|
||||||
CREATE INDEX `IDX_notes_utcDateCreated` ON `notes` (`utcDateCreated`);
|
|
||||||
CREATE TABLE IF NOT EXISTS "note_revisions" (`noteRevisionId` TEXT NOT NULL PRIMARY KEY,
|
CREATE TABLE IF NOT EXISTS "note_revisions" (`noteRevisionId` TEXT NOT NULL PRIMARY KEY,
|
||||||
`noteId` TEXT NOT NULL,
|
`noteId` TEXT NOT NULL,
|
||||||
`title` TEXT,
|
`title` TEXT,
|
||||||
@ -127,3 +72,61 @@ CREATE INDEX `IDX_note_revisions_utcDateCreated` ON `note_revisions` (`utcDateCr
|
|||||||
CREATE INDEX `IDX_note_revisions_utcDateLastEdited` ON `note_revisions` (`utcDateLastEdited`);
|
CREATE INDEX `IDX_note_revisions_utcDateLastEdited` ON `note_revisions` (`utcDateLastEdited`);
|
||||||
CREATE INDEX `IDX_note_revisions_dateCreated` ON `note_revisions` (`dateCreated`);
|
CREATE INDEX `IDX_note_revisions_dateCreated` ON `note_revisions` (`dateCreated`);
|
||||||
CREATE INDEX `IDX_note_revisions_dateLastEdited` ON `note_revisions` (`dateLastEdited`);
|
CREATE INDEX `IDX_note_revisions_dateLastEdited` ON `note_revisions` (`dateLastEdited`);
|
||||||
|
CREATE TABLE IF NOT EXISTS "notes" (
|
||||||
|
`noteId` TEXT NOT NULL,
|
||||||
|
`title` TEXT NOT NULL DEFAULT "note",
|
||||||
|
`contentLength` INT NOT NULL,
|
||||||
|
`isProtected` INT NOT NULL DEFAULT 0,
|
||||||
|
`type` TEXT NOT NULL DEFAULT 'text',
|
||||||
|
`mime` TEXT NOT NULL DEFAULT 'text/html',
|
||||||
|
`hash` TEXT DEFAULT "" NOT NULL,
|
||||||
|
`isDeleted` INT NOT NULL DEFAULT 0,
|
||||||
|
`deleteId` TEXT DEFAULT NULL,
|
||||||
|
`isErased` INT NOT NULL DEFAULT 0,
|
||||||
|
`dateCreated` TEXT NOT NULL,
|
||||||
|
`dateModified` TEXT NOT NULL,
|
||||||
|
`utcDateCreated` TEXT NOT NULL,
|
||||||
|
`utcDateModified` TEXT NOT NULL,
|
||||||
|
PRIMARY KEY(`noteId`));
|
||||||
|
CREATE INDEX `IDX_notes_isDeleted` ON `notes` (`isDeleted`);
|
||||||
|
CREATE INDEX `IDX_notes_title` ON `notes` (`title`);
|
||||||
|
CREATE INDEX `IDX_notes_type` ON `notes` (`type`);
|
||||||
|
CREATE INDEX `IDX_notes_dateCreated` ON `notes` (`dateCreated`);
|
||||||
|
CREATE INDEX `IDX_notes_dateModified` ON `notes` (`dateModified`);
|
||||||
|
CREATE INDEX `IDX_notes_utcDateModified` ON `notes` (`utcDateModified`);
|
||||||
|
CREATE INDEX `IDX_notes_utcDateCreated` ON `notes` (`utcDateCreated`);
|
||||||
|
CREATE TABLE IF NOT EXISTS "branches" (
|
||||||
|
`branchId` TEXT NOT NULL,
|
||||||
|
`noteId` TEXT NOT NULL,
|
||||||
|
`parentNoteId` TEXT NOT NULL,
|
||||||
|
`notePosition` INTEGER NOT NULL,
|
||||||
|
`prefix` TEXT,
|
||||||
|
`isExpanded` INTEGER NOT NULL DEFAULT 0,
|
||||||
|
`isDeleted` INTEGER NOT NULL DEFAULT 0,
|
||||||
|
`deleteId` TEXT DEFAULT NULL,
|
||||||
|
`utcDateModified` TEXT NOT NULL,
|
||||||
|
utcDateCreated TEXT NOT NULL,
|
||||||
|
hash TEXT DEFAULT "" NOT NULL,
|
||||||
|
PRIMARY KEY(`branchId`));
|
||||||
|
CREATE INDEX `IDX_branches_noteId_parentNoteId` ON `branches` (`noteId`,`parentNoteId`);
|
||||||
|
CREATE INDEX IDX_branches_parentNoteId ON branches (parentNoteId);
|
||||||
|
CREATE TABLE IF NOT EXISTS "attributes"
|
||||||
|
(
|
||||||
|
attributeId TEXT not null primary key,
|
||||||
|
noteId TEXT not null,
|
||||||
|
type TEXT not null,
|
||||||
|
name TEXT not null,
|
||||||
|
value TEXT default '' not null,
|
||||||
|
position INT default 0 not null,
|
||||||
|
utcDateCreated TEXT not null,
|
||||||
|
utcDateModified TEXT not null,
|
||||||
|
isDeleted INT not null,
|
||||||
|
`deleteId` TEXT DEFAULT NULL,
|
||||||
|
hash TEXT default "" not null,
|
||||||
|
isInheritable int DEFAULT 0 NULL);
|
||||||
|
CREATE INDEX IDX_attributes_name_value
|
||||||
|
on attributes (name, value);
|
||||||
|
CREATE INDEX IDX_attributes_noteId_index
|
||||||
|
on attributes (noteId);
|
||||||
|
CREATE INDEX IDX_attributes_value_index
|
||||||
|
on attributes (value);
|
||||||
|
@ -16,6 +16,7 @@ const sql = require('../services/sql');
|
|||||||
* @property {int} position
|
* @property {int} position
|
||||||
* @property {boolean} isInheritable
|
* @property {boolean} isInheritable
|
||||||
* @property {boolean} isDeleted
|
* @property {boolean} isDeleted
|
||||||
|
* @property {string|null} deleteId - ID identifying delete transaction
|
||||||
* @property {string} utcDateCreated
|
* @property {string} utcDateCreated
|
||||||
* @property {string} utcDateModified
|
* @property {string} utcDateModified
|
||||||
*
|
*
|
||||||
|
@ -16,6 +16,7 @@ const sql = require('../services/sql');
|
|||||||
* @property {string} prefix
|
* @property {string} prefix
|
||||||
* @property {boolean} isExpanded
|
* @property {boolean} isExpanded
|
||||||
* @property {boolean} isDeleted
|
* @property {boolean} isDeleted
|
||||||
|
* @property {string|null} deleteId - ID identifying delete transaction
|
||||||
* @property {string} utcDateModified
|
* @property {string} utcDateModified
|
||||||
* @property {string} utcDateCreated
|
* @property {string} utcDateCreated
|
||||||
*
|
*
|
||||||
@ -25,7 +26,7 @@ class Branch extends Entity {
|
|||||||
static get entityName() { return "branches"; }
|
static get entityName() { return "branches"; }
|
||||||
static get primaryKeyName() { return "branchId"; }
|
static get primaryKeyName() { return "branchId"; }
|
||||||
// notePosition is not part of hash because it would produce a lot of updates in case of reordering
|
// notePosition is not part of hash because it would produce a lot of updates in case of reordering
|
||||||
static get hashedProperties() { return ["branchId", "noteId", "parentNoteId", "isDeleted", "prefix"]; }
|
static get hashedProperties() { return ["branchId", "noteId", "parentNoteId", "isDeleted", "deleteId", "prefix"]; }
|
||||||
|
|
||||||
constructor(row = {}) {
|
constructor(row = {}) {
|
||||||
super(row);
|
super(row);
|
||||||
|
@ -24,6 +24,7 @@ const RELATION_DEFINITION = 'relation-definition';
|
|||||||
* @property {int} contentLength - length of content
|
* @property {int} contentLength - length of content
|
||||||
* @property {boolean} isProtected - true if note is protected
|
* @property {boolean} isProtected - true if note is protected
|
||||||
* @property {boolean} isDeleted - true if note is deleted
|
* @property {boolean} isDeleted - true if note is deleted
|
||||||
|
* @property {string|null} deleteId - ID identifying delete transaction
|
||||||
* @property {boolean} isErased - true if note's content is erased after it has been deleted
|
* @property {boolean} isErased - true if note's content is erased after it has been deleted
|
||||||
* @property {string} dateCreated - local date time (with offset)
|
* @property {string} dateCreated - local date time (with offset)
|
||||||
* @property {string} dateModified - local date time (with offset)
|
* @property {string} dateModified - local date time (with offset)
|
||||||
@ -35,7 +36,7 @@ const RELATION_DEFINITION = 'relation-definition';
|
|||||||
class Note extends Entity {
|
class Note extends Entity {
|
||||||
static get entityName() { return "notes"; }
|
static get entityName() { return "notes"; }
|
||||||
static get primaryKeyName() { return "noteId"; }
|
static get primaryKeyName() { return "noteId"; }
|
||||||
static get hashedProperties() { return ["noteId", "title", "type", "isProtected", "isDeleted"]; }
|
static get hashedProperties() { return ["noteId", "title", "type", "isProtected", "isDeleted", "deleteId"]; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param row - object containing database row from "notes" table
|
* @param row - object containing database row from "notes" table
|
||||||
|
@ -28,31 +28,38 @@ export async function showDialog() {
|
|||||||
const groupedByDate = groupByDate(result);
|
const groupedByDate = groupByDate(result);
|
||||||
|
|
||||||
for (const [dateDay, dayChanges] of groupedByDate) {
|
for (const [dateDay, dayChanges] of groupedByDate) {
|
||||||
const changesListEl = $('<ul>');
|
const $changesList = $('<ul>');
|
||||||
|
|
||||||
const dayEl = $('<div>').append($('<b>').html(utils.formatDate(dateDay))).append(changesListEl);
|
const dayEl = $('<div>').append($('<b>').html(utils.formatDate(dateDay))).append($changesList);
|
||||||
|
|
||||||
for (const change of dayChanges) {
|
for (const change of dayChanges) {
|
||||||
const formattedTime = utils.formatTime(utils.parseDate(change.date));
|
const formattedTime = utils.formatTime(utils.parseDate(change.date));
|
||||||
|
|
||||||
let noteLink;
|
let $noteLink;
|
||||||
|
|
||||||
if (change.current_isDeleted) {
|
if (change.current_isDeleted) {
|
||||||
noteLink = change.current_title;
|
$noteLink = $("<span>").text(change.current_title);
|
||||||
|
|
||||||
|
if (change.canBeUndeleted) {
|
||||||
|
$noteLink
|
||||||
|
.append(' (')
|
||||||
|
.append($(`<a href="">`).text("undelete"))
|
||||||
|
.append(')');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
const note = await treeCache.getNote(change.noteId);
|
const note = await treeCache.getNote(change.noteId);
|
||||||
const notePath = await treeService.getSomeNotePath(note);
|
const notePath = await treeService.getSomeNotePath(note);
|
||||||
|
|
||||||
noteLink = await linkService.createNoteLink(notePath, {
|
$noteLink = await linkService.createNoteLink(notePath, {
|
||||||
title: change.title,
|
title: change.title,
|
||||||
showNotePath: true
|
showNotePath: true
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
changesListEl.append($('<li>')
|
$changesList.append($('<li>')
|
||||||
.append(formattedTime + ' - ')
|
.append(formattedTime + ' - ')
|
||||||
.append(noteLink));
|
.append($noteLink));
|
||||||
}
|
}
|
||||||
|
|
||||||
$content.append(dayEl);
|
$content.append(dayEl);
|
||||||
@ -85,5 +92,6 @@ function groupByDate(result) {
|
|||||||
|
|
||||||
groupedByDate.get(dateDay).push(row);
|
groupedByDate.get(dateDay).push(row);
|
||||||
}
|
}
|
||||||
|
|
||||||
return groupedByDate;
|
return groupedByDate;
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,12 @@ function getNotePathFromUrl(url) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function createNoteLink(notePath, options = {}) {
|
async function createNoteLink(notePath, options = {}) {
|
||||||
|
if (!notePath || !notePath.trim()) {
|
||||||
|
console.error("Missing note path");
|
||||||
|
|
||||||
|
return $("<span>").text("[missing note]");
|
||||||
|
}
|
||||||
|
|
||||||
let noteTitle = options.title;
|
let noteTitle = options.title;
|
||||||
const showTooltip = options.showTooltip === undefined ? true : options.showTooltip;
|
const showTooltip = options.showTooltip === undefined ? true : options.showTooltip;
|
||||||
const showNotePath = options.showNotePath === undefined ? false : options.showNotePath;
|
const showNotePath = options.showNotePath === undefined ? false : options.showNotePath;
|
||||||
|
@ -316,6 +316,8 @@ async function getSomeNotePath(note) {
|
|||||||
cur = parents[0];
|
cur = parents[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
path.push('root');
|
||||||
|
|
||||||
return path.reverse().join('/');
|
return path.reverse().join('/');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,7 +101,8 @@ async function deleteBranch(req) {
|
|||||||
const branch = await repository.getBranch(req.params.branchId);
|
const branch = await repository.getBranch(req.params.branchId);
|
||||||
const taskContext = TaskContext.getInstance(req.query.taskId, 'delete-notes');
|
const taskContext = TaskContext.getInstance(req.query.taskId, 'delete-notes');
|
||||||
|
|
||||||
const noteDeleted = await notes.deleteBranch(branch, taskContext);
|
const deleteId = utils.randomString(10);
|
||||||
|
const noteDeleted = await notes.deleteBranch(branch, deleteId, taskContext);
|
||||||
|
|
||||||
if (last) {
|
if (last) {
|
||||||
taskContext.taskSucceeded();
|
taskContext.taskSucceeded();
|
||||||
|
@ -55,12 +55,15 @@ async function deleteNote(req) {
|
|||||||
const taskId = req.query.taskId;
|
const taskId = req.query.taskId;
|
||||||
const last = req.query.last === 'true';
|
const last = req.query.last === 'true';
|
||||||
|
|
||||||
|
// note how deleteId is separate from taskId - single taskId produces separate deleteId for each "top level" deleted note
|
||||||
|
const deleteId = utils.randomString(10);
|
||||||
|
|
||||||
const note = await repository.getNote(noteId);
|
const note = await repository.getNote(noteId);
|
||||||
|
|
||||||
const taskContext = TaskContext.getInstance(taskId, 'delete-notes');
|
const taskContext = TaskContext.getInstance(taskId, 'delete-notes');
|
||||||
|
|
||||||
for (const branch of await note.getBranches()) {
|
for (const branch of await note.getBranches()) {
|
||||||
await noteService.deleteBranch(branch, taskContext);
|
await noteService.deleteBranch(branch, deleteId, taskContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (last) {
|
if (last) {
|
||||||
|
@ -10,6 +10,8 @@ async function getRecentChanges() {
|
|||||||
SELECT
|
SELECT
|
||||||
notes.noteId,
|
notes.noteId,
|
||||||
notes.isDeleted AS current_isDeleted,
|
notes.isDeleted AS current_isDeleted,
|
||||||
|
notes.deleteId AS current_deleteId,
|
||||||
|
notes.isErased AS current_isErased,
|
||||||
notes.title AS current_title,
|
notes.title AS current_title,
|
||||||
notes.isProtected AS current_isProtected,
|
notes.isProtected AS current_isProtected,
|
||||||
note_revisions.title,
|
note_revisions.title,
|
||||||
@ -19,21 +21,23 @@ async function getRecentChanges() {
|
|||||||
JOIN notes USING(noteId)
|
JOIN notes USING(noteId)
|
||||||
ORDER BY
|
ORDER BY
|
||||||
note_revisions.utcDateCreated DESC
|
note_revisions.utcDateCreated DESC
|
||||||
LIMIT 1000
|
LIMIT 200
|
||||||
)
|
)
|
||||||
UNION ALL SELECT * FROM (
|
UNION ALL SELECT * FROM (
|
||||||
SELECT
|
SELECT
|
||||||
notes.noteId,
|
notes.noteId,
|
||||||
notes.isDeleted AS current_isDeleted,
|
notes.isDeleted AS current_isDeleted,
|
||||||
|
notes.deleteId AS current_deleteId,
|
||||||
|
notes.isErased AS current_isErased,
|
||||||
notes.title AS current_title,
|
notes.title AS current_title,
|
||||||
notes.isProtected AS current_isProtected,
|
notes.isProtected AS current_isProtected,
|
||||||
notes.title,
|
notes.title,
|
||||||
notes.utcDateCreated AS date
|
notes.utcDateModified AS date
|
||||||
FROM
|
FROM
|
||||||
notes
|
notes
|
||||||
ORDER BY
|
ORDER BY
|
||||||
utcDateCreated DESC
|
utcDateModified DESC
|
||||||
LIMIT 1000
|
LIMIT 200
|
||||||
)
|
)
|
||||||
ORDER BY date DESC
|
ORDER BY date DESC
|
||||||
LIMIT 200`);
|
LIMIT 200`);
|
||||||
@ -48,6 +52,27 @@ async function getRecentChanges() {
|
|||||||
change.title = change.current_title = "[Protected]";
|
change.title = change.current_title = "[Protected]";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (change.current_isDeleted) {
|
||||||
|
if (change.current_isErased) {
|
||||||
|
change.canBeUndeleted = false;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const deleteId = change.current_deleteId;
|
||||||
|
|
||||||
|
const undeletedParentCount = await sql.getValue(`
|
||||||
|
SELECT COUNT(parentNote.noteId)
|
||||||
|
FROM branches
|
||||||
|
JOIN notes AS parentNote ON parentNote.noteId = branches.parentNoteId
|
||||||
|
WHERE branches.noteId = ?
|
||||||
|
AND branches.isDeleted = 1
|
||||||
|
AND branches.deleteId = ?
|
||||||
|
AND parentNote.isDeleted = 0`, [change.noteId, deleteId]);
|
||||||
|
|
||||||
|
// note (and the subtree) can be undeleted if there's at least one undeleted parent (whose branch would be undeleted by this op)
|
||||||
|
change.canBeUndeleted = undeletedParentCount > 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return recentChanges;
|
return recentChanges;
|
||||||
|
@ -4,8 +4,8 @@ const build = require('./build');
|
|||||||
const packageJson = require('../../package');
|
const packageJson = require('../../package');
|
||||||
const {TRILIUM_DATA_DIR} = require('./data_dir');
|
const {TRILIUM_DATA_DIR} = require('./data_dir');
|
||||||
|
|
||||||
const APP_DB_VERSION = 155;
|
const APP_DB_VERSION = 156;
|
||||||
const SYNC_VERSION = 13;
|
const SYNC_VERSION = 14;
|
||||||
const CLIPPER_PROTOCOL_VERSION = "1.0";
|
const CLIPPER_PROTOCOL_VERSION = "1.0";
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
@ -389,8 +389,14 @@ async function updateNote(noteId, noteUpdates) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @return {boolean} - true if note has been deleted, false otherwise */
|
/**
|
||||||
async function deleteBranch(branch, taskContext) {
|
* @param {Branch} branch
|
||||||
|
* @param {string} deleteId
|
||||||
|
* @param {TaskContext} taskContext
|
||||||
|
*
|
||||||
|
* @return {boolean} - true if note has been deleted, false otherwise
|
||||||
|
*/
|
||||||
|
async function deleteBranch(branch, deleteId, taskContext) {
|
||||||
taskContext.increaseProgressCount();
|
taskContext.increaseProgressCount();
|
||||||
|
|
||||||
if (!branch || branch.isDeleted) {
|
if (!branch || branch.isDeleted) {
|
||||||
@ -405,6 +411,7 @@ async function deleteBranch(branch, taskContext) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
branch.isDeleted = true;
|
branch.isDeleted = true;
|
||||||
|
branch.deleteId = deleteId;
|
||||||
await branch.save();
|
await branch.save();
|
||||||
|
|
||||||
const note = await branch.getNote();
|
const note = await branch.getNote();
|
||||||
@ -412,19 +419,22 @@ async function deleteBranch(branch, taskContext) {
|
|||||||
|
|
||||||
if (notDeletedBranches.length === 0) {
|
if (notDeletedBranches.length === 0) {
|
||||||
note.isDeleted = true;
|
note.isDeleted = true;
|
||||||
|
note.deleteId = deleteId;
|
||||||
await note.save();
|
await note.save();
|
||||||
|
|
||||||
for (const childBranch of await note.getChildBranches()) {
|
for (const childBranch of await note.getChildBranches()) {
|
||||||
await deleteBranch(childBranch, taskContext);
|
await deleteBranch(childBranch, deleteId, taskContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const attribute of await note.getOwnedAttributes()) {
|
for (const attribute of await note.getOwnedAttributes()) {
|
||||||
attribute.isDeleted = true;
|
attribute.isDeleted = true;
|
||||||
|
attribute.deleteId = deleteId;
|
||||||
await attribute.save();
|
await attribute.save();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const relation of await note.getTargetRelations()) {
|
for (const relation of await note.getTargetRelations()) {
|
||||||
relation.isDeleted = true;
|
relation.isDeleted = true;
|
||||||
|
relation.deleteId = deleteId;
|
||||||
await relation.save();
|
await relation.save();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user