forked from cybrespace/mastodon
Add search and sort functions to hashtag admin UI (#11829)
* Add search and sort functions to hashtag admin UI * Move scope processing from tags_controller to tag_filter * Fix based on method naming conventions * Fixed not to get 500 errors for invalid requests
This commit is contained in:
parent
b7420b8643
commit
ef0d22f232
|
@ -2,7 +2,6 @@
|
|||
|
||||
module Admin
|
||||
class TagsController < BaseController
|
||||
before_action :set_tags, only: :index
|
||||
before_action :set_tag, except: [:index, :batch, :approve_all, :reject_all]
|
||||
before_action :set_usage_by_domain, except: [:index, :batch, :approve_all, :reject_all]
|
||||
before_action :set_counters, except: [:index, :batch, :approve_all, :reject_all]
|
||||
|
@ -10,6 +9,7 @@ module Admin
|
|||
def index
|
||||
authorize :tag, :index?
|
||||
|
||||
@tags = filtered_tags.page(params[:page])
|
||||
@form = Form::TagBatch.new
|
||||
end
|
||||
|
||||
|
@ -48,10 +48,6 @@ module Admin
|
|||
|
||||
private
|
||||
|
||||
def set_tags
|
||||
@tags = filtered_tags.page(params[:page])
|
||||
end
|
||||
|
||||
def set_tag
|
||||
@tag = Tag.find(params[:id])
|
||||
end
|
||||
|
@ -73,16 +69,11 @@ module Admin
|
|||
end
|
||||
|
||||
def filtered_tags
|
||||
scope = Tag
|
||||
scope = scope.discoverable if filter_params[:context] == 'directory'
|
||||
scope = scope.unreviewed if filter_params[:review] == 'unreviewed'
|
||||
scope = scope.reviewed.order(reviewed_at: :desc) if filter_params[:review] == 'reviewed'
|
||||
scope = scope.pending_review.order(requested_review_at: :desc) if filter_params[:review] == 'pending_review'
|
||||
scope.order(max_score: :desc)
|
||||
TagFilter.new(filter_params).results
|
||||
end
|
||||
|
||||
def filter_params
|
||||
params.slice(:context, :review, :page).permit(:context, :review, :page)
|
||||
params.slice(:directory, :reviewed, :unreviewed, :pending_review, :page, :popular, :active, :name).permit(:directory, :reviewed, :unreviewed, :pending_review, :page, :popular, :active, :name)
|
||||
end
|
||||
|
||||
def tag_params
|
||||
|
|
|
@ -5,7 +5,7 @@ module Admin::FilterHelper
|
|||
REPORT_FILTERS = %i(resolved account_id target_account_id).freeze
|
||||
INVITE_FILTER = %i(available expired).freeze
|
||||
CUSTOM_EMOJI_FILTERS = %i(local remote by_domain shortcode).freeze
|
||||
TAGS_FILTERS = %i(context review).freeze
|
||||
TAGS_FILTERS = %i(directory reviewed unreviewed pending_review popular active name).freeze
|
||||
INSTANCES_FILTERS = %i(limited by_domain).freeze
|
||||
FOLLOWERS_FILTERS = %i(relationship status by_domain activity order).freeze
|
||||
|
||||
|
|
|
@ -39,6 +39,7 @@ class Tag < ApplicationRecord
|
|||
scope :listable, -> { where(listable: [true, nil]) }
|
||||
scope :discoverable, -> { listable.joins(:account_tag_stat).where(AccountTagStat.arel_table[:accounts_count].gt(0)).order(Arel.sql('account_tag_stats.accounts_count desc')) }
|
||||
scope :most_used, ->(account) { joins(:statuses).where(statuses: { account: account }).group(:id).order(Arel.sql('count(*) desc')) }
|
||||
scope :matches_name, ->(value) { where(arel_table[:name].matches("#{value}%")) }
|
||||
|
||||
delegate :accounts_count,
|
||||
:accounts_count=,
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class TagFilter
|
||||
attr_reader :params
|
||||
|
||||
def initialize(params)
|
||||
@params = params
|
||||
end
|
||||
|
||||
def results
|
||||
scope = Tag.unscoped
|
||||
|
||||
params.each do |key, value|
|
||||
next if key.to_s == 'page'
|
||||
|
||||
scope.merge!(scope_for(key, value.to_s.strip)) if value.present?
|
||||
end
|
||||
|
||||
scope.order(id: :desc)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def scope_for(key, value)
|
||||
case key.to_s
|
||||
when 'directory'
|
||||
Tag.discoverable
|
||||
when 'reviewed'
|
||||
Tag.reviewed.order(reviewed_at: :desc)
|
||||
when 'unreviewed'
|
||||
Tag.unreviewed
|
||||
when 'pending_review'
|
||||
Tag.pending_review.order(requested_review_at: :desc)
|
||||
when 'popular'
|
||||
Tag.order('max_score DESC NULLS LAST')
|
||||
when 'active'
|
||||
Tag.order('last_status_at DESC NULLS LAST')
|
||||
when 'name'
|
||||
Tag.matches_name(value)
|
||||
else
|
||||
raise "Unknown filter: #{key}"
|
||||
end
|
||||
end
|
||||
end
|
|
@ -8,16 +8,36 @@
|
|||
.filter-subset
|
||||
%strong= t('admin.tags.context')
|
||||
%ul
|
||||
%li= filter_link_to t('generic.all'), context: nil
|
||||
%li= filter_link_to t('admin.tags.directory'), context: 'directory'
|
||||
%li= filter_link_to t('generic.all'), directory: nil
|
||||
%li= filter_link_to t('admin.tags.directory'), directory: '1'
|
||||
|
||||
.filter-subset
|
||||
%strong= t('admin.tags.review')
|
||||
%ul
|
||||
%li= filter_link_to t('generic.all'), review: nil
|
||||
%li= filter_link_to t('admin.tags.unreviewed'), review: 'unreviewed'
|
||||
%li= filter_link_to t('admin.tags.reviewed'), review: 'reviewed'
|
||||
%li= filter_link_to safe_join([t('admin.accounts.moderation.pending'), "(#{Tag.pending_review.count})"], ' '), review: 'pending_review'
|
||||
%li= filter_link_to t('generic.all'), reviewed: nil, unreviewed: nil, pending_review: nil
|
||||
%li= filter_link_to t('admin.tags.unreviewed'), unreviewed: '1', reviewed: nil, pending_review: nil
|
||||
%li= filter_link_to t('admin.tags.reviewed'), reviewed: '1', unreviewed: nil, pending_review: nil
|
||||
%li= filter_link_to safe_join([t('admin.accounts.moderation.pending'), "(#{Tag.pending_review.count})"], ' '), pending_review: '1', reviewed: nil, unreviewed: nil
|
||||
|
||||
.filter-subset
|
||||
%strong= t('generic.order_by')
|
||||
%ul
|
||||
%li= filter_link_to t('admin.tags.most_recent'), popular: nil, active: nil
|
||||
%li= filter_link_to t('admin.tags.most_popular'), popular: '1', active: nil
|
||||
%li= filter_link_to t('admin.tags.last_active'), active: '1', popular: nil
|
||||
|
||||
= form_tag admin_tags_url, method: 'GET', class: 'simple_form' do
|
||||
.fields-group
|
||||
- Admin::FilterHelper::TAGS_FILTERS.each do |key|
|
||||
= hidden_field_tag key, params[key] if params[key].present?
|
||||
|
||||
- %i(name).each do |key|
|
||||
.input.string.optional
|
||||
= text_field_tag key, params[key], class: 'string optional', placeholder: I18n.t("admin.tags.#{key}")
|
||||
|
||||
.actions
|
||||
%button= t('admin.accounts.search')
|
||||
= link_to t('admin.accounts.reset'), admin_tags_path, class: 'button negative'
|
||||
|
||||
%hr.spacer/
|
||||
|
||||
|
|
|
@ -521,6 +521,10 @@ en:
|
|||
context: Context
|
||||
directory: In directory
|
||||
in_directory: "%{count} in directory"
|
||||
last_active: Last active
|
||||
most_popular: Most popular
|
||||
most_recent: Most recent
|
||||
name: Hashtag
|
||||
review: Review status
|
||||
reviewed: Reviewed
|
||||
title: Hashtags
|
||||
|
|
|
@ -131,6 +131,8 @@ en:
|
|||
must_be_follower: Block notifications from non-followers
|
||||
must_be_following: Block notifications from people you don't follow
|
||||
must_be_following_dm: Block direct messages from people you don't follow
|
||||
invite:
|
||||
comment: Comment
|
||||
invite_request:
|
||||
text: Why do you want to join?
|
||||
notification_emails:
|
||||
|
|
Loading…
Reference in New Issue