Improve report layout (#7188)

* Use table for statuses in report

* Display reported account and reporter in the same table

* Split accounts and general report info into two tables again

* Redesign report statuses table, notes, merge notes and action log

* Remove unused translations

* Fix code style issue

* Fix code style issue

* Fix code style issue
signup-info-prompt
Eugen Rochko 2018-04-20 02:28:48 +02:00 committed by GitHub
parent 1663368724
commit a9c440637c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
55 changed files with 380 additions and 249 deletions

View File

@ -8,7 +8,7 @@ module Admin
def create def create
authorize :status, :update? authorize :status, :update?
@form = Form::StatusBatch.new(form_status_batch_params.merge(current_account: current_account)) @form = Form::StatusBatch.new(form_status_batch_params.merge(current_account: current_account, action: action_from_button))
flash[:alert] = I18n.t('admin.statuses.failed_to_execute') unless @form.save flash[:alert] = I18n.t('admin.statuses.failed_to_execute') unless @form.save
redirect_to admin_report_path(@report) redirect_to admin_report_path(@report)
@ -35,7 +35,17 @@ module Admin
end end
def form_status_batch_params def form_status_batch_params
params.require(:form_status_batch).permit(:action, status_ids: []) params.require(:form_status_batch).permit(status_ids: [])
end
def action_from_button
if params[:nsfw_on]
'nsfw_on'
elsif params[:nsfw_off]
'nsfw_off'
elsif params[:delete]
'delete'
end
end end
def set_report def set_report

View File

@ -11,10 +11,10 @@ module Admin
def show def show
authorize @report, :show? authorize @report, :show?
@report_note = @report.notes.new
@report_notes = @report.notes.latest @report_note = @report.notes.new
@report_history = @report.history @report_notes = (@report.notes.latest + @report.history).sort_by(&:created_at)
@form = Form::StatusBatch.new @form = Form::StatusBatch.new
end end
def update def update

View File

@ -1,4 +1,20 @@
# frozen_string_literal: true # frozen_string_literal: true
module Admin::AccountModerationNotesHelper module Admin::AccountModerationNotesHelper
def admin_account_link_to(account)
link_to admin_account_path(account.id), class: name_tag_classes(account) do
safe_join([
image_tag(account.avatar.url, width: 15, height: 15, alt: display_name(account), class: 'avatar'),
content_tag(:span, account.acct, class: 'username'),
], ' ')
end
end
private
def name_tag_classes(account)
classes = ['name-tag']
classes << 'suspended' if account.suspended?
classes.join(' ')
end
end end

View File

@ -63,4 +63,8 @@ module ApplicationHelper
def opengraph(property, content) def opengraph(property, content)
tag(:meta, content: content, property: property) tag(:meta, content: content, property: property)
end end
def react_component(name, props = {})
content_tag(:div, nil, data: { component: name.to_s.camelcase, props: Oj.dump(props) })
end
end end

View File

@ -113,6 +113,19 @@ module StreamEntriesHelper
end end
end end
def fa_visibility_icon(status)
case status.visibility
when 'public'
fa_icon 'globe fw'
when 'unlisted'
fa_icon 'unlock-alt fw'
when 'private'
fa_icon 'lock fw'
when 'direct'
fa_icon 'envelope fw'
end
end
private private
def simplified_text(text) def simplified_text(text)

View File

@ -24,6 +24,7 @@ delegate(document, batchCheckboxClassName, 'change', () => {
const checkAllElement = document.querySelector('#batch_checkbox_all'); const checkAllElement = document.querySelector('#batch_checkbox_all');
if (checkAllElement) { if (checkAllElement) {
checkAllElement.checked = [].every.call(document.querySelectorAll(batchCheckboxClassName), (content) => content.checked); checkAllElement.checked = [].every.call(document.querySelectorAll(batchCheckboxClassName), (content) => content.checked);
checkAllElement.indeterminate = !checkAllElement.checked && [].some.call(document.querySelectorAll(batchCheckboxClassName), (content) => content.checked);
} }
}); });

View File

