aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--module/calp/html/vcomponent.scm350
-rw-r--r--module/calp/html/view/calendar.scm6
-rw-r--r--module/calp/html/view/calendar/month.scm23
-rw-r--r--module/calp/html/view/calendar/week.scm175
-rw-r--r--static/components/vevent-block.ts61
-rw-r--r--static/style.scss11
6 files changed, 329 insertions, 297 deletions
diff --git a/module/calp/html/vcomponent.scm b/module/calp/html/vcomponent.scm
index b5a4260e..43efe656 100644
--- a/module/calp/html/vcomponent.scm
+++ b/module/calp/html/vcomponent.scm
@@ -200,98 +200,6 @@
)))
-(define-public (edit-template calendars)
- `(div (@ (class " eventtext edit-tab "))
- (form (@ (class "edit-form"))
- (select (@ (class "calendar-selection"))
- (option "- Choose a Calendar -")
- ,@(let ((dflt (get-config 'default-calendar)))
- (map (lambda (calendar)
- (define name (prop calendar 'NAME))
- `(option (@ (value ,(base64encode name))
- ,@(when (string=? name dflt)
- '((selected))))
- ,name))
- calendars)))
- (h3 (input (@ (type "text")
- (placeholder "Sammanfattning")
- (name "summary") (required)
- (data-property "summary")
- ; (value ,(prop ev 'SUMMARY))
- )))
-
- (div (@ (class "timeinput"))
-
- ,@(with-label
- "Starttid"
- '(date-time-input (@ (name "dtstart")
- (data-property "dtstart")
- )))
-
- ,@(with-label
- "Sluttid"
- '(date-time-input (@ (name "dtend")
- (data-property "dtend"))))
-
- (div (@ (class "checkboxes"))
- ,@(with-label
- "Heldag?"
- `(input (@ (type "checkbox")
- (name "wholeday")
- )))
- ,@(with-label
- "Upprepande?"
- `(input (@ (type "checkbox")
- (name "has_repeats")
- ))))
-
- )
-
- ,@(with-label
- "Plats"
- `(input (@ (placeholder "Plats")
- (name "location")
- (type "text")
- (data-property "location")
- ; (value ,(or (prop ev 'LOCATION) ""))
- )))
-
- ,@(with-label
- "Beskrivning"
- `(textarea (@ (placeholder "Beskrivning")
- (data-property "description")
- (name "description"))
- ; ,(prop ev 'DESCRIPTION)
- ))
-
- ,@(with-label
- "Kategorier"
- `(input-list
- (@ (name "categories")
- (data-property "categories"))
- (input (@ (type "text")
- (placeholder "Kattegori")))))
-
- ;; TODO This should be a "list" where any field can be edited
- ;; directly. Major thing holding us back currently is that
- ;; <input-list /> doesn't supported advanced inputs
- ;; (div (@ (class "input-list"))
- ;; (div (@ (class "unit final newfield"))
- ;; (input (@ (type "text")
- ;; (list "known-fields")
- ;; (placeholder "Nytt fält")))
- ;; (select (@ (name "TYPE"))
- ;; (option (@ (value "TEXT")) "Text"))
- ;; (span
- ;; (input (@ (type "text")
- ;; (placeholder "Värde"))))))
-
- ;; (hr)
-
-
- (input (@ (type "submit")))
- )))
-
;; Single event in side bar (text objects)
@@ -427,3 +335,261 @@
(prop event 'DTSTART)))
"~Y-~m-~dT~H:~M:~S"))))))
+
+(define (week-day-select args)
+ `(select (@ ,@args)
+ (option "-")
+ ,@(map (lambda (x) `(option (@ (value ,(car x))) ,(cadr x)))
+ '((MO "Monday")
+ (TU "Tuesday")
+ (WE "Wednesday")
+ (TH "Thursday")
+ (FR "Friday")
+ (SA "Saturday")
+ (SU "Sunday")))))
+
+
+;;; Templates
+
+
+;; edit tab of popup
+(define-public (edit-template calendars)
+ `(template
+ (@ (id "vevent-edit"))
+ (div (@ (class " eventtext edit-tab "))
+ (form (@ (class "edit-form"))
+ (select (@ (class "calendar-selection"))
+ (option "- Choose a Calendar -")
+ ,@(let ((dflt (get-config 'default-calendar)))
+ (map (lambda (calendar)
+ (define name (prop calendar 'NAME))
+ `(option (@ (value ,(base64encode name))
+ ,@(when (string=? name dflt)
+ '((selected))))
+ ,name))
+ calendars)))
+ (h3 (input (@ (type "text")
+ (placeholder "Sammanfattning")
+ (name "summary") (required)
+ (data-property "summary")
+ ; (value ,(prop ev 'SUMMARY))
+ )))
+
+ (div (@ (class "timeinput"))
+
+ ,@(with-label
+ "Starttid"
+ '(date-time-input (@ (name "dtstart")
+ (data-property "dtstart")
+ )))
+
+ ,@(with-label
+ "Sluttid"
+ '(date-time-input (@ (name "dtend")
+ (data-property "dtend"))))
+
+ (div (@ (class "checkboxes"))
+ ,@(with-label
+ "Heldag?"
+ `(input (@ (type "checkbox")
+ (name "wholeday")
+ )))
+ ,@(with-label
+ "Upprepande?"
+ `(input (@ (type "checkbox")
+ (name "has_repeats")
+ ))))
+
+ )
+
+ ,@(with-label
+ "Plats"
+ `(input (@ (placeholder "Plats")
+ (name "location")
+ (type "text")
+ (data-property "location")
+ ; (value ,(or (prop ev 'LOCATION) ""))
+ )))
+
+ ,@(with-label
+ "Beskrivning"
+ `(textarea (@ (placeholder "Beskrivning")
+ (data-property "description")
+ (name "description"))
+ ; ,(prop ev 'DESCRIPTION)
+ ))
+
+ ,@(with-label
+ "Kategorier"
+ `(input-list
+ (@ (name "categories")
+ (data-property "categories"))
+ (input (@ (type "text")
+ (placeholder "Kattegori")))))
+
+ ;; TODO This should be a "list" where any field can be edited
+ ;; directly. Major thing holding us back currently is that
+ ;; <input-list /> doesn't supported advanced inputs
+ ;; (div (@ (class "input-list"))
+ ;; (div (@ (class "unit final newfield"))
+ ;; (input (@ (type "text")
+ ;; (list "known-fields")
+ ;; (placeholder "Nytt fält")))
+ ;; (select (@ (name "TYPE"))
+ ;; (option (@ (value "TEXT")) "Text"))
+ ;; (span
+ ;; (input (@ (type "text")
+ ;; (placeholder "Värde"))))))
+
+ ;; (hr)
+
+
+ (input (@ (type "submit")))
+ ))))
+
+;; description in sidebar / tab of popup
+;; Template data for <vevent-description />
+(define-public (description-template)
+ '(template
+ (@ (id "vevent-description"))
+ (div (@ (class " vevent eventtext summary-tab " ()))
+ (h3 ((span (@ (class "repeating")) ; "↺"
+ )
+ (span (@ (class "summary")
+ (data-property "summary")))))
+ (div (div (time (@ (class "dtstart")
+ (data-property "dtstart")
+ (data-fmt "~L~H:~M")
+ (datetime ; "2021-09-29T19:56:46"
+ ))
+ ; "19:56"
+ )
+ "\xa0—\xa0"
+ (time (@ (class "dtend")
+ (data-property "dtend")
+ (data-fmt "~L~H:~M")
+ (datetime ; "2021-09-29T19:56:46"
+ ))
+ ; "20:56"
+ ))
+ (div (@ (class "fields"))
+ (div (b "Plats: ")
+ (div (@ (class "location")
+ (data-property "location"))
+ ; "Alsättersgatan 13"
+ ))
+ (div (@ (class "description")
+ (data-property "description"))
+ ; "With a description"
+ )
+
+ (div (@ (class "categories")
+ (data-property "categories")))
+ ;; (div (@ (class "categories"))
+ ;; (a (@ (class "category")
+ ;; (href "/search/?"
+ ;; "q=%28member%20%22test%22%20%28or%20%28prop%20event%20%28quote%20CATEGORIES%29%29%20%28quote%20%28%29%29%29%29"))
+ ;; test))
+ ;; (div (@ (class "rrule"))
+ ;; "Upprepas "
+ ;; "varje vecka"
+ ;; ".")
+ (div (@ (class "last-modified"))
+ "Senast ändrad -"
+ ; "2021-09-29 19:56"
+ ))))))
+
+(define-public (vevent-edit-rrule-template)
+ `(template
+ (@ (id "vevent-edit-rrule"))
+ (div (@ (class "eventtext"))
+ (h2 "Upprepningar")
+ (dl
+ (dt "Frequency")
+ (dd (select (@ (name "freq"))
+ (option "-")
+ ,@(map (lambda (x) `(option (@ (value ,x)) ,(string-titlecase (symbol->string x))))
+ '(SECONDLY MINUTELY HOURLY DAILY WEEKLY MONTHLY YEARLY))))
+
+ (dt "Until")
+ (dd (date-time-input (@ (name "until"))))
+
+ (dt "Conut")
+ (dd (input (@ (type "number") (name "count") (min 0))))
+
+ (dt "Interval")
+ (dd (input (@ (type "number") (name "interval") ; min and max depend on FREQ
+ )))
+
+ ,@(concatenate
+ (map (lambda (pair)
+ (define name (list-ref pair 0))
+ (define pretty-name (list-ref pair 1))
+ (define min (list-ref pair 2))
+ (define max (list-ref pair 3))
+ `((dt ,pretty-name)
+ (dd (input-list (@ (name ,name))
+ (input (@ (type "number")
+ (min ,min) (max ,max)))))))
+ '((bysecond "By Second" 0 60)
+ (byminute "By Minute" 0 59)
+ (byhour "By Hour" 0 23)
+ (bymonthday "By Month Day" -31 31) ; except 0
+ (byyearday "By Year Day" -366 366) ; except 0
+ (byweekno "By Week Number" -53 53) ; except 0
+ (bymonth "By Month" 1 12)
+ (bysetpos "By Set Position" -366 366) ; except 0
+ )))
+
+ ;; (dt "By Week Day")
+ ;; (dd (input-list (@ (name "byweekday"))
+ ;; (input (@ (type number)
+ ;; (min -53) (max 53) ; except 0
+ ;; ))
+ ;; ,(week-day-select '())
+ ;; ))
+
+ (dt "Weekstart")
+ (dd ,(week-day-select '((name "wkst")))))))
+ )
+
+
+;; Based on popup:s output
+(define-public (popup-template)
+ `(template
+ (@ (id "popup-template"))
+ ;; becomes the direct child of <popup-element/>
+ (div (@ (class "popup-root window")
+ (onclick "event.stopPropagation()"))
+
+ (nav (@ (class "popup-control"))
+ (button (@ (class "close-button")
+ (title "Stäng")
+ (aria-label "Close"))
+ "×")
+ (button (@ (class "maximize-button")
+ (title "Fullskärm")
+ ;; (aria-label "")
+ )
+ "🗖")
+ (button (@ (class "remove-button")
+ (title "Ta Bort"))
+ "🗑"))
+
+ (tab-group (@ (class "window-body"))
+ (vevent-description
+ (@ (data-label "📅") (data-title "Översikt")
+ (class "vevent")))
+
+ (vevent-edit
+ (@ (data-label "🖊") (data-title "Redigera")))
+
+ ;; (vevent-edit-rrule
+ ;; (@ (data-label "↺") (data-title "Upprepningar")))
+
+ (vevent-changelog
+ (@ (data-label "📒") (date-title "Changelog")))
+
+ ,@(when (debug)
+ '((vevent-dl
+ (@ (data-label "🐸") (data-title "Debug")))))))))
diff --git a/module/calp/html/view/calendar.scm b/module/calp/html/view/calendar.scm
index 62d55210..d08210bc 100644
--- a/module/calp/html/view/calendar.scm
+++ b/module/calp/html/view/calendar.scm
@@ -339,6 +339,12 @@ window.default_calendar='~a';"
;; ;; ,(popup event (string-append "popup" (html-id event))))
;; ))
+ ;;; Templates used by our custom components
+ ,((@ (calp html vcomponent) edit-template) calendars)
+ ,((@ (calp html vcomponent) description-template))
+ ,((@ (calp html vcomponent) vevent-edit-rrule-template))
+ ,((@ (calp html vcomponent) popup-template))
+
;; Auto-complets when adding new fields to a component
;; Any string is however still valid.
(datalist (@ (id "known-fields"))
diff --git a/module/calp/html/view/calendar/month.scm b/module/calp/html/view/calendar/month.scm
index 0ac69292..0e29f5b2 100644
--- a/module/calp/html/view/calendar/month.scm
+++ b/module/calp/html/view/calendar/month.scm
@@ -11,7 +11,7 @@
:select (really-long-event?
events-between))
:use-module ((calp html vcomponent)
- :select (make-block))
+ :select (make-block output-uid))
:use-module ((vcomponent group)
:select (group-stream get-groups-between))
)
@@ -77,11 +77,26 @@
(repeating-naturals 1 7)
)))
- ;; These popups are relative the document root. Can thus be placed anywhere in the DOM.
+ ;; These popups are relative the document root.
+ ;; Can thus be placed anywhere in the DOM.
,@(for event in (stream->list
(events-between start-date end-date events))
- ((@ (calp html vcomponent) popup) event
- (string-append "popup" ((@ (calp html util) html-id) event))))
+ `(popup-element
+ (@ (class "vevent")
+ (data-uid ,(output-uid event)))))
+
+ (template
+ (@ (id "vevent-block"))
+ ;; TODO this is more or less copied verbatim from week's
+ ;; version, warts and all. Figure out what should and shouldn't
+ ;; be shared between the two.
+ (div (@ (data-calendar "unknown"))
+ (div (@ (class "event-body"))
+ (span (@ (class "repeating")))
+ (span (@ (class "summary")
+ (data-property "summary")))
+ (span (@ (class "location")
+ (data-property "location"))))))
))
diff --git a/module/calp/html/view/calendar/week.scm b/module/calp/html/view/calendar/week.scm
index 16ceeb6f..3eb8752b 100644
--- a/module/calp/html/view/calendar/week.scm
+++ b/module/calp/html/view/calendar/week.scm
@@ -59,184 +59,19 @@
(@ (class "vevent")
(data-uid ,(output-uid event)))))))
- ;; description in sidebar / tab of popup
- (template (@ (id "vevent-description"))
- ,(description-template)
- )
-
- ;; edit tab of popup
- (template (@ (id "vevent-edit"))
- ,((@ (calp html vcomponent) edit-template)
- calendars
- ))
- ;; "physical" block
+ ;; This template is here, instead of in (calp html calendar) since it only
+ ;; applies to this specific view. (calp html calendar month) is assumed to
+ ;; have its own variant of it.
(template (@ (id "vevent-block"))
,(block-template)
)
- (template (@ (id "vevent-edit-rrule"))
- ,(vevent-edit-rrule-template))
-
- ;; Based on popup:s output
- (template (@ (id "popup-template"))
- ,(popup-template)))))
-
-
-(define-record-type tab
- (fields title label body))
-
-(define (popup-template)
-
- ;; becomes the direct child of <popup-element/>
- `(div (@ (class "popup-root window")
- (onclick "event.stopPropagation()"))
-
- (nav (@ (class "popup-control"))
- (button (@ (class "close-button")
- (title "Stäng")
- (aria-label "Close"))
- "×")
- (button (@ (class "maximize-button")
- (title "Fullskärm")
- ;; (aria-label "")
- )
- "🗖")
- (button (@ (class "remove-button")
- (title "Ta Bort"))
- "🗑"))
-
- (tab-group (@ (class "window-body"))
- (vevent-description
- (@ (data-label "📅") (data-title "Översikt")
- (class "vevent")))
-
- (vevent-edit
- (@ (data-label "🖊") (data-title "Redigera")))
-
- ;; (vevent-edit-rrule
- ;; (@ (data-label "↺") (data-title "Upprepningar")))
-
- (vevent-changelog
- (@ (data-label "📒") (date-title "Changelog")))
- ,@(when (debug)
- '((vevent-dl
- (@ (data-label "🐸") (data-title "Debug")))))
- )))
-
-(define (week-day-select args)
- `(select (@ ,@args)
- (option "-")
- ,@(map (lambda (x) `(option (@ (value ,(car x))) ,(cadr x)))
- '((MO "Monday")
- (TU "Tuesday")
- (WE "Wednesday")
- (TH "Thursday")
- (FR "Friday")
- (SA "Saturday")
- (SU "Sunday")))))
-
-(define (vevent-edit-rrule-template)
- `(div (@ (class "eventtext"))
- (h2 "Upprepningar")
- (dl
- (dt "Frequency")
- (dd (select (@ (name "freq"))
- (option "-")
- ,@(map (lambda (x) `(option (@ (value ,x)) ,(string-titlecase (symbol->string x))))
- '(SECONDLY MINUTELY HOURLY DAILY WEEKLY MONTHLY YEARLY))))
-
- (dt "Until")
- (dd (date-time-input (@ (name "until"))))
-
- (dt "Conut")
- (dd (input (@ (type "number") (name "count") (min 0))))
-
- (dt "Interval")
- (dd (input (@ (type "number") (name "interval") ; min and max depend on FREQ
- )))
-
- ,@(concatenate
- (map (lambda (pair)
- (define name (list-ref pair 0))
- (define pretty-name (list-ref pair 1))
- (define min (list-ref pair 2))
- (define max (list-ref pair 3))
- `((dt ,pretty-name)
- (dd (input-list (@ (name ,name))
- (input (@ (type "number")
- (min ,min) (max ,max)))))))
- '((bysecond "By Second" 0 60)
- (byminute "By Minute" 0 59)
- (byhour "By Hour" 0 23)
- (bymonthday "By Month Day" -31 31) ; except 0
- (byyearday "By Year Day" -366 366) ; except 0
- (byweekno "By Week Number" -53 53) ; except 0
- (bymonth "By Month" 1 12)
- (bysetpos "By Set Position" -366 366) ; except 0
- )))
-
- ;; (dt "By Week Day")
- ;; (dd (input-list (@ (name "byweekday"))
- ;; (input (@ (type number)
- ;; (min -53) (max 53) ; except 0
- ;; ))
- ;; ,(week-day-select '())
- ;; ))
-
- (dt "Weekstart")
- (dd ,(week-day-select '((name "wkst")))))))
-
-;; Template data for <vevent-description />
-(define (description-template)
- '(div (@ (class " vevent eventtext summary-tab " ()))
- (h3 ((span (@ (class "repeating")) ; "↺"
- )
- (span (@ (class "summary")
- (data-property "summary")))))
- (div (div (time (@ (class "dtstart")
- (data-property "dtstart")
- (data-fmt "~L~H:~M")
- (datetime ; "2021-09-29T19:56:46"
- ))
- ; "19:56"
- )
- "\xa0—\xa0"
- (time (@ (class "dtend")
- (data-property "dtend")
- (data-fmt "~L~H:~M")
- (datetime ; "2021-09-29T19:56:46"
- ))
- ; "20:56"
- ))
- (div (@ (class "fields"))
- (div (b "Plats: ")
- (div (@ (class "location")
- (data-property "location"))
- ; "Alsättersgatan 13"
- ))
- (div (@ (class "description")
- (data-property "description"))
- ; "With a description"
- )
+)))
- (div (@ (class "categories")
- (data-property "categories")))
- ;; (div (@ (class "categories"))
- ;; (a (@ (class "category")
- ;; (href "/search/?"
- ;; "q=%28member%20%22test%22%20%28or%20%28prop%20event%20%28quote%20CATEGORIES%29%29%20%28quote%20%28%29%29%29%29"))
- ;; test))
- ;; (div (@ (class "rrule"))
- ;; "Upprepas "
- ;; "varje vecka"
- ;; ".")
- (div (@ (class "last-modified"))
- "Senast ändrad -"
- ; "2021-09-29 19:56"
- )))))
+;; "physical" block
(define (block-template)
`(div (@ ; (id ,(html-id ev))
(data-calendar "unknown")
diff --git a/static/components/vevent-block.ts b/static/components/vevent-block.ts
index 6b3e7dec..95c72592 100644
--- a/static/components/vevent-block.ts
+++ b/static/components/vevent-block.ts
@@ -48,34 +48,36 @@ class ComponentBlock extends ComponentVEvent {
/* -------------------------------------------------- */
- let p;
- if ((p = data.getProperty('dtstart'))) {
- let c = this.closest('.event-container') as HTMLElement
- let start = parseDate(c.dataset.start!).getTime()
- let end = parseDate(c.dataset.end!).getTime();
- // console.log(p);
- let pp = to_local(p).getTime()
- let result = 100 * (Math.min(end, Math.max(start, pp)) - start) / (end - start) + "%"
- if (c.classList.contains('longevents')) {
- this.style.left = result
- } else {
- this.style.top = result
+ if (window.VIEW === 'week') {
+ let p;
+ if ((p = data.getProperty('dtstart'))) {
+ let c = this.closest('.event-container') as HTMLElement
+ let start = parseDate(c.dataset.start!).getTime()
+ let end = parseDate(c.dataset.end!).getTime();
+ // console.log(p);
+ let pp = to_local(p).getTime()
+ let result = 100 * (Math.min(end, Math.max(start, pp)) - start) / (end - start) + "%"
+ if (c.classList.contains('longevents')) {
+ this.style.left = result
+ } else {
+ this.style.top = result
+ }
+ // console.log('dtstart', p);
}
- // console.log('dtstart', p);
- }
- if ((p = data.getProperty('dtend'))) {
- // console.log('dtend', p);
- let c = this.closest('.event-container') as HTMLElement
- let start = parseDate(c.dataset.start!).getTime()
- let end = parseDate(c.dataset.end!).getTime();
- let pp = to_local(p).getTime()
- let result = 100 - (100 * (Math.min(end, Math.max(start, pp)) - start) / (end - start)) + "%"
- if (c.classList.contains('longevents')) {
- this.style.width = 'unset';
- this.style.right = result;
- } else {
- this.style.height = 'unset';
- this.style.bottom = result;
+ if ((p = data.getProperty('dtend'))) {
+ // console.log('dtend', p);
+ let c = this.closest('.event-container') as HTMLElement
+ let start = parseDate(c.dataset.start!).getTime()
+ let end = parseDate(c.dataset.end!).getTime();
+ let pp = to_local(p).getTime()
+ let result = 100 - (100 * (Math.min(end, Math.max(start, pp)) - start) / (end - start)) + "%"
+ if (c.classList.contains('longevents')) {
+ this.style.width = 'unset';
+ this.style.right = result;
+ } else {
+ this.style.height = 'unset';
+ this.style.bottom = result;
+ }
}
}
@@ -84,7 +86,10 @@ class ComponentBlock extends ComponentVEvent {
}
if (data.getProperty('rrule') !== undefined) {
- (this.getElementsByClassName('repeating')![0] as HTMLElement).innerText = '↺'
+ let rep = this.getElementsByClassName('repeating')
+ if (rep && rep.length !== 0) {
+ (rep[0] as HTMLElement).innerText = '↺'
+ }
}
}
}
diff --git a/static/style.scss b/static/style.scss
index 92ab9441..2ae55a31 100644
--- a/static/style.scss
+++ b/static/style.scss
@@ -332,12 +332,15 @@ along with their colors.
.cal-cell {
overflow-y: auto;
- .event {
+ .event, vevent-block {
font-size: 8pt;
border-radius: 5px;
padding: 2px;
- margin: 2px;
+ margin-top: 2px;
+ margin-bottom: 2px;
font-family: arial;
+
+ box-sizing: border-box;
}
}
@@ -545,7 +548,9 @@ vevent-block, .event {
background-color: var(--color);
color: var(--complement);
- position: absolute;
+ // position: absolute;
+ display: block;
+
width: 100%;
min-height: 1em;
border: 1px solid black;