Show reported collections in moderation interface (#37898)
This commit is contained in:
parent
6f859364fb
commit
e288bf6516
22
app/controllers/admin/collections_controller.rb
Normal file
22
app/controllers/admin/collections_controller.rb
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module Admin
|
||||||
|
class CollectionsController < BaseController
|
||||||
|
before_action :set_account
|
||||||
|
before_action :set_collection, only: :show
|
||||||
|
|
||||||
|
def show
|
||||||
|
authorize @collection, :show?
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def set_account
|
||||||
|
@account = Account.find(params[:account_id])
|
||||||
|
end
|
||||||
|
|
||||||
|
def set_collection
|
||||||
|
@collection = @account.collections.includes(accepted_collection_items: :account).find(params[:id])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@ -50,7 +50,7 @@ module Admin
|
|||||||
private
|
private
|
||||||
|
|
||||||
def filtered_reports
|
def filtered_reports
|
||||||
ReportFilter.new(filter_params).results.order(id: :desc).includes(:account, :target_account)
|
ReportFilter.new(filter_params).results.order(id: :desc).includes(:account, :target_account, :collections)
|
||||||
end
|
end
|
||||||
|
|
||||||
def filter_params
|
def filter_params
|
||||||
@ -58,7 +58,7 @@ module Admin
|
|||||||
end
|
end
|
||||||
|
|
||||||
def set_report
|
def set_report
|
||||||
@report = Report.find(params[:id])
|
@report = Report.includes(collections: :accepted_collection_items).find(params[:id])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -26,6 +26,7 @@ class Collection < ApplicationRecord
|
|||||||
belongs_to :tag, optional: true
|
belongs_to :tag, optional: true
|
||||||
|
|
||||||
has_many :collection_items, dependent: :delete_all
|
has_many :collection_items, dependent: :delete_all
|
||||||
|
has_many :accepted_collection_items, -> { accepted }, class_name: 'CollectionItem', inverse_of: :collection # rubocop:disable Rails/HasManyOrHasOneDependent
|
||||||
has_many :collection_reports, dependent: :delete_all
|
has_many :collection_reports, dependent: :delete_all
|
||||||
|
|
||||||
validates :name, presence: true
|
validates :name, presence: true
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
.batch-table__row{ class: [!account.unavailable? && account.user_pending? && 'batch-table__row--attention', (account.unavailable? || account.user_unconfirmed?) && 'batch-table__row--muted'] }
|
.batch-table__row{ class: [!account.unavailable? && account.user_pending? && 'batch-table__row--attention', (account.unavailable? || account.user_unconfirmed?) && 'batch-table__row--muted'] }
|
||||||
%label.batch-table__row__select.batch-table__row__select--aligned.batch-checkbox
|
%label.batch-table__row__select.batch-table__row__select--aligned.batch-checkbox
|
||||||
= f.check_box :account_ids, { multiple: true, include_hidden: false }, account.id
|
- if local_assigns[:f].present?
|
||||||
|
= f.check_box :account_ids, { multiple: true, include_hidden: false }, account.id
|
||||||
.batch-table__row__content.batch-table__row__content--unpadded
|
.batch-table__row__content.batch-table__row__content--unpadded
|
||||||
%table.accounts-table
|
%table.accounts-table
|
||||||
%tbody
|
%tbody
|
||||||
|
|||||||
21
app/views/admin/collections/show.html.haml
Normal file
21
app/views/admin/collections/show.html.haml
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
- content_for :page_title do
|
||||||
|
= t('admin.collections.collection_title', name: @account.pretty_acct)
|
||||||
|
|
||||||
|
- content_for :heading_actions do
|
||||||
|
= link_to t('admin.collections.open'), account_collection_path(@account, @collection), class: 'button', target: '_blank', rel: 'noopener'
|
||||||
|
|
||||||
|
%h3= t('admin.collections.contents')
|
||||||
|
|
||||||
|
= render 'admin/shared/collection', collection: @collection
|
||||||
|
|
||||||
|
%hr.spacer/
|
||||||
|
|
||||||
|
%h3= t('admin.collections.accounts')
|
||||||
|
|
||||||
|
.batch-table
|
||||||
|
.batch-table__toolbar
|
||||||
|
.batch-table__body
|
||||||
|
- if @collection.accepted_collection_items.none?
|
||||||
|
= nothing_here 'nothing-here--under-tabs'
|
||||||
|
- else
|
||||||
|
= render partial: 'admin/accounts/account', collection: @collection.accepted_collection_items.map(&:account)
|
||||||
@ -67,6 +67,11 @@
|
|||||||
= material_symbol('photo_camera')
|
= material_symbol('photo_camera')
|
||||||
= report.media_attachments_count
|
= report.media_attachments_count
|
||||||
|
|
||||||
|
- if Mastodon::Feature.collections_enabled?
|
||||||
|
%span.report-card__summary__item__content__icon{ title: t('admin.accounts.collections') }
|
||||||
|
= material_symbol('groups-fill')
|
||||||
|
= report.collections.size
|
||||||
|
|
||||||
- if report.forwarded?
|
- if report.forwarded?
|
||||||
·
|
·
|
||||||
= t('admin.reports.forwarded_to', domain: target_account.domain)
|
= t('admin.reports.forwarded_to', domain: target_account.domain)
|
||||||
|
|||||||
@ -32,7 +32,7 @@
|
|||||||
%hr.spacer/
|
%hr.spacer/
|
||||||
|
|
||||||
%h3
|
%h3
|
||||||
= t 'admin.reports.statuses'
|
= t 'admin.reports.reported_content'
|
||||||
%small.section-skip-link
|
%small.section-skip-link
|
||||||
= link_to '#actions' do
|
= link_to '#actions' do
|
||||||
= material_symbol 'keyboard_double_arrow_down'
|
= material_symbol 'keyboard_double_arrow_down'
|
||||||
@ -41,6 +41,9 @@
|
|||||||
%p
|
%p
|
||||||
= t 'admin.reports.statuses_description_html'
|
= t 'admin.reports.statuses_description_html'
|
||||||
|
|
||||||
|
%h4
|
||||||
|
= t 'admin.reports.statuses'
|
||||||
|
|
||||||
= form_with model: @form, url: batch_admin_account_statuses_path(@report.target_account_id, report_id: @report.id) do |f|
|
= form_with model: @form, url: batch_admin_account_statuses_path(@report.target_account_id, report_id: @report.id) do |f|
|
||||||
.batch-table
|
.batch-table
|
||||||
.batch-table__toolbar
|
.batch-table__toolbar
|
||||||
@ -58,6 +61,22 @@
|
|||||||
- else
|
- else
|
||||||
= render partial: 'admin/shared/status_batch_row', collection: @statuses, as: :status, locals: { f: f }
|
= render partial: 'admin/shared/status_batch_row', collection: @statuses, as: :status, locals: { f: f }
|
||||||
|
|
||||||
|
- if Mastodon::Feature.collections_enabled?
|
||||||
|
%h4
|
||||||
|
= t 'admin.reports.collections'
|
||||||
|
|
||||||
|
%form
|
||||||
|
.batch-table
|
||||||
|
.batch-table__toolbar
|
||||||
|
%label.batch-table__toolbar__select.batch-checkbox-all
|
||||||
|
-# = check_box_tag :batch_checkbox_all, nil, false
|
||||||
|
.batch-table__toolbar__actions
|
||||||
|
.batch-table__body
|
||||||
|
- if @report.collections.empty?
|
||||||
|
= nothing_here 'nothing-here--under-tabs'
|
||||||
|
- else
|
||||||
|
= render partial: 'admin/shared/collection_batch_row', collection: @report.collections, as: :collection
|
||||||
|
|
||||||
- if @report.unresolved?
|
- if @report.unresolved?
|
||||||
%hr.spacer/
|
%hr.spacer/
|
||||||
|
|
||||||
|
|||||||
22
app/views/admin/shared/_collection.html.haml
Normal file
22
app/views/admin/shared/_collection.html.haml
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
.status__card
|
||||||
|
- if collection.tag.present?
|
||||||
|
.status__prepend
|
||||||
|
= link_to collection.tag.formatted_name, admin_tag_path(collection.tag_id)
|
||||||
|
|
||||||
|
.status__content
|
||||||
|
%h6= collection.name
|
||||||
|
|
||||||
|
%p= collection.description
|
||||||
|
|
||||||
|
.detailed-status__meta
|
||||||
|
= conditional_link_to can?(:show, collection), admin_account_collection_path(collection.account.id, collection), class: 'detailed-status__datetime' do
|
||||||
|
%time.formatted{ datetime: collection.created_at.iso8601, title: l(collection.created_at) }><= l(collection.created_at)
|
||||||
|
- if collection.sensitive?
|
||||||
|
·
|
||||||
|
= material_symbol('visibility_off')
|
||||||
|
= t('stream_entries.sensitive_content')
|
||||||
|
·
|
||||||
|
= t('admin.collections.number_of_accounts', count: collection.accepted_collection_items.size)
|
||||||
|
·
|
||||||
|
= link_to account_collection_path(collection.account, collection), class: 'detailed-status__link', target: 'blank', rel: 'noopener' do
|
||||||
|
= t('admin.collections.view_publicly')
|
||||||
5
app/views/admin/shared/_collection_batch_row.html.haml
Normal file
5
app/views/admin/shared/_collection_batch_row.html.haml
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
.batch-table__row
|
||||||
|
%label.batch-table__row__select.batch-checkbox
|
||||||
|
-# = f.check_box :collection_ids, { multiple: true, include_hidden: false }, collection.id
|
||||||
|
.batch-table__row__content
|
||||||
|
= render partial: 'admin/shared/collection', object: collection
|
||||||
@ -56,6 +56,7 @@ en:
|
|||||||
label: Change role
|
label: Change role
|
||||||
no_role: No role
|
no_role: No role
|
||||||
title: Change role for %{username}
|
title: Change role for %{username}
|
||||||
|
collections: Collections
|
||||||
confirm: Confirm
|
confirm: Confirm
|
||||||
confirmed: Confirmed
|
confirmed: Confirmed
|
||||||
confirming: Confirming
|
confirming: Confirming
|
||||||
@ -340,6 +341,15 @@ en:
|
|||||||
unpublish: Unpublish
|
unpublish: Unpublish
|
||||||
unpublished_msg: Announcement successfully unpublished!
|
unpublished_msg: Announcement successfully unpublished!
|
||||||
updated_msg: Announcement successfully updated!
|
updated_msg: Announcement successfully updated!
|
||||||
|
collections:
|
||||||
|
accounts: Accounts
|
||||||
|
collection_title: Collection by %{name}
|
||||||
|
contents: Contents
|
||||||
|
number_of_accounts:
|
||||||
|
one: 1 account
|
||||||
|
other: "%{count} accounts"
|
||||||
|
open: Open
|
||||||
|
view_publicly: View publicly
|
||||||
critical_update_pending: Critical update pending
|
critical_update_pending: Critical update pending
|
||||||
custom_emojis:
|
custom_emojis:
|
||||||
assign_category: Assign category
|
assign_category: Assign category
|
||||||
@ -679,6 +689,7 @@ en:
|
|||||||
cancel: Cancel
|
cancel: Cancel
|
||||||
category: Category
|
category: Category
|
||||||
category_description_html: The reason this account and/or content was reported will be cited in communication with the reported account
|
category_description_html: The reason this account and/or content was reported will be cited in communication with the reported account
|
||||||
|
collections: Collections
|
||||||
comment:
|
comment:
|
||||||
none: None
|
none: None
|
||||||
comment_description_html: 'To provide more information, %{name} wrote:'
|
comment_description_html: 'To provide more information, %{name} wrote:'
|
||||||
@ -708,12 +719,13 @@ en:
|
|||||||
report: 'Report #%{id}'
|
report: 'Report #%{id}'
|
||||||
reported_account: Reported account
|
reported_account: Reported account
|
||||||
reported_by: Reported by
|
reported_by: Reported by
|
||||||
|
reported_content: Reported content
|
||||||
reported_with_application: Reported with application
|
reported_with_application: Reported with application
|
||||||
resolved: Resolved
|
resolved: Resolved
|
||||||
resolved_msg: Report successfully resolved!
|
resolved_msg: Report successfully resolved!
|
||||||
skip_to_actions: Skip to actions
|
skip_to_actions: Skip to actions
|
||||||
status: Status
|
status: Status
|
||||||
statuses: Reported content
|
statuses: Posts
|
||||||
statuses_description_html: Offending content will be cited in communication with the reported account
|
statuses_description_html: Offending content will be cited in communication with the reported account
|
||||||
summary:
|
summary:
|
||||||
action_preambles:
|
action_preambles:
|
||||||
|
|||||||
@ -153,6 +153,8 @@ namespace :admin do
|
|||||||
resource :reset, only: [:create]
|
resource :reset, only: [:create]
|
||||||
resource :action, only: [:new, :create], controller: 'account_actions'
|
resource :action, only: [:new, :create], controller: 'account_actions'
|
||||||
|
|
||||||
|
resources :collections, only: [:show]
|
||||||
|
|
||||||
resources :statuses, only: [:index, :show] do
|
resources :statuses, only: [:index, :show] do
|
||||||
collection do
|
collection do
|
||||||
post :batch
|
post :batch
|
||||||
|
|||||||
20
spec/requests/admin/collections_spec.rb
Normal file
20
spec/requests/admin/collections_spec.rb
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
RSpec.describe 'Admin Collections' do
|
||||||
|
describe 'GET /admin/accounts/:account_id/collections/:id' do
|
||||||
|
let(:collection) { Fabricate(:collection) }
|
||||||
|
|
||||||
|
before do
|
||||||
|
sign_in Fabricate(:admin_user)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'returns success' do
|
||||||
|
get admin_account_collection_path(collection.account_id, collection)
|
||||||
|
|
||||||
|
expect(response)
|
||||||
|
.to have_http_status(200)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
68
spec/requests/admin/reports_spec.rb
Normal file
68
spec/requests/admin/reports_spec.rb
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
RSpec.describe 'Admin Reports' do
|
||||||
|
describe 'GET /admin/reports' do
|
||||||
|
before do
|
||||||
|
sign_in Fabricate(:admin_user)
|
||||||
|
|
||||||
|
Fabricate.times(2, :report)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'returns success' do
|
||||||
|
get admin_reports_path
|
||||||
|
|
||||||
|
expect(response)
|
||||||
|
.to have_http_status(200)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'GET /admin/reports/:id' do
|
||||||
|
let(:report) { Fabricate(:report) }
|
||||||
|
|
||||||
|
before do
|
||||||
|
sign_in Fabricate(:admin_user)
|
||||||
|
end
|
||||||
|
|
||||||
|
shared_examples 'successful return' do
|
||||||
|
it 'returns success' do
|
||||||
|
get admin_report_path(report)
|
||||||
|
|
||||||
|
expect(response)
|
||||||
|
.to have_http_status(200)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'with a simple report' do
|
||||||
|
it_behaves_like 'successful return'
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'with a reported status' do
|
||||||
|
before do
|
||||||
|
status = Fabricate(:status, account: report.target_account)
|
||||||
|
report.update(status_ids: [status.id])
|
||||||
|
end
|
||||||
|
|
||||||
|
it_behaves_like 'successful return'
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'with a reported collection', feature: :collections do
|
||||||
|
before do
|
||||||
|
report.collections << Fabricate(:collection, account: report.target_account)
|
||||||
|
end
|
||||||
|
|
||||||
|
it_behaves_like 'successful return'
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'with both status and collection', feature: :collections do
|
||||||
|
before do
|
||||||
|
status = Fabricate(:status, account: report.target_account)
|
||||||
|
report.update(status_ids: [status.id])
|
||||||
|
report.collections << Fabricate(:collection, account: report.target_account)
|
||||||
|
end
|
||||||
|
|
||||||
|
it_behaves_like 'successful return'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
Loading…
x
Reference in New Issue
Block a user