From 327b322b9583f760cd02ddad7a2a8890df26cc8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hugo=20H=C3=B6rnquist?= Date: Thu, 23 Jun 2022 01:39:08 +0200 Subject: work --- static/components/edit-rrule.ts | 12 +++---- static/components/popup-element.ts | 13 ++++---- static/components/tab-group-element.ts | 11 ++++--- static/components/vevent-block.ts | 4 +-- static/components/vevent-description.ts | 4 +-- static/components/vevent-edit.ts | 25 +++++++++----- static/components/vevent.ts | 58 ++++++++++++++++++++++++++++----- 7 files changed, 88 insertions(+), 39 deletions(-) (limited to 'static/components') diff --git a/static/components/edit-rrule.ts b/static/components/edit-rrule.ts index a361bdee..8575d9bc 100644 --- a/static/components/edit-rrule.ts +++ b/static/components/edit-rrule.ts @@ -11,8 +11,8 @@ import { RecurrenceRule } from '../vevent' */ class EditRRule extends ComponentVEvent { - constructor(uid?: string) { - super(uid); + constructor(uid?: string, instance?: string) { + super(uid, instance); if (!this.template) { throw 'vevent-edit-rrule template required'; @@ -25,7 +25,7 @@ class EditRRule extends ComponentVEvent { for (let el of this.querySelectorAll('[name]')) { el.addEventListener('input', () => { // console.log(this); - let data = vcal_objects.get(this.uid)!; + let data = this.getData()!; let rrule = data.getProperty('rrule') if (!rrule) { console.warn('RRUle missing from object'); @@ -41,9 +41,9 @@ class EditRRule extends ComponentVEvent { } } - connectedCallback() { - this.redraw(vcal_objects.get(this.uid)!) - } + // connectedCallback() { + // this.redraw(this.getData()!) + // } redraw(data: VEvent) { diff --git a/static/components/popup-element.ts b/static/components/popup-element.ts index 3300f885..5dc627d0 100644 --- a/static/components/popup-element.ts +++ b/static/components/popup-element.ts @@ -15,12 +15,12 @@ class PopupElement extends ComponentVEvent { * the top, and allowing global keyboard bindings to affect it. */ static activePopup: PopupElement | null = null; - constructor(uid?: string) { - super(uid); + constructor(uid?: string, instance?: string) { + super(uid, instance); /* TODO populate remaining (??) */ - let obj = vcal_objects.get(this.uid); + let obj = this.getData(); if (obj && obj.calendar) { this.dataset.calendar = obj.calendar; } @@ -48,8 +48,6 @@ class PopupElement extends ComponentVEvent { let template = document.getElementById('popup-template') as HTMLTemplateElement let body = (template.content.cloneNode(true) as DocumentFragment).firstElementChild!; - let uid = this.uid; - /* nav bar */ let nav = body.getElementsByClassName("popup-control")[0] as HTMLElement; bind_popup_control(nav); @@ -61,7 +59,8 @@ class PopupElement extends ComponentVEvent { maximize_btn.addEventListener('click', () => this.maximize()); let remove_btn = body.querySelector('.popup-control .remove-button') as HTMLButtonElement - remove_btn.addEventListener('click', () => remove_event(uid)); + /* TODO repeating removal */ + remove_btn.addEventListener('click', () => remove_event(this.uid)); /* end nav bar */ this.replaceChildren(body); @@ -147,7 +146,7 @@ class PopupElement extends ComponentVEvent { */ function setup_popup_element(ev: VEvent): PopupElement { let uid = ev.getProperty('uid'); - let popup = new PopupElement(uid); + let popup = new PopupElement(uid, ev.getProperty('dtstart')?.format('~Y-~m-~dT~H:~M:~S')); ev.register(popup); /* TODO propper way to find popup container */ (document.querySelector('.days') as Element).appendChild(popup); diff --git a/static/components/tab-group-element.ts b/static/components/tab-group-element.ts index e90997e9..11949870 100644 --- a/static/components/tab-group-element.ts +++ b/static/components/tab-group-element.ts @@ -26,8 +26,8 @@ class TabGroupElement extends ComponentVEvent { tabs: HTMLElement[] = []; tabLabels: HTMLElement[] = []; - constructor(uid?: string) { - super(uid); + constructor(uid?: string, instance?: string) { + super(uid!, instance!); this.menu = makeElement('div', {}, { role: 'tablist', @@ -43,7 +43,8 @@ class TabGroupElement extends ComponentVEvent { if (!this.has_rrule_tab()) { /* Note that EditRRule register itself to be updated on changes to the event */ - this.addTab(new EditRRule(data.getProperty('uid')), + this.addTab(new EditRRule(data.getProperty('uid'), + data.getProperty('dtstart')?.format('~Y-~m-~dT~H:~M:~S')), "↺", "Upprepningar"); } } else { @@ -71,7 +72,7 @@ class TabGroupElement extends ComponentVEvent { } /* redraw might add or remove tabs depending on our data, so call it here */ - this.redraw(vcal_objects.get(this.uid)!); + this.redraw(this.getData()!); /* All tabs should now be ready, focus the first one */ if (this.tabLabels.length > 0) { @@ -144,7 +145,7 @@ class TabGroupElement extends ComponentVEvent { if (tab.firstChild) { let child = tab.firstChild as HTMLElement; if (isRedrawable(child)) { - vcal_objects.get(this.uid)?.unregister(child) + this.getData()?.unregister(child) } } diff --git a/static/components/vevent-block.ts b/static/components/vevent-block.ts index 8cf61d30..f97a0e54 100644 --- a/static/components/vevent-block.ts +++ b/static/components/vevent-block.ts @@ -10,8 +10,8 @@ import { parseDate, to_local } from '../lib' A grahpical block in the week view. */ class ComponentBlock extends ComponentVEvent { - constructor(uid?: string) { - super(uid); + constructor(uid?: string, instance?: string) { + super(uid!, instance!); if (!this.template) { throw 'vevent-block template required'; diff --git a/static/components/vevent-description.ts b/static/components/vevent-description.ts index f0d224be..efa619c4 100644 --- a/static/components/vevent-description.ts +++ b/static/components/vevent-description.ts @@ -9,8 +9,8 @@ import { formatters } from '../formatters' */ class ComponentDescription extends ComponentVEvent { - constructor(uid?: string) { - super(uid); + constructor(uid?: string, instance?: string) { + super(uid!, instance!); if (!this.template) { throw 'vevent-description template required'; } diff --git a/static/components/vevent-edit.ts b/static/components/vevent-edit.ts index bf72678c..108146a3 100644 --- a/static/components/vevent-edit.ts +++ b/static/components/vevent-edit.ts @@ -14,8 +14,8 @@ import { to_boolean, gensym } from '../lib' */ class ComponentEdit extends ComponentVEvent { - constructor(uid?: string) { - super(uid); + constructor(uid?: string, instance?: string) { + super(uid, instance); if (!this.template) { throw 'vevent-edit template required'; @@ -39,10 +39,10 @@ class ComponentEdit extends ComponentVEvent { /* Edit tab is rendered here. It's left blank server-side, since it only makes sense to have something here if we have javascript */ - let data = vcal_objects.get(this.uid) + let data = this.getData() if (!data) { - throw `Data missing for uid ${this.dataset.uid}.` + throw `Data missing for uid ${this.getKey()}.` } @@ -59,7 +59,7 @@ class ComponentEdit extends ComponentVEvent { el.addEventListener('change', (e) => { let v = (e.target as HTMLSelectElement).selectedOptions[0].value - let obj = vcal_objects.get(this.uid)! + let obj = this.getData()! obj.calendar = v; }); } @@ -70,7 +70,7 @@ class ComponentEdit extends ComponentVEvent { for (let el of this.querySelectorAll("[data-property]")) { // console.log(el); el.addEventListener('input', (e) => { - let obj = vcal_objects.get(this.uid) + let obj = this.getData() // console.log(el, e); if (obj === undefined) { throw 'No object with uid ' + this.uid @@ -117,18 +117,25 @@ class ComponentEdit extends ComponentVEvent { /* TODO unselecting and reselecting this checkbox deletes all entered data. Cache it somewhere */ if (has_repeats.checked) { - vcal_objects.get(this.uid)!.setProperty('rrule', new RecurrenceRule()) + this.getData()!.setProperty('rrule', new RecurrenceRule()) } else { /* TODO is this a good way to remove a property ? */ - vcal_objects.get(this.uid)!.setProperty('rrule', undefined) + this.getData()!.setProperty('rrule', undefined) } }) } let submit = this.querySelector('form') as HTMLFormElement + /* TODO If start or end DATE is changed, only allow THIS */ + /* if only time component was changed, allow all */ submit.addEventListener('submit', (e) => { console.log(submit, e); - create_event(vcal_objects.get(this.uid)!); + // submit button pressed (e.submitter); + let submit_type = 'all'; + if (e.submitter) { + submit_type = e.submitter.dataset.key!; + } + create_event(submit_type, this.getData()!); e.preventDefault(); return false; diff --git a/static/components/vevent.ts b/static/components/vevent.ts index 5852a2ff..abf0f4c0 100644 --- a/static/components/vevent.ts +++ b/static/components/vevent.ts @@ -12,12 +12,13 @@ abstract class ComponentVEvent extends HTMLElement { template: HTMLTemplateElement | null uid: string + instance: string | null - constructor(uid?: string) { + constructor(uid?: string, instance?: string) { super(); this.template = document.getElementById(this.tagName.toLowerCase()) as HTMLTemplateElement | null - let real_uid; + let real_uid, real_instance; if (uid) { // console.log('Got UID directly'); @@ -29,6 +30,7 @@ abstract class ComponentVEvent extends HTMLElement { // console.log('Had UID as direct attribute'); real_uid = this.dataset.uid; } else { + /* TODO when is this case relevant? */ let el = this.closest('[data-uid]') if (el) { // console.log('Found UID higher up in the tree'); @@ -48,7 +50,32 @@ abstract class ComponentVEvent extends HTMLElement { this.uid = real_uid; this.dataset.uid = real_uid; - vcal_objects.get(this.uid)?.register(this); + if (instance) { + real_instance = instance + } else { + if (this.dataset.instance) { + real_instance = this.dataset.instance + } else { + let el = this.closest('[data-instance]') + if (el) { + real_instance = (el as HTMLElement).dataset.instance + if (real_instance === undefined) { + real_instance = null; + } + } else { + real_instance = null + } + } + } + this.instance = real_instance; + if (real_instance) { + this.dataset.instance = real_instance; + } + + /* TODO */ + /* Here, choose different rules depending on if we are repeating or not */ + + vcal_objects.get(this.getKey())?.register(this); /* We DON'T have a redraw here in the general case, since the HTML rendered server-side should be fine enough for us. @@ -56,12 +83,27 @@ abstract class ComponentVEvent extends HTMLElement { should take care of that some other way */ } - connectedCallback() { + getKey(): string { let uid = this.dataset.uid - if (uid) { - let v = vcal_objects.get(uid) - if (v) this.redraw(v); - } + // let instance_id = ev.getProperty('dtstart')!.format('~Y-~m-~dT~H:~M:~S') + let instance = this.dataset.instance + if (!uid) throw new Error("UID missing"); + let key = uid; + /* NOTE proper composite keys would be nice, since this can collide with + a regular key. However, javascript's Map doesn't support lists (or + object) as keys by default. */ + if (instance) key += '---' + instance; + return key; + } + + /* This return different object for different instances */ + getData(): VEvent | undefined { + return vcal_objects.get(this.getKey()) + } + + connectedCallback() { + let v = this.getData(); + if (v) this.redraw(v); } abstract redraw(data: VEvent): void -- cgit v1.2.3