Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions app/controllers/topics_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@ class TopicsController < ApplicationController
before_action :set_topic, only: [ :show, :edit, :update, :destroy, :archive, :unarchive ]

def index
@pagy, @topics = pagy(scope.includes(:documents_attachments).search_with_params(search_params))
topics = scope.includes(:documents_attachments).search_with_params(search_params)
topics = topics.reorder(created_at: Topic.sort_order(search_params[:order]&.to_sym)) if search_params[:sort] == "created_at"

@pagy, @topics = pagy(topics)
@available_providers = other_available_providers
@languages = scope.map(&:language).uniq.sort_by(&:name)
end
Expand Down Expand Up @@ -107,7 +110,7 @@ def mutator
def search_params
return { state: :active } unless params[:search].present?

params.require(:search).permit(:query, :state, :language_id, :year, :month, :order, tag_list: [])
params.require(:search).permit(:query, :state, :language_id, :year, :month, :sort, :order, tag_list: [])
end
helper_method :search_params

Expand Down
27 changes: 27 additions & 0 deletions app/helpers/topics_helper.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,31 @@
module TopicsHelper
def topic_sort_header(label, column)
current_column = search_params[:sort].presence_in(%w[published_at created_at]) || "published_at"
current_order = search_params[:order].presence_in(%w[asc desc]) || "desc"
active = current_column == column.to_s
next_order = current_order
next_order = current_order == "asc" ? "desc" : "asc" if active
indicator = active ? (current_order == "asc" ? "▲" : "▼") : "↕"
query = search_params.to_h.merge(sort: column, order: next_order)

link_to topics_path(search: query),
class: "inline-flex items-center gap-1 hover:text-gray-900 focus-visible:outline-2 focus-visible:outline-offset-2",
aria: { label: "Sort by #{label} #{next_order == "asc" ? "ascending" : "descending"}" },
data: { turbo_frame: "_top" } do
safe_join([
content_tag(:span, label),
content_tag(:span, indicator, class: active ? "text-gray-700" : "text-gray-400", aria: { hidden: true }),
])
end
end

def topic_sort_aria(column)
current_column = search_params[:sort].presence_in(%w[published_at created_at]) || "published_at"
return "none" unless current_column == column.to_s

search_params[:order] == "asc" ? "ascending" : "descending"
end

def card_preview_media(file)
case file.content_type
in /image/ then render_image(file)
Expand Down
21 changes: 8 additions & 13 deletions app/views/topics/_list.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,21 @@
<% if @topics.any? %>
<% @topics.each do |topic| %>
<tr class="border-b border-gray-100 transition-all hover:bg-gray-50">
<!-- Published -->
<td class="table-cell text-gray-500 font-mono text-xs">
<%= topic.published_at&.strftime("%b %d, %Y") %>
</td>

<!-- Title -->
<td class="table-cell">
<div class="flex flex-col items-center gap-1">
<div class="font-semibold text-gray-900 text-sm"><%= topic.title %></div>
<div class="text-gray-500 text-xs">Published <%= topic.published_at&.strftime('%b %d, %Y') %></div>
</div>
</td>

<!-- Description -->
<td class="hide-mobile table-cell text-gray-700 text-sm">
<% if topic.description.present? %>
<%= truncate(topic.description, length: 60, omission: '…') %>
<% else %>
<span class="text-gray-400 italic">No description</span>
<% end %>
</td>

<!-- UID -->
<td class="hide-mobile table-cell text-gray-500 font-mono text-xs">
<%= topic.uid.present? ? truncate(topic.uid, length: 12, omission: '…') : '-' %>
<!-- Added -->
<td class="table-cell text-gray-500 font-mono text-xs">
<%= topic.created_at.strftime("%b %d, %Y") %>
</td>

<!-- Language -->
Expand Down
1 change: 1 addition & 0 deletions app/views/topics/_search.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
</div>
<div class="card-body-sm">
<%= form_for :search, url: topics_path, method: :get, data: { controller: "topics", topics_target: "searchForm", turbo_frame: "topic-list", turbo_action: "advance" } do |f| %>
<%= f.hidden_field :sort, value: params.dig(:search, :sort) if params.dig(:search, :sort) == "created_at" %>
Comment thread
dmitrytrager marked this conversation as resolved.
Outdated
<div id="topics-search-grid" class="form-grid-auto items-start">
<!-- Query -->
<div class="form-grid-full">
Expand Down
18 changes: 9 additions & 9 deletions app/views/topics/index.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@

<!-- Search Card -->
<div class="mb-8">
<%= render "search", providers: @providers, languages: @languages, params: search_params %>
<%= render "search", providers: @providers, languages: @languages %>
</div>