@ -141,14 +141,15 @@
} }
hr { hr {
margin: 20px 0; width: 100%;
height: 0;
border: 0; border: 0;
background: transparent; border-bottom: 1px solid rgba($ui-base-lighter-color, .6);
border-bottom: 1px solid $ui-base-color; margin: 20px 0;
&.section-break { &.spacer {
margin: 30px 0; height: 1px;
border-bottom: 2px solid $ui-base-lighter-color; border: 0;
} }
} }
@ -335,34 +336,8 @@
} }
} }
.report-note__comment { .simple_form.new_report_note {
margin-bottom: 20px; max-width: 100%;
}
.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: $inverted-text-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 {
@ -390,13 +365,6 @@
} }
} }
.batch-checkbox,
.batch-checkbox-all {
display: flex;
align-items: center;
margin-right: 5px;
}
.back-link { .back-link {
margin-bottom: 10px; margin-bottom: 10px;
font-size: 14px; font-size: 14px;
@ -416,7 +384,7 @@
} }
.log-entry { .log-entry {
margin-bottom: 8px; margin-bottom: 20px;
line-height: 20px; line-height: 20px;
&__header { &__header {
@ -514,9 +482,12 @@
} }
} }
a.name-tag,
.name-tag { .name-tag {
display: flex; display: flex;
align-items: center; align-items: center;
text-decoration: none;
color: $ui-secondary-color;
.avatar { .avatar {
display: block; display: block;
@ -528,4 +499,52 @@
.username { .username {
font-weight: 500; font-weight: 500;
} }
&.suspended {
.username {
text-decoration: line-through;
color: lighten($error-red, 12%);
}
.avatar {
filter: grayscale(100%);
opacity: 0.8;
}
}
}
.speech-bubble {
margin-bottom: 20px;
border-left: 4px solid $ui-highlight-color;
&.positive {
border-left-color: $success-green;
}
&.negative {
border-left-color: lighten($error-red, 12%);
}
&__bubble {
padding: 16px;
padding-left: 14px;
font-size: 15px;
line-height: 20px;
border-radius: 4px 4px 4px 0;
position: relative;
font-weight: 500;
a {
color: $ui-primary-color;
}
}
&__owner {
padding: 8px;
padding-left: 12px;
}
time {
color: $darker-text-color;
}
} }

View File

@ -1006,6 +1006,15 @@
padding: 10px; padding: 10px;
border-bottom: 1px solid lighten($ui-base-color, 8%); border-bottom: 1px solid lighten($ui-base-color, 8%);
&.compact {
padding: 0;
border-bottom: 0;
.account__avatar-wrapper {
margin-left: 0;
}
}
.account__display-name { .account__display-name {
flex: 1 1 auto; flex: 1 1 auto;
display: block; display: block;
@ -1029,7 +1038,6 @@
.account__avatar { .account__avatar {
@include avatar-radius(); @include avatar-radius();
position: relative; position: relative;
cursor: pointer;
&-inline { &-inline {
display: inline-block; display: inline-block;
@ -1038,6 +1046,10 @@
} }
} }
a .account__avatar {
cursor: pointer;
}
.account__avatar-overlay { .account__avatar-overlay {
@include avatar-size(48px); @include avatar-size(48px);
@ -1286,7 +1298,7 @@
.status__display-name, .status__display-name,
.reply-indicator__display-name, .reply-indicator__display-name,
.detailed-status__display-name, .detailed-status__display-name,
.account__display-name { a.account__display-name {
&:hover strong { &:hover strong {
text-decoration: underline; text-decoration: underline;
} }

View File

@ -11,6 +11,7 @@
vertical-align: top; vertical-align: top;
border-top: 1px solid $ui-base-color; border-top: 1px solid $ui-base-color;
text-align: left; text-align: left;
background: darken($ui-base-color, 4%);
} }
& > thead > tr > th { & > thead > tr > th {
@ -48,9 +49,38 @@
} }
} }
&.inline-table > tbody > tr:nth-child(odd) > td, &.inline-table {
&.inline-table > tbody > tr:nth-child(odd) > th { & > tbody > tr:nth-child(odd) {
background: transparent; & > td,
& > th {
background: transparent;
}
}
& > tbody > tr:first-child {
& > td,
& > th {
border-top: 0;
}
}
}
&.batch-table {
& > thead > tr > th {
background: $ui-base-color;
border-top: 1px solid darken($ui-base-color, 8%);
border-bottom: 1px solid darken($ui-base-color, 8%);
&:first-child {
border-radius: 4px 0 0;
border-left: 1px solid darken($ui-base-color, 8%);
}
&:last-child {
border-radius: 0 4px 0 0;
border-right: 1px solid darken($ui-base-color, 8%);
}
}
} }
} }
@ -63,6 +93,13 @@ samp {
font-family: 'mastodon-font-monospace', monospace; font-family: 'mastodon-font-monospace', monospace;
} }
button.table-action-link {
background: transparent;
border: 0;
font: inherit;
}
button.table-action-link,
a.table-action-link { a.table-action-link {
text-decoration: none; text-decoration: none;
display: inline-block; display: inline-block;
@ -79,4 +116,77 @@ a.table-action-link {
font-weight: 400; font-weight: 400;
margin-right: 5px; margin-right: 5px;
} }
&:first-child {
padding-left: 0;
}
}
.batch-table {
&__toolbar,
&__row {
display: flex;
&__select {
box-sizing: border-box;
padding: 8px 16px;
cursor: pointer;
min-height: 100%;
input {
margin-top: 8px;
}
}
&__actions,
&__content {
padding: 8px 0;
padding-right: 16px;
flex: 1 1 auto;
}
}
&__toolbar {
border: 1px solid darken($ui-base-color, 8%);
background: $ui-base-color;
border-radius: 4px 0 0;
height: 47px;
align-items: center;
&__actions {
text-align: right;
padding-right: 16px - 5px;
}
}
&__row {
border: 1px solid darken($ui-base-color, 8%);
border-top: 0;
background: darken($ui-base-color, 4%);
&:hover {
background: darken($ui-base-color, 2%);
}
&:nth-child(even) {
background: $ui-base-color;
&:hover {
background: lighten($ui-base-color, 2%);
}
}
&__content {
padding-top: 12px;
padding-bottom: 16px;
}
}
.status__content {
padding-top: 0;
strong {
font-weight: 700;
}
}
} }

View File

@ -1,4 +1,4 @@
%li.log-entry .log-entry
.log-entry__header .log-entry__header
.log-entry__avatar .log-entry__avatar
= image_tag action_log.account.avatar.url(:original), alt: '', width: 40, height: 40, class: 'avatar' = image_tag action_log.account.avatar.url(:original), alt: '', width: 40, height: 40, class: 'avatar'

View File

@ -1,7 +1,6 @@
- content_for :page_title do - content_for :page_title do
= t('admin.action_logs.title') = t('admin.action_logs.title')
%ul = render @action_logs
= render @action_logs
= paginate @action_logs = paginate @action_logs

View File

@ -1,9 +1,7 @@
%li .speech-bubble
%h4 .speech-bubble__bubble
= report_note.account.acct
%div{ style: 'float: right' }
%time.formatted{ datetime: report_note.created_at.iso8601, title: 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)
%div{ class: 'report-note__comment' }
= simple_format(h(report_note.content)) = simple_format(h(report_note.content))
.speech-bubble__owner
= admin_account_link_to report_note.account
%time.formatted{ datetime: report_note.created_at.iso8601 }= 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)

View File

