mirror of
				https://github.com/TriliumNext/Notes.git
				synced 2025-11-04 15:11:31 +08: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,
 | 
			
		||||
  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` (
 | 
			
		||||
                                                              `entityName`,
 | 
			
		||||
                                                              `entityId`
 | 
			
		||||
@ -47,12 +34,6 @@ CREATE UNIQUE INDEX `IDX_sync_entityName_entityId` ON `sync` (
 | 
			
		||||
CREATE INDEX `IDX_sync_utcSyncDate` ON `sync` (
 | 
			
		||||
                                            `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" (
 | 
			
		||||
                                                   `noteId`	TEXT NOT NULL,
 | 
			
		||||
                                                   `content`	TEXT NULL DEFAULT NULL,
 | 
			
		||||
@ -68,46 +49,10 @@ CREATE TABLE recent_notes
 | 
			
		||||
    utcDateCreated TEXT not null,
 | 
			
		||||
    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,
 | 
			
		||||
                                                 `content`	TEXT,
 | 
			
		||||
                                                 hash TEXT DEFAULT '' 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,
 | 
			
		||||
                                                 `noteId`	TEXT NOT NULL,
 | 
			
		||||
                                                 `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_dateCreated` ON `note_revisions` (`dateCreated`);
 | 
			
		||||
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 {boolean} isInheritable
 | 
			
		||||
 * @property {boolean} isDeleted
 | 
			
		||||
 * @property {string|null} deleteId - ID identifying delete transaction
 | 
			
		||||
 * @property {string} utcDateCreated
 | 
			
		||||
 * @property {string} utcDateModified
 | 
			
		||||
 *
 | 
			
		||||
 | 
			
		||||
@ -16,6 +16,7 @@ const sql = require('../services/sql');
 | 
			
		||||
 * @property {string} prefix
 | 
			
		||||
 * @property {boolean} isExpanded
 | 
			
		||||
 * @property {boolean} isDeleted
 | 
			
		||||
 * @property {string|null} deleteId - ID identifying delete transaction
 | 
			
		||||
 * @property {string} utcDateModified
 | 
			
		||||
 * @property {string} utcDateCreated
 | 
			
		||||
 *
 | 
			
		||||
