diff --git a/public/language/en-GB/admin/advanced/events.json b/public/language/en-GB/admin/advanced/events.json index 766eb5e951..56d9457971 100644 --- a/public/language/en-GB/admin/advanced/events.json +++ b/public/language/en-GB/admin/advanced/events.json @@ -2,5 +2,11 @@ "events": "Events", "no-events": "There are no events", "control-panel": "Events Control Panel", - "delete-events": "Delete Events" + "delete-events": "Delete Events", + "filters": "Filters", + "filters-apply": "Apply Filters", + "filter-type": "Event Type", + "filter-start": "Start Date", + "filter-end": "End Date", + "filter-perPage": "Per Page" } \ No newline at end of file diff --git a/public/less/admin/advanced/events.less b/public/less/admin/advanced/events.less index 1ab80d047c..4f4c95afbb 100644 --- a/public/less/admin/advanced/events.less +++ b/public/less/admin/advanced/events.less @@ -1,6 +1,8 @@ -.delete-event { - i { - cursor: pointer; - margin-left: 10px; +.events-list { + .delete-event { + i { + cursor: pointer; + margin-left: 10px; + } } -} \ No newline at end of file +} diff --git a/public/src/admin/advanced/events.js b/public/src/admin/advanced/events.js index 42895451dc..147ad193e5 100644 --- a/public/src/admin/advanced/events.js +++ b/public/src/admin/advanced/events.js @@ -25,10 +25,14 @@ define('admin/advanced/events', function () { }); }); - $('#filter').on('change', function () { - var filter = $(this).val(); - ajaxify.go('admin/advanced/events' + (filter ? '?filter=' + filter : '')); - }); + $('#apply').on('click', Events.refresh); + }; + + Events.refresh = function (event) { + event.preventDefault(); + + var formEl = $('#filters'); + ajaxify.go('admin/advanced/events?' + formEl.serialize()); }; return Events; diff --git a/src/controllers/admin/events.js b/src/controllers/admin/events.js index 73038f2894..080f72f336 100644 --- a/src/controllers/admin/events.js +++ b/src/controllers/admin/events.js @@ -10,26 +10,31 @@ var eventsController = module.exports; eventsController.get = function (req, res, next) { var page = parseInt(req.query.page, 10) || 1; - var itemsPerPage = 20; + var itemsPerPage = parseInt(req.query.perPage, 10) || 20; var start = (page - 1) * itemsPerPage; var stop = start + itemsPerPage - 1; - var currentFilter = req.query.filter || ''; + // Limit by date + var from = req.query.start ? new Date(req.query.start) || undefined : undefined; + var to = req.query.end ? new Date(req.query.end) || undefined : new Date(); + from = from && from.setHours(0, 0, 0, 0); // setHours returns a unix timestamp (Number, not Date) + to = to && to.setHours(23, 59, 59, 999); // setHours returns a unix timestamp (Number, not Date) + + var currentFilter = req.query.type || ''; async.waterfall([ function (next) { async.parallel({ eventCount: function (next) { - db.sortedSetCard('events:time' + (currentFilter ? ':' + currentFilter : ''), next); + db.sortedSetCount('events:time' + (currentFilter ? ':' + currentFilter : ''), from || '-inf', to, next); }, events: function (next) { - events.getEvents(currentFilter, start, stop, next); + events.getEvents(currentFilter, start, stop, from || '-inf', to, next); }, }, next); }, function (results) { - var types = [''].concat(events.types); - var filters = types.map(function (type) { + var types = [''].concat(events.types).map(function (type) { return { value: type, name: type || 'all', @@ -42,7 +47,8 @@ eventsController.get = function (req, res, next) { res.render('admin/advanced/events', { events: results.events, pagination: pagination.create(page, pageCount, req.query), - filters: filters, + types: types, + query: req.query, }); }, ], next); diff --git a/src/events.js b/src/events.js index 1c6aeae09c..6da4abda5b 100644 --- a/src/events.js +++ b/src/events.js @@ -48,6 +48,7 @@ events.types = [ 'export:uploads', 'account-locked', 'getUsersCSV', + // To add new types from plugins, just Array.push() to this array ]; /** @@ -82,10 +83,17 @@ events.log = function (data, callback) { }); }; -events.getEvents = function (filter, start, stop, callback) { +events.getEvents = function (filter, start, stop, from, to, callback) { + // from/to optional + if (typeof from === 'function' && !to && !callback) { + callback = from; + from = 0; + to = Date.now(); + } + async.waterfall([ function (next) { - db.getSortedSetRevRange('events:time' + (filter ? ':' + filter : ''), start, stop, next); + db.getSortedSetRevRangeByScore('events:time' + (filter ? ':' + filter : ''), start, stop - start + 1, to, from, next); }, function (eids, next) { db.getObjects(eids.map(eid => 'event:' + eid), next); diff --git a/src/views/admin/advanced/events.tpl b/src/views/admin/advanced/events.tpl index 55ad612a56..f7a4a94c3c 100644 --- a/src/views/admin/advanced/events.tpl +++ b/src/views/admin/advanced/events.tpl @@ -1,10 +1,5 @@
-
[[admin/advanced/events:events]]
@@ -14,19 +9,21 @@
- #{events.eid} {events.type} + #{events.eid} + {events.type} + uid {events.uid} + {events.ip} - + -
{events.user.icon:text}
+
{events.user.icon:text}
- {events.user.username} (uid {events.uid}) (IP {events.ip}) + {events.user.username} {events.timestampISO} -

-
{events.jsonString}
+
{events.jsonString}
@@ -36,9 +33,36 @@
-
+
[[admin/advanced/events:filters]]
- + +
+
+
+
+