@ -0,0 +1,19 @@
- size ||= 36
.account.compact
.account__wrapper
- if account.nil?
.account__display-name
.account__avatar-wrapper
.account__avatar{ style: "background-image: url(#{full_asset_url('avatars/original/missing.png', skip_pipeline: true)}); width: #{size}px; height: #{size}px; background-size: #{size}px #{size}px" }
%span.display-name
%strong= t 'about.contact_missing'
%span.display-name__account= t 'about.contact_unavailable'
- else
= link_to TagManager.instance.url_for(account), class: 'account__display-name' do
.account__avatar-wrapper
.account__avatar{ style: "background-image: url(#{account.avatar.url}); width: #{size}px; height: #{size}px; background-size: #{size}px #{size}px" }
%span.display-name
%bdi
%strong.display-name__html.emojify= display_name(account)
%span.display-name__account @#{account.acct}

View File

@ -1,20 +0,0 @@
.table-wrapper
%table.table
%tbody
%tr
%td= t('admin.reports.account.created_reports')
%td= link_to pluralize(account.reports.count, t('admin.reports.account.report')), admin_reports_path(account_id: account.id)
%tr
%td= t('admin.reports.account.targeted_reports')
%td= link_to pluralize(account.targeted_reports.count, t('admin.reports.account.report')), admin_reports_path(target_account_id: account.id)
%tr
%td= t('admin.reports.account.moderation_notes')
%td= link_to pluralize(account.targeted_moderation_notes.count, t('admin.reports.account.note')), admin_reports_path(target_account_id: account.id)
- if account.silenced? || account.suspended?
%tr
%td= t('admin.reports.account.moderation.title')
%td
- if account.silenced?
%p= t('admin.reports.account.moderation.silenced')
- if account.suspended?
%p= t('admin.reports.account.moderation.suspended')

View File

@ -0,0 +1,6 @@
.speech-bubble.positive
.speech-bubble__bubble
= t("admin.action_logs.actions.#{action_log.action}_#{action_log.target_type.underscore}", name: content_tag(:span, action_log.account.username, class: 'username'), target: content_tag(:span, log_target(action_log), class: 'target')).html_safe
.speech-bubble__owner
= admin_account_link_to(action_log.account)
%time.formatted{ datetime: action_log.created_at.iso8601 }= l action_log.created_at

View File

@ -2,9 +2,9 @@
%td.id %td.id
= "##{report.id}" = "##{report.id}"
%td.target %td.target
= link_to report.target_account.acct, admin_account_path(report.target_account.id) = admin_account_link_to report.target_account
%td.reporter %td.reporter
= link_to report.account.acct, admin_account_path(report.account.id) = admin_account_link_to report.account
%td %td
%div{ title: report.comment } %div{ title: report.comment }
= truncate(report.comment, length: 30, separator: ' ') = truncate(report.comment, length: 30, separator: ' ')
@ -21,6 +21,6 @@
- if report.assigned_account.nil? - if report.assigned_account.nil?
\- \-
- else - else
= link_to report.assigned_account.acct, admin_account_path(report.assigned_account.id) = admin_account_link_to report.assigned_account
%td %td
= table_link_to 'circle', t('admin.reports.view'), admin_report_path(report) = table_link_to 'circle', t('admin.reports.view'), admin_report_path(report)

View File

@ -0,0 +1,28 @@
.batch-table__row
%label.batch-table__row__select.batch-checkbox
= f.check_box :status_ids, { multiple: true, include_hidden: false }, status.id
.batch-table__row__content
.status__content><
- unless status.spoiler_text.blank?
%p><
%strong= Formatter.instance.format_spoiler(status)
= Formatter.instance.format(status)
- unless status.media_attachments.empty?
- if status.media_attachments.first.video?
- video = status.media_attachments.first
= react_component :video, src: video.file.url(:original), preview: video.file.url(:small), sensitive: status.sensitive? && !current_account&.user&.setting_display_sensitive_media, width: 610, height: 343, inline: true
- else
= react_component :media_gallery, height: 343, sensitive: status.sensitive? && !current_account&.user&.setting_display_sensitive_media, 'autoPlayGif': current_account&.user&.setting_auto_play_gif, media: status.media_attachments.map { |a| ActiveModelSerializers::SerializableResource.new(a, serializer: REST::MediaAttachmentSerializer).as_json }
.detailed-status__meta
= link_to TagManager.instance.url_for(status), class: 'detailed-status__datetime', target: stream_link_target, rel: 'noopener' do
%time.formatted{ datetime: status.created_at.iso8601, title: l(status.created_at) }= l(status.created_at)
·
= fa_visibility_icon(status)
= t("statuses.visibilities.#{status.visibility}")
- if status.sensitive?
·
= fa_icon('eye-slash fw')
= t('stream_entries.sensitive_content')

View File

@ -8,20 +8,17 @@
%li= filter_link_to t('admin.reports.unresolved'), resolved: nil %li= filter_link_to t('admin.reports.unresolved'), resolved: nil
%li= filter_link_to t('admin.reports.resolved'), resolved: '1' %li= filter_link_to t('admin.reports.resolved'), resolved: '1'
= form_tag do .table-wrapper
%table.table
.table-wrapper %thead
%table.table %tr
%thead %th= t('admin.reports.id')
%tr %th= t('admin.reports.target')
-# %th %th= t('admin.reports.reported_by')
%th= t('admin.reports.id') %th= t('admin.reports.report_contents')
%th= t('admin.reports.target') %th= t('admin.reports.assigned')
%th= t('admin.reports.reported_by') %th
%th= t('admin.reports.report_contents') %tbody
%th= t('admin.reports.assigned') = render @reports
%th
%tbody
= render @reports
= paginate @reports = paginate @reports

View File

