Add batch actions to collections and possibility to report multiple collections (#38991)

This commit is contained in:
Pia B. 2026-05-12 18:13:01 +02:00 committed by GitHub
parent d2f640272f
commit 7c05f56fe8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 234 additions and 9 deletions

View File

@ -4,13 +4,48 @@ module Admin
class CollectionsController < BaseController
before_action :set_account
before_action :set_collection, only: :show
before_action :set_collections, except: :show
PER_PAGE = 20
def index
authorize [:admin, :collection], :index?
@collection_batch_action = Admin::CollectionBatchAction.new
end
def show
authorize @collection, :show?
end
def batch
authorize [:admin, :collection], :index?
@collection_batch_action = Admin::CollectionBatchAction.new(admin_collection_batch_action_params.merge(current_account: current_account, report_id: params[:report_id], type: 'report'))
@collection_batch_action.save!
rescue ActionController::ParameterMissing
flash[:alert] = I18n.t('admin.collections.no_collection_selected')
ensure
redirect_to after_create_redirect_path
end
private
def after_create_redirect_path
report_id = @collections_batch_action&.report_id || params[:report_id]
if report_id.present?
admin_report_path(report_id)
else
admin_account_collections_path(params[:account_id], params[:page])
end
end
def admin_collection_batch_action_params
params
.expect(admin_collection_batch_action: [collection_ids: []])
end
def set_account
@account = Account.find(params[:account_id])
end
@ -18,5 +53,9 @@ module Admin
def set_collection
@collection = @account.collections.includes(accepted_collection_items: :account).find(params[:id])
end
def set_collections
@collections = @account.collections.includes(accepted_collection_items: :account).page(params[:page]).per(PER_PAGE)
end
end
end

View File

@ -0,0 +1,42 @@
# frozen_string_literal: true
class Admin::CollectionBatchAction < Admin::BaseAction
TYPES = %w(
report
remove_from_report
).freeze
attr_accessor :collection_ids
private
def process_action!
return unless collection_ids
add_to_report!
end
def add_to_report!
@report = Report.new(report_params) unless with_report?
@report.collections = (@report.collections + selected_collections).uniq
@report.save!
@report_id = @report.id
end
def selected_collections
@report.target_account.collections.where(id: collection_ids)
end
def report_params
{ account: current_account, target_account: target_account }
end
def collection
@collection ||= Collection.where(id: collection_ids.first)
end
def target_account
@target_account ||= collection.first.account
end
end

View File

@ -0,0 +1,49 @@
- content_for :page_title do
= t('admin.collections.title', name: @account.pretty_acct)
.filters
.filter-subset
%ul
%li= filter_link_to t('generic.all'), id: nil
.back-link
- if params[:report_id]
= link_to admin_report_path(params[:report_id].to_i) do
= material_symbol 'chevron_left'
= t('admin.collections.back_to_report')
- else
= link_to admin_account_path(@account.id) do
= material_symbol 'chevron_left'
= t('admin.collections.back_to_account')
%hr.spacer/
= form_with model: @collection_batch_action, url: batch_admin_account_collections_path(@account.id) do |f|
= hidden_field_tag :page, params[:page] || 1
= hidden_field_tag :report_id, params[:report_id]
.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
- unless @collections.empty?
- if params[:report_id]
= f.button safe_join([material_symbol('add'), t('admin.collections.batch.add_to_report', id: params[:report_id])]),
class: 'table-action-link',
data: { confirm: t('admin.reports.are_you_sure') },
name: :report,
type: :submit
- else
= f.button safe_join([material_symbol('flag'), t('admin.collections.batch.report')]),
class: 'table-action-link',
data: { confirm: t('admin.reports.are_you_sure') },
name: :report,
type: :submit
.batch-table__body
- if @collections.empty?
= nothing_here 'nothing-here--under-tabs'
- else
= render partial: 'admin/shared/collection_batch_row', collection: @collections, as: :collection, locals: { f: f }
= paginate @collections

View File

@ -67,17 +67,19 @@
%summary
= t 'admin.reports.collections', count: @report.collections.size
%form
= form_with model: @form, url: batch_admin_account_collections_path(@report.target_account_id, report_id: @report.id) do |f|
.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
= link_to safe_join([material_symbol('add'), t('admin.reports.add_to_report')]),
admin_account_collections_path(@report.target_account_id, report_id: @report.id),
class: 'table-action-link'
.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
= render partial: 'admin/shared/collection_batch_row', collection: @report.collections, as: :collection, locals: { f: f }
- if @report.unresolved?
%hr.spacer/

View File

@ -1,5 +1,5 @@
.batch-table__row
%label.batch-table__row__select.batch-checkbox
-# = f.check_box :collection_ids, { multiple: true, include_hidden: false }, collection.id
= f.check_box :collection_ids, { multiple: true, include_hidden: false }, collection.id
.batch-table__row__content
= render partial: 'admin/shared/collection', object: collection

View File

@ -345,12 +345,19 @@ en:
updated_msg: Announcement successfully updated!
collections:
accounts: Accounts
back_to_account: Back to account page
back_to_report: Back to report page
batch:
add_to_report: 'Add to report #%{id}'
report: Report
collection_title: Collection by %{name}
contents: Contents
no_collection_selected: No collections were changed as none were selected
number_of_accounts:
one: 1 account
other: "%{count} accounts"
open: Open
title: Account collections - @%{name}
view_publicly: View publicly
critical_update_pending: Critical update pending
custom_emojis:

View File

@ -157,7 +157,7 @@ namespace :admin do
resource :reset, only: [:create]
resource :action, only: [:new, :create], controller: 'account_actions'
resources :collections, only: [:show]
resources :collections, only: [:index, :show], concerns: :batch
resources :statuses, only: [:index, :show], concerns: :batch
resources :relationships, only: [:index]

View File

@ -0,0 +1,50 @@
# frozen_string_literal: true
require 'rails_helper'
RSpec.describe Admin::CollectionBatchAction do
subject do
described_class.new(
current_account:,
collection_ids:,
report_id:,
type:
)
end
let(:account) { Fabricate(:account) }
let(:target_account) { Fabricate(:account) }
let(:current_account) { Fabricate(:admin_user).account }
let(:collection) { Fabricate(:collection, account: account) }
let(:collection_ids) { [collection.id] }
let(:report) { Fabricate(:report, account: target_account, target_account: account) }
let(:type) { 'report' }
before 'create collection report' do
report.collections << collection
report.save!
end
describe '#save!' do
context 'when with_report? is true' do
let(:other_collection) { Fabricate(:collection, account: account) }
let(:report_id) { report.id }
it 'creates no report and adds the collection to the existing report' do
collection_ids << other_collection.id
expect { subject.save! }.to_not change(Report, :count)
expect(report.collections).to include(other_collection)
end
end
context 'when with_report? is false' do
let(:report_id) { nil }
it 'creates a new report from the collection_ids' do
expect { subject.save! }.to change(Report, :count).by(1)
expect(Report.last.collections).to include(collection)
end
end
end
end

View File

@ -3,13 +3,19 @@
require 'rails_helper'
RSpec.describe 'Admin Collections' do
let(:account) { Fabricate(:account) }
let(:other_account) { Fabricate(:account) }
let(:collection) { Fabricate(:collection, account: account) }
let!(:second_collection) { Fabricate(:collection, account: account) }
let(:report) { Fabricate(:report, account: other_account, target_account: account) }
before do
sign_in Fabricate(:admin_user)
end
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)
@ -17,4 +23,34 @@ RSpec.describe 'Admin Collections' do
.to have_http_status(200)
end
end
describe 'GET /admin/accounts/:account_id/collections/' do
it 'returns http success' do
get admin_account_collections_path(account_id: account.id, id: collection.id)
expect(response).to have_http_status(200)
end
end
describe 'POST /admin/accounts/:account_id/collections/batch' do
subject { post batch_admin_account_collections_path(account_id: account.id, report_id: report_id, admin_collection_batch_action: { collection_ids: [collection.id, second_collection.id] }) }
context 'with a valid report' do
let(:report_id) { report.id }
it 'redirects to the report page' do
report.collections << collection
subject
expect(response).to redirect_to(admin_report_path(report.id))
end
end
context 'with an invalid report' do
let(:report_id) { nil }
it 'redirects to the account collections page' do
subject
expect(response).to redirect_to(admin_account_collections_path(account.id))
end
end
end
end