Skip to content

Conversation

jjaffeux
Copy link
Contributor

@jjaffeux jjaffeux commented Jul 21, 2025

This commit makes the following changes:

  • uses fullcalendar 6
  • replaces the server generated upcoming dates for recurring events with a frontend implementation of the RRULE standard (using the fullcalendar RRULE plugin)
  • displays a preview of the event on click on the upcoming events calendar

@github-actions github-actions bot added i18n PRs which update English locale files or i18n related code discourse-calendar labels Jul 21, 2025
@jjaffeux jjaffeux force-pushed the core-full-calendar-6 branch from 55dbfa9 to 1e0ae7c Compare August 12, 2025 07:40
@jjaffeux jjaffeux marked this pull request as ready for review August 12, 2025 13:36
@jjaffeux jjaffeux force-pushed the core-full-calendar-6 branch from d82141e to 2caa2af Compare August 18, 2025 12:34
@@ -30,7 +30,7 @@ export default class DownloadCalendar extends Component {
this.args.model.calendar.title,
this.args.model.calendar.dates,
{
recurrenceRule: this.args.model.calendar.recurrenceRule,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just using the same rrule name everywhere

render json:
ActiveModel::ArraySerializer.new(
@events,
each_serializer: serializer,
each_serializer: BasicEventSerializer,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

always using the same serializer for lists, technically that could break stuff, but I didn't find anything

Copy link
Contributor

@renato renato Aug 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this has potential to strip fields that our frontend isn't using, but customers are relying on externally (not sure, I didn't compare field-by-field yet). Context from Meta: /t/-/287566/14

@@ -124,6 +121,8 @@ def filtered_events_params
:limit,
:before,
:attending_user,
:before,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we only had before, I added after to be able to have a range

@@ -59,40 +59,19 @@ def create_or_update_event_date

return if !starts_at_changed && !ends_at_changed

event_dates.update_all(finished_at: Time.current)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this was fixing a bug introduced months ago which was causing recurring events to be marke as finished

@@ -59,40 +59,19 @@ def create_or_update_event_date

return if !starts_at_changed && !ends_at_changed

event_dates.update_all(finished_at: Time.current)
set_next_date
end

def set_next_date
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just a full refactoring of these methods

end

def starts_at
# For recurring events, use the original start time to be consistent with rrule
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that was a bug we have had for a long time, but now that we use rrule everywhere we can just use the original start

),
this.siteSettings
);
schedule("afterRender", () => {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

without this the dates are not in the DOM yet at this point

<Description @description={{@event.description}} />
{{#if @event.canUpdateAttendance}}
<Status @event={{@event}} />
<AsyncContent @asyncData={{this.loadEvent}}>
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the biggest change is to make it possible to load an event if not provided as param

@@ -0,0 +1,165 @@
import Component from "@glimmer/component";
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this was all in JS/DOM code before, I made it a proper component

/>
</template>;

export default class FullCalendar extends Component {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same this was all JS/DOM code before

@@ -1,163 +1,9 @@
.discourse-calendar-wrap {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed most styling as things changed too much

@@ -12,4 +12,17 @@
desaturate(lighten($tertiary, 40%), 20%),
darken($tertiary, 10%)
)};
--fc-border-color: var(--primary-low);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is where most styling is decided for the full calendar now

@@ -4,85 +4,154 @@ module DiscoursePostEvent
class EventFinder
def self.search(user, params = {})
guardian = Guardian.new(user)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

refactored the whole file and added few filtering options

@@ -2,3 +2,5 @@ export { Calendar } from "@fullcalendar/core";
export { default as DayGrid } from "@fullcalendar/daygrid";
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this file allows to efficiently load the full calendar when needed

Copy link
Contributor

@martin-brennan martin-brennan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if this is just my local setup being weird, but the event popover is unstyled:

image

This is in a topic calendar with this post :

image

Anyway, looking really excellent man, approving because all my review comments are stylistic kind of ones, and testing is happening already for the UI internally.


// header is now generated in the component
// remove the old header generated when cooking if it exists
element.querySelector(".discourse-calendar-header")?.remove?.();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like there can't be many of these in the wild...maybe we mark these posts for rebake in a migration so we can remove this at some point?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also fine if not, just would be good if we didn't have to keep forever

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No it should be good to use const here, const allows mutation, but not reassignement:

> const test = [];
> undefined
> test.push(1);
> 1

@@ -47,18 +47,10 @@ discourse_calendar:
default: 2
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need a DB migration to cleanup all these removed settings from the site_settings table

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah yes right, thanks.

2799cc0

@jjaffeux
Copy link
Contributor Author

Not sure if this is just my local setup being weird, but the event popover is unstyled:

image This is in a topic calendar with this post : image Anyway, looking really excellent man, approving because all my review comments are stylistic kind of ones, and testing is happening already for the UI internally.

I fixed this I think

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
discourse-calendar i18n PRs which update English locale files or i18n related code
Development

Successfully merging this pull request may close these issues.

4 participants