Add ability to filter instances by those which are not limited

pull/31481/head
Emelia Smith 2024-08-18 00:30:23 +02:00
parent 4bfb8887bf
commit 0248bca3c7
No known key found for this signature in database
5 changed files with 70 additions and 25 deletions

View File

@ -56,6 +56,12 @@ module Admin
end
def set_instances
# If we have `limited` in the query parameters, remove it and redirect to suspended:
return redirect_to admin_instances_path filter_params.merge(status: :suspended) if params[:limited].present?
# If we're in limited federation mode and have a status parameter, remove it:
return redirect_to admin_instances_path filter_params.merge(status: nil) if limited_federation_mode? && params[:status].present?
@instances = filtered_instances.page(params[:page])
end
@ -68,7 +74,7 @@ module Admin
end
def filtered_instances
InstanceFilter.new(limited_federation_mode? ? { allowed: true } : filter_params).results
InstanceFilter.new(limited_federation_mode? ? filter_params.merge(status: :allowed) : filter_params).results
end
def filter_params

View File

@ -2,7 +2,7 @@
class InstanceFilter
KEYS = %i(
limited
status
by_domain
availability
).freeze
@ -27,10 +27,8 @@ class InstanceFilter
def scope_for(key, value)
case key.to_s
when 'limited'
Instance.joins(:domain_block).reorder(domain_blocks: { id: :desc })
when 'allowed'
Instance.joins(:domain_allow).reorder(domain_allows: { id: :desc })
when 'status'
status_scope(value)
when 'by_domain'
Instance.matches_domain(value)
when 'availability'
@ -40,6 +38,27 @@ class InstanceFilter
end
end
def status_scope(value)
# The `join where` queries here look like they have a bug due to `domain_block`
# vs `domain_blocks`, however the table is `domain_blocks` while the relation on
# Instances is `domain_block`
case value.to_sym
when :allowed
Instance.joins(:domain_allow).reorder(Arel.sql('domain_allows.id desc'))
when :suspended
Instance.joins(:domain_block).where(domain_blocks: { severity: :suspend }).reorder(Arel.sql('domain_blocks.id desc'))
when :silenced
Instance.joins(:domain_block).where(domain_blocks: { severity: :silence }).reorder(Arel.sql('domain_blocks.id desc'))
when :noop
Instance.joins(:domain_block).where(domain_blocks: { severity: :noop }).reorder(Arel.sql('domain_blocks.id desc'))
when :not_limited
# Finds all instances where there isn't a record in the domain_blocks table
Instance.left_outer_joins(:domain_block).where(domain_blocks: { domain: nil })
else
raise Mastodon::InvalidParameterError, "Unknown limited scope value: #{value}"
end
end
def availability_scope(value)
case value
when 'failing'

View File

@ -15,10 +15,14 @@
.filter-subset
%strong= t('admin.instances.moderation.title')
%ul
%li= filter_link_to t('admin.instances.moderation.all'), limited: nil
- unless limited_federation_mode?
%li= filter_link_to t('admin.instances.moderation.limited'), limited: '1'
- if limited_federation_mode?
%li= filter_link_to t('admin.instances.moderation.allowed'), status: nil
- else
%li= filter_link_to t('admin.instances.moderation.all'), status: nil
%li= filter_link_to t('admin.instances.moderation.not_limited'), status: 'not_limited'
%li= filter_link_to t('admin.instances.moderation.noop'), status: 'noop'
%li= filter_link_to t('admin.instances.moderation.silenced'), status: 'silenced'
%li= filter_link_to t('admin.instances.moderation.suspended'), status: 'suspended'
.filter-subset
%strong= t('admin.instances.availability.title')
@ -27,22 +31,20 @@
%li= filter_link_to t('admin.instances.delivery.failing'), availability: 'failing'
%li= filter_link_to t('admin.instances.delivery.unavailable'), availability: 'unavailable'
- unless limited_federation_mode?
= form_with url: admin_instances_url, method: :get, class: :simple_form do |form|
.fields-group
- InstanceFilter::KEYS.each do |key|
= form.hidden_field key, value: params[key] if params[key].present?
= form_with url: admin_instances_url, method: :get, class: :simple_form do |form|
.fields-group
- InstanceFilter::KEYS.each do |key|
= form.hidden_field key, value: params[key] if params[key].present?
- %i(by_domain).each do |key|
.input.string.optional
= form.text_field key,
value: params[key],
class: 'string optional',
placeholder: I18n.t("admin.instances.#{key}")
.input.string.optional
= form.text_field :by_domain,
value: params[:by_domain],
class: 'string optional',
placeholder: t('admin.instances.by_domain')
.actions
%button.button= t('admin.accounts.search')
= link_to t('admin.accounts.reset'), admin_instances_path, class: 'button negative'
.actions
%button.button= t('admin.accounts.search')
= link_to t('admin.accounts.reset'), admin_instances_path, class: 'button negative'
%hr.spacer/

View File

@ -539,7 +539,11 @@ en:
other: "%{count} known accounts"
moderation:
all: All
limited: Limited
allowed: Allowed
noop: Filtered
not_limited: Not Limited
silenced: Silenced
suspended: Suspended
title: Moderation
private_comment: Private comment
public_comment: Public comment

View File

@ -34,6 +34,20 @@ RSpec.describe Admin::InstancesController do
expect(response).to have_http_status(200)
end
describe 'outdated filter parameters' do
it 'redirect to status suspended when just limited is set' do
get :index, params: { limited: 1 }
expect(response).to redirect_to admin_instances_path({ status: :suspended })
end
it 'retains other filters when redirecting if limited is set' do
get :index, params: { limited: 1, availability: 'failing' }
expect(response).to redirect_to admin_instances_path({ status: :suspended, availability: 'failing' })
end
end
def instance_directory_links
response.parsed_body.css('div.directory__tag a')
end