notifications: add context field
This commit is contained in:
9
migrations/20241211205706-notifications-add-context.js
Normal file
9
migrations/20241211205706-notifications-add-context.js
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
exports.up = async function (db) {
|
||||||
|
await db.runSql('ALTER TABLE notifications ADD COLUMN context VARCHAR(128) DEFAULT ""');
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.down = async function (db) {
|
||||||
|
await db.runSql('ALTER TABLE notifications DROP COLUMN context');
|
||||||
|
};
|
||||||
@@ -272,6 +272,7 @@ CREATE TABLE IF NOT EXISTS notifications(
|
|||||||
message TEXT,
|
message TEXT,
|
||||||
acknowledged BOOLEAN DEFAULT false,
|
acknowledged BOOLEAN DEFAULT false,
|
||||||
creationTime TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
creationTime TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
context VARCHAR(128) DEFAULT "", // used along with "type" to create uniqueness
|
||||||
|
|
||||||
INDEX creationTime_index (creationTime),
|
INDEX creationTime_index (creationTime),
|
||||||
FOREIGN KEY(eventId) REFERENCES eventlog(id),
|
FOREIGN KEY(eventId) REFERENCES eventlog(id),
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ const assert = require('assert'),
|
|||||||
mailer = require('./mailer.js'),
|
mailer = require('./mailer.js'),
|
||||||
users = require('./users.js');
|
users = require('./users.js');
|
||||||
|
|
||||||
const NOTIFICATION_FIELDS = [ 'id', 'eventId', 'type', 'title', 'message', 'creationTime', 'acknowledged' ];
|
const NOTIFICATION_FIELDS = [ 'id', 'eventId', 'type', 'title', 'message', 'creationTime', 'acknowledged', 'context' ];
|
||||||
|
|
||||||
function postProcess(result) {
|
function postProcess(result) {
|
||||||
assert.strictEqual(typeof result, 'object');
|
assert.strictEqual(typeof result, 'object');
|
||||||
@@ -63,8 +63,8 @@ async function add(type, title, message, data) {
|
|||||||
assert.strictEqual(typeof message, 'string');
|
assert.strictEqual(typeof message, 'string');
|
||||||
assert.strictEqual(typeof data, 'object');
|
assert.strictEqual(typeof data, 'object');
|
||||||
|
|
||||||
const query = 'INSERT INTO notifications (type, title, message, acknowledged, eventId) VALUES (?, ?, ?, ?, ?)';
|
const query = 'INSERT INTO notifications (type, title, message, acknowledged, eventId, context) VALUES (?, ?, ?, ?, ?, ?)';
|
||||||
const args = [ type, title, message, false, data?.eventId || null ];
|
const args = [ type, title, message, false, data?.eventId || null, data.context || '' ];
|
||||||
|
|
||||||
const result = await database.query(query, args);
|
const result = await database.query(query, args);
|
||||||
return String(result.insertId);
|
return String(result.insertId);
|
||||||
@@ -79,10 +79,11 @@ async function get(id) {
|
|||||||
return postProcess(result[0]);
|
return postProcess(result[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getByType(type) {
|
async function getByType(type, context) {
|
||||||
assert.strictEqual(typeof type, 'string');
|
assert.strictEqual(typeof type, 'string');
|
||||||
|
assert.strictEqual(typeof context, 'string');
|
||||||
|
|
||||||
const results = await database.query(`SELECT ${NOTIFICATION_FIELDS} from notifications WHERE type = ? ORDER BY creationTime LIMIT 1`, [ type ]);
|
const results = await database.query(`SELECT ${NOTIFICATION_FIELDS} from notifications WHERE type = ? AND context = ? ORDER BY creationTime LIMIT 1`, [ type, context || '']);
|
||||||
if (results.length === 0) return null;
|
if (results.length === 0) return null;
|
||||||
|
|
||||||
return postProcess(results[0]);
|
return postProcess(results[0]);
|
||||||
@@ -280,16 +281,14 @@ async function pin(type, title, message, options) {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const isUpdateType = type === exports.TYPE_BOX_UPDATE || type === exports.TYPE_MANUAL_APP_UPDATE_NEEDED;
|
const result = await getByType(type, options.context || '');
|
||||||
if (options.context) type = `${type}-${options.context}`; // create a unique type for this context
|
if (!result) return await add(type, title, message, { eventId: null, context: options.context || '' });
|
||||||
|
|
||||||
const result = await getByType(type);
|
|
||||||
if (!result) return await add(type, title, message, { eventId: null });
|
|
||||||
|
|
||||||
// do not reset the ack state if user has already seen the update notification
|
// do not reset the ack state if user has already seen the update notification
|
||||||
|
const isUpdateType = type === exports.TYPE_BOX_UPDATE || type === exports.TYPE_MANUAL_APP_UPDATE_NEEDED;
|
||||||
const acknowledged = (isUpdateType && result.message === message) ? result.acknowledged : false;
|
const acknowledged = (isUpdateType && result.message === message) ? result.acknowledged : false;
|
||||||
|
|
||||||
await update(result, { id: result.id, title, message, acknowledged, creationTime: new Date() });
|
await update(result, { title, message, acknowledged, creationTime: new Date() });
|
||||||
return result.id;
|
return result.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -297,8 +296,7 @@ async function unpin(type, options) {
|
|||||||
assert.strictEqual(typeof type, 'string'); // TYPE_
|
assert.strictEqual(typeof type, 'string'); // TYPE_
|
||||||
assert.strictEqual(typeof options, 'object');
|
assert.strictEqual(typeof options, 'object');
|
||||||
|
|
||||||
if (options.context) type = `${type}-${options.context}`; // create a unique type for this context
|
await database.query('UPDATE notifications SET acknowledged=1 WHERE type = ? AND context = ?', [ type, options.context || '' ]);
|
||||||
await database.query('UPDATE notifications SET acknowledged=1 WHERE type = ?', [ type ]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function onEvent(id, action, source, data) {
|
async function onEvent(id, action, source, data) {
|
||||||
|
|||||||
@@ -132,6 +132,8 @@ describe('Notifications', function () {
|
|||||||
it('can add pin', async function () {
|
it('can add pin', async function () {
|
||||||
pinId = await notifications.pin(notifications.TYPE_REBOOT, 'Reboot required', 'Do it now', {});
|
pinId = await notifications.pin(notifications.TYPE_REBOOT, 'Reboot required', 'Do it now', {});
|
||||||
|
|
||||||
|
console.log(pinId);
|
||||||
|
|
||||||
const result = await notifications.get(pinId);
|
const result = await notifications.get(pinId);
|
||||||
expect(result.title).to.be('Reboot required');
|
expect(result.title).to.be('Reboot required');
|
||||||
expect(result.message).to.be('Do it now');
|
expect(result.message).to.be('Do it now');
|
||||||
|
|||||||
Reference in New Issue
Block a user