From ca99de5d4a913a5dada84c22b8b3eaf7d3740e8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hugo=20H=C3=B6rnquist?= Date: Wed, 10 Nov 2021 00:15:28 +0100 Subject: Handle calendar change through dropdown. --- module/calp/html/view/calendar.scm | 55 +++++++++++++++++++++-------- static/globals.ts | 71 ++++++++++++++++++++++++++++++-------- static/vevent.ts | 9 +++++ 3 files changed, 106 insertions(+), 29 deletions(-) diff --git a/module/calp/html/view/calendar.scm b/module/calp/html/view/calendar.scm index 634f6a69..580d721e 100644 --- a/module/calp/html/view/calendar.scm +++ b/module/calp/html/view/calendar.scm @@ -351,20 +351,45 @@ SEQUENCE REQUEST-STATUS ))) - (div (@ (style "display:none !important;") - (id "xcal-data")) - ,((@ (vcomponent xcal output) ns-wrap) - (map (@ (vcomponent xcal output) vcomponent->sxcal) - ;; A simple filter-sorted-stream on event-overlaps? here fails. See tests/annoying-events.scm - (stream->list - (stream-filter - (lambda (ev) - ((@ (vcomponent datetime) event-overlaps?) - ev start-date - (date+ end-date (date day: 1)))) - (stream-take-while (lambda (ev) (date< - (as-date (prop ev 'DTSTART)) - (date+ end-date (date day: 1)))) - events))))))) + ;; (div (@ (style "display:none !important;")) + ;; ,(map (lambda (calendar) + ;; (prop calendar 'NAME)) + ;; calendars)) + + ,@(let ((flat-events + ;; A simple filter-sorted-stream on event-overlaps? here fails. + ;; See tests/annoying-events.scm + (stream->list + (stream-filter + (lambda (ev) + ((@ (vcomponent datetime) event-overlaps?) + ev start-date + (date+ end-date (date day: 1)))) + (stream-take-while (lambda (ev) (date< + (as-date (prop ev 'DTSTART)) + (date+ end-date (date day: 1)))) + events))))) + + `((div (@ (style "display:none !important;") + (id "calendar-event-mapping")) + ,(let ((ht (make-hash-table))) + (for-each (lambda (event) + (define name (prop (parent event) 'NAME)) + (hash-set! ht name + (cons (prop event 'UID) + (hash-ref ht name '())))) + flat-events) + (map (lambda (pair) + `(calendar (@ (key ,(base64encode (car pair)))) + ,@(map (lambda (uid) `(li ,uid)) + (cdr pair)))) + (hash-map->list cons ht)))) + + (div (@ (style "display:none !important;") + (id "xcal-data")) + ,((@ (vcomponent xcal output) ns-wrap) + (map (@ (vcomponent xcal output) vcomponent->sxcal) + flat-events + )))))) )) diff --git a/static/globals.ts b/static/globals.ts index c812958b..daf5a2f7 100644 --- a/static/globals.ts +++ b/static/globals.ts @@ -9,7 +9,8 @@ import { VEvent, xml_to_vcal } from './vevent' import { bind_popup_control } from './dragable' import { uid, parseDate, gensym, to_local, boolean, makeElement } from './lib' -const vcal_objects: Map = new Map() +const vcal_objects: Map = new Map; +(window as any).vcal_objects = vcal_objects; interface HasValue { value: string @@ -146,10 +147,31 @@ class ComponentEdit extends ComponentVEvent { throw `Data missing for uid ${this.dataset.uid}.` } - this.redraw(data); // return; + /* Handle calendar dropdown */ + for (let el of this.getElementsByClassName('calendar-selection')) { + for (let opt of el.getElementsByTagName('option')) { + opt.selected = false; + if (opt.value == event_calendar_mapping.get(this.uid)) { + data.setCalendar(opt.value); + opt.selected = true; + /* No break since we want to set the remainders 'selected' to false */ + } + } + + el.addEventListener('change', (e) => { + let v = (e.target as HTMLSelectElement).selectedOptions[0].value + // e.selectedOptions[0].innerText + + let obj = vcal_objects.get(this.uid)! + obj.setCalendar(v); + }); + } + + this.redraw(data); + for (let el of this.getElementsByClassName("interactive")) { // console.log(el); el.addEventListener('input', () => { @@ -203,6 +225,15 @@ class ComponentEdit extends ComponentVEvent { } } + for (let el of body.getElementsByTagName('calendar-selection')) { + for (let opt of el.getElementsByTagName('option')) { + opt.selected = false; + if (opt.value == data._calendar) { + opt.selected = true; + } + } + } + if (this.firstTime) { this.replaceChildren(body); this.firstTime = false; @@ -284,9 +315,15 @@ class ComponentBlock extends ComponentVEvent { this.style.bottom = result; } } + + if (data._calendar) { + this.dataset.calendar = data._calendar; + } } } +const event_calendar_mapping: Map = new Map; + window.addEventListener('load', function() { // let json_objects_el = document.getElementById('json-objects'); @@ -298,6 +335,15 @@ window.addEventListener('load', function() { vcal_objects.set(ev.getProperty('uid'), ev) } + + let div2 = document.getElementById('calendar-event-mapping')!; + for (let calendar of div2.children) { + for (let child of calendar.children) { + event_calendar_mapping.set( + child.innerHTML, calendar.getAttribute('key')!); + } + } + /* - .popup - .block @@ -466,8 +512,15 @@ class PopupElement extends ComponentVEvent { this.tabcount = 0 } - redraw() { - console.warn('IMPLEMENT ME'); + redraw(data: VEvent) { + // console.warn('IMPLEMENT ME'); + + if (data._calendar) { + this.dataset.calendar = data._calendar; + } + + /* TODO is there any case where we want to propagate the draw to any of + our tabs? or are all our tabs independent? */ } connectedCallback() { @@ -509,16 +562,6 @@ class PopupElement extends ComponentVEvent { /* end nav bar */ this.replaceChildren(body); - - let that = this; - this.getElementsByClassName("calendar-selection")[0] - .addEventListener('change', function() { - let uid = (that.closest('[data-uid]') as HTMLElement).dataset.uid! - let obj = vcal_objects.get(uid) - // TODO this procedure - // this.value; - // event.properties.calendar = this.value; - }); } addTab(tab: TabElement) { diff --git a/static/vevent.ts b/static/vevent.ts index e0424ad7..c9068106 100644 --- a/static/vevent.ts +++ b/static/vevent.ts @@ -80,6 +80,8 @@ class VEvent { */ registered: Redrawable[] + _calendar: string | null = null; + constructor(properties: Map = new Map(), components: VEvent[] = []) { this.components = components; this.registered = []; @@ -127,6 +129,13 @@ class VEvent { } } + setCalendar(calendar: string) { + this._calendar = calendar; + for (let el of this.registered) { + el.redraw(this); + } + } + register(htmlNode: Redrawable) { this.registered.push(htmlNode); } -- cgit v1.2.3