<!-- Topics Table Card -->
Expand Down Expand Up @@ -83,14 +83,14 @@
<table class="w-full border-collapse table-fixed">
<thead>
<tr class="bg-gradient-gray border-b-2 border-gray-200">
<th class="px-6 py-5 text-left text-xs font-bold text-gray-600 uppercase tracking-wider truncate">Title</th>
<th class="px-6 py-5 text-left text-xs font-bold text-gray-600 uppercase tracking-wider truncate hide-mobile">Description</th>
<th class="px-6 py-5 text-left text-xs font-bold text-gray-600 uppercase tracking-wider truncate hide-mobile">UID</th>
<th class="px-6 py-5 text-left text-xs font-bold text-gray-600 uppercase tracking-wider truncate">Language</th>
<th class="px-6 py-5 text-left text-xs font-bold text-gray-600 uppercase tracking-wider truncate hide-mobile">Provider</th>
<th class="px-6 py-5 text-left text-xs font-bold text-gray-600 uppercase tracking-wider truncate"># of Documents</th>
<th class="px-6 py-5 text-left text-xs font-bold text-gray-600 uppercase tracking-wider truncate">State</th>
<th class="px-6 py-5 text-right text-xs font-bold text-gray-600 uppercase tracking-wider w-40 actions-col">Actions</th>
<th scope="col" class="px-6 py-5 text-left text-xs font-bold text-gray-600 uppercase tracking-wider truncate" aria-sort="<%= topic_sort_aria(:published_at) %>"><%= topic_sort_header("Published", :published_at) %></th>
<th scope="col" class="px-6 py-5 text-left text-xs font-bold text-gray-600 uppercase tracking-wider truncate">Title</th>
<th scope="col" class="px-6 py-5 text-left text-xs font-bold text-gray-600 uppercase tracking-wider truncate" aria-sort="<%= topic_sort_aria(:created_at) %>"><%= topic_sort_header("Added", :created_at) %></th>
<th scope="col" class="px-6 py-5 text-left text-xs font-bold text-gray-600 uppercase tracking-wider truncate">Language</th>
<th scope="col" class="px-6 py-5 text-left text-xs font-bold text-gray-600 uppercase tracking-wider truncate hide-mobile">Provider</th>
<th scope="col" class="px-6 py-5 text-left text-xs font-bold text-gray-600 uppercase tracking-wider truncate"># of Documents</th>
<th scope="col" class="px-6 py-5 text-left text-xs font-bold text-gray-600 uppercase tracking-wider truncate">State</th>
<th scope="col" class="px-6 py-5 text-right text-xs font-bold text-gray-600 uppercase tracking-wider w-40 actions-col">Actions</th>
</tr>
</thead>
<%= render "list", topics: @topics, params: search_params %>
Expand Down
45 changes: 45 additions & 0 deletions spec/requests/topics/index_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,51 @@
expect(page).to have_css("td", text: "1")
end

it "displays published and added dates without description or UID columns" do
create(
:topic,
provider:,
published_at: Time.zone.local(2021, 1, 1),
created_at: Time.zone.local(2022, 2, 2)
)

get topics_url

expect(page).to have_css("th", text: "Published")
expect(page).to have_css("th", text: "Added")
expect(page).to have_css("td", text: "Jan 01, 2021")
expect(page).to have_css("td", text: "Feb 02, 2022")
expect(page).not_to have_css("th", text: "Description")
expect(page).not_to have_css("th", text: "UID")

added_link = page.find_link("Added")
expect(added_link[:href]).to include("search%5Bsort%5D=created_at", "search%5Border%5D=desc")
expect(added_link["data-turbo-frame"]).to eq("_top")
expect(page).to have_css("th:not(.hide-mobile)", text: "Published")
expect(page).to have_css("th:not(.hide-mobile)", text: "Added")
end

it "sorts topics by the selected column and direction" do
newer_topic = create(:topic, provider:, title: "Newer", created_at: Time.zone.local(2022, 1, 1))
older_topic = create(:topic, provider:, title: "Older", created_at: Time.zone.local(2021, 1, 1))

get topics_url, params: { search: { state: "active", sort: "created_at", order: "asc" } }

expect(assigns(:topics)).to eq([ older_topic, newer_topic ])
expect(page).to have_css("input[type='hidden'][name='search[sort]'][value='created_at']", visible: :all)
expect(page).to have_select("search_order", selected: "asc")
expect(page).to have_css("th[aria-sort='ascending']", text: "Added")
end

it "falls back to published date for an unsupported sort column" do
older_topic = create(:topic, provider:, published_at: Time.zone.local(2021, 1, 1))
newer_topic = create(:topic, provider:, published_at: Time.zone.local(2022, 1, 1))

get topics_url, params: { search: { state: "active", sort: "uid", order: "asc" } }

expect(assigns(:topics)).to eq([ older_topic, newer_topic ])
end

describe "searching" do
context "with a query" do
it "filters topics by query" do
Expand Down