Feature: Improve reports ui (#7032)

* Further improvements to Reports UI

- Clean up notes display
- Clean up add new note form
- Simplify controller
- Allow reopening a report with a note
- Show created at date for reports
- Fix report details table formatting

* Show history of report using Admin::ActionLog beneath the report

* Fix incorrect log message when reopening a report

* Implement fetching of all ActionLog items that could be related to the report

* Ensure adding a report_note updates the report's updated_at

* Limit Report History to actions that happened between the report being created and the report being resolved

* Fix linting issues

* Improve report history builder

Thanks @gargron for the improvements
main
Emelia Smith 2018-04-10 20:27:59 +02:00 committed by Eugen Rochko
parent 45c9f16f71
commit d9b62e34da
8 changed files with 147 additions and 43 deletions

View File

@ -8,19 +8,26 @@ module Admin
authorize ReportNote, :create? authorize ReportNote, :create?
@report_note = current_account.report_notes.new(resource_params) @report_note = current_account.report_notes.new(resource_params)
@report = @report_note.report
if @report_note.save if @report_note.save
if params[:create_and_resolve] if params[:create_and_resolve]
@report_note.report.update!(action_taken: true, action_taken_by_account_id: current_account.id) @report.resolve!(current_account)
log_action :resolve, @report_note.report log_action :resolve, @report
redirect_to admin_reports_path, notice: I18n.t('admin.reports.resolved_msg') redirect_to admin_reports_path, notice: I18n.t('admin.reports.resolved_msg')
else return
redirect_to admin_report_path(@report_note.report_id), notice: I18n.t('admin.report_notes.created_msg')
end end
if params[:create_and_unresolve]
@report.unresolve!
log_action :reopen, @report
end
redirect_to admin_report_path(@report), notice: I18n.t('admin.report_notes.created_msg')
else else
@report = @report_note.report
@report_notes = @report.notes.latest @report_notes = @report.notes.latest
@report_history = @report.history
@form = Form::StatusBatch.new @form = Form::StatusBatch.new
render template: 'admin/reports/show' render template: 'admin/reports/show'

View File

@ -13,6 +13,7 @@ module Admin
authorize @report, :show? authorize @report, :show?
@report_note = @report.notes.new @report_note = @report.notes.new
@report_notes = @report.notes.latest @report_notes = @report.notes.latest
@report_history = @report.history
@form = Form::StatusBatch.new @form = Form::StatusBatch.new
end end
@ -38,36 +39,33 @@ module Admin
@report.update!(assigned_account_id: nil) @report.update!(assigned_account_id: nil)
log_action :unassigned, @report log_action :unassigned, @report
when 'reopen' when 'reopen'
@report.update!(action_taken: false, action_taken_by_account_id: nil) @report.unresolve!
log_action :reopen, @report log_action :reopen, @report
when 'resolve' when 'resolve'
@report.update!(action_taken_by_current_attributes) @report.resolve!(current_account)
log_action :resolve, @report log_action :resolve, @report
when 'suspend' when 'suspend'
Admin::SuspensionWorker.perform_async(@report.target_account.id) Admin::SuspensionWorker.perform_async(@report.target_account.id)
log_action :resolve, @report log_action :resolve, @report
log_action :suspend, @report.target_account log_action :suspend, @report.target_account
resolve_all_target_account_reports resolve_all_target_account_reports
@report.reload
when 'silence' when 'silence'
@report.target_account.update!(silenced: true) @report.target_account.update!(silenced: true)
log_action :resolve, @report log_action :resolve, @report
log_action :silence, @report.target_account log_action :silence, @report.target_account
resolve_all_target_account_reports resolve_all_target_account_reports
@report.reload
else else
raise ActiveRecord::RecordNotFound raise ActiveRecord::RecordNotFound
end end
end @report.reload
def action_taken_by_current_attributes
{ action_taken: true, action_taken_by_account_id: current_account.id }
end end
def resolve_all_target_account_reports def resolve_all_target_account_reports
unresolved_reports_for_target_account.update_all( unresolved_reports_for_target_account.update_all(action_taken: true, action_taken_by_account_id: current_account.id)
action_taken_by_current_attributes
)
end end
def unresolved_reports_for_target_account def unresolved_reports_for_target_account

View File

@ -145,6 +145,11 @@
border: 0; border: 0;
background: transparent; background: transparent;
border-bottom: 1px solid $ui-base-color; border-bottom: 1px solid $ui-base-color;
&.section-break {
margin: 30px 0;
border-bottom: 2px solid $ui-base-lighter-color;
}
} }
.muted-hint { .muted-hint {
@ -330,6 +335,36 @@
} }
} }
.report-note__comment {
margin-bottom: 20px;
}
.report-note__form {
margin-bottom: 20px;
.report-note__textarea {
box-sizing: border-box;
border: 0;
padding: 7px 4px;
margin-bottom: 10px;
font-size: 16px;
color: $ui-base-color;
display: block;
width: 100%;
outline: 0;
font-family: inherit;
resize: vertical;
}
.report-note__buttons {
text-align: right;
}
.report-note__button {
margin: 0 0 5px 5px;
}
}
.batch-form-box { .batch-form-box {
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;

View File

@ -39,4 +39,50 @@ class Report < ApplicationRecord
def media_attachments def media_attachments
MediaAttachment.where(status_id: status_ids) MediaAttachment.where(status_id: status_ids)
end end
def assign_to_self!(current_account)
update!(assigned_account_id: current_account.id)
end
def unassign!
update!(assigned_account_id: nil)
end
def resolve!(acting_account)
update!(action_taken: true, action_taken_by_account_id: acting_account.id)
end
def unresolve!
update!(action_taken: false, action_taken_by_account_id: nil)
end
def unresolved?
!action_taken?
end
def history
time_range = created_at..updated_at
sql = [
Admin::ActionLog.where(
target_type: 'Report',
target_id: id,
created_at: time_range
).unscope(:order),
Admin::ActionLog.where(
target_type: 'Account',
target_id: target_account_id,
created_at: time_range
).unscope(:order),
Admin::ActionLog.where(
target_type: 'Status',
target_id: status_ids,
created_at: time_range
).unscope(:order),
].map { |query| "(#{query.to_sql})" }.join(' UNION ALL ')
Admin::ActionLog.from("(#{sql}) AS admin_action_logs")
end
end end

View File

@ -13,7 +13,7 @@
class ReportNote < ApplicationRecord class ReportNote < ApplicationRecord
belongs_to :account belongs_to :account
belongs_to :report, inverse_of: :notes belongs_to :report, inverse_of: :notes, touch: true
scope :latest, -> { reorder('created_at ASC') } scope :latest, -> { reorder('created_at ASC') }

View File

@ -1,11 +1,9 @@
%tr %li
%td %h4
%p = report_note.account.acct
%strong= report_note.account.acct %div{ style: 'float: right' }
on
%time.formatted{ datetime: report_note.created_at.iso8601, title: l(report_note.created_at) } %time.formatted{ datetime: report_note.created_at.iso8601, title: l(report_note.created_at) }
= l report_note.created_at = l report_note.created_at
= table_link_to 'trash', t('admin.reports.notes.delete'), admin_report_note_path(report_note), method: :delete if can?(:destroy, report_note) = table_link_to 'trash', t('admin.reports.notes.delete'), admin_report_note_path(report_note), method: :delete if can?(:destroy, report_note)
%br/ %div{ class: 'report-note__comment' }
%br/
= simple_format(h(report_note.content)) = simple_format(h(report_note.content))

View File

@ -5,7 +5,7 @@
= t('admin.reports.report', id: @report.id) = t('admin.reports.report', id: @report.id)
%div{ style: 'overflow: hidden; margin-bottom: 20px' } %div{ style: 'overflow: hidden; margin-bottom: 20px' }
- if !@report.action_taken? - if @report.unresolved?
%div{ style: 'float: right' } %div{ style: 'float: right' }
= link_to t('admin.reports.silence_account'), admin_report_path(@report, outcome: 'silence'), method: :put, class: 'button' = link_to t('admin.reports.silence_account'), admin_report_path(@report, outcome: 'silence'), method: :put, class: 'button'
= link_to t('admin.reports.suspend_account'), admin_report_path(@report, outcome: 'suspend'), method: :put, class: 'button' = link_to t('admin.reports.suspend_account'), admin_report_path(@report, outcome: 'suspend'), method: :put, class: 'button'
@ -17,22 +17,29 @@
.table-wrapper .table-wrapper
%table.table.inline-table %table.table.inline-table
%tbody %tbody
%tr
%th= t('admin.reports.created_at')
%td{colspan: 2}
%time.formatted{ datetime: @report.created_at.iso8601 }
%tr %tr
%th= t('admin.reports.updated_at') %th= t('admin.reports.updated_at')
%td{colspan: 2} %td{colspan: 2}
%time.formatted{ datetime: @report.updated_at.iso8601 } %time.formatted{ datetime: @report.updated_at.iso8601 }
%tr %tr
%th= t('admin.reports.status') %th= t('admin.reports.status')
%td{colspan: 2} %td
- if @report.action_taken? - if @report.action_taken?
= t('admin.reports.resolved') = t('admin.reports.resolved')
= table_link_to 'envelope-open', t('admin.reports.reopen'), admin_report_path(@report, outcome: 'reopen'), method: :put
- else - else
= t('admin.reports.unresolved') = t('admin.reports.unresolved')
%td{style: "text-align: right; overflow: hidden;"}
- if @report.action_taken?
= table_link_to 'envelope-open', t('admin.reports.reopen'), admin_report_path(@report, outcome: 'reopen'), method: :put
- if !@report.action_taken_by_account.nil? - if !@report.action_taken_by_account.nil?
%tr %tr
%th= t('admin.reports.action_taken_by') %th= t('admin.reports.action_taken_by')
%td= @report.action_taken_by_account.acct %td{colspan: 2}
= @report.action_taken_by_account.acct
- else - else
%tr %tr
%th= t('admin.reports.assigned') %th= t('admin.reports.assigned')
@ -47,6 +54,8 @@
- if !@report.assigned_account.nil? - if !@report.assigned_account.nil?
= table_link_to 'trash', t('admin.reports.unassign'), admin_report_path(@report, outcome: 'unassign'), method: :put = table_link_to 'trash', t('admin.reports.unassign'), admin_report_path(@report, outcome: 'unassign'), method: :put
%hr{ class: "section-break"}/
.report-accounts .report-accounts
.report-accounts__item .report-accounts__item
%h3= t('admin.reports.reported_account') %h3= t('admin.reports.reported_account')
@ -88,22 +97,28 @@
= link_to admin_report_reported_status_path(@report, status), method: :delete, class: 'icon-button trash-button', title: t('admin.reports.delete'), data: { confirm: t('admin.reports.are_you_sure') }, remote: true do = link_to admin_report_reported_status_path(@report, status), method: :delete, class: 'icon-button trash-button', title: t('admin.reports.delete'), data: { confirm: t('admin.reports.are_you_sure') }, remote: true do
= fa_icon 'trash' = fa_icon 'trash'
%hr/ %hr{ class: "section-break"}/
%h3= t('admin.reports.notes.label') %h3= t('admin.reports.notes.label')
- if @report_notes.length > 0 - if @report_notes.length > 0
.table-wrapper %ul
%table.table
%thead
%tr
%th
%tbody
= render @report_notes = render @report_notes
= simple_form_for @report_note, url: admin_report_notes_path do |f| %h4= t('admin.reports.notes.new_label')
= form_for @report_note, url: admin_report_notes_path, html: { class: 'report-note__form' } do |f|
= render 'shared/error_messages', object: @report_note = render 'shared/error_messages', object: @report_note
= f.input :content = f.text_area :content, placeholder: t('admin.reports.notes.placeholder'), rows: 6, class: 'report-note__textarea'
= f.hidden_field :report_id = f.hidden_field :report_id
= f.button :button, t('admin.reports.notes.create'), type: :submit %div{ class: 'report-note__buttons' }
= f.button :button, t('admin.reports.notes.create_and_resolve'), type: :submit, name: :create_and_resolve - if @report.unresolved?
= f.submit t('admin.reports.notes.create_and_resolve'), name: :create_and_resolve, class: 'button report-note__button'
- else
= f.submit t('admin.reports.notes.create_and_unresolve'), name: :create_and_unresolve, class: 'button report-note__button'
= f.submit t('admin.reports.notes.create'), class: 'button report-note__button'
- if @report_history.length > 0
%h3= t('admin.reports.history')
%ul
= render @report_history

View File

@ -256,8 +256,8 @@ en:
title: Filter title: Filter
title: Invites title: Invites
report_notes: report_notes:
created_msg: Moderation note successfully created! created_msg: Report note successfully created!
destroyed_msg: Moderation note successfully destroyed! destroyed_msg: Report note successfully deleted!
reports: reports:
action_taken_by: Action taken by action_taken_by: Action taken by
are_you_sure: Are you sure? are_you_sure: Are you sure?
@ -266,15 +266,20 @@ en:
comment: comment:
label: Report Comment label: Report Comment
none: None none: None
created_at: Reported
delete: Delete delete: Delete
history: Moderation History
id: ID id: ID
mark_as_resolved: Mark as resolved mark_as_resolved: Mark as resolved
mark_as_unresolved: Mark as unresolved mark_as_unresolved: Mark as unresolved
notes: notes:
create: Add Note create: Add Note
create_and_resolve: Resolve with Note create_and_resolve: Resolve with Note
create_and_unresolve: Reopen with Note
delete: Delete delete: Delete
label: Notes label: Moderator Notes
new_label: Add Moderator Note
placeholder: Describe what actions have been taken, or any other updates to this report…
nsfw: nsfw:
'false': Unhide media attachments 'false': Unhide media attachments
'true': Hide media attachments 'true': Hide media attachments