FIX: recurring events not displayed on /upcoming-events (#676)
When we introduced the DiscoursePostEventEvent model and the API service, the recurrent events stopped working as their logic still relied on the old naming convention, upcoming_dates. This PR changes the addRecurrentEvents logic to work with and to create DiscoursePostEventEvents for each of the upcomingDates, and changes the logic on the Category calendar to also work with the DiscoursePostEventEvent instance instead of the plain object, as well as re-using the API service to fetch the events. The function passed to onPageChange was also changed to async/await with some minor changes for clarity.
This commit is contained in:
parent
764fd67b5e
commit
3c833c99e3
|
|
@ -47,7 +47,7 @@ function initializeDiscourseCalendar(api) {
|
|||
selector = `.topic-list:not(.shared-drafts) .${outletName}-outlet`;
|
||||
}
|
||||
|
||||
api.onPageChange((url) => {
|
||||
api.onPageChange(async (url) => {
|
||||
const categoryCalendarNode = document.querySelector(
|
||||
`${selector}.category-calendar`
|
||||
);
|
||||
|
|
@ -98,7 +98,8 @@ function initializeDiscourseCalendar(api) {
|
|||
categoryCalendarNode.innerHTML =
|
||||
'<div class="calendar"><div class="spinner medium"></div></div>';
|
||||
|
||||
loadFullCalendar().then(() => {
|
||||
await loadFullCalendar();
|
||||
|
||||
const options = [`postId=${postId}`];
|
||||
|
||||
const optionals = ["weekends", "tzPicker", "defaultView"];
|
||||
|
|
@ -113,13 +114,11 @@ function initializeDiscourseCalendar(api) {
|
|||
const rawCalendar = `[calendar ${options.join(" ")}]\n[/calendar]`;
|
||||
const cookRaw = cook(rawCalendar);
|
||||
const loadPost = ajax(`/posts/${postId}.json`);
|
||||
Promise.all([cookRaw, loadPost]).then((results) => {
|
||||
const cooked = results[0];
|
||||
const post = results[1];
|
||||
|
||||
const [cooked, post] = await Promise.all([cookRaw, loadPost]);
|
||||
|
||||
categoryCalendarNode.innerHTML = cooked.toString();
|
||||
render($(".calendar"), post);
|
||||
});
|
||||
});
|
||||
} else {
|
||||
if (!categoryEventNode) {
|
||||
return;
|
||||
|
|
@ -131,10 +130,8 @@ function initializeDiscourseCalendar(api) {
|
|||
);
|
||||
|
||||
if (foundCategory) {
|
||||
loadFullCalendar().then(() => {
|
||||
let fullCalendar = new window.FullCalendar.Calendar(
|
||||
categoryEventNode,
|
||||
{
|
||||
await loadFullCalendar();
|
||||
let fullCalendar = new window.FullCalendar.Calendar(categoryEventNode, {
|
||||
...fullCalendarDefaultOptions(),
|
||||
eventPositioned: (info) => {
|
||||
if (siteSettings.events_max_rows === 0) {
|
||||
|
|
@ -161,8 +158,7 @@ function initializeDiscourseCalendar(api) {
|
|||
}
|
||||
fullCalendar.updateSize();
|
||||
},
|
||||
}
|
||||
);
|
||||
});
|
||||
const params = {
|
||||
category_id: browsedCategory.id,
|
||||
include_subcategories: true,
|
||||
|
|
@ -170,17 +166,16 @@ function initializeDiscourseCalendar(api) {
|
|||
if (siteSettings.include_expired_events_on_calendar) {
|
||||
params.include_expired = true;
|
||||
}
|
||||
const loadEvents = ajax(`/discourse-post-event/events`, {
|
||||
data: params,
|
||||
});
|
||||
|
||||
const tagsColorsMap = JSON.parse(siteSettings.map_events_to_color);
|
||||
|
||||
Promise.all([loadEvents]).then((results) => {
|
||||
const [{ events }] = results;
|
||||
const discoursePostEventApiService = api.container.lookup(
|
||||
"service:discourse-post-event-api"
|
||||
);
|
||||
|
||||
const events = await discoursePostEventApiService.events(params);
|
||||
addRecurrentEvents(events).forEach((event) => {
|
||||
const { starts_at, ends_at, post, category_id } = event;
|
||||
const { startsAt, endsAt, post, categoryId } = event;
|
||||
|
||||
let backgroundColor;
|
||||
|
||||
|
|
@ -200,19 +195,19 @@ function initializeDiscourseCalendar(api) {
|
|||
)?.color;
|
||||
backgroundColor =
|
||||
categoryColorFromMap ||
|
||||
`#${Category.findById(category_id)?.color}`;
|
||||
`#${Category.findById(categoryId)?.color}`;
|
||||
}
|
||||
|
||||
let classNames;
|
||||
if (moment(ends_at || starts_at).isBefore(moment())) {
|
||||
if (moment(endsAt || startsAt).isBefore(moment())) {
|
||||
classNames = "fc-past-event";
|
||||
}
|
||||
|
||||
fullCalendar.addEvent({
|
||||
title: formatEventName(event),
|
||||
start: starts_at,
|
||||
end: ends_at || starts_at,
|
||||
allDay: !isNotFullDayEvent(moment(starts_at), moment(ends_at)),
|
||||
start: startsAt,
|
||||
end: endsAt || startsAt,
|
||||
allDay: !isNotFullDayEvent(moment(startsAt), moment(endsAt)),
|
||||
url: getURL(`/t/-/${post.topic.id}/${post.post_number}`),
|
||||
backgroundColor,
|
||||
classNames,
|
||||
|
|
@ -220,8 +215,6 @@ function initializeDiscourseCalendar(api) {
|
|||
});
|
||||
|
||||
fullCalendar.render();
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,12 +1,17 @@
|
|||
import DiscoursePostEventEvent from "../models/discourse-post-event-event";
|
||||
|
||||
export default function addRecurrentEvents(events) {
|
||||
return events.flatMap((event) => {
|
||||
const upcomingEvents =
|
||||
event.upcoming_dates?.map((upcomingDate) => ({
|
||||
...event,
|
||||
event.upcomingDates?.map((upcomingDate) =>
|
||||
DiscoursePostEventEvent.create({
|
||||
name: event.name,
|
||||
post: event.post,
|
||||
category_id: event.categoryId,
|
||||
starts_at: upcomingDate.starts_at,
|
||||
ends_at: upcomingDate.ends_at,
|
||||
upcoming_dates: [],
|
||||
})) || [];
|
||||
})
|
||||
) || [];
|
||||
|
||||
return [event, ...upcomingEvents];
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
import { visit } from "@ember/test-helpers";
|
||||
import { test } from "qunit";
|
||||
import { tomorrow } from "discourse/lib/time-utils";
|
||||
import { tomorrow, twoDays } from "discourse/lib/time-utils";
|
||||
import {
|
||||
acceptance,
|
||||
exists,
|
||||
query,
|
||||
queryAll,
|
||||
} from "discourse/tests/helpers/qunit-helpers";
|
||||
|
||||
acceptance("Discourse Calendar - Upcoming Events Calendar", function (needs) {
|
||||
|
|
@ -38,7 +39,7 @@ acceptance("Discourse Calendar - Upcoming Events Calendar", function (needs) {
|
|||
events: [
|
||||
{
|
||||
id: 67501,
|
||||
starts_at: tomorrow(),
|
||||
starts_at: tomorrow().add(1, "hour"),
|
||||
ends_at: null,
|
||||
timezone: "Asia/Calcutta",
|
||||
post: {
|
||||
|
|
@ -51,6 +52,12 @@ acceptance("Discourse Calendar - Upcoming Events Calendar", function (needs) {
|
|||
},
|
||||
},
|
||||
name: "Awesome Event",
|
||||
upcoming_dates: [
|
||||
{
|
||||
starts_at: twoDays().format("YYYY-MM-DDT15:14:00.000Z"),
|
||||
ends_at: twoDays().format("YYYY-MM-DDT16:14:00.000Z"),
|
||||
},
|
||||
],
|
||||
category_id: 1,
|
||||
},
|
||||
{
|
||||
|
|
@ -101,4 +108,21 @@ acceptance("Discourse Calendar - Upcoming Events Calendar", function (needs) {
|
|||
"Event item uses the proper color from category 2"
|
||||
);
|
||||
});
|
||||
|
||||
test("upcoming events calendar shows recurrent events", async (assert) => {
|
||||
await visit("/upcoming-events");
|
||||
|
||||
const [, first, second] = queryAll(".fc-event .fc-title");
|
||||
assert.equal(first.textContent, "Awesome Event");
|
||||
assert.equal(second.textContent, "Awesome Event");
|
||||
|
||||
const firstCell = first.closest("td");
|
||||
const secondCell = second.closest("td");
|
||||
|
||||
assert.notEqual(
|
||||
firstCell,
|
||||
secondCell,
|
||||
"events should be in different days"
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in New Issue