diff --git a/public/src/admin/settings/activitypub.js b/public/src/admin/settings/activitypub.js new file mode 100644 index 0000000000..ad112b2398 --- /dev/null +++ b/public/src/admin/settings/activitypub.js @@ -0,0 +1,79 @@ +'use strict'; + +define('admin/settings/activitypub', [ + 'benchpress', + 'bootbox', + 'categorySelector', + 'api', +], function (Benchpress, bootbox, categorySelector, api) { + const Module = {}; + + Module.init = function () { + const rulesEl = document.getElementById('rules'); + if (rulesEl) { + rulesEl.addEventListener('click', (e) => { + const subselector = e.target.closest('[data-action]'); + if (subselector) { + const action = subselector.getAttribute('data-action'); + switch (action) { + case 'rules.add': { + Module.throwRulesModal(); + break; + } + + case 'rules.delete': { + const rid = subselector.closest('tr').getAttribute('data-rid'); + api.del(`/admin/activitypub/rules/${rid}`, {}).then(async (data) => { + const html = await Benchpress.render('admin/settings/activitypub', { rules: data }, 'rules'); + const tbodyEl = document.querySelector('#rules tbody'); + if (tbodyEl) { + tbodyEl.innerHTML = html; + } + }); + } + } + } + }); + } + }; + + Module.throwRulesModal = function () { + Benchpress.render('admin/partials/activitypub/rules', {}).then(function (html) { + const submit = function () { + const formEl = modal.find('form').get(0); + const payload = Object.fromEntries(new FormData(formEl)); + + api.post('/admin/activitypub/rules', payload).then(async (data) => { + const html = await Benchpress.render('admin/settings/activitypub', { rules: data }, 'rules'); + const tbodyEl = document.querySelector('#rules tbody'); + if (tbodyEl) { + tbodyEl.innerHTML = html; + } + }); + }; + const modal = bootbox.dialog({ + title: '[[admin/settings/activitypub:rules.add]]', + message: html, + buttons: { + save: { + label: '[[global:save]]', + className: 'btn-primary', + callback: submit, + }, + }, + }); + + // category switcher + categorySelector.init(modal.find('[component="category-selector"]'), { + onSelect: function (selectedCategory) { + modal.find('[name="cid"]').val(selectedCategory.cid); + }, + cacheList: false, + showLinks: true, + template: 'admin/partials/category/selector-dropdown-right', + }); + }); + }; + + return Module; +}); diff --git a/src/activitypub/rules.js b/src/activitypub/rules.js new file mode 100644 index 0000000000..3a9a560552 --- /dev/null +++ b/src/activitypub/rules.js @@ -0,0 +1,33 @@ +'use strict'; + +const db = require('../database'); +const utils = require('../utils'); + +const Rules = module.exports; + +Rules.list = async () => { + const rids = await db.getSortedSetMembers('categorization:rid'); + let rules = await db.getObjects(rids.map(rid => `rid:${rid}`)); + rules = rules.map((rule, idx) => { + rule.rid = rids[idx]; + return rule; + }); + + return rules; +}; + +Rules.add = async (type, value, cid) => { + const uuid = utils.generateUUID(); + + await Promise.all([ + db.setObject(`rid:${uuid}`, { type, value, cid }), + db.sortedSetAdd('categorization:rid', Date.now(), uuid), + ]); +}; + +Rules.delete = async (rid) => { + await Promise.all([ + db.sortedSetRemove('categorization:rid', rid), + db.delete(`rid:${rid}`), + ]); +}; \ No newline at end of file diff --git a/src/views/admin/partials/activitypub/rules.tpl b/src/views/admin/partials/activitypub/rules.tpl new file mode 100644 index 0000000000..e321a86744 --- /dev/null +++ b/src/views/admin/partials/activitypub/rules.tpl @@ -0,0 +1,26 @@ +
[[admin/settings/activitypub:rules.modal.title]]
+[[admin/settings/activitypub:rules.modal.instructions]]
+ +