diff --git a/application/libraries/KalenderLib.php b/application/libraries/KalenderLib.php index fd2ba949d..a9a2b1e7d 100644 --- a/application/libraries/KalenderLib.php +++ b/application/libraries/KalenderLib.php @@ -86,9 +86,18 @@ class KalenderLib tbl_lehreinheitgruppe.verband as le_verband, tbl_lehreinheitgruppe.gruppe as le_gruppe, le_gruppe.direktinskription as le_direktinskription, - - - '); + CASE + WHEN vonstunde.stunde IS NOT NULL AND bisstunde.stunde IS NOT NULL + THEN bisstunde.stunde - vonstunde.stunde + 1 + ELSE ROUND( + COALESCE( + ( + SELECT SUM(EXTRACT(EPOCH FROM (LEAST(stunde.ende, tbl_kalender.bis::time) - GREATEST(stunde.beginn, tbl_kalender.von::time))) / 60) / 45 + FROM lehre.tbl_stunde stunde + WHERE stunde.beginn < tbl_kalender.bis::time AND stunde.ende > tbl_kalender.von::time) + ,0) + ,2 + ) END AS verplante_stunden'); $this->_ci->KalenderModel->addJoin('lehre.tbl_kalender_lehreinheit', 'tbl_kalender.kalender_id = tbl_kalender_lehreinheit.kalender_id', 'LEFT'); $this->_ci->KalenderModel->addJoin('lehre.tbl_kalender_event', 'tbl_kalender.kalender_id = tbl_kalender_event.kalender_id', 'LEFT'); @@ -134,6 +143,9 @@ class KalenderLib ); $this->_ci->KalenderModel->addJoin('public.tbl_studiengang le_studiengang', 'le_lehrverband.studiengang_kz = le_studiengang.studiengang_kz', 'LEFT'); + $this->_ci->KalenderModel->db->join('lehre.tbl_stunde vonstunde', 'tbl_kalender.von::time = vonstunde.beginn', 'LEFT', FALSE); + $this->_ci->KalenderModel->db->join('lehre.tbl_stunde bisstunde', 'tbl_kalender.bis::time = bisstunde.ende', 'LEFT', FALSE); + $this->_ci->KalenderModel->db->where('tbl_kalender.von >=', $start_date); $this->_ci->KalenderModel->db->where('tbl_kalender.bis <', $end_date); @@ -174,6 +186,7 @@ class KalenderLib 'lehrfach_bez' => isset($row->lehrfach_bezeichnung) ? $row->lehrfach_bezeichnung : '', 'farbe' => isset($row->farbe) ? $row->farbe : '', 'lehrveranstaltung_id' => $row->lehrveranstaltung_id, + 'verplante_stunden' => $row->verplante_stunden, 'organisationseinheit' => isset($row->oe_kurzbz) ? $row->oe_kurzbz : '', 'kalender_id' => $id, 'lehreinheit_id' => [], diff --git a/public/css/Studentenverwaltung.css b/public/css/Studentenverwaltung.css index 870a58bdf..470ea03e9 100644 --- a/public/css/Studentenverwaltung.css +++ b/public/css/Studentenverwaltung.css @@ -8,6 +8,8 @@ @import './components/Notiz.css'; @import './components/Messages.css'; @import './components/AppMenu.css'; +@import './components/horizontalsplit.css'; + html { font-size: .875em; diff --git a/public/css/components/calendar/frame.css b/public/css/components/calendar/frame.css index d17cc06b4..68b907179 100644 --- a/public/css/components/calendar/frame.css +++ b/public/css/components/calendar/frame.css @@ -68,9 +68,16 @@ /* Grid */ .fhc-calendar-base-grid { --fhc-calendar-axis-collapsible: .2fr; + --fhc-calendar-axis-collapsible-manual: .1fr; + background-color: var(--fhc-calendar-bg-gap); grid-gap: var(--fhc-calendar-gap-header, calc(var(--fhc-calendar-gap, 1px) * 2)); } + +.fhc-calendar-base-grid-line-collapsed { + overflow: hidden; +} + .fhc-calendar-base-grid .grid-header { background-color: var(--fhc-calendar-bg-header-gap, var(--fhc-calendar-bg-gap)); } diff --git a/public/js/components/Calendar/Base/Grid.js b/public/js/components/Calendar/Base/Grid.js index d63a8d7e6..df322c151 100644 --- a/public/js/components/Calendar/Base/Grid.js +++ b/public/js/components/Calendar/Base/Grid.js @@ -61,7 +61,11 @@ export default { flipAxis: Boolean, allDayEvents: Boolean, axisMainCollapsible: Boolean, - snapToGrid: Boolean + snapToGrid: Boolean, + dayVisibility: { + type: Array, + default: null + } }, data() { return { @@ -160,7 +164,17 @@ export default { hasValidEvents() { return this.events.find(e => e.length); }, - styleGridCols() { + styleGridCols() + { + if (this.dayVisibility) + { + let anyVisible = this.dayVisibility.some(day => day); + if (anyVisible) + { + return this.axisMain.map((day, i) => this.isDayCollapsed(i) ? 'var(--fhc-calendar-axis-collapsible-manual, 0.1fr)' : '1fr').join(' '); + } + } + let cols = 'repeat(' + this.axisMain.length + ', 1fr)'; if (this.axisMainCollapsible) { if (this.hasValidEvents) @@ -479,6 +493,16 @@ export default { } }); }, + isDayCollapsed(index) + { + if (this.dayVisibility) + { + let anyVisible = this.dayVisibility.some(day => day); + if (anyVisible) + return !this.dayVisibility[index]; + } + return this.axisMainCollapsible && this.hasValidEvents && !this.events[index].length; + } }, setup() { @@ -504,7 +528,7 @@ export default { v-for="(date, index) in axisMain" :key="index" class="main-header" - :class="{'collapsed-header': axisMainCollapsible && hasValidEvents && !events[index].length}" + :class="{'collapsed-header': isDayCollapsed(index)}" :style="'grid-' + axisCol + ':' + (2+index)" > @@ -592,6 +616,7 @@ export default { :date="date" :events="eventsNormal[index]" :backgrounds="backgrounds[index]" + :class="{ 'fhc-calendar-base-grid-line-collapsed': isDayCollapsed(index) }" style="position:relative" @resize-start="handleResizeStart" :style="'grid-' + axisRow + ':1/-1;grid-' + axisCol + ':' + (1+index)" diff --git a/public/js/components/Calendar/Mode/Week/View.js b/public/js/components/Calendar/Mode/Week/View.js index 333559c46..034ddb759 100644 --- a/public/js/components/Calendar/Mode/Week/View.js +++ b/public/js/components/Calendar/Mode/Week/View.js @@ -2,6 +2,8 @@ import CalendarGrid from '../../Base/Grid.js'; import LabelDay from '../../Base/Label/Day.js'; import LabelDow from '../../Base/Label/Dow.js'; import LabelTime from '../../Base/Label/Time.js'; +import FormInput from "../../../Form/Input.js"; + export default { name: "WeekView", @@ -9,7 +11,8 @@ export default { CalendarGrid, LabelDay, LabelDow, - LabelTime + LabelTime, + FormInput }, inject: { timeGrid: "timeGrid", @@ -23,6 +26,11 @@ export default { }, collapseEmptyDays: Boolean }, + data() { + return { + visibleDays: JSON.parse(localStorage.getItem('fhc-calender-visible-days')) ?? [true, true, true, true, true, true, true] + } + }, computed: { start() { return this.day.startOf('week', { useLocaleWeeks: true }); @@ -44,11 +52,19 @@ export default { const end = this.hoursPlan?.end ?? 23; return Array.from({ length: end - start + 1 }, (e, i) => luxon.Duration.fromObject({ hours: i + start })); } + }, + dayVisibility() { + return this.axisMain.map(date => this.visibleDays[date.weekday -1]) } }, methods: { isToday(date) { return date.hasSame(luxon.DateTime.now().setZone(this.timezone), 'day'); + }, + toggleDay(day) + { + this.visibleDays.splice(day, 1, !this.visibleDays[day]) + localStorage.setItem('fhc-calender-visible-days', JSON.stringify(this.visibleDays)) } }, template: /* html */` @@ -60,9 +76,10 @@ export default { :axis-main-collapsible="collapseEmptyDays" :snap-to-grid="!!timeGrid" all-day-events + :day-visibility="dayVisibility" > -