FEATURE: dropdown to filter staff action logs

This commit is contained in:
Sam 2017-05-30 11:25:42 -04:00
parent 22b488704e
commit 607998af33
8 changed files with 105 additions and 51 deletions

View File

@ -5,9 +5,20 @@ import StaffActionLog from 'admin/models/staff-action-log';
export default Ember.Controller.extend({
loading: false,
filters: null,
userHistoryActions: [],
filtersExists: Ember.computed.gt('filterCount', 0),
filterActionIdChanged: function(){
const filterActionId = this.get('filterActionId');
if (filterActionId) {
this._changeFilters({
action_name: this.get('userHistoryActions').findBy("id", parseInt(filterActionId,10)).name_raw,
action_id: filterActionId
});
}
}.observes('filterActionId'),
actionFilter: function() {
var name = this.get('filters.action_name');
if (name) {
@ -20,7 +31,6 @@ export default Ember.Controller.extend({
showInstructions: Ember.computed.gt('model.length', 0),
refresh: function() {
var self = this;
this.set('loading', true);
var filters = this.get('filters'),
@ -37,10 +47,21 @@ export default Ember.Controller.extend({
});
this.set('filterCount', count);
StaffActionLog.findAll(params).then(function(result) {
self.set('model', result);
}).finally(function() {
self.set('loading', false);
StaffActionLog.findAll(params).then((result) => {
this.set('model', result.staff_action_logs);
if (this.get('userHistoryActions').length === 0) {
let actionTypes = result.user_history_actions.map(pair => {
return {
id: pair.id,
name: I18n.t("admin.logs.staff_actions.actions." + pair.name),
name_raw: pair.name
};
});
actionTypes = _.sortBy(actionTypes, row => row.name);
this.set('userHistoryActions', actionTypes);
}
}).finally(()=>{
this.set('loading', false);
});
},
@ -63,6 +84,7 @@ export default Ember.Controller.extend({
changed.action_name = null;
changed.action_id = null;
changed.custom_type = null;
this.set("filterActionId", null);
} else {
changed[key] = null;
}
@ -70,6 +92,7 @@ export default Ember.Controller.extend({
},
clearAllFilters: function() {
this.set("filterActionId", null);
this.resetFilters();
},

View File

@ -57,10 +57,13 @@ StaffActionLog.reopenClass({
},
findAll: function(filters) {
return ajax("/admin/logs/staff_action_logs.json", { data: filters }).then(function(staff_actions) {
return staff_actions.map(function(s) {
return StaffActionLog.create(s);
});
return ajax("/admin/logs/staff_action_logs.json", { data: filters }).then((data) => {
return {
staff_action_logs: data.staff_action_logs.map(function(s) {
return StaffActionLog.create(s);
}),
user_history_actions: data.user_history_actions
};
});
}
});

View File

@ -1,41 +1,43 @@
<div class="staff-action-logs-controls">
<a {{action "clearAllFilters"}} class="clear-filters filter {{unless filtersExists 'invisible'}}">
<span class="label">{{i18n 'admin.logs.staff_actions.clear_filters'}}</span>
</a>
{{#if actionFilter}}
<a {{action "clearFilter" "actionFilter"}} class="filter">
<span class="label">{{i18n 'admin.logs.action'}}</span>: {{actionFilter}}
{{fa-icon "times-circle"}}
{{#if filtersExists}}
<div>
<a {{action "clearAllFilters"}} class="clear-filters filter">
<span class="label">{{i18n 'admin.logs.staff_actions.clear_filters'}}</span>
</a>
{{#if actionFilter}}
<a {{action "clearFilter" "actionFilter"}} class="filter">
<span class="label">{{i18n 'admin.logs.action'}}</span>: {{actionFilter}}
{{fa-icon "times-circle"}}
</a>
{{/if}}
{{#if filters.acting_user}}
<a {{action "clearFilter" "acting_user"}} class="filter">
<span class="label">{{i18n 'admin.logs.staff_actions.staff_user'}}</span>: {{filters.acting_user}}
{{fa-icon "times-circle"}}
</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}}
{{fa-icon "times-circle"}}
</a>
{{/if}}
{{#if filters.subject}}
<a {{action "clearFilter" "subject"}} class="filter">
<span class="label">{{i18n 'admin.logs.staff_actions.subject'}}</span>: {{filters.subject}}
{{fa-icon "times-circle"}}
</a>
{{/if}}
</div>
{{else}}
{{i18n "admin.logs.staff_actions.filter"}} {{combo-box content=userHistoryActions nameProperty="name" value=filterActionId none="admin.logs.staff_actions.all"}}
{{/if}}
{{#if filters.acting_user}}
<a {{action "clearFilter" "acting_user"}} class="filter">
<span class="label">{{i18n 'admin.logs.staff_actions.staff_user'}}</span>: {{filters.acting_user}}
{{fa-icon "times-circle"}}
</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}}
{{fa-icon "times-circle"}}
</a>
{{/if}}
{{#if filters.subject}}
<a {{action "clearFilter" "subject"}} class="filter">
<span class="label">{{i18n 'admin.logs.staff_actions.subject'}}</span>: {{filters.subject}}
{{fa-icon "times-circle"}}
</a>
{{/if}}
</div>
<div class="pull-right">
{{d-button action="exportStaffActionLogs" label="admin.export_csv.button_text" icon="download"}}
</div>
<br>
<div class="staff-action-logs-instructions {{unless showInstructions 'invisible'}}">
{{i18n 'admin.logs.staff_actions.instructions'}}
<div class="pull-right">
{{d-button action="exportStaffActionLogs" label="admin.export_csv.button_text" icon="download"}}
</div>
</div>
<div class="clearfix"></div>
<div class='table staff-actions'>
<div class="heading-container">

View File

@ -1305,10 +1305,6 @@ table.api-keys {
}
}
.staff-action-logs-instructions {
margin: 0 0 10px 10px;
}
// Ember.ListView
.ember-list-view {

View File

@ -2,8 +2,12 @@ class Admin::StaffActionLogsController < Admin::AdminController
def index
filters = params.slice(*UserHistory.staff_filters)
staff_action_logs = UserHistory.staff_action_records(current_user, filters).to_a
render_serialized(staff_action_logs, UserHistorySerializer)
render json: StaffActionLogsSerializer.new({
staff_action_logs: staff_action_logs,
user_history_actions: UserHistory.staff_actions.sort.map{|name| {id: UserHistory.actions[name], name: name}}
}, root: false)
end
def diff

View File

@ -0,0 +1,12 @@
class StaffActionLogsSerializer < ApplicationSerializer
attributes :user_history_actions
has_many :staff_action_logs, serializer: UserHistorySerializer, embed: :objects
def staff_action_logs
object[:staff_action_logs]
end
def user_history_actions
object[:user_history_actions]
end
end

View File

@ -3025,8 +3025,9 @@ en:
block: "block"
do_nothing: "do nothing"
staff_actions:
all: "all"
filter: "Filter:"
title: "Staff Actions"
instructions: "Click usernames and actions to filter the list. Click profile pictures to go to user pages."
clear_filters: "Show Everything"
staff_user: "Staff User"
target_user: "Target User"
@ -3079,6 +3080,8 @@ en:
change_readonly_mode: "change readonly mode"
backup_download: "download backup"
backup_destroy: "destroy backup"
reviewed_post: "reviewed post"
custom_staff: "plugin custom action"
screened_emails:
title: "Screened Emails"
description: "When someone tries to create a new account, the following email addresses will be checked and the registration will be blocked, or some other action performed."

View File

@ -9,10 +9,21 @@ describe Admin::StaffActionLogsController do
context '.index' do
it 'works' do
xhr :get, :index
it 'generates logs' do
topic = Fabricate(:topic)
_record = StaffActionLogger.new(Discourse.system_user).log_topic_deletion(topic)
xhr :get, :index, action_id: UserHistory.actions[:delete_topic]
json = JSON.parse(response.body)
expect(response).to be_success
expect(::JSON.parse(response.body)).to be_a(Array)
expect(json["staff_action_logs"].length).to eq(1)
expect(json["staff_action_logs"][0]["action_name"]).to eq("delete_topic")
expect(json["user_history_actions"]).to include({"id" => UserHistory.actions[:delete_topic], "name" => 'delete_topic'})
end
end