|
|
|
@ -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) {
|
|
|
|
|