Add filtering to staff logs page

This commit is contained in:
Neil Lalonde 2013-08-09 16:58:57 -04:00
parent 652169daf6
commit bb492eb8bf
9 changed files with 115 additions and 26 deletions

View File

@ -8,36 +8,52 @@
**/ **/
Discourse.AdminLogsStaffActionLogsController = Ember.ArrayController.extend(Discourse.Presence, { Discourse.AdminLogsStaffActionLogsController = Ember.ArrayController.extend(Discourse.Presence, {
loading: false, loading: false,
filters: null, filters: {},
show: function(filters) { show: function() {
var self = this; var self = this;
this.set('loading', true); this.set('loading', true);
Discourse.URL.set('queryParams', this.get('filters')); // TODO: doesn't work
Discourse.StaffActionLog.findAll(this.get('filters')).then(function(result) { Discourse.StaffActionLog.findAll(this.get('filters')).then(function(result) {
self.set('content', result); self.set('content', result);
self.set('loading', false); self.set('loading', false);
}); });
}, }.observes('filters.action_name', 'filters.staff_user', 'filters.target_user'),
toggleFullDetails: function(target) { toggleFullDetails: function(target) {
target.set('showFullDetails', !target.get('showFullDetails')); target.set('showFullDetails', !target.get('showFullDetails'));
}, },
clearFiltersClass: function() { filtersExists: function() {
if (this.get('filters') === null) { return (_.size(this.get('filters')) > 0);
return 'invisible'; }.property('filters.action_name', 'filters.staff_user', 'filters.target_user'),
} else {
return '';
}
}.property('filters'),
clearFilters: function() { clearFilter: function(key) {
this.set('filters', null); delete this.get('filters')[key];
this.show(); this.notifyPropertyChange('filters');
},
clearAllFilters: function() {
this.set('filters', {});
}, },
filterByAction: function(action) { filterByAction: function(action) {
this.set('filters', {action_name: action}); this.set('filters.action_name', action);
this.show(); },
actionFilter: function() {
if (this.get('filters.action_name')) {
return I18n.t("admin.logs.staff_actions.actions." + this.get('filters.action_name'));
} else {
return null;
}
}.property('filters.action_name'),
filterByStaffUser: function(staff_user) {
this.set('filters.staff_user', staff_user.username);
},
filterByTargetUser: function(target_user) {
this.set('filters.target_user', target_user.username);
} }
}); });

View File

@ -43,7 +43,18 @@ Discourse.AdminLogsStaffActionLogsRoute = Discourse.Route.extend({
this.render('admin/templates/logs/staff_action_logs', {into: 'adminLogs'}); this.render('admin/templates/logs/staff_action_logs', {into: 'adminLogs'});
}, },
setupController: function() { setupController: function(controller) {
return this.controllerFor('adminLogsStaffActionLogs').show(); var queryParams = Discourse.URL.get('queryParams');
if (queryParams) {
controller.set('filters', queryParams);
}
return controller.show();
},
deactivate: function() {
this._super();
// Clear any filters when we leave the route
Discourse.URL.set('queryParams', null);
} }
}); });

View File

