diff --git a/README.md b/README.md index 6d3b883..9cdd4e9 100644 --- a/README.md +++ b/README.md @@ -77,6 +77,7 @@ env = GRIST_ROOT_URL=https://grist.tiker.net env = GRIST_API_KEY_FILE=/home/grist-av/.grist-api-key env = GRIST_DOC_ID=rLJPGJ9RLJ4TRVx4AxT2tW env = SECRET_KEY=CHANGE_ME +env = CAL_TIMEZONES=America/Chicago,local,UTC # Optional. Only effective if both are provided. env = NOTIFY_FROM=andreask@illinois.edu diff --git a/availability/app.py b/availability/app.py index 00aa86a..6b9b942 100644 --- a/availability/app.py +++ b/availability/app.py @@ -279,6 +279,9 @@ def render_calendar( if slots is None: slots = [] + timezones = [tzname.strip() + for tzname in os.environ.get("CAL_TIMEZONES", "local,UTC").split(",")] + initial_date = None last_date = None events = [] @@ -322,8 +325,8 @@ def render_calendar( if has_spans: for span in spans: events.append({ - "start": span.start.isoformat(), - "end": span.end.isoformat(), + "start": span.start.timestamp() * 1000, + "end": span.end.timestamp() * 1000, "editable": True, "extendedProps": { "type": "span", @@ -350,7 +353,8 @@ def render_calendar( js_url=url_for("static", filename="availability.js"), has_slots=has_slots, allow_maybe=av_request.allow_maybe, - has_spans=has_spans) + has_spans=has_spans, + timezones=timezones) def send_notify(av_request: AvailabilityRequest, text_response: str, diff --git a/availability/static/availability.js b/availability/static/availability.js index 3355436..044c8eb 100644 --- a/availability/static/availability.js +++ b/availability/static/availability.js @@ -53,22 +53,29 @@ function calSelect(info) { styleEvent(ev); } +function fullcalDateToISO(date, calendar) { + // eslint-disable-next-line no-unused-vars + return FullCalendar.Luxon3.toLuxonDateTime(date, calendar).toISO(); +} + function onSubmit() { const slots = []; const spans = []; - document.calendarInstance.getEvents().forEach((ev) => { + const cal = document.calendarInstance; + + cal.getEvents().forEach((ev) => { if (ev.extendedProps.type === 'slot') { slots.push({ rspan_id: ev.extendedProps.rspan_id, - start: ev.start, - end: ev.end, + start: fullcalDateToISO(ev.start, cal), + end: fullcalDateToISO(ev.end, cal), available: ev.extendedProps.available, }); } else if (ev.extendedProps.type === 'span') { spans.push({ - start: ev.start, - end: ev.end, + start: fullcalDateToISO(ev.start, cal), + end: fullcalDateToISO(ev.end, cal), maybe: ev.extendedProps.maybe, }); } @@ -84,7 +91,7 @@ function onSubmit() { } // eslint-disable-next-line no-unused-vars -function initialize(initialDate, nDays, events, hasSpans) { +function initialize(initialDate, nDays, events, hasSpans, timezones) { document.addEventListener( 'DOMContentLoaded', () => { @@ -92,6 +99,7 @@ function initialize(initialDate, nDays, events, hasSpans) { // eslint-disable-next-line no-undef const calendar = new FullCalendar.Calendar(calendarEl, { // plugins: [timeGridPlugin], + timeZone: timezones[0], initialView: 'timeGridNDay', headerToolbar: { start: false, @@ -122,6 +130,25 @@ function initialize(initialDate, nDays, events, hasSpans) { document.calendarInstance = calendar; document.getElementById('submitButton').addEventListener('click', onSubmit); + document.getElementById('calPreviousButton').addEventListener('click', () => { + calendar.prev(); + }); + document.getElementById('calNextButton').addEventListener('click', () => { + calendar.next(); + }); + + const tzSelect = document.getElementById('timezone'); + for (let i = 0; i < timezones.length; i += 1) { + const opt = document.createElement('option'); + const tzName = timezones[i]; + opt.value = tzName; + opt.innerHTML = tzName; + tzSelect.appendChild(opt); + } + + tzSelect.addEventListener('change', () => { + calendar.setOption('timeZone', tzSelect.value); + }); }, ); } diff --git a/availability/templates/base.html b/availability/templates/base.html index 88e4492..bd8fa56 100644 --- a/availability/templates/base.html +++ b/availability/templates/base.html @@ -5,6 +5,7 @@ + {% block in_head %} {% endblock %} diff --git a/availability/templates/index.html b/availability/templates/index.html index bd785ba..7f808e3 100644 --- a/availability/templates/index.html +++ b/availability/templates/index.html @@ -1,14 +1,17 @@ {% extends "base.html" %} {% block in_head %} - + + + {% endblock %} @@ -37,8 +40,6 @@