2
0
Fork 0
mirror of https://github.com/discourse/discourse.git synced 2025-10-03 17:21:20 +08:00

FEATURE: allow date-based filters to accept a day count (#33197)

This allows date based filters to use a count of days as well as the
existing date string system (`YYYY-MM-DD`). This is convenient if you
want a dynamic list based on the current date, you could use:
`created-after:7` to return topics from the past week.

This will work for: 

 - created-before/after
 - activity-before/after
 - latest-post-before/after
 
This also makes filters consistent with our existing query params like
`?before=7`



This came up in:
https://meta.discourse.org/t/creating-a-custom-filter-homepage/370062
and is something that we mentioned internally while defining our domain
specific language for the /filter route, but never implemented.
This commit is contained in:
Kris 2025-06-13 13:45:50 -04:00 committed by GitHub
parent 038e511552
commit bc4844cb93
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 55 additions and 0 deletions

View file

@ -145,6 +145,11 @@ class TopicsFilter
Time.zone.parse(
"#{match_data[:year].to_i}-#{match_data[:month].to_i}-#{match_data[:day].to_i}",
)
elsif value =~ /\A\d+\z/
# Handle integer as number of days ago (0 = today at midnight)
days = value.to_i
return nil if days < 0
days.days.ago.beginning_of_day
end
when "likes-min", "likes-max", "likes-op-min", "likes-op-max", "posts-min", "posts-max",
"posters-min", "posters-max", "views-min", "views-max"

View file

@ -1331,6 +1331,56 @@ RSpec.describe TopicsFilter do
).to eq([])
end
end

describe "when query string is `#{filter}-after:1`" do
it "should only return topics with #{description} after 1 day ago" do
freeze_time do
old_topic = Fabricate(:topic, column => 2.days.ago)
recent_topic = Fabricate(:topic, column => Time.zone.now)

expect(
TopicsFilter
.new(guardian: Guardian.new)
.filter_from_query_string("#{filter}-after:1")
.pluck(:id),
).to contain_exactly(recent_topic.id)
end
end
end

describe "when query string is `#{filter}-before:1`" do
it "should only return topics with #{description} before 1 day ago" do
freeze_time do
old_topic = Fabricate(:topic, column => 2.days.ago)
recent_topic = Fabricate(:topic, column => Time.zone.now)

results =
TopicsFilter
.new(guardian: Guardian.new)
.filter_from_query_string("#{filter}-before:1")
.where(id: [old_topic.id, recent_topic.id])
.pluck(:id)

expect(results).to contain_exactly(old_topic.id)
end
end
end

describe "when query string is `#{filter}-after:0`" do
it "should only return topics with #{description} after today" do
freeze_time do
old_topic = Fabricate(:topic, column => 2.days.ago)
recent_topic = Fabricate(:topic, column => Time.zone.now)

expect(
TopicsFilter
.new(guardian: Guardian.new)
.filter_from_query_string("#{filter}-after:0")
.pluck(:id),
).to contain_exactly(recent_topic.id)
end
end
end
end

describe "when filtering by activity of topics" do