Filter admin users by status (#16238)

* Use correct table heading for username

* WIP add role filter and crayonsify forms

* styling

* responsive

* Add form back in that was removed by merge conflict fix

* Suggest only valid search options

* Add basic tests for search and filter by role

* Add aria for search field

Co-authored-by: Suzanne Aitchison <suzanne@forem.com>

* Add email to aria

Co-authored-by: Julianna Tetreault <32834804+juliannatetreault@users.noreply.github.com>

Co-authored-by: Paweł Ludwiczak <ludwiczakpawel@gmail.com>
Co-authored-by: Suzanne Aitchison <suzanne@forem.com>
Co-authored-by: Julianna Tetreault <32834804+juliannatetreault@users.noreply.github.com>
This commit is contained in:
Andy Zhao 2022-03-02 11:13:59 -05:00 committed by GitHub
parent eff161ba58
commit 33e9bac0f7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 40 additions and 36 deletions

View file

@ -1 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path fill="none" d="M0 0h24v24H0z"/><path d="M2.8 5.2L7 8l4.186-5.86a1 1 0 0 1 1.628 0L17 8l4.2-2.8a1 1 0 0 1 1.547.95l-1.643 13.967a1 1 0 0 1-.993.883H3.889a1 1 0 0 1-.993-.883L1.253 6.149A1 1 0 0 1 2.8 5.2zM12 15a2 2 0 1 0 0-4 2 2 0 0 0 0 4z"/></svg>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24">
<path fill="none" d="M0 0h24v24H0z"/>
<path d="M2.8 5.2 7 8l4.186-5.86a1 1 0 0 1 1.628 0L17 8l4.2-2.8a1 1 0 0 1 1.547.95l-1.643 13.967a1 1 0 0 1-.993.883H3.889a1 1 0 0 1-.993-.883L1.253 6.149A1 1 0 0 1 2.8 5.2zM12 15a2 2 0 1 0 0-4 2 2 0 0 0 0 4z"/>
</svg>

Before

Width:  |  Height:  |  Size: 336 B

After

Width:  |  Height:  |  Size: 348 B

View file

@ -180,7 +180,10 @@ const adminFeatureArticle = async (id, featured) => {
try {
const response = await request(`/articles/${id}/admin_featured_toggle`, {
method: 'PATCH',
body: JSON.stringify({ id, article: { featured: featured === 'true' ? 0 : 1 } }),
body: JSON.stringify({
id,
article: { featured: featured === 'true' ? 0 : 1 },
}),
credentials: 'same-origin',
});
@ -401,14 +404,11 @@ export function addBottomActionsListeners() {
},
);
const featureArticleBtn = document.getElementById('feature-article-btn');
if (featureArticleBtn) {
featureArticleBtn.addEventListener('click', () => {
const {
articleId: id,
articleFeatured: featured,
} = featureArticleBtn.dataset;
const { articleId: id, articleFeatured: featured } =
featureArticleBtn.dataset;
adminFeatureArticle(id, featured);
});
}

View file

@ -1,4 +1,4 @@
const [ firstFlashDismissBtn ] =
const [firstFlashDismissBtn] =
document.getElementsByClassName('js-flash-close-btn');
// This allows screen reader users to become aware of the message (as well as bringing focus to the top of the main content).

View file

@ -1,4 +1,4 @@
<nav aria-label="People" class="flex justify-between gap-4">
<nav aria-label="People" class="mb-2 flex justify-between gap-4">
<ul class="crayons-navigation crayons-navigation--horizontal">
<li>
<%= link_to "People", admin_users_path, class: "crayons-navigation__item #{'crayons-navigation__item--current' if params[:controller] == 'admin/users'}", "aria-current": ("page" if params[:controller] == "admin/users") %>
@ -22,28 +22,15 @@
</nav>
<% if params[:controller] == "admin/users" %>
<nav aria-label="People groups" class="flex justify-between gap-4">
<ul class="crayons-navigation crayons-navigation--horizontal">
<li>
<%= link_to "All", admin_users_path, class: "crayons-navigation__item #{'crayons-navigation__item--current' if params[:controller] == 'admin/users' && params[:role].blank?}" %>
</li>
<li>
<%= link_to "Admins", admin_users_path(role: :admin), class: "crayons-navigation__item #{'crayons-navigation__item--current' if params[:controller] == 'admin/users' && params[:role] == 'admin'}" %>
</li>
<li>
<%= link_to "Super Admins", admin_users_path(role: :super_admin), class: "crayons-navigation__item #{'crayons-navigation__item--current' if params[:controller] == 'admin/users' && params[:role] == 'super_admin'}" %>
</li>
<li>
<%= link_to "Trusted", admin_users_path(role: :trusted), class: "crayons-navigation__item #{'crayons-navigation__item--current' if params[:controller] == 'admin/users' && params[:role] == 'trusted'}" %>
</li>
<li>
<%= link_to "Tag Mods", admin_users_path(role: :tag_moderator), class: "crayons-navigation__item #{'crayons-navigation__item--current' if params[:controller] == 'admin/users' && params[:role] == 'tag_moderator'}" %>
</li>
</ul>
<%= form_with url: admin_users_path, method: :get, local: true, class: "flex gap-2" do |f| %>
<%= f.text_field :search, value: params[:search], class: "crayons-textfield", placeholder: "Search..." %>
<%= f.hidden_field :role, value: params[:role] if params[:role].present? %>
<%= f.submit "Search", class: "c-btn c-btn--secondary" %>
<% end %>
</nav>
<%= form_with url: admin_users_path, method: :get, local: true, class: "flex flex-col m:flex-row gap-3 m:items-center crayons-card crayons-card--secondary p-3" do |f| %>
<div class="crayons-field flex-1 flex-row items-center gap-2">
<%= f.label :search, class: "crayons-field__label whitespace-nowrap" %>
<%= f.text_field :search, value: params[:search], class: "crayons-textfield mt-0", placeholder: "Name, username, email, or Twitter/GitHub usernames", aria: { label: "Filter by name, username, email, or Twitter/GitHub usernames" } %>
</div>
<div class="crayons-field flex-row items-center gap-2">
<%= f.label :role, "Filter by Role", class: "crayons-field__label whitespace-nowrap" %>
<%= f.select :role, options_for_select(Role::ROLES, params[:role]), { include_blank: true }, class: "crayons-select mt-0" %>
</div>
<%= f.submit "Filter", class: "c-btn c-btn--secondary" %>
<% end %>
<% end %>

View file

@ -8,7 +8,7 @@
<table class="crayons-table" width="100%">
<thead>
<tr>
<th scope="col">User</th>
<th scope="col">Username</th>
<th scope="col">ID</th>
<th scope="col">Name</th>
<th scope="col">Twitter</th>

View file

@ -180,7 +180,7 @@
<% @recent_featured_count = Article.where(featured: true).where("published_at > ?", 1.day.ago).size %>
<div class="article-admin-action mt-2">
<button
class="c-btn c-btn--primary w-100 <%= "crayons-btn--destructive" if @moderatable.featured%>"
class="c-btn c-btn--primary w-100 <%= "crayons-btn--destructive" if @moderatable.featured %>"
id="feature-article-btn"
data-article-featured="<%= @moderatable.featured %>"
data-article-id="<%= @moderatable.id %>"
@ -191,7 +191,7 @@
<div class="block additional-subtext-section py-4 pt-2">
<%= t("views.moderations.actions.featured_past_day", count: @recent_featured_count) %>
</div>
</div>
<div class="article-admin-action">
<button

View file

@ -16,6 +16,20 @@ RSpec.describe "/admin/users", type: :request do
get admin_users_path
expect(response.body).to include(user.username)
end
context "when searching" do
it "finds the proper user by GitHub username" do
get "#{admin_users_path}?search=#{user.github_username}"
expect(response.body).to include(CGI.escapeHTML(user.github_username))
end
end
context "when filtering by role" do
it "filters and shows the proper user(s)" do
get "#{admin_users_path}?search&role=super_admin"
expect(response.body).to include(CGI.escapeHTML(admin.name))
end
end
end
describe "GET /admin/users/:id" do