Add sorting feature to /admin/tags (#12249)

* Use Ransack for admin/tags

* Update admin tags index to use search with Ransack

* Add feature to sort tags in /admin/tags

* Add test for viewing /admin/tags pages

* Add aria labels for sort links

* Make links a bit more accessible
This commit is contained in:
Andy Zhao 2021-01-13 17:03:17 -05:00 committed by GitHub
parent 76894934e9
commit eed4df0fa4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 74 additions and 23 deletions

View file

@ -2,21 +2,15 @@ module Admin
class TagsController < Admin::ApplicationController
layout "admin"
before_action :set_default_options, only: %i[index]
before_action :badges_for_options, only: %i[new create edit update]
after_action only: [:update] do
Audit::Logger.log(:moderator, current_user, params.dup)
end
def index
@tags = case params[:state]
when "supported"
Tag.where(supported: true).order(taggings_count: :desc).page(params[:page]).per(50)
when "unsupported"
Tag.where(supported: false).order(taggings_count: :desc).page(params[:page]).per(50)
else
Tag.order(taggings_count: :desc).page(params[:page]).per(50)
end
@tags = @tags.where("tags.name ILIKE :search", search: "%#{params[:search]}%") if params[:search].present?
@q = Tag.ransack(params[:q])
@tags = @q.result.page(params[:page]).per(50)
end
def new
@ -53,6 +47,11 @@ module Admin
private
def set_default_options
params[:q] = { supported_not_null: "true" } if params[:q].blank?
params[:q][:s] = "taggings_count desc" if params[:q][:s].blank?
end
def badges_for_options
@badges_for_options = Badge.pluck(:title, :id)
end

View file

@ -1,23 +1,25 @@
<div class="flex items-center mb-6">
<div class="crayons-tabs">
<div class="nav-item">
<a href="/admin/tags" class="crayons-tabs__item <%= "crayons-tabs__item--current" if params[:state].blank? %>">All</a>
<a href="/admin/tags?q[supported_not_null]=true" class="crayons-tabs__item <%= "crayons-tabs__item--current" if params.dig(:q, :supported_not_null) %>" aria-label="All Tags">All</a>
</div>
<div class="nav-item">
<a href="/admin/tags?state=supported" class="crayons-tabs__item <%= "crayons-tabs__item--current" if params[:state] == "supported" %>">Supported</a>
<a href="/admin/tags?q[supported_eq]=true" class="crayons-tabs__item <%= "crayons-tabs__item--current" if params.dig(:q, :supported_eq) == "true" %>" aria-label="Supported Tags">Supported</a>
</div>
<div class="nav-item">
<a href="/admin/tags?state=unsupported" class="crayons-tabs__item <%= "crayons-tabs__item--current" if params[:state] == "unsupported" %>">Unsupported</a>
<a href="/admin/tags?q[supported_eq]=false" class="crayons-tabs__item <%= "crayons-tabs__item--current" if params.dig(:q, :supported_eq) == "false" %>" aria-label="Unsupported Tags">Unsupported</a>
</div>
</div>
<div class="m-auto">
<%= form_tag(admin_tags_path, method: "get", class: "inline-flex") do %>
<%= text_field_tag(:search, params[:search], aria: { label: "Search" }, class: "crayons-textfield") %>
<% if params[:state].present? %>
<%= hidden_field_tag(:state, params[:state]) %>
<%= search_form_for(@q, url: admin_tags_path, class: "inline-flex") do |f| %>
<%= f.search_field(:name_cont, aria: { label: "Search" }, class: "crayons-textfield") %>
<% if params.dig(:q, :supported_eq) %>
<%= f.hidden_field(:supported_eq) %>
<% else %>
<%= f.hidden_field(:supported_not_null) %>
<% end %>
<%= submit_tag("Search", class: "crayons-btn ml-2") %>
<%= f.submit "Search", class: "crayons-btn ml-2" %>
<% end %>
</div>
@ -31,18 +33,18 @@
<table class="crayons-table" width="100%">
<thead>
<tr>
<th scope="col">Tag</th>
<th scope="col">ID</th>
<th scope="col">Alias For</th>
<th scope="col">Taggings Count</th>
<th scope="col">Category</th>
<th scope="col"><%= sort_link(@q, :name, {}, { aria: { label: "Sort by Name" } }) %></th>
<th scope="col"><%= sort_link(@q, :id, {}, { aria: { label: "Sort by ID" } }) %></th>
<th scope="col"><%= sort_link(@q, :alias_for, {}, { aria: { label: "Sort by Alias For" } }) %></th>
<th scope="col"><%= sort_link(@q, :taggings_count, {}, { aria: { label: "Sort by Taggings Count" } }) %></th>
<th scope="col"><%= sort_link(@q, :category, {}, { aria: { label: "Sort by Category" } }) %></th>
<th scope="col">Is Moderated?</th>
</tr>
</thead>
<tbody class="crayons-card">
<% @tags.each do |tag| %>
<tr>
<td><%= link_to tag.name, edit_admin_tag_path(tag.id) %></td>
<td><%= link_to tag.name, edit_admin_tag_path(tag.id), aria: { label: "#{tag.name} tag" } %></td>
<td><%= tag.id %></td>
<td><%= tag.alias_for %></td>
<td><%= tag.taggings_count %></td>

View file

@ -0,0 +1,50 @@
require "rails_helper"
RSpec.describe "Admin updates a tag", type: :system do
let(:super_admin) { create(:user, :super_admin) }
let!(:tag1) { create(:tag, name: "alpha", supported: true, taggings_count: 1) }
let!(:tag2) { create(:tag, name: "betical", supported: false, taggings_count: 2) }
context "when viewing the default page" do
before do
sign_in super_admin
visit admin_tags_path
end
it "defaults to viewing all tags" do
tag_table_body = find(".crayons-card")
expect(tag_table_body.all("tr>td>a").count).to eq 2
end
it "defaults to sorting by taggings count, descending" do
tag_links = find(".crayons-card").all("tr>td>a")
expect(tag_links[0].text).to include tag2.name
expect(tag_links[1].text).to include tag1.name
end
it "can sort by other columns, like tag name" do
find_link(text: "Name").click
tag_links = find(".crayons-card").all("tr>td>a")
expect(tag_links[0].text).to include tag1.name
expect(tag_links[1].text).to include tag2.name
end
end
context "when viewing supported tags" do
it "shows only supported tags" do
sign_in super_admin
visit "#{admin_tags_path}?q[supported_eq]=true"
expect(page.body).to include tag1.name
expect(page.body).not_to include tag2.name
end
end
context "when viewing unsupported tags" do
it "shows only unsupported tags" do
sign_in super_admin
visit "#{admin_tags_path}?q[supported_eq]=false"
expect(page.body).to include tag2.name
expect(page.body).not_to include tag1.name
end
end
end