@ -14,16 +14,28 @@
- else - else
= link_to t('admin.reports.mark_as_unresolved'), admin_report_path(@report, outcome: 'reopen'), method: :put, class: 'button' = link_to t('admin.reports.mark_as_unresolved'), admin_report_path(@report, outcome: 'reopen'), method: :put, class: 'button'
%hr.spacer
.table-wrapper .table-wrapper
%table.table.inline-table %table.table.inline-table
%tbody %tbody
%tr
%th= t('admin.reports.reported_account')
%td= admin_account_link_to @report.target_account
%td= table_link_to 'flag', pluralize(@report.target_account.targeted_reports.count, t('admin.reports.account.report')), admin_reports_path(target_account_id: @report.target_account.id)
%td= table_link_to 'file', pluralize(@report.target_account.targeted_moderation_notes.count, t('admin.reports.account.note')), admin_reports_path(target_account_id: @report.target_account.id)
%tr
%th= t('admin.reports.reported_by')
%td= admin_account_link_to @report.account
%td= table_link_to 'flag', pluralize(@report.account.targeted_reports.count, t('admin.reports.account.report')), admin_reports_path(target_account_id: @report.account.id)
%td= table_link_to 'file', pluralize(@report.account.targeted_moderation_notes.count, t('admin.reports.account.note')), admin_reports_path(target_account_id: @report.account.id)
%tr %tr
%th= t('admin.reports.created_at') %th= t('admin.reports.created_at')
%td{colspan: 2} %td{ colspan: 3 }
%time.formatted{ datetime: @report.created_at.iso8601 } %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: 3 }
%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')
@ -32,14 +44,14 @@
= t('admin.reports.resolved') = t('admin.reports.resolved')
- else - else
= t('admin.reports.unresolved') = t('admin.reports.unresolved')
%td{style: "text-align: right; overflow: hidden;"} %td{ colspan: 2 }
- if @report.action_taken? - if @report.action_taken?
= table_link_to 'envelope-open', t('admin.reports.reopen'), admin_report_path(@report, outcome: 'reopen'), method: :put = 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{colspan: 2} %td{ colspan: 3 }
= @report.action_taken_by_account.acct = admin_account_link_to @report.action_taken_by_account
- else - else
%tr %tr
%th= t('admin.reports.assigned') %th= t('admin.reports.assigned')
@ -47,78 +59,55 @@
- if @report.assigned_account.nil? - if @report.assigned_account.nil?
\- \-
- else - else
= link_to @report.assigned_account.acct, admin_account_path(@report.assigned_account.id) = admin_account_link_to @report.assigned_account
%td{style: "text-align: right"} %td
- if @report.assigned_account != current_user.account - if @report.assigned_account != current_user.account
= table_link_to 'user', t('admin.reports.assign_to_self'), admin_report_path(@report, outcome: 'assign_to_self'), method: :put = table_link_to 'user', t('admin.reports.assign_to_self'), admin_report_path(@report, outcome: 'assign_to_self'), method: :put
%td
- 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"}/ %hr.spacer
.report-accounts .speech-bubble
.report-accounts__item .speech-bubble__bubble= simple_format(@report.comment.presence || t('admin.reports.comment.none'))
%h3= t('admin.reports.reported_account') .speech-bubble__owner
= render 'authorize_follows/card', account: @report.target_account, admin: true = admin_account_link_to @report.account
= render 'admin/reports/account_details', account: @report.target_account %time.formatted{ datetime: @report.created_at.iso8601 }
.report-accounts__item
%h3= t('admin.reports.reported_by')
= render 'authorize_follows/card', account: @report.account, admin: true
= render 'admin/reports/account_details', account: @report.account
%h3= t('admin.reports.comment.label')
= simple_format(@report.comment.presence || t('admin.reports.comment.none'))
- unless @report.statuses.empty? - unless @report.statuses.empty?
%hr/ %hr.spacer/
%h3= t('admin.reports.statuses')
= form_for(@form, url: admin_report_reported_statuses_path(@report.id)) do |f| = form_for(@form, url: admin_report_reported_statuses_path(@report.id)) do |f|
.batch-form-box .batch-table
.batch-checkbox-all .batch-table__toolbar
= check_box_tag :batch_checkbox_all, nil, false %label.batch-table__toolbar__select.batch-checkbox-all
= f.select :action, Form::StatusBatch::ACTION_TYPE.map{|action| [t("admin.statuses.batch.#{action}"), action]} = check_box_tag :batch_checkbox_all, nil, false
= f.submit t('admin.statuses.execute'), data: { confirm: t('admin.reports.are_you_sure') }, class: 'button' .batch-table__toolbar__actions
.media-spoiler-toggle-buttons = f.button safe_join([fa_icon('eye-slash'), t('admin.statuses.batch.nsfw_on')]), name: :nsfw_on, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') }
.media-spoiler-show-button.button= t('admin.statuses.media.show') = f.button safe_join([fa_icon('eye'), t('admin.statuses.batch.nsfw_off')]), name: :nsfw_off, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') }
.media-spoiler-hide-button.button= t('admin.statuses.media.hide') = f.button safe_join([fa_icon('trash'), t('admin.statuses.batch.delete')]), name: :delete, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') }
- @report.statuses.each do |status| .batch-table__body
.report-status{ data: { id: status.id } } = render partial: 'admin/reports/status', collection: @report.statuses, locals: { f: f }
.batch-checkbox
= f.check_box :status_ids, { multiple: true, include_hidden: false }, status.id
.activity-stream.activity-stream-headless
.entry= render 'stream_entries/simple_status', status: status
.report-status__actions
- unless status.media_attachments.empty?
= link_to admin_report_reported_status_path(@report, status, status: { sensitive: !status.sensitive }), method: :put, class: 'icon-button nsfw-button', title: t("admin.reports.nsfw.#{!status.sensitive}") do
= fa_icon status.sensitive? ? 'eye' : 'eye-slash'
= 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'
%hr{ class: "section-break"}/ %hr.spacer/
%h3= t('admin.reports.notes.label') - @report_notes.each do |item|
- if item.is_a?(Admin::ActionLog)
= render partial: 'action_log', locals: { action_log: item }
- elsif item.is_a?(ReportNote)
= render item
- if @report_notes.length > 0 = simple_form_for @report_note, url: admin_report_notes_path do |f|
%ul
= render @report_notes
%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.text_area :content, placeholder: t('admin.reports.notes.placeholder'), rows: 6, class: 'report-note__textarea' = f.input :report_id, as: :hidden
= f.hidden_field :report_id
%div{ class: 'report-note__buttons' } .field-group
= f.input :content, placeholder: t('admin.reports.notes.placeholder'), rows: 6
.actions
- if @report.unresolved? - if @report.unresolved?
= f.submit t('admin.reports.notes.create_and_resolve'), name: :create_and_resolve, class: 'button report-note__button' = f.button :button, t('admin.reports.notes.create_and_resolve'), name: :create_and_resolve, type: :submit
- else - else
= f.submit t('admin.reports.notes.create_and_unresolve'), name: :create_and_unresolve, class: 'button report-note__button' = f.button :button, t('admin.reports.notes.create_and_unresolve'), name: :create_and_unresolve, type: :submit
= f.submit t('admin.reports.notes.create'), class: 'button report-note__button' = f.button :button, t('admin.reports.notes.create'), type: :submit
- if @report_history.length > 0
%h3= t('admin.reports.history')
%ul
= render @report_history

