diff --git a/app/controllers/discourse_post_event/events_controller.rb b/app/controllers/discourse_post_event/events_controller.rb index ffaf58fe..6c1f4c51 100644 --- a/app/controllers/discourse_post_event/events_controller.rb +++ b/app/controllers/discourse_post_event/events_controller.rb @@ -119,7 +119,14 @@ module DiscoursePostEvent private def filtered_events_params - params.permit(:post_id, :category_id, :include_subcategories, :include_expired, :limit) + params.permit( + :post_id, + :category_id, + :include_subcategories, + :include_expired, + :limit, + :before, + ) end end end diff --git a/assets/javascripts/discourse/components/upcoming-events-list.gjs b/assets/javascripts/discourse/components/upcoming-events-list.gjs index c9a5b776..2a9e790a 100644 --- a/assets/javascripts/discourse/components/upcoming-events-list.gjs +++ b/assets/javascripts/discourse/components/upcoming-events-list.gjs @@ -13,6 +13,7 @@ import { isNotFullDayEvent } from "../lib/guess-best-date-format"; export const DEFAULT_MONTH_FORMAT = "MMMM YYYY"; export const DEFAULT_DATE_FORMAT = "dddd, MMM D"; export const DEFAULT_TIME_FORMAT = "LT"; +const DEFAULT_UPCOMING_DAYS = 180; const DEFAULT_COUNT = 8; export default class UpcomingEventsList extends Component { @@ -28,6 +29,7 @@ export default class UpcomingEventsList extends Component { dateFormat = this.args.params?.dateFormat ?? DEFAULT_DATE_FORMAT; timeFormat = this.args.params?.timeFormat ?? DEFAULT_TIME_FORMAT; count = this.args.params?.count ?? DEFAULT_COUNT; + upcomingDays = this.args.params?.upcomingDays ?? DEFAULT_UPCOMING_DAYS; title = I18n.t( "discourse_calendar.discourse_post_event.upcoming_events_list.title" @@ -48,7 +50,7 @@ export default class UpcomingEventsList extends Component { constructor() { super(...arguments); - this.appEvents.on("page:changed", this, this.updateEventsByMonth); + this.appEvents.on("page:changed", this, this.updateEventsList); } get shouldRender() { @@ -75,13 +77,17 @@ export default class UpcomingEventsList extends Component { } @action - async updateEventsByMonth() { + async updateEventsList() { this.isLoading = true; this.hasError = false; try { const { events } = await ajax("/discourse-post-event/events", { - data: { category_id: this.categoryId, limit: this.count }, + data: { + category_id: this.categoryId, + limit: this.count, + before: moment().add(this.upcomingDays, "days").toISOString(), + }, }); this.eventsByMonth = this.groupByMonthAndDay(events); @@ -148,7 +154,7 @@ export default class UpcomingEventsList extends Component { {{this.errorMessage}} diff --git a/lib/discourse_post_event/event_finder.rb b/lib/discourse_post_event/event_finder.rb index d9e51e4d..2ad87985 100644 --- a/lib/discourse_post_event/event_finder.rb +++ b/lib/discourse_post_event/event_finder.rb @@ -33,6 +33,10 @@ module DiscoursePostEvent events = events.where(id: Array(params[:post_id])) if params[:post_id] + if params[:before].present? + events = events.where("dcped.starts_at < ?", params[:before].to_datetime) + end + if params[:category_id].present? if params[:include_subcategories].present? events = diff --git a/spec/lib/discourse_post_event/event_finder_spec.rb b/spec/lib/discourse_post_event/event_finder_spec.rb index 9b4bfa68..dc3437e0 100644 --- a/spec/lib/discourse_post_event/event_finder_spec.rb +++ b/spec/lib/discourse_post_event/event_finder_spec.rb @@ -182,5 +182,17 @@ describe DiscoursePostEvent::EventFinder do expect(finder.search(current_user, { limit: 2 })).to match_array([event1, event2]) end end + + describe "with a before parameter provided" do + let!(:event1) { Fabricate(:event) } + let!(:event2) { Fabricate(:event) } + let!(:event3) { Fabricate(:event, original_starts_at: 2.hours.ago) } + + it "returns the events started before the provided value" do + expect(finder.search(current_user, { before: event2.starts_at.to_s })).to match_array( + [event3], + ) + end + end end end diff --git a/spec/requests/events_controller_spec.rb b/spec/requests/events_controller_spec.rb index b53b60b0..1ee8bc9d 100644 --- a/spec/requests/events_controller_spec.rb +++ b/spec/requests/events_controller_spec.rb @@ -298,6 +298,15 @@ module DiscoursePostEvent expect(events.length).to eq(1) expect(events[0]["id"]).to eq(event_1.id) end + + it "filters events before the provided datetime if before param provided" do + get "/discourse-post-event/events.json?category_id=#{category.id}&include_subcategories=true&include_expired=true&before=#{event_2.starts_at}" + + expect(response.status).to eq(200) + events = response.parsed_body["events"] + expect(events.length).to eq(1) + expect(events[0]["id"]).to eq(event_3.id) + end end end end diff --git a/test/javascripts/integration/components/upcoming-events-list-test.gjs b/test/javascripts/integration/components/upcoming-events-list-test.gjs index 591ca78b..cec9e8dc 100644 --- a/test/javascripts/integration/components/upcoming-events-list-test.gjs +++ b/test/javascripts/integration/components/upcoming-events-list-test.gjs @@ -293,10 +293,36 @@ module("Integration | Component | upcoming-events-list", function (hooks) { "it displays the event name" ); }); + + test("with events, overridden upcomingDays parameter", async function (assert) { + pretender.get("/discourse-post-event/events", twoEventsResponseHandler); + + await render(); + + this.appEvents.trigger("page:changed", { url: "/" }); + + await waitFor(".loading-container .spinner", { count: 0 }); + + assert.strictEqual( + queryAll(".upcoming-events-list__event").length, + 1, + "it limits the results to started_at before the provided parameter" + ); + + assert.deepEqual( + [...queryAll(".upcoming-events-list__event-name")].map( + (el) => el.innerText + ), + ["Awesome Event"], + "it displays the event name" + ); + }); }); function twoEventsResponseHandler({ queryParams }) { - const events = [ + let events = [ { id: 67501, starts_at: tomorrowAllDay, @@ -333,7 +359,15 @@ function twoEventsResponseHandler({ queryParams }) { }, ]; - return response({ - events: queryParams.limit ? events.slice(0, queryParams.limit) : events, - }); + if (queryParams.limit) { + events.splice(queryParams.limit); + } + + if (queryParams.before) { + events = events.filter((event) => { + return moment(event.starts_at).isBefore(queryParams.before); + }); + } + + return response({ events }); }