mirror of
https://github.com/NodeBB/NodeBB.git
synced 2026-03-03 11:01:20 +01:00
feat: allow re-ordering of auto-categorization rules
This commit is contained in:
@@ -7,6 +7,8 @@ define('admin/settings/activitypub', [
|
|||||||
'api',
|
'api',
|
||||||
'alerts',
|
'alerts',
|
||||||
'translator',
|
'translator',
|
||||||
|
|
||||||
|
'jquery-ui/widgets/sortable',
|
||||||
], function (Benchpress, bootbox, categorySelector, api, alerts, translator) {
|
], function (Benchpress, bootbox, categorySelector, api, alerts, translator) {
|
||||||
const ActivityPub = {};
|
const ActivityPub = {};
|
||||||
|
|
||||||
@@ -106,30 +108,55 @@ define('admin/settings/activitypub', [
|
|||||||
|
|
||||||
function setupRules() {
|
function setupRules() {
|
||||||
const rulesEl = document.getElementById('rules');
|
const rulesEl = document.getElementById('rules');
|
||||||
if (rulesEl) {
|
if (!rulesEl) {
|
||||||
rulesEl.addEventListener('click', (e) => {
|
return;
|
||||||
const subselector = e.target.closest('[data-action]');
|
}
|
||||||
if (subselector) {
|
|
||||||
const action = subselector.getAttribute('data-action');
|
|
||||||
switch (action) {
|
|
||||||
case 'rules.add': {
|
|
||||||
ActivityPub.throwRulesModal();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case 'rules.delete': {
|
rulesEl.addEventListener('click', (e) => {
|
||||||
const rid = subselector.closest('tr').getAttribute('data-rid');
|
const subselector = e.target.closest('[data-action]');
|
||||||
api.del(`/admin/activitypub/rules/${rid}`, {}).then(async (data) => {
|
if (subselector) {
|
||||||
const html = await Benchpress.render('admin/settings/activitypub', { rules: data }, 'rules');
|
const action = subselector.getAttribute('data-action');
|
||||||
const tbodyEl = document.querySelector('#rules tbody');
|
switch (action) {
|
||||||
if (tbodyEl) {
|
case 'rules.add': {
|
||||||
tbodyEl.innerHTML = html;
|
ActivityPub.throwRulesModal();
|
||||||
}
|
break;
|
||||||
}).catch(alerts.error);
|
}
|
||||||
}
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}).catch(alerts.error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const tbodyEl = $(rulesEl).find('tbody');
|
||||||
|
tbodyEl.sortable({
|
||||||
|
handle: '.drag-handle',
|
||||||
|
helper: fixWidthHelper,
|
||||||
|
placeholder: 'ui-state-highlight',
|
||||||
|
axis: 'y',
|
||||||
|
update: function () {
|
||||||
|
var rids = [];
|
||||||
|
tbodyEl.find('tr').each(function () {
|
||||||
|
rids.push($(this).data('rid'));
|
||||||
|
});
|
||||||
|
|
||||||
|
api.put('/admin/activitypub/rules/order', { rids }).catch(alerts.error);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
function fixWidthHelper(e, ui) {
|
||||||
|
ui.children().each(function () {
|
||||||
|
$(this).width($(this).width());
|
||||||
});
|
});
|
||||||
|
return ui;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -41,4 +41,12 @@ Rules.delete = async (rid) => {
|
|||||||
db.sortedSetRemove('categorization:rid', rid),
|
db.sortedSetRemove('categorization:rid', rid),
|
||||||
db.delete(`rid:${rid}`),
|
db.delete(`rid:${rid}`),
|
||||||
]);
|
]);
|
||||||
|
};
|
||||||
|
|
||||||
|
Rules.reorder = async (rids) => {
|
||||||
|
const exists = await db.isSortedSetMembers('categorization:rid', rids);
|
||||||
|
rids = rids.filter((_, idx) => exists[idx]);
|
||||||
|
const scores = Array.from({ length: rids.length }, (_, idx) => idx);
|
||||||
|
|
||||||
|
await db.sortedSetAdd('categorization:rid', scores, rids);
|
||||||
};
|
};
|
||||||
@@ -104,6 +104,12 @@ Admin.activitypub.deleteRule = async (req, res) => {
|
|||||||
helpers.formatApiResponse(200, res, await activitypub.rules.list());
|
helpers.formatApiResponse(200, res, await activitypub.rules.list());
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Admin.activitypub.reorderRules = async (req, res) => {
|
||||||
|
const { rids } = req.body;
|
||||||
|
await activitypub.rules.reorder(rids);
|
||||||
|
helpers.formatApiResponse(200, res, await activitypub.rules.list());
|
||||||
|
};
|
||||||
|
|
||||||
Admin.activitypub.addRelay = async (req, res) => {
|
Admin.activitypub.addRelay = async (req, res) => {
|
||||||
const { url } = req.body;
|
const { url } = req.body;
|
||||||
|
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ module.exports = function () {
|
|||||||
|
|
||||||
setupApiRoute(router, 'post', '/activitypub/rules', [...middlewares, middleware.checkRequired.bind(null, ['cid', 'value', 'type'])], controllers.write.admin.activitypub.addRule);
|
setupApiRoute(router, 'post', '/activitypub/rules', [...middlewares, middleware.checkRequired.bind(null, ['cid', 'value', 'type'])], controllers.write.admin.activitypub.addRule);
|
||||||
setupApiRoute(router, 'delete', '/activitypub/rules/:rid', [...middlewares], controllers.write.admin.activitypub.deleteRule);
|
setupApiRoute(router, 'delete', '/activitypub/rules/:rid', [...middlewares], controllers.write.admin.activitypub.deleteRule);
|
||||||
|
setupApiRoute(router, 'put', '/activitypub/rules/order', [...middlewares, middleware.checkRequired.bind(null, ['rids'])], controllers.write.admin.activitypub.reorderRules);
|
||||||
setupApiRoute(router, 'post', '/activitypub/relays', [...middlewares, middleware.checkRequired.bind(null, ['url'])], controllers.write.admin.activitypub.addRelay);
|
setupApiRoute(router, 'post', '/activitypub/relays', [...middlewares, middleware.checkRequired.bind(null, ['url'])], controllers.write.admin.activitypub.addRelay);
|
||||||
setupApiRoute(router, 'delete', '/activitypub/relays/:url', [...middlewares], controllers.write.admin.activitypub.removeRelay);
|
setupApiRoute(router, 'delete', '/activitypub/relays/:url', [...middlewares], controllers.write.admin.activitypub.removeRelay);
|
||||||
|
|
||||||
|
|||||||
@@ -51,14 +51,18 @@
|
|||||||
<p>[[admin/settings/activitypub:rules-intro]]</p>
|
<p>[[admin/settings/activitypub:rules-intro]]</p>
|
||||||
<table class="table table-striped" id="rules">
|
<table class="table table-striped" id="rules">
|
||||||
<thead>
|
<thead>
|
||||||
|
<th></th>
|
||||||
<th>[[admin/settings/activitypub:rules.type]]</th>
|
<th>[[admin/settings/activitypub:rules.type]]</th>
|
||||||
<th>[[admin/settings/activitypub:rules.value]]</th>
|
<th>[[admin/settings/activitypub:rules.value]]</th>
|
||||||
<th>[[admin/settings/activitypub:rules.cid]]</th>
|
<th>[[admin/settings/activitypub:rules.cid]]</th>
|
||||||
<th></th>
|
<th></th>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody class="sortable-container">
|
||||||
{{{ each rules }}}
|
{{{ each rules }}}
|
||||||
<tr data-rid="{./rid}">
|
<tr data-rid="{./rid}">
|
||||||
|
<td class="align-items-center" style="cursor: move;">
|
||||||
|
<i class="fa fa-grip-lines text-muted drag-handle"></i>
|
||||||
|
</td>
|
||||||
<td>{./type}</td>
|
<td>{./type}</td>
|
||||||
<td>{./value}</td>
|
<td>{./value}</td>
|
||||||
<td>{./cid}</td>
|
<td>{./cid}</td>
|
||||||
|
|||||||
Reference in New Issue
Block a user