diff --git a/app/controllers/admin/collections_controller.rb b/app/controllers/admin/collections_controller.rb index 4701500f9f..2698abbd45 100644 --- a/app/controllers/admin/collections_controller.rb +++ b/app/controllers/admin/collections_controller.rb @@ -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 diff --git a/app/models/admin/collection_batch_action.rb b/app/models/admin/collection_batch_action.rb new file mode 100644 index 0000000000..d08f17d747 --- /dev/null +++ b/app/models/admin/collection_batch_action.rb @@ -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 diff --git a/app/views/admin/collections/index.html.haml b/app/views/admin/collections/index.html.haml new file mode 100644 index 0000000000..10c9e65b5e --- /dev/null +++ b/app/views/admin/collections/index.html.haml @@ -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 diff --git a/app/views/admin/reports/show.html.haml b/app/views/admin/reports/show.html.haml index 2d20b6a969..0aa2f69ba5 100644 --- a/app/views/admin/reports/show.html.haml +++ b/app/views/admin/reports/show.html.haml @@ -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/ diff --git a/app/views/admin/shared/_collection_batch_row.html.haml b/app/views/admin/shared/_collection_batch_row.html.haml index 8bf7857e95..8f42ab8db4 100644 --- a/app/views/admin/shared/_collection_batch_row.html.haml +++ b/app/views/admin/shared/_collection_batch_row.html.haml @@ -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 diff --git a/config/locales/en.yml b/config/locales/en.yml index b0533881ba..4a95e738b4 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -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: diff --git a/config/routes/admin.rb b/config/routes/admin.rb index 770a9cd777..a48defb3b9 100644 --- a/config/routes/admin.rb +++ b/config/routes/admin.rb @@ -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] diff --git a/spec/models/admin/collection_batch_action_spec.rb b/spec/models/admin/collection_batch_action_spec.rb new file mode 100644 index 0000000000..0ed57817e0 --- /dev/null +++ b/spec/models/admin/collection_batch_action_spec.rb @@ -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 diff --git a/spec/requests/admin/collections_spec.rb b/spec/requests/admin/collections_spec.rb index 0e87e277ae..6cb3a1ec2d 100644 --- a/spec/requests/admin/collections_spec.rb +++ b/spec/requests/admin/collections_spec.rb @@ -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