View File

@ -22,11 +22,11 @@
- if !status.media_attachments.empty? - if !status.media_attachments.empty?
- if status.media_attachments.first.video? - if status.media_attachments.first.video?
- video = status.media_attachments.first - video = status.media_attachments.first
%div{ data: { component: 'Video', props: Oj.dump(src: video.file.url(:original), preview: video.file.url(:small), sensitive: status.sensitive? && !current_account&.user&.setting_display_sensitive_media, width: 670, height: 380, detailed: true, inline: true) }} = react_component :video, src: video.file.url(:original), preview: video.file.url(:small), sensitive: status.sensitive? && !current_account&.user&.setting_display_sensitive_media, width: 670, height: 380, detailed: true, inline: true
- else - else
%div{ data: { component: 'MediaGallery', props: Oj.dump(height: 380, sensitive: status.sensitive? && !current_account&.user&.setting_display_sensitive_media, standalone: true, 'autoPlayGif': current_account&.user&.setting_auto_play_gif, 'reduceMotion': current_account&.user&.setting_reduce_motion, media: status.media_attachments.map { |a| ActiveModelSerializers::SerializableResource.new(a, serializer: REST::MediaAttachmentSerializer).as_json }) }} = react_component :media_gallery, height: 380, sensitive: status.sensitive? && !current_account&.user&.setting_display_sensitive_media, standalone: true, 'autoPlayGif': current_account&.user&.setting_auto_play_gif, 'reduceMotion': current_account&.user&.setting_reduce_motion, media: status.media_attachments.map { |a| ActiveModelSerializers::SerializableResource.new(a, serializer: REST::MediaAttachmentSerializer).as_json }
- elsif status.preview_cards.first - elsif status.preview_cards.first
%div{ data: { component: 'Card', props: Oj.dump('maxDescription': 160, card: ActiveModelSerializers::SerializableResource.new(status.preview_cards.first, serializer: REST::PreviewCardSerializer).as_json) }} = react_component :card, 'maxDescription': 160, card: ActiveModelSerializers::SerializableResource.new(status.preview_cards.first, serializer: REST::PreviewCardSerializer).as_json
.detailed-status__meta .detailed-status__meta
%data.dt-published{ value: status.created_at.to_time.iso8601 } %data.dt-published{ value: status.created_at.to_time.iso8601 }

View File

@ -23,6 +23,6 @@
- unless status.media_attachments.empty? - unless status.media_attachments.empty?
- if status.media_attachments.first.video? - if status.media_attachments.first.video?
- video = status.media_attachments.first - video = status.media_attachments.first
%div{ data: { component: 'Video', props: Oj.dump(src: video.file.url(:original), preview: video.file.url(:small), sensitive: status.sensitive? && !current_account&.user&.setting_display_sensitive_media, width: 610, height: 343, inline: true) }} = react_component :video, src: video.file.url(:original), preview: video.file.url(:small), sensitive: status.sensitive? && !current_account&.user&.setting_display_sensitive_media, width: 610, height: 343, inline: true
- else - else
%div{ data: { component: 'MediaGallery', props: Oj.dump(height: 343, sensitive: status.sensitive? && !current_account&.user&.setting_display_sensitive_media, 'autoPlayGif': current_account&.user&.setting_auto_play_gif, media: status.media_attachments.map { |a| ActiveModelSerializers::SerializableResource.new(a, serializer: REST::MediaAttachmentSerializer).as_json }) }} = react_component :media_gallery, height: 343, sensitive: status.sensitive? && !current_account&.user&.setting_display_sensitive_media, 'autoPlayGif': current_account&.user&.setting_auto_play_gif, media: status.media_attachments.map { |a| ActiveModelSerializers::SerializableResource.new(a, serializer: REST::MediaAttachmentSerializer).as_json }

View File

@ -240,7 +240,6 @@ ar:
action_taken_by: تم اتخاذ الإجراء مِن طرف action_taken_by: تم اتخاذ الإجراء مِن طرف
are_you_sure: هل أنت متأكد ؟ are_you_sure: هل أنت متأكد ؟
comment: comment:
label: تعليق
none: لا شيء none: لا شيء
delete: حذف delete: حذف
id: معرّف ID id: معرّف ID

View File

@ -243,7 +243,6 @@ ca:
action_taken_by: Mesures adoptades per action_taken_by: Mesures adoptades per
are_you_sure: N'estàs segur? are_you_sure: N'estàs segur?
comment: comment:
label: Comentari
none: Cap none: Cap
delete: Suprimeix delete: Suprimeix
id: ID id: ID

