From c986f9a9476a6a84473a37f5167c01922c561768 Mon Sep 17 00:00:00 2001 From: Joffrey JAFFEUX Date: Thu, 14 Mar 2024 21:32:15 +0100 Subject: [PATCH] DEV: adds details/location options to downloadCalendar (#26177) This will now only be used for google to pre-fill the associated fields in: https://calendar.google.com/calendar/u/0/r/eventedit --- .../discourse/app/lib/download-calendar.js | 36 +++++++++------ .../discourse/app/lib/plugin-api.gjs | 6 +-- .../tests/unit/lib/download-calendar-test.js | 46 ++++++++++++++++++- 3 files changed, 70 insertions(+), 18 deletions(-) diff --git a/app/assets/javascripts/discourse/app/lib/download-calendar.js b/app/assets/javascripts/discourse/app/lib/download-calendar.js index 238a8cf0dde..a0c33add6e8 100644 --- a/app/assets/javascripts/discourse/app/lib/download-calendar.js +++ b/app/assets/javascripts/discourse/app/lib/download-calendar.js @@ -3,7 +3,7 @@ import User from "discourse/models/user"; import { getOwnerWithFallback } from "discourse-common/lib/get-owner"; import getURL from "discourse-common/lib/get-url"; -export function downloadCalendar(title, dates, recurrenceRule = null) { +export function downloadCalendar(title, dates, options = {}) { const currentUser = User.current(); const formattedDates = formatDates(dates); @@ -11,20 +11,20 @@ export function downloadCalendar(title, dates, recurrenceRule = null) { switch (currentUser.user_option.default_calendar) { case "none_selected": - _displayModal(title, formattedDates, recurrenceRule); + _displayModal(title, formattedDates, options); break; case "ics": - downloadIcs(title, formattedDates, recurrenceRule); + downloadIcs(title, formattedDates, options); break; case "google": - downloadGoogle(title, formattedDates, recurrenceRule); + downloadGoogle(title, formattedDates, options); break; } } -export function downloadIcs(title, dates, recurrenceRule) { +export function downloadIcs(title, dates, options = {}) { const REMOVE_FILE_AFTER = 20_000; - const file = new File([generateIcsData(title, dates, recurrenceRule)], { + const file = new File([generateIcsData(title, dates, options)], { type: "text/plain", }); @@ -37,7 +37,7 @@ export function downloadIcs(title, dates, recurrenceRule) { setTimeout(() => window.URL.revokeObjectURL(file), REMOVE_FILE_AFTER); //remove file to avoid memory leaks } -export function downloadGoogle(title, dates, recurrenceRule) { +export function downloadGoogle(title, dates, options = {}) { dates.forEach((date) => { const link = new URL("https://www.google.com/calendar/event"); link.searchParams.append("action", "TEMPLATE"); @@ -49,8 +49,16 @@ export function downloadGoogle(title, dates, recurrenceRule) { )}` ); - if (recurrenceRule) { - link.searchParams.append("recur", `RRULE:${recurrenceRule}`); + if (options.recurrenceRule) { + link.searchParams.append("recur", `RRULE:${options.recurrenceRule}`); + } + + if (options.location) { + link.searchParams.append("location", options.location); + } + + if (options.details) { + link.searchParams.append("details", options.details); } window.open(getURL(link.href).trim(), "_blank", "noopener", "noreferrer"); @@ -68,7 +76,7 @@ export function formatDates(dates) { }); } -export function generateIcsData(title, dates, recurrenceRule) { +export function generateIcsData(title, dates, options = {}) { let data = "BEGIN:VCALENDAR\nVERSION:2.0\nPRODID:-//Discourse//EN\n"; dates.forEach((date) => { const startDate = moment(date.startsAt); @@ -80,7 +88,7 @@ export function generateIcsData(title, dates, recurrenceRule) { `DTSTAMP:${moment().utc().format("YMMDDTHHmmss")}Z\n` + `DTSTART:${startDate.utc().format("YMMDDTHHmmss")}Z\n` + `DTEND:${endDate.utc().format("YMMDDTHHmmss")}Z\n` + - (recurrenceRule ? `RRULE:${recurrenceRule}\n` : ``) + + (options.recurrenceRule ? `RRULE:${options.recurrenceRule}\n` : ``) + `SUMMARY:${title}\n` + "END:VEVENT\n" ); @@ -89,10 +97,12 @@ export function generateIcsData(title, dates, recurrenceRule) { return data; } -function _displayModal(title, dates, recurrenceRule) { +function _displayModal(title, dates, options = {}) { const modal = getOwnerWithFallback(this).lookup("service:modal"); modal.show(downloadCalendarModal, { - model: { calendar: { title, dates, recurrenceRule } }, + model: { + calendar: { title, dates, recurrenceRule: options.recurrenceRule }, + }, }); } diff --git a/app/assets/javascripts/discourse/app/lib/plugin-api.gjs b/app/assets/javascripts/discourse/app/lib/plugin-api.gjs index 9eaf8fb363c..cdc05e4fdc7 100644 --- a/app/assets/javascripts/discourse/app/lib/plugin-api.gjs +++ b/app/assets/javascripts/discourse/app/lib/plugin-api.gjs @@ -2116,12 +2116,12 @@ class PluginApi { * endsAt: "2021-10-12T16:00:00.000Z", * }, * ], - * "FREQ=DAILY;BYDAY=MO,TU,WE,TH,FR" + * { recurrenceRule: "FREQ=DAILY;BYDAY=MO,TU,WE,TH,FR", location: "Paris", details: "Foo" } * ); * ``` */ - downloadCalendar(title, dates, recurrenceRule = null) { - downloadCalendar(title, dates, recurrenceRule); + downloadCalendar(title, dates, options = {}) { + downloadCalendar(title, dates, options); } /** diff --git a/app/assets/javascripts/discourse/tests/unit/lib/download-calendar-test.js b/app/assets/javascripts/discourse/tests/unit/lib/download-calendar-test.js index 9ff25083d13..764279e43f2 100644 --- a/app/assets/javascripts/discourse/tests/unit/lib/download-calendar-test.js +++ b/app/assets/javascripts/discourse/tests/unit/lib/download-calendar-test.js @@ -62,7 +62,7 @@ END:VCALENDAR` endsAt: "2021-10-12T16:00:00.000Z", }, ], - "FREQ=DAILY;BYDAY=MO,TU,WE,TH,FR" + { recurrenceRule: "FREQ=DAILY;BYDAY=MO,TU,WE,TH,FR" } ); assert.equal( data, @@ -109,7 +109,7 @@ END:VCALENDAR` endsAt: "2021-10-12T16:00:00.000Z", }, ], - "FREQ=DAILY;BYDAY=MO,TU,WE,TH,FR" + { recurrenceRule: "FREQ=DAILY;BYDAY=MO,TU,WE,TH,FR" } ); assert.ok( window.open.calledWith( @@ -121,6 +121,48 @@ END:VCALENDAR` ); }); + test("correct location for Google when location given", function (assert) { + downloadGoogle( + "event", + [ + { + startsAt: "2021-10-12T15:00:00.000Z", + endsAt: "2021-10-12T16:00:00.000Z", + }, + ], + { location: "Paris" } + ); + assert.ok( + window.open.calledWith( + "https://www.google.com/calendar/event?action=TEMPLATE&text=event&dates=20211012T150000Z%2F20211012T160000Z&location=Paris", + "_blank", + "noopener", + "noreferrer" + ) + ); + }); + + test("correct details for Google when details given", function (assert) { + downloadGoogle( + "event", + [ + { + startsAt: "2021-10-12T15:00:00.000Z", + endsAt: "2021-10-12T16:00:00.000Z", + }, + ], + { details: "Cool" } + ); + assert.ok( + window.open.calledWith( + "https://www.google.com/calendar/event?action=TEMPLATE&text=event&dates=20211012T150000Z%2F20211012T160000Z&details=Cool", + "_blank", + "noopener", + "noreferrer" + ) + ); + }); + test("calculates end date when none given", function (assert) { let dates = formatDates([{ startsAt: "2021-10-12T15:00:00.000Z" }]); assert.deepEqual(