@ -1,8 +1,26 @@
<div class="staff-action-logs-controls">
<p> <a {{action clearAllFilters}} {{bindAttr class=":clear-filters :filter filtersExists::invisible"}}>
<a {{action clearFilters}} {{bindAttr class="clearFiltersClass"}}>{{i18n admin.logs.staff_actions.clear_filters}}</a> <span class="label">{{i18n admin.logs.staff_actions.clear_filters}}</span>
</p> </a>
{{#if actionFilter}}
<a {{action clearFilter "action_name"}} class="filter">
<span class="label">{{i18n admin.logs.action}}</span>: {{actionFilter}}
<i class="icon icon-remove-sign"></i>
</a>
{{/if}}
{{#if filters.staff_user}}
<a {{action clearFilter "staff_user"}} class="filter">
<span class="label">{{i18n admin.logs.staff_actions.staff_user}}</span>: {{filters.staff_user}}
<i class="icon icon-remove-sign"></i>
</a>
{{/if}}
{{#if filters.target_user}}
<a {{action clearFilter "target_user"}} class="filter">
<span class="label">{{i18n admin.logs.staff_actions.target_user}}</span>: {{filters.target_user}}
<i class="icon icon-remove-sign"></i>
</a>
{{/if}}
</div>
<div class='table staff-actions'> <div class='table staff-actions'>
<div class="heading-container"> <div class="heading-container">
@ -26,3 +44,9 @@
{{/if}} {{/if}}
{{/if}} {{/if}}
</div> </div>
{{#unless loading}}
<div class="staff-action-logs-instructions">
{{i18n admin.logs.staff_actions.instructions}}
</div>
{{/unless}}

View File

@ -1,6 +1,6 @@
<div class="col value first staff_user"> <div class="col value first staff_user">
{{#linkTo 'adminUser' staff_user}}{{avatar staff_user imageSize="tiny"}}{{/linkTo}} {{#linkTo 'adminUser' staff_user}}{{avatar staff_user imageSize="tiny"}}{{/linkTo}}
{{#linkTo 'adminUser' staff_user}}{{staff_user.username}}{{/linkTo}} <a {{action filterByStaffUser staff_user}}>{{staff_user.username}}</a>
</div> </div>
<div class="col value action"> <div class="col value action">
<a {{action filterByAction action_name}}>{{actionName}}</a> <a {{action filterByAction action_name}}>{{actionName}}</a>
@ -8,7 +8,7 @@
<div class="col value target_user"> <div class="col value target_user">
{{#if target_user}} {{#if target_user}}
{{#linkTo 'adminUser' target_user}}{{avatar target_user imageSize="tiny"}}{{/linkTo}} {{#linkTo 'adminUser' target_user}}{{avatar target_user imageSize="tiny"}}{{/linkTo}}
{{#linkTo 'adminUser' target_user}}{{target_user.username}}{{/linkTo}} <a {{action filterByTargetUser target_user}}>{{target_user.username}}</a>
{{else}} {{else}}
&mdash; &mdash;
{{/if}} {{/if}}

View File

@ -739,6 +739,31 @@ table {
} }
} }
.staff-action-logs-controls {
margin: 0 0 20px 6px;
a.filter {
display: inline-block;
background-color: #ddd;
padding: 3px 10px;
border-radius: 3px;
margin-left: 5px;
color: #444;
&:hover {
color: $link-color-hover;
}
.label {
font-weight: bold;
}
i {
margin-left: 6px;
}
}
}
.staff-action-logs-instructions {
margin: 50px 0 0 10px;
}
// Ember.ListView // Ember.ListView
.ember-list-view { .ember-list-view {

View File

@ -1,7 +1,7 @@
class Admin::StaffActionLogsController < Admin::AdminController class Admin::StaffActionLogsController < Admin::AdminController
def index def index
staff_action_logs = StaffActionLog.with_filters(params.slice(:action_name)).limit(200).order('id DESC').includes(:staff_user, :target_user).to_a staff_action_logs = StaffActionLog.with_filters(params.slice(:action_name, :staff_user, :target_user)).limit(200).order('id DESC').includes(:staff_user, :target_user).to_a
render_serialized(staff_action_logs, StaffActionLogSerializer) render_serialized(staff_action_logs, StaffActionLogSerializer)
end end

View File

@ -17,6 +17,11 @@ class StaffActionLog < ActiveRecord::Base
if filters[:action_name] and action_id = StaffActionLog.actions[filters[:action_name].to_sym] if filters[:action_name] and action_id = StaffActionLog.actions[filters[:action_name].to_sym]
query = query.where('action = ?', action_id) query = query.where('action = ?', action_id)
end end
[:staff_user, :target_user].each do |key|
if filters[key] and obj_id = User.where(username_lower: filters[key].downcase).pluck(:id)
query = query.where("#{key.to_s}_id = ?", obj_id)
end
end
query query
end end
end end

View File

@ -1177,7 +1177,8 @@ en:
do_nothing: "do nothing" do_nothing: "do nothing"
staff_actions: staff_actions:
title: "Staff Actions" title: "Staff Actions"
clear_filters: "Show All" instructions: "Click usernames and actions to filter the list. Click avatars to go to user pages."
clear_filters: "Show Everything"
staff_user: "Staff User" staff_user: "Staff User"
target_user: "Target User" target_user: "Target User"
when: "When" when: "When"

View File

@ -0,0 +1,7 @@
class AddFilterIndexesToStaffActionLogs < ActiveRecord::Migration
def change
add_index :staff_action_logs, [:action, :id]
add_index :staff_action_logs, [:staff_user_id, :id]
add_index :staff_action_logs, [:target_user_id, :id]
end
end