View File

@ -243,7 +243,6 @@ de:
action_taken_by: Maßnahme ergriffen durch action_taken_by: Maßnahme ergriffen durch
are_you_sure: Bist du dir sicher? are_you_sure: Bist du dir sicher?
comment: comment:
label: Kommentar
none: Kein none: Kein
delete: Löschen delete: Löschen
id: ID id: ID

View File

@ -260,40 +260,29 @@ en:
destroyed_msg: Report note successfully deleted! destroyed_msg: Report note successfully deleted!
reports: reports:
account: account:
created_reports: Reports created by this account
moderation:
silenced: Silenced
suspended: Suspended
title: Moderation
moderation_notes: Moderation Notes
note: note note: note
report: report report: report
targeted_reports: Reports made about this account
action_taken_by: Action taken by action_taken_by: Action taken by
are_you_sure: Are you sure? are_you_sure: Are you sure?
assign_to_self: Assign to me assign_to_self: Assign to me
assigned: Assigned Moderator assigned: Assigned moderator
comment: comment:
label: Report Comment
none: None none: None
created_at: Reported 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 create_and_unresolve: Reopen with note
delete: Delete delete: Delete
label: Moderator Notes
new_label: Add Moderator Note
placeholder: Describe what actions have been taken, or any other updates to this report… 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
reopen: Reopen Report reopen: Reopen report
report: 'Report #%{id}' report: 'Report #%{id}'
report_contents: Contents report_contents: Contents
reported_account: Reported account reported_account: Reported account
@ -302,7 +291,6 @@ en:
resolved_msg: Report successfully resolved! resolved_msg: Report successfully resolved!
silence_account: Silence account silence_account: Silence account
status: Status status: Status
statuses: Reported Toots
suspend_account: Suspend account suspend_account: Suspend account
target: Target target: Target
title: Reports title: Reports
@ -366,8 +354,8 @@ en:
back_to_account: Back to account page back_to_account: Back to account page
batch: batch:
delete: Delete delete: Delete
nsfw_off: NSFW OFF nsfw_off: Mark as not sensitive
nsfw_on: NSFW ON nsfw_on: Mark as sensitive
execute: Execute execute: Execute
failed_to_execute: Failed to execute failed_to_execute: Failed to execute
media: media:

View File

@ -243,7 +243,6 @@ eo:
action_taken_by: Ago farita de action_taken_by: Ago farita de
are_you_sure: Ĉu vi certas? are_you_sure: Ĉu vi certas?
comment: comment:
label: Komento
none: Nenio none: Nenio
delete: Forigi delete: Forigi
id: ID id: ID

View File

@ -243,7 +243,6 @@ es:
action_taken_by: Acción tomada por action_taken_by: Acción tomada por
are_you_sure: "¿Estás seguro?" are_you_sure: "¿Estás seguro?"
comment: comment:
label: Comentario
none: Ninguno none: Ninguno
delete: Eliminar delete: Eliminar
id: ID id: ID

View File

@ -243,7 +243,6 @@ fa:
action_taken_by: انجام‌دهنده action_taken_by: انجام‌دهنده
are_you_sure: آیا مطمئن هستید؟ are_you_sure: آیا مطمئن هستید؟
comment: comment:
label: توضیح
none: خالی none: خالی
delete: پاک‌کردن delete: پاک‌کردن
id: شناسه id: شناسه

View File

@ -243,7 +243,6 @@ fi:
action_taken_by: Toimenpiteen tekijä action_taken_by: Toimenpiteen tekijä
are_you_sure: Oletko varma? are_you_sure: Oletko varma?
comment: comment:
label: Kommentti
none: Ei mitään none: Ei mitään
delete: Poista delete: Poista
id: Tunniste id: Tunniste

View File

@ -243,7 +243,6 @@ fr:
action_taken_by: Intervention de action_taken_by: Intervention de
are_you_sure: Êtes vous certain⋅e? are_you_sure: Êtes vous certain⋅e?
comment: comment:
label: Commentaire
none: Aucun none: Aucun
delete: Supprimer delete: Supprimer
id: ID id: ID

View File

@ -243,7 +243,6 @@ gl:
action_taken_by: Acción tomada por action_taken_by: Acción tomada por
are_you_sure: Está segura? are_you_sure: Está segura?
comment: comment:
label: Comentario
none: Nada none: Nada
delete: Eliminar delete: Eliminar
id: ID id: ID

View File

@ -180,7 +180,6 @@ he:
reports: reports:
are_you_sure: 100% על בטוח? are_you_sure: 100% על בטוח?
comment: comment:
label: הערה
none: ללא none: ללא
delete: מחיקה delete: מחיקה
id: ID id: ID

View File

@ -243,7 +243,6 @@ hu:
action_taken_by: 'Kezelte:' action_taken_by: 'Kezelte:'
are_you_sure: Biztos vagy benne? are_you_sure: Biztos vagy benne?
comment: comment:
label: Hozzászólás
none: Egyik sem none: Egyik sem
delete: Törlés delete: Törlés
id: ID id: ID

View File

@ -106,7 +106,6 @@ id:
title: Server yang diketahui title: Server yang diketahui
reports: reports:
comment: comment:
label: Komentar
none: Tidak ada none: Tidak ada
delete: Hapus delete: Hapus
id: ID id: ID

View File

@ -105,7 +105,6 @@ io:
title: Known Instances title: Known Instances
reports: reports:
comment: comment:
label: Comment
none: None none: None
delete: Delete delete: Delete
id: ID id: ID

View File

