From b8823052f5cbec1d6b0302b27a83cc8927e9fc1d Mon Sep 17 00:00:00 2001 From: Johann Hoffmann Date: Wed, 5 Feb 2025 16:03:20 +0100 Subject: [PATCH] deactivate old month page css for day number and events in favor of new computed style (can be redesigned but is being handled in js instead of css class); save & inject/provide observed resize from already existing ResizeObserver to be able to access concrete container width/height values we already had all the time anyway; added some comment to 2year old TODO concerning calendar breakpoints; check if navbar is showing before toggling programmatically; remove some unused code; week time line spawns in dayLane which is representing today to avoid caluclating left/right offsets -> WIP accurately retrieving lane width somehow else, currently approximated; --- public/css/components/calendar.css | 64 +++++++++---------- public/js/apps/Dashboard/Fhc.js | 4 +- public/js/components/Calendar/Calendar.js | 41 ++++++------ public/js/components/Calendar/Day/Page.js | 2 +- public/js/components/Calendar/Header.js | 21 +----- public/js/components/Calendar/Minimized.js | 1 - public/js/components/Calendar/Month/Page.js | 47 ++++++-------- public/js/components/Calendar/Week/Page.js | 23 ++++--- .../components/DashboardWidget/Stundenplan.js | 2 +- 9 files changed, 90 insertions(+), 115 deletions(-) diff --git a/public/css/components/calendar.css b/public/css/components/calendar.css index 4f10a5eaf..8df453d6d 100644 --- a/public/css/components/calendar.css +++ b/public/css/components/calendar.css @@ -131,19 +131,19 @@ .fhc-calendar-md .fhc-calendar-month-page-day.active { border-color: var(--bs-secondary); } -.fhc-calendar-lg .fhc-calendar-month-page-day .events, -.fhc-calendar-md .fhc-calendar-month-page-day .events { - display: block; - overflow: auto; - font-size: 0.7em; -} -.fhc-calendar-lg .fhc-calendar-month-page-day .events span, -.fhc-calendar-md .fhc-calendar-month-page-day .events span { - display: block; - margin: 0.2em; - padding: 0.1em 0.4em; - border-radius: 0.1em; -} +/*.fhc-calendar-lg .fhc-calendar-month-page-day .events,*/ +/*.fhc-calendar-md .fhc-calendar-month-page-day .events {*/ +/* display: block;*/ +/* overflow: auto;*/ +/* font-size: 0.7em;*/ +/*}*/ +/*.fhc-calendar-lg .fhc-calendar-month-page-day .events span,*/ +/*.fhc-calendar-md .fhc-calendar-month-page-day .events span {*/ +/* display: block;*/ +/* margin: 0.2em;*/ +/* padding: 0.1em 0.4em;*/ +/* border-radius: 0.1em;*/ +/*}*/ .fhc-calendar-lg .fhc-calendar-years .col-4, .fhc-calendar-md .fhc-calendar-years .col-4 { padding: 0.09375em 0; @@ -217,25 +217,25 @@ background-color: rgba(var(--bs-secondary-rgb), 0.25); border-radius: 50%; } -.fhc-calendar-sm .fhc-calendar-month-page-day .no, -.fhc-calendar-xs .fhc-calendar-month-page-day .no { - display: flex; - align-items: center; - justify-content: center; - width: 80%; - height: 80%; - margin: 10%; -} -.fhc-calendar-sm .fhc-calendar-month-page-day .events, -.fhc-calendar-xs .fhc-calendar-month-page-day .events { - position: absolute; - bottom: 0; - left: 10%; - width: 80%; - height: 10%; - overflow: hidden; - display: flex; -} +/*.fhc-calendar-sm .fhc-calendar-month-page-day .no,*/ +/*.fhc-calendar-xs .fhc-calendar-month-page-day .no {*/ +/* display: flex;*/ +/* align-items: center;*/ +/* justify-content: center;*/ +/* width: 80%;*/ +/* height: 80%;*/ +/* margin: 10%;*/ +/*}*/ +/*.fhc-calendar-sm .fhc-calendar-month-page-day .events,*/ +/*.fhc-calendar-xs .fhc-calendar-month-page-day .events {*/ +/* position: absolute;*/ +/* bottom: 0;*/ +/* left: 10%;*/ +/* width: 80%;*/ +/* height: 10%;*/ +/* overflow: hidden;*/ +/* display: flex;*/ +/*}*/ .fhc-calendar-sm .fhc-calendar-month-page-day .events span, .fhc-calendar-xs .fhc-calendar-month-page-day .events span { overflow: hidden; diff --git a/public/js/apps/Dashboard/Fhc.js b/public/js/apps/Dashboard/Fhc.js index 17b59c235..5570dd76d 100644 --- a/public/js/apps/Dashboard/Fhc.js +++ b/public/js/apps/Dashboard/Fhc.js @@ -104,7 +104,9 @@ const app = Vue.createApp({ event.preventDefault(); // Prevent browser navigation if(this.isMobile) { // toggle the menu - document.getElementById('nav-main-btn').click(); + const navMain = document.getElementById('nav-main'); + // fix unwanted toggle from off to on for some links on mobile + if(navMain.classList.contains('show')) document.getElementById('nav-main-btn').click(); } this.$router.push(route); diff --git a/public/js/components/Calendar/Calendar.js b/public/js/components/Calendar/Calendar.js index fb947a585..0bae84583 100644 --- a/public/js/components/Calendar/Calendar.js +++ b/public/js/components/Calendar/Calendar.js @@ -28,7 +28,10 @@ export default { todayDate, date: this.date, focusDate: this.focusDate, - size: Vue.computed({ get: () => this.size, set: v => this.size = v }), + size: Vue.computed({ get: () => this.size }), + calendarHeight: Vue.computed({ get: () => this.calendarHeight }), + calendarWidth: Vue.computed({ get: () => this.calendarWidth }), + events: Vue.computed(() => this.eventsPerDay), filteredEvents: Vue.computed(() => this.filteredEvents), minimized: Vue.computed({ get: () => this.minimized, set: v => this.$emit('update:minimized', v) }), @@ -36,11 +39,9 @@ export default { noMonthView: this.noMonthView, noWeekView: this.noWeekView, eventsAreNull: Vue.computed(() => this.events === null), - classHeader: this.classHeader, mode: Vue.computed(()=>this.mode), selectedEvent: Vue.computed(() => this.selectedEvent), setSelectedEvent: (event)=>{this.selectedEvent = event;}, - widget: this.widget }; }, props: { @@ -57,17 +58,9 @@ export default { type: String, default: 'month' }, - classHeader: { - type: [String, Object, Array], - default: '' - }, minimized: Boolean, noWeekView: Boolean, - noMonthView: Boolean, - widget: { - type: Boolean, - default: false - } + noMonthView: Boolean }, watch:{ selectedEvent:{ @@ -110,11 +103,14 @@ export default { date: new CalendarDate(), focusDate: new CalendarDate(), size: 0, + containerWidth: 0, + containerHeight: 0, selectedEvent:null, } }, computed: { - sizeClass() { + sizeClass() { + // mainly determines calendar font-size return 'fhc-calendar-' + ['xs', 'sm', 'md', 'lg'][this.size]; }, mode: { @@ -210,16 +206,25 @@ export default { if (this.$refs.container) { new ResizeObserver(entries => { for (const entry of entries) { - let w = entry.contentBoxSize ? entry.contentBoxSize[0].inlineSize : entry.contentRect.width; - // TODO(chris): rework sizing - if (w > 600) + const w = entry.contentBoxSize ? entry.contentBoxSize[0].inlineSize : entry.contentRect.width; + const h = entry.contentBoxSize ? entry.contentBoxSize[0].blockSize : entry.contentRect.height; + + // https://getbootstrap.com/docs/5.0/layout/breakpoints/ + // bootstrap breakpoints watch window size and this function monitors container size of calendar itself. + // calendar is using bootstrap breakpoints which influence layout, which retriggers this function + // -> some width constellations will loop so we dont use values around bs5 breakpoints + // ['xs', 'sm', 'md', 'lg'][this.size] + if (w >= 600) this.size = 3; - else if (w > 350) + else if (w >= 350) this.size = 2; - else if (w > 250) + else if (w >= 250) this.size = 1; else this.size = 0; + + this.containerWidth = w + this.containerHeight = h } }).observe(this.$refs.container); } diff --git a/public/js/components/Calendar/Day/Page.js b/public/js/components/Calendar/Day/Page.js index 0c2e3212e..85a9cbc84 100644 --- a/public/js/components/Calendar/Day/Page.js +++ b/public/js/components/Calendar/Day/Page.js @@ -103,7 +103,7 @@ export default { } }, dayText(){ - if(!this.size || !this.day)return {}; + if(!this.day)return {}; return { heading: this.day.toLocaleString(this.$p.user_locale.value, { dateStyle: 'short' }), tag: this.day.toLocaleString(this.$p.user_locale.value, { weekday: this.size < 2 ? 'narrow' : (this.size < 3 ? 'short' : 'long') }), diff --git a/public/js/components/Calendar/Header.js b/public/js/components/Calendar/Header.js index 876ebd172..2770d055b 100644 --- a/public/js/components/Calendar/Header.js +++ b/public/js/components/Calendar/Header.js @@ -13,11 +13,9 @@ export default { inject: [ 'eventsAreNull', 'size', - 'classHeader', 'mode', 'noWeekView', 'noMonthView', - 'widget' ], props: { title: String @@ -28,25 +26,8 @@ export default { 'next', 'click' ], - computed: { - myClassHeader() { - // TODO(chris): + {'btn-sm': !this.size} - let c = this.classHeader; - if (Array.isArray(c)) { - if (!this.size) - c.push('btn-sm'); - } else if (typeof c === 'string' || c instanceof String) { - if (!this.size) - c += ' btn-sm'; - } else { - c['btn-sm'] = !this.size; - } - - return c; - } - }, template: /*html*/` -
+
diff --git a/public/js/components/Calendar/Minimized.js b/public/js/components/Calendar/Minimized.js index ace5dce48..96db36ada 100644 --- a/public/js/components/Calendar/Minimized.js +++ b/public/js/components/Calendar/Minimized.js @@ -8,7 +8,6 @@ export default { 'size', 'minimized', 'date', - 'classHeader' ], data() { return { diff --git a/public/js/components/Calendar/Month/Page.js b/public/js/components/Calendar/Month/Page.js index 851834fd5..04e3a8e64 100644 --- a/public/js/components/Calendar/Month/Page.js +++ b/public/js/components/Calendar/Month/Page.js @@ -18,7 +18,7 @@ export default { 'showWeeks', 'noWeekView', 'selectedEvent', - 'setSelectedEvent', + 'setSelectedEvent' ], props: { year: Number, @@ -71,12 +71,9 @@ export default { const isNotThisMonth = day.getMonth() != this.month const isInThePast = day.getTime() < this.today // this.date is just the focusDate but not the initial Date - - if(isHighlightedWeek) classstring += ' fhc-highlight-week' if(isHighlightedDay) classstring += ' fhc-highlight-day' - - if(isThisDate) classstring += ' active' + if(isNotThisMonth) classstring += ' opacity-25' if(isInThePast) classstring += ' fhc-calendar-past' return classstring @@ -112,38 +109,29 @@ export default { }, getNumberStyle(day) { - // TODO: move this to active css class in calendar.css const styleObj = {} - // styleObj.display = 'inline-block'; - // styleObj.widt = '32px'; /* Adjust based on the calendar cell size */ - // styleObj.height = '32px'; - // styleObj['line-height'] = '32px'; - // styleObj['text-align'] = 'center'; - // styleObj['font-weight'] = 'bold'; - // styleObj['font-size'] = '14px'; - // - // if(day.getDate() === this.todayDate.getDate() - // && day.getMonth() === this.todayDate.getMonth() - // && day.getFullYear() === this.todayDate.getFullYear()) { - // styleObj['background-color'] = '#00649c'; // fh blau - // styleObj.color = 'white'; - // } else { - // // styleObj['background-color'] = '#ffffff'; // fh blau - // // styleObj.color = 'white'; /* White text for contrast */ - // } + styleObj.display = 'inline-block'; + styleObj.height = '32px'; + styleObj['line-height'] = '32px'; + styleObj['text-align'] = 'center'; + styleObj['font-weight'] = 'bold'; + styleObj['font-size'] = '14px'; + + if(day.getDate() === this.todayDate.getDate() + && day.getMonth() === this.todayDate.getMonth() + && day.getFullYear() === this.todayDate.getFullYear()) { + styleObj['background-color'] = '#00649c'; // fh blau + styleObj.color = 'white'; + } return styleObj } }, mounted() { const container = document.getElementById("calendarContainer") - if(container) container.style['overflow-y'] = 'scroll' + if(container) container.style['overflow-y'] = 'auto' }, - // unmounted() { - // const container = document.getElementById("calendarContainer") - // if(container) container.style['overflow-y'] = '' - // }, template: /*html*/`
@@ -173,5 +161,6 @@ export default { -
` +
+` } diff --git a/public/js/components/Calendar/Week/Page.js b/public/js/components/Calendar/Week/Page.js index 09dc48056..e090b8ec2 100644 --- a/public/js/components/Calendar/Week/Page.js +++ b/public/js/components/Calendar/Week/Page.js @@ -36,6 +36,9 @@ export default { 'input', ], computed: { + laneWidth() { + return this.width / this.days.length + }, curTime() { const now = new Date(); return String(now.getHours()).padStart(2, '0') + ':' + String(now.getMinutes()).padStart(2, '0'); @@ -137,10 +140,6 @@ export default { ) }, curIndicatorStyle() { - const todayIndex = this.days.findIndex(d => d.getFullYear() === this.todayDate.getFullYear() && - d.getMonth() === this.todayDate.getMonth() && - d.getDate() === this.todayDate.getDate() - ) return { 'pointer-events': 'none', @@ -149,8 +148,7 @@ export default { 'z-index': 2, 'border-color': '#00649C!important', top: this.getDayTimePercent + '%', - left: 'calc(('+this.width+'px + 3em) /'+this.days.length+'*'+todayIndex+')', - right: 'calc(('+this.width+'px - 3em)/'+this.days.length+'*'+(this.days.length - 1 - todayIndex)+')', + width: this.laneWidth + 'px' // todo: manage the real value of 1fr somehow } }, getDayTimePercent() { @@ -314,16 +312,17 @@ export default { {{hourPositionTime}}
- -
- {{curTime}} -
-
+
{{hour}}:00
+ +
+ {{curTime}} +
+

this is a placeholder which means that no template was passed to the Calendar Page slot

-
+
diff --git a/public/js/components/DashboardWidget/Stundenplan.js b/public/js/components/DashboardWidget/Stundenplan.js index aca6227d8..732176c0c 100644 --- a/public/js/components/DashboardWidget/Stundenplan.js +++ b/public/js/components/DashboardWidget/Stundenplan.js @@ -178,7 +178,7 @@ export default {
-