mirror of
https://github.com/NodeBB/NodeBB.git
synced 2026-01-01 21:30:30 +01:00
feat: logic for bulk actions in flags list, #8571
This commit is contained in:
@@ -72,5 +72,9 @@
|
||||
"modal-submit-success": "Content has been flagged for moderation.",
|
||||
"modal-submit-confirm": "Confirm Submission",
|
||||
"modal-submit-confirm-text": "You have a custom reason specified already. Are you sure you wish to submit via quick-report?",
|
||||
"modal-submit-confirm-text-help": "Submitting a quick report will overwrite any custom reasons defined."
|
||||
"modal-submit-confirm-text-help": "Submitting a quick report will overwrite any custom reasons defined.",
|
||||
|
||||
"bulk-actions": "Bulk Actions",
|
||||
"bulk-resolve": "Resolve Flag(s)",
|
||||
"bulk-success": "%1 flags updated"
|
||||
}
|
||||
@@ -5,11 +5,14 @@ define('forum/flags/list', ['components', 'Chart'], function (components, Chart)
|
||||
|
||||
Flags.init = function () {
|
||||
Flags.enableFilterForm();
|
||||
Flags.enableCheckboxes();
|
||||
Flags.handleBulkActions();
|
||||
|
||||
components.get('flags/list').on('click', '[data-flag-id]', function () {
|
||||
var flagId = this.getAttribute('data-flag-id');
|
||||
ajaxify.go('flags/' + flagId);
|
||||
});
|
||||
components.get('flags/list')
|
||||
.on('click', '[data-flag-id]', function () {
|
||||
var flagId = this.getAttribute('data-flag-id');
|
||||
ajaxify.go('flags/' + flagId);
|
||||
});
|
||||
|
||||
var graphWrapper = $('#flags-daily-wrapper');
|
||||
var graphFooter = graphWrapper.siblings('.panel-footer');
|
||||
@@ -38,6 +41,137 @@ define('forum/flags/list', ['components', 'Chart'], function (components, Chart)
|
||||
});
|
||||
};
|
||||
|
||||
Flags.enableCheckboxes = function () {
|
||||
var flagsList = document.querySelector('[component="flags/list"]');
|
||||
var checkboxes = flagsList.querySelectorAll('[data-flag-id] input[type="checkbox"]');
|
||||
var bulkEl = document.querySelector('[component="flags/bulk-actions"] button');
|
||||
var lastClicked;
|
||||
|
||||
document.querySelector('[data-action="toggle-all"]').addEventListener('click', function () {
|
||||
var state = this.checked;
|
||||
|
||||
checkboxes.forEach(function (el) {
|
||||
el.checked = state;
|
||||
});
|
||||
});
|
||||
|
||||
flagsList.addEventListener('click', function (e) {
|
||||
var subselector = e.target.closest('input[type="checkbox"]');
|
||||
if (subselector) {
|
||||
// Stop checkbox clicks from going into the flag details
|
||||
e.stopImmediatePropagation();
|
||||
|
||||
if (lastClicked && e.shiftKey && lastClicked !== subselector) {
|
||||
// Select all the checkboxes in between
|
||||
var state = subselector.checked;
|
||||
var started = false;
|
||||
|
||||
checkboxes.forEach(function (el) {
|
||||
if ([subselector, lastClicked].some(function (ref) {
|
||||
return ref === el;
|
||||
})) {
|
||||
started = !started;
|
||||
}
|
||||
|
||||
if (started) {
|
||||
el.checked = state;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// (De)activate bulk actions button based on checkboxes' state
|
||||
bulkEl.disabled = !Array.prototype.some.call(checkboxes, function (el) {
|
||||
return el.checked;
|
||||
});
|
||||
|
||||
lastClicked = subselector;
|
||||
}
|
||||
|
||||
// If you miss the checkbox, don't descend into the flag details, either
|
||||
if (e.target.querySelector('input[type="checkbox"]')) {
|
||||
e.stopImmediatePropagation();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
Flags.handleBulkActions = function () {
|
||||
document.querySelector('[component="flags/bulk-actions"]').addEventListener('click', function (e) {
|
||||
var subselector = e.target.closest('[data-action]');
|
||||
if (subselector) {
|
||||
var action = subselector.getAttribute('data-action');
|
||||
var flagIds = Flags.getSelected();
|
||||
var promises = [];
|
||||
|
||||
flagIds.forEach(function (flagId) {
|
||||
promises.push(new Promise(function (resolve, reject) {
|
||||
var handler = function (err) {
|
||||
if (err) {
|
||||
reject(err);
|
||||
}
|
||||
|
||||
resolve(arguments[1]);
|
||||
};
|
||||
|
||||
switch (action) {
|
||||
case 'bulk-assign':
|
||||
socket.emit('flags.update', {
|
||||
flagId: flagId,
|
||||
data: [
|
||||
{
|
||||
name: 'assignee',
|
||||
value: app.user.uid,
|
||||
},
|
||||
],
|
||||
}, handler);
|
||||
break;
|
||||
|
||||
case 'bulk-mark-resolved':
|
||||
socket.emit('flags.update', {
|
||||
flagId: flagId,
|
||||
data: [
|
||||
{
|
||||
name: 'state',
|
||||
value: 'resolved',
|
||||
},
|
||||
],
|
||||
}, handler);
|
||||
break;
|
||||
}
|
||||
}));
|
||||
});
|
||||
|
||||
Promise.allSettled(promises).then(function (results) {
|
||||
var fulfilled = results.filter(function (res) {
|
||||
return res.status === 'fulfilled';
|
||||
}).length;
|
||||
var errors = results.filter(function (res) {
|
||||
return res.status === 'rejected';
|
||||
});
|
||||
if (fulfilled) {
|
||||
app.alertSuccess('[[flags:bulk-success, ' + fulfilled + ']]');
|
||||
}
|
||||
|
||||
console.log(errors);
|
||||
errors.forEach(function (res) {
|
||||
app.alertError(res.reason);
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
Flags.getSelected = function () {
|
||||
var checkboxes = document.querySelectorAll('[component="flags/list"] [data-flag-id] input[type="checkbox"]');
|
||||
var payload = [];
|
||||
checkboxes.forEach(function (el) {
|
||||
if (el.checked) {
|
||||
payload.push(el.closest('[data-flag-id]').getAttribute('data-flag-id'));
|
||||
}
|
||||
});
|
||||
|
||||
return payload;
|
||||
};
|
||||
|
||||
Flags.handleGraphs = function () {
|
||||
var dailyCanvas = document.getElementById('flags:daily');
|
||||
var dailyLabels = utils.getDaysArray().map(function (text, idx) {
|
||||
|
||||
Reference in New Issue
Block a user