@ -25,7 +26,7 @@ class Branch extends Entity {
 | 
			
		||||
    static get entityName() { return "branches"; }
 | 
			
		||||
    static get primaryKeyName() { return "branchId"; }
 | 
			
		||||
    // 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 = {}) {
 | 
			
		||||
        super(row);
 | 
			
		||||
 | 
			
		||||
@ -24,6 +24,7 @@ const RELATION_DEFINITION = 'relation-definition';
 | 
			
		||||
 * @property {int} contentLength - length of content
 | 
			
		||||
 * @property {boolean} isProtected - true if note is protected
 | 
			
		||||
 * @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 {string} dateCreated - 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 {
 | 
			
		||||
    static get entityName() { return "notes"; }
 | 
			
		||||
    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
 | 
			
		||||
 | 
			
		||||
@ -28,31 +28,38 @@ export async function showDialog() {
 | 
			
		||||
    const groupedByDate = groupByDate(result);
 | 
			
		||||
 | 
			
		||||
    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) {
 | 
			
		||||
            const formattedTime = utils.formatTime(utils.parseDate(change.date));
 | 
			
		||||
 | 
			
		||||
            let noteLink;
 | 
			
		||||
            let $noteLink;
 | 
			
		||||
 | 
			
		||||
            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 {
 | 
			
		||||
                const note = await treeCache.getNote(change.noteId);
 | 
			
		||||
                const notePath = await treeService.getSomeNotePath(note);
 | 
			
		||||
 | 
			
		||||
                noteLink = await linkService.createNoteLink(notePath, {
 | 
			
		||||
                $noteLink = await linkService.createNoteLink(notePath, {
 | 
			
		||||
                    title: change.title,
 | 
			
		||||
                    showNotePath: true
 | 
			
		||||
                });
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            changesListEl.append($('<li>')
 | 
			
		||||
            $changesList.append($('<li>')
 | 
			
		||||
                .append(formattedTime + ' - ')
 | 
			
		||||
                .append(noteLink));
 | 
			
		||||
                .append($noteLink));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $content.append(dayEl);
 | 
			
		||||
@ -85,5 +92,6 @@ function groupByDate(result) {
 | 
			
		||||
 | 
			
		||||
        groupedByDate.get(dateDay).push(row);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return groupedByDate;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -10,6 +10,12 @@ function getNotePathFromUrl(url) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async function createNoteLink(notePath, options = {}) {
 | 
			
		||||
    if (!notePath || !notePath.trim()) {
 | 
			
		||||
        console.error("Missing note path");
 | 
			
		||||
 | 
			
		||||
        return $("<span>").text("[missing note]");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    let noteTitle = options.title;
 | 
			
		||||
    const showTooltip = options.showTooltip === undefined ? true : options.showTooltip;
 | 
			
		||||
    const showNotePath = options.showNotePath === undefined ? false : options.showNotePath;
 | 
			
		||||
 | 
			
		||||
@ -316,6 +316,8 @@ async function getSomeNotePath(note) {
 | 
			
		||||
        cur = parents[0];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    path.push('root');
 | 
			
		||||
 | 
			
		||||
    return path.reverse().join('/');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -101,7 +101,8 @@ async function deleteBranch(req) {
 | 
			
		||||
    const branch = await repository.getBranch(req.params.branchId);
 | 
			
		||||
    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) {
 | 
			
		||||
        taskContext.taskSucceeded();
 | 
			
		||||
 | 
			
		||||
@ -55,12 +55,15 @@ async function deleteNote(req) {
 | 
			
		||||
    const taskId = req.query.taskId;
 | 
			
		||||
    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 taskContext = TaskContext.getInstance(taskId, 'delete-notes');
 | 
			
		||||
 | 
			
		||||
    for (const branch of await note.getBranches()) {
 | 
			
		||||
        await noteService.deleteBranch(branch, taskContext);
 | 
			
		||||
        await noteService.deleteBranch(branch, deleteId, taskContext);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (last) {
 | 
			
		||||
 | 
			
		||||
@ -10,6 +10,8 @@ async function getRecentChanges() {
 | 
			
		||||
            SELECT 
 | 
			
		||||
                notes.noteId,
 | 
			
		||||
                notes.isDeleted AS current_isDeleted,
 | 
			
		||||
                notes.deleteId AS current_deleteId,
 | 
			
		||||
                notes.isErased AS current_isErased,
 | 
			
		||||
                notes.title AS current_title,
 | 
			
		||||
                notes.isProtected AS current_isProtected,
 | 
			
		||||
                note_revisions.title,
 | 
			
		||||
@ -19,21 +21,23 @@ async function getRecentChanges() {
 | 
			
		||||
                JOIN notes USING(noteId)
 | 
			
		||||
            ORDER BY
 | 
			
		||||
                note_revisions.utcDateCreated DESC
 | 
			
		||||
            LIMIT 1000
 | 
			
		||||
            LIMIT 200
 | 
			
		||||
        )
 | 
			
		||||
        UNION ALL SELECT * FROM (
 | 
			
		||||
            SELECT
 | 
			
		||||
                notes.noteId,
 | 
			
		||||
                notes.isDeleted AS current_isDeleted,
 | 
			
		||||
                notes.deleteId AS current_deleteId,
 | 
			
		||||
                notes.isErased AS current_isErased,
 | 
			
		||||
                notes.title AS current_title,
 | 
			
		||||
                notes.isProtected AS current_isProtected,
 | 
			
		||||
                notes.title,
 | 
			
		||||
                notes.utcDateCreated AS date
 | 
			
		||||
                notes.utcDateModified AS date
 | 
			
		||||
            FROM
 | 
			
		||||
                notes
 | 
			
		||||
            ORDER BY
 | 
			
		||||
                utcDateCreated DESC
 | 
			
		||||
            LIMIT 1000
 | 
			
		||||
                utcDateModified DESC
 | 
			
		||||
            LIMIT 200
 | 
			
		||||
        )
 | 
			
		||||
        ORDER BY date DESC 
 | 
			
		||||
        LIMIT 200`);
 | 
			
		||||
@ -48,6 +52,27 @@ async function getRecentChanges() {
 | 
			
		||||
                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;
 | 
			
		||||
 | 
			
		||||
@ -4,8 +4,8 @@ const build = require('./build');
 | 
			
		||||
const packageJson = require('../../package');
 | 
			
		||||
const {TRILIUM_DATA_DIR} = require('./data_dir');
 | 
			
		||||
 | 
			
		||||
const APP_DB_VERSION = 155;
 | 
			
		||||
const SYNC_VERSION = 13;
 | 
			
		||||
const APP_DB_VERSION = 156;
 | 
			
		||||
const SYNC_VERSION = 14;
 | 
			
		||||
const CLIPPER_PROTOCOL_VERSION = "1.0";
 | 
			
		||||
 | 
			
		||||
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();
 | 
			
		||||
 | 
			
		||||
    if (!branch || branch.isDeleted) {
 | 
			
		||||
@ -405,6 +411,7 @@ async function deleteBranch(branch, taskContext) {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    branch.isDeleted = true;
 | 
			
		||||
    branch.deleteId = deleteId;
 | 
			
		||||
    await branch.save();
 | 
			
		||||
 | 
			
		||||
    const note = await branch.getNote();
 | 
			
		||||
@ -412,19 +419,22 @@ async function deleteBranch(branch, taskContext) {
 | 
			
		||||
 | 
			
		||||
    if (notDeletedBranches.length === 0) {
 | 
			
		||||
        note.isDeleted = true;
 | 
			
		||||
        note.deleteId = deleteId;
 | 
			
		||||
        await note.save();
 | 
			
		||||
 | 
			
		||||
        for (const childBranch of await note.getChildBranches()) {
 | 
			
		||||
            await deleteBranch(childBranch, taskContext);
 | 
			
		||||
            await deleteBranch(childBranch, deleteId, taskContext);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        for (const attribute of await note.getOwnedAttributes()) {
 | 
			
		||||
            attribute.isDeleted = true;
 | 
			
		||||
            attribute.deleteId = deleteId;
 | 
			
		||||
            await attribute.save();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        for (const relation of await note.getTargetRelations()) {
 | 
			
		||||
            relation.isDeleted = true;
 | 
			
		||||
            relation.deleteId = deleteId;
 | 
			
		||||
            await relation.save();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user