@ -264,11 +264,9 @@ ja:
assign_to_self: 担当になる assign_to_self: 担当になる
assigned: 担当者 assigned: 担当者
comment: comment:
label: コメント
none: なし none: なし
created_at: レポート日時 created_at: レポート日時
delete: 削除 delete: 削除
history: モデレーション履歴
id: ID id: ID
mark_as_resolved: 解決済みとしてマーク mark_as_resolved: 解決済みとしてマーク
mark_as_unresolved: 未解決として再び開く mark_as_unresolved: 未解決として再び開く
@ -277,8 +275,6 @@ ja:
create_and_resolve: 書き込み、解決済みにする create_and_resolve: 書き込み、解決済みにする
create_and_unresolve: 書き込み、未解決として開く create_and_unresolve: 書き込み、未解決として開く
delete: 削除 delete: 削除
label: モデレーターメモ
new_label: モデレーターメモの追加
placeholder: このレポートに取られた措置やその他更新を記述してください placeholder: このレポートに取られた措置やその他更新を記述してください
nsfw: nsfw:
'false': NSFW オフ 'false': NSFW オフ
@ -292,7 +288,6 @@ ja:
resolved_msg: レポートを解決済みにしました! resolved_msg: レポートを解決済みにしました!
silence_account: アカウントをサイレンス silence_account: アカウントをサイレンス
status: ステータス status: ステータス
statuses: 通報されたトゥート
suspend_account: アカウントを停止 suspend_account: アカウントを停止
target: ターゲット target: ターゲット
title: レポート title: レポート

View File

@ -245,7 +245,6 @@ ko:
action_taken_by: 신고 처리자 action_taken_by: 신고 처리자
are_you_sure: 정말로 실행하시겠습니까? are_you_sure: 정말로 실행하시겠습니까?
comment: comment:
label: 코멘트
none: 없음 none: 없음
delete: 삭제 delete: 삭제
id: ID id: ID

View File

@ -243,7 +243,6 @@ nl:
action_taken_by: Actie uitgevoerd door action_taken_by: Actie uitgevoerd door
are_you_sure: Weet je het zeker? are_you_sure: Weet je het zeker?
comment: comment:
label: Opmerking
none: Geen none: Geen
delete: Verwijderen delete: Verwijderen
id: ID id: ID

View File

@ -243,7 +243,6 @@
action_taken_by: Handling utført av action_taken_by: Handling utført av
are_you_sure: Er du sikker? are_you_sure: Er du sikker?
comment: comment:
label: Kommentar
none: Ingen none: Ingen
delete: Slett delete: Slett
id: ID id: ID

View File

@ -243,7 +243,6 @@ oc:
action_taken_by: Mesura menada per action_taken_by: Mesura menada per
are_you_sure: Es segur? are_you_sure: Es segur?
comment: comment:
label: Comentari
none: Pas cap none: Pas cap
delete: Suprimir delete: Suprimir
id: ID id: ID

View File

@ -261,25 +261,16 @@ pl:
destroyed_msg: Pomyślnie usunięto notatkę moderacyjną. destroyed_msg: Pomyślnie usunięto notatkę moderacyjną.
reports: reports:
account: account:
created_reports: Zgłoszenia utworzone z tego konta
moderation:
silenced: Wyciszone
suspended: Zawieszone
title: Moderacja
moderation_notes: Notatki moderacyjne
note: notatka note: notatka
report: zgłoszenie report: zgłoszenie
targeted_reports: Zgłoszenia dotycząće tego konta
action_taken_by: Działanie podjęte przez action_taken_by: Działanie podjęte przez
are_you_sure: Czy na pewno? are_you_sure: Czy na pewno?
assign_to_self: Przypisz do siebie assign_to_self: Przypisz do siebie
assigned: Przypisany moderator assigned: Przypisany moderator
comment: comment:
label: Komentarz do zgłoszenia
none: Brak none: Brak
created_at: Zgłoszono created_at: Zgłoszono
delete: Usuń delete: Usuń
history: Historia moderacji
id: ID id: ID
mark_as_resolved: Oznacz jako rozwiązane mark_as_resolved: Oznacz jako rozwiązane
mark_as_unresolved: Oznacz jako nierozwiązane mark_as_unresolved: Oznacz jako nierozwiązane
@ -288,8 +279,6 @@ pl:
create_and_resolve: Rozwiąż i pozostaw notatkę create_and_resolve: Rozwiąż i pozostaw notatkę
create_and_unresolve: Cofnij rozwiązanie i pozostaw notatkę create_and_unresolve: Cofnij rozwiązanie i pozostaw notatkę
delete: Usuń delete: Usuń
label: Notatki
new_label: Dodaj notatkę moderacyjną
placeholder: Opisz wykonane akcje i inne szczegóły dotyczące tego zgłoszenia… placeholder: Opisz wykonane akcje i inne szczegóły dotyczące tego zgłoszenia…
nsfw: nsfw:
'false': Nie oznaczaj jako NSFW 'false': Nie oznaczaj jako NSFW
@ -303,7 +292,6 @@ pl:
resolved_msg: Pomyślnie rozwiązano zgłoszenie. resolved_msg: Pomyślnie rozwiązano zgłoszenie.
silence_account: Wycisz konto silence_account: Wycisz konto
status: Stan status: Stan
statuses: Zgłoszone wpisy
suspend_account: Zawieś konto suspend_account: Zawieś konto
target: Cel target: Cel
title: Zgłoszenia title: Zgłoszenia

View File

@ -243,7 +243,6 @@ pt-BR:
action_taken_by: Ação realizada por action_taken_by: Ação realizada por
are_you_sure: Você tem certeza? are_you_sure: Você tem certeza?
comment: comment:
label: Comentário
none: Nenhum none: Nenhum
delete: Excluir delete: Excluir
id: ID id: ID

View File

@ -243,7 +243,6 @@ pt:
action_taken_by: Ação tomada por action_taken_by: Ação tomada por
are_you_sure: Tens a certeza? are_you_sure: Tens a certeza?
comment: comment:
label: Comentário
none: Nenhum none: Nenhum
delete: Eliminar delete: Eliminar
id: ID id: ID

