diff --git a/db/migrations/0217__attachments.sql b/db/migrations/0217__attachments.sql index 121c02414..4d55a9238 100644 --- a/db/migrations/0217__attachments.sql +++ b/db/migrations/0217__attachments.sql @@ -6,6 +6,7 @@ CREATE TABLE IF NOT EXISTS "attachments" mime TEXT not null, title TEXT not null, isProtected INT not null DEFAULT 0, + position INT default 0 not null, blobId TEXT DEFAULT null, dateModified TEXT NOT NULL, utcDateModified TEXT not null, diff --git a/db/schema.sql b/db/schema.sql index 2d770999a..6adda2fbe 100644 --- a/db/schema.sql +++ b/db/schema.sql @@ -117,6 +117,7 @@ CREATE TABLE IF NOT EXISTS "attachments" mime TEXT not null, title TEXT not null, isProtected INT not null DEFAULT 0, + position INT default 0 not null, blobId TEXT DEFAULT null, dateModified TEXT NOT NULL, utcDateModified TEXT not null, diff --git a/src/becca/entities/battachment.js b/src/becca/entities/battachment.js index 53a2034bd..963994ae9 100644 --- a/src/becca/entities/battachment.js +++ b/src/becca/entities/battachment.js @@ -4,10 +4,9 @@ const utils = require('../../services/utils'); const dateUtils = require('../../services/date_utils'); const becca = require('../becca'); const AbstractBeccaEntity = require("./abstract_becca_entity"); +const sql = require("../../services/sql"); /** - * FIXME: how to order attachments? - * * Attachment represent data related/attached to the note. Conceptually similar to attributes, but intended for * larger amounts of data and generally not accessible to the user. * @@ -42,6 +41,8 @@ class BAttachment extends AbstractBeccaEntity { this.mime = row.mime; /** @type {string} */ this.title = row.title; + /** @type {number} */ + this.position = row.position; /** @type {string} */ this.blobId = row.blobId; /** @type {boolean} */ @@ -80,6 +81,12 @@ class BAttachment extends AbstractBeccaEntity { beforeSaving() { super.beforeSaving(); + if (this.position === undefined || this.position === null) { + this.position = 10 + sql.getValue(`SELECT COALESCE(MAX(position), 0) + FROM attachments + WHERE parentId = ?`, [this.noteId]); + } + this.dateModified = dateUtils.localNowDateTime(); this.utcDateModified = dateUtils.utcNowDateTime(); } @@ -91,6 +98,7 @@ class BAttachment extends AbstractBeccaEntity { role: this.role, mime: this.mime, title: this.title, + position: this.position, blobId: this.blobId, isProtected: !!this.isProtected, isDeleted: false, diff --git a/src/becca/entities/battribute.js b/src/becca/entities/battribute.js index 49b9fa258..61213061a 100644 --- a/src/becca/entities/battribute.js +++ b/src/becca/entities/battribute.js @@ -188,9 +188,11 @@ class BAttribute extends AbstractBeccaEntity { this.value = ""; } - if (this.position === undefined) { - // TODO: can be calculated from becca - this.position = 1 + sql.getValue(`SELECT COALESCE(MAX(position), 0) FROM attributes WHERE noteId = ?`, [this.noteId]); + if (this.position === undefined || this.position === null) { + const maxExistingPosition = this.getNote().getAttributes() + .reduce((maxPosition, attr) => Math.max(maxPosition, attr.position), 0); + + this.position = maxExistingPosition + 10; } if (!this.isInheritable) { diff --git a/src/becca/entities/bnote.js b/src/becca/entities/bnote.js index e3260de09..a16143406 100644 --- a/src/becca/entities/bnote.js +++ b/src/becca/entities/bnote.js @@ -1218,10 +1218,10 @@ class BNote extends AbstractBeccaEntity { * @param {string} name - name of the attribute, not including the leading ~/# * @param {string} [value] - value of the attribute - text for labels, target note ID for relations; optional. * @param {boolean} [isInheritable=false] - * @param {int} [position] + * @param {int|null} [position] * @returns {BAttribute} */ - addAttribute(type, name, value = "", isInheritable = false, position = 1000) { + addAttribute(type, name, value = "", isInheritable = false, position = null) { const BAttribute = require("./battribute"); return new BAttribute({ diff --git a/src/share/routes.js b/src/share/routes.js index 6ea82e62a..cd3aa206b 100644 --- a/src/share/routes.js +++ b/src/share/routes.js @@ -37,6 +37,7 @@ function requestCredentials(res) { .sendStatus(401); } +/** @returns {SNote|boolean} */ function checkNoteAccess(noteId, req, res) { const note = shaca.getNote(noteId);