View File

@ -245,7 +245,6 @@ ru:
action_taken_by: 'Действие предпринято:' action_taken_by: 'Действие предпринято:'
are_you_sure: Вы уверены? are_you_sure: Вы уверены?
comment: comment:
label: Комментарий
none: Нет none: Нет
delete: Удалить delete: Удалить
id: ID id: ID

View File

@ -243,7 +243,6 @@ sk:
action_taken_by: Zákrok vykonal action_taken_by: Zákrok vykonal
are_you_sure: Ste si istý/á? are_you_sure: Ste si istý/á?
comment: comment:
label: Vyjadriť sa
none: Žiadne none: Žiadne
delete: Vymazať delete: Vymazať
id: Identifikácia id: Identifikácia

View File

@ -245,7 +245,6 @@ sr-Latn:
action_taken_by: Akciju izveo action_taken_by: Akciju izveo
are_you_sure: Da li ste sigurni? are_you_sure: Da li ste sigurni?
comment: comment:
label: Komentar
none: Ništa none: Ništa
delete: Obriši delete: Obriši
id: ID id: ID

View File

@ -245,7 +245,6 @@ sr:
action_taken_by: Акцију извео action_taken_by: Акцију извео
are_you_sure: Да ли сте сигурни? are_you_sure: Да ли сте сигурни?
comment: comment:
label: Коментар
none: Ништа none: Ништа
delete: Обриши delete: Обриши
id: ID id: ID

View File

@ -243,7 +243,6 @@ sv:
action_taken_by: Åtgärder vidtagna av action_taken_by: Åtgärder vidtagna av
are_you_sure: Är du säker? are_you_sure: Är du säker?
comment: comment:
label: Kommentar
none: Ingen none: Ingen
delete: Radera delete: Radera
id: ID id: ID

View File

@ -108,7 +108,6 @@ th:
title: Known Instances title: Known Instances
reports: reports:
comment: comment:
label: คอมเม้นต์
none: None none: None
delete: ลบ delete: ลบ
id: ไอดี id: ไอดี

View File

@ -107,7 +107,6 @@ tr:
title: Bilinen Sunucular title: Bilinen Sunucular
reports: reports:
comment: comment:
label: Yorum
none: Yok none: Yok
delete: Sil delete: Sil
id: ID id: ID

View File

@ -99,7 +99,6 @@ uk:
undo: Відмінити undo: Відмінити
reports: reports:
comment: comment:
label: Коментар
none: Немає none: Немає
delete: Видалити delete: Видалити
id: ID id: ID

View File

@ -241,7 +241,6 @@ zh-CN:
action_taken_by: 操作执行者 action_taken_by: 操作执行者
are_you_sure: 你确定吗? are_you_sure: 你确定吗?
comment: comment:
label: 备注
none: 没有 none: 没有
delete: 删除 delete: 删除
id: ID id: ID

View File

@ -259,25 +259,16 @@ zh-HK:
destroyed_msg: 舉報筆記已刪除。 destroyed_msg: 舉報筆記已刪除。
reports: reports:
account: account:
created_reports: 由此帳號發出的舉報
moderation:
silenced: 被靜音的
suspended: 被停權的
title: 管理操作
moderation_notes: 管理筆記
note: 筆記 note: 筆記
report: 舉報 report: 舉報
targeted_reports: 關於此帳號的舉報
action_taken_by: 操作執行者 action_taken_by: 操作執行者
are_you_sure: 你確認嗎? are_you_sure: 你確認嗎?
assign_to_self: 指派給自己 assign_to_self: 指派給自己
assigned: 指派負責人 assigned: 指派負責人
comment: comment:
label: 詳細解釋
none: 沒有 none: 沒有
created_at: 日期 created_at: 日期
delete: 刪除 delete: 刪除
history: 執行紀錄
id: ID id: ID
mark_as_resolved: 標示為「已處理」 mark_as_resolved: 標示為「已處理」
mark_as_unresolved: 標示為「未處理」 mark_as_unresolved: 標示為「未處理」
@ -286,8 +277,6 @@ zh-HK:
create_and_resolve: 建立筆記並標示為「已處理」 create_and_resolve: 建立筆記並標示為「已處理」
create_and_unresolve: 建立筆記並標示為「未處理」 create_and_unresolve: 建立筆記並標示為「未處理」
delete: 刪除 delete: 刪除
label: 管理筆記
new_label: 建立管理筆記
placeholder: 記錄已執行的動作,或其他更新 placeholder: 記錄已執行的動作,或其他更新
nsfw: nsfw:
'false': 取消 NSFW 標記 'false': 取消 NSFW 標記
@ -301,7 +290,6 @@ zh-HK:
resolved_msg: 舉報已處理。 resolved_msg: 舉報已處理。
silence_account: 將用戶靜音 silence_account: 將用戶靜音
status: 狀態 status: 狀態
statuses: 被舉報的文章
suspend_account: 將用戶停權 suspend_account: 將用戶停權
target: 對象 target: 對象
title: 舉報 title: 舉報

View File

@ -79,7 +79,6 @@ zh-TW:
title: 網域封鎖 title: 網域封鎖
reports: reports:
comment: comment:
label: 留言
none: none:
delete: 刪除 delete: 刪除
id: ID id: ID

View File

@ -13,7 +13,7 @@ describe Admin::ReportedStatusesController do
describe 'POST #create' do describe 'POST #create' do
subject do subject do
-> { post :create, params: { report_id: report, form_status_batch: { action: action, status_ids: status_ids } } } -> { post :create, params: { :report_id => report, action => '', :form_status_batch => { status_ids: status_ids } } }
end end
let(:action) { 'nsfw_on' } let(:action) { 'nsfw_on' }