diff --git a/application/controllers/api/frontend/v1/LvMenu.php b/application/controllers/api/frontend/v1/LvMenu.php
index 45741b567..6f4f5ad97 100644
--- a/application/controllers/api/frontend/v1/LvMenu.php
+++ b/application/controllers/api/frontend/v1/LvMenu.php
@@ -423,7 +423,7 @@ class LvMenu extends FHCAPI_Controller
{
if($row->gruppe_kurzbz != '')
{
- $bngrp_uids = $this->Benutzergrupp_model->getUids($row->gruppe_kurzbz, $angezeigtes_stsem);
+ $bngrp_uids = $this->Benutzergruppe_model->getUids($row->gruppe_kurzbz, $angezeigtes_stsem);
if(count($bngrp_uids) > 0)
{
if(!$row->mailgrp)
diff --git a/public/js/apps/Cis/Stundenplan.js b/public/js/apps/Cis/Stundenplan.js
index cbca415e0..cb019952c 100644
--- a/public/js/apps/Cis/Stundenplan.js
+++ b/public/js/apps/Cis/Stundenplan.js
@@ -11,6 +11,8 @@ const app = Vue.createApp({
events: null,
calendarDate: new CalendarDate(new Date()),
currentlySelectedEvent: null,
+ currentDay: new Date(),
+ minimized: false,
}
},
components: {
@@ -32,17 +34,23 @@ const app = Vue.createApp({
},
},
methods:{
-
+ selectDay: function(day){
+ this.currentDay = day;
+ },
showModal: function(event){
this.currentlySelectedEvent = event;
Vue.nextTick(() => {
this.$refs.lvmodal.show();
});
},
- updateRange: function (data) {
- let tmp_date = new CalendarDate(data.start);
+ updateRange: function ({start,end}) {
+
+ let checkDate = (date) => {
+ return date.m != this.calendarDate.m || date.y != this.calendarDate.y;
+ }
+
// only load month data if the month or year has changed
- if(tmp_date.m != this.calendarDate.m || tmp_date.y != this.calendarDate.y){
+ if (checkDate(new CalendarDate(start)) && checkDate(new CalendarDate(end))){
// reset the events before querying the new events to activate the loading spinner
this.events = null;
this.calendarDate = tmp_date;
@@ -51,15 +59,12 @@ const app = Vue.createApp({
});
}
},
-
calendarDateToString: function (calendarDate) {
-
return calendarDate instanceof CalendarDate ?
[calendarDate.y, calendarDate.m + 1, calendarDate.d].join('-') :
null;
},
-
loadEvents: function(){
Promise.allSettled([
this.$fhcApi.factory.stundenplan.getStundenplan(this.monthFirstDay, this.monthLastDay),
@@ -96,11 +101,12 @@ const app = Vue.createApp({
created(){
this.loadEvents();
},
+ //TODO: Stundenplan phrase
template:/*html*/`
Stundenplan
-
-
+
+
{{event?.orig.topic}}
@@ -108,6 +114,14 @@ const app = Vue.createApp({
{{event?.orig.ort_kurzbz}}
+
+
+ {{event?.orig.topic}}
+ {{lektor.kurzbz}}
+ {{event?.orig.ort_kurzbz}}
+
+
+
`
});
diff --git a/public/js/components/Calendar/Calendar.js b/public/js/components/Calendar/Calendar.js
index a38f630be..dd12456ca 100644
--- a/public/js/components/Calendar/Calendar.js
+++ b/public/js/components/Calendar/Calendar.js
@@ -3,6 +3,7 @@ import CalendarMonths from './Months.js';
import CalendarYears from './Years.js';
import CalendarWeek from './Week.js';
import CalendarWeeks from './Weeks.js';
+import CalendarDay from './Day.js';
import CalendarMinimized from './Minimized.js';
import CalendarDate from '../../composables/CalendarDate.js';
@@ -16,6 +17,7 @@ export default {
CalendarYears,
CalendarWeek,
CalendarWeeks,
+ CalendarDay,
CalendarMinimized,
},
provide() {
@@ -104,7 +106,6 @@ export default {
},
methods: {
handleInput(day) {
- console.log(day[0], "first",day[1],"second")
this.$emit(day[0], day[1]);
}
},
@@ -142,6 +143,9 @@ export default {
+
+
+
`
}
diff --git a/public/js/components/Calendar/Day.js b/public/js/components/Calendar/Day.js
new file mode 100644
index 000000000..dc9795850
--- /dev/null
+++ b/public/js/components/Calendar/Day.js
@@ -0,0 +1,52 @@
+import CalendarAbstract from './Abstract.js';
+import CalendarPane from './Pane.js';
+import CalendarDayPage from './Day/Page.js';
+import CalendarDate from '../../composables/CalendarDate.js';
+
+export default {
+ mixins: [
+ CalendarAbstract
+ ],
+ components: {
+ CalendarDayPage,
+ CalendarPane
+ },
+ computed: {
+ title() {
+ return this.focusDate.format({ year: 'numeric' }) + ' KW ' + this.focusDate.w;
+ }
+ },
+ methods: {
+ paneChanged(dir) {
+ let previousDate = new CalendarDate(this.focusDate);
+ this.focusDate.d += dir;
+ this.emitRangeChanged(previousDate);
+ },
+ emitRangeChanged(previousDate) {
+ this.$emit('change:range', { start: previousDate, end:this.focusDate });
+ },
+ prev() {
+ this.$refs.pane.prev();
+ },
+ next() {
+ this.$refs.pane.next();
+ },
+ selectEvent(event) {
+ this.$emit('input', ['select:event', event]);
+ }
+ },
+ created() {
+ this.emitRangeChanged();
+ },
+ template: /*html*/`
+
+
+
+
+
+
+
+
+
+
`
+}
diff --git a/public/js/components/Calendar/Day/Page.js b/public/js/components/Calendar/Day/Page.js
new file mode 100644
index 000000000..0da529b98
--- /dev/null
+++ b/public/js/components/Calendar/Day/Page.js
@@ -0,0 +1,154 @@
+import CalendarDate from '../../../composables/CalendarDate.js';
+
+function ggt(m, n) { return n == 0 ? m : ggt(n, m % n); }
+function kgv(m, n) { return (m * n) / ggt(m, n); }
+
+export default {
+ data() {
+ return {
+ hourPosition: null,
+ hourPositionTime: null,
+ }
+ },
+ inject: [
+ 'date',
+ 'focusDate',
+ 'size',
+ 'events',
+ 'noMonthView'
+ ],
+ props: {
+ year: Number,
+ week: Number
+ },
+ emits: [
+ 'updateMode',
+ 'page:back',
+ 'page:forward',
+ 'input'
+ ],
+ computed: {
+ hours() {
+ // returns an array with elements starting at 7 and ending at 24
+ return [...Array(24).keys()].filter(hour => hour >= 7 && hour <= 24);
+ },
+ days() {
+ let startDay = this.focusDate;
+ let result = [];
+ result.push(new Date(startDay.y, startDay.m, startDay.d));
+ return result;
+ },
+ eventsPerDayAndHour() {
+ const res = {};
+ this.days.forEach(day => {
+ let key = day.toDateString();
+
+ let nextDay = new Date(day);
+ nextDay.setDate(nextDay.getDate() + 1);
+ nextDay.setMilliseconds(nextDay.getMilliseconds() - 1);
+ let d = { events: [], lanes: 1 };
+ if (this.events[key]) {
+ this.events[key].forEach(evt => {
+ let event = {
+ orig: evt, lane: 1, maxLane: 1, start: evt.start < day ? day : evt.start, end: evt.end > nextDay ? nextDay : evt.end, shared: [], setSharedMaxRecursive(doneItems) {
+ this.maxLane = Math.max(doneItems[0].maxLane, this.maxLane);
+ doneItems.push(this);
+ this.shared.filter(other => !doneItems.includes(other)).forEach(i => i.setSharedMaxRecursive(doneItems));
+ }
+ };
+ event.shared = d.events.filter(other => other.start < event.end && other.end > event.start);
+ event.shared.forEach(other => other.shared.push(event));
+ let occupiedLanes = event.shared.map(other => other.lane);
+ while (occupiedLanes.includes(event.lane))
+ event.lane++;
+ event.maxLane = Math.max(...[event.lane], ...occupiedLanes);
+ if (event.maxLane > 1) {
+ event.setSharedMaxRecursive([event]);
+ }
+ d.events.push(event);
+ });
+ d.lanes = d.events.map(e => e.maxLane).reduce((res, i) => kgv(res, i), 1);
+ }
+ res[key] = d;
+ });
+ return res;
+ },
+ smallestTimeFrame() {
+ return [30, 15, 10, 5][this.size];
+ }
+ },
+ methods: {
+ calcHourPosition(event) {
+ let top = this.$refs.eventcontainer.getBoundingClientRect().top;
+ let position = event.clientY - top;
+ this.hourPosition = position;
+ // position percentage of total height
+ let timePercentage = (position / this.$refs.eventcontainer.offsetHeight) * 100;
+ // minute percentage of total minutes
+ let result = (this.hours.length * 60) * (timePercentage / 100);
+ // calculate time in float
+ let currentMinutes = ((result + (this.hours[0] * 60)) / 60);
+ // get hour part of time
+ let currentHour = Math.floor(currentMinutes);
+ // get float part of time
+ let minutePercentage = currentMinutes % currentHour;
+ // calculate minutes from float part of time
+ let minute = Math.round(60 * minutePercentage);
+ // in case the rounding made the minutes 60, increase the hour and reset the minutes
+ if (minute == 60) {
+ currentHour++;
+ minute = 0;
+ }
+ // add padding to minutes that consist of only one digit
+ minute.toString().length == 1 ? minute = "0" + minute : minute;
+ this.hourPositionTime = currentHour + ":" + minute;
+ },
+ getAbsolutePositionForHour(hour) {
+ // used for the absolute positioning of the gutters of hours
+ return (100 / this.hours.length) * (hour - (24 - this.hours.length)) + '%';
+ },
+ changeToMonth(day) {
+ if (!this.noMonthView) {
+ this.date.set(day);
+ this.focusDate.set(day);
+ this.$emit('updateMode', 'month');
+ }
+ },
+ dateToMinutesOfDay(day) {
+ return Math.floor(((day.getHours() - 7) * 60 + day.getMinutes()) / this.smallestTimeFrame) + 1;
+ }
+ },
+ mounted() {
+ setTimeout(() => this.$refs.eventcontainer.scrollTop = this.$refs.eventcontainer.scrollHeight / 3 + 1, 0);
+ },
+ template: /*html*/`
+
+
+
+
+
+
+ {{hourPositionTime}}
+
+
+
+
+
+
+ this is a placeholder which means that no template was passed to the Calendar Page slot
+
+
+
+
+
+
+
+
`
+}
diff --git a/public/js/components/Calendar/Header.js b/public/js/components/Calendar/Header.js
index 57e9024e1..aece861b4 100644
--- a/public/js/components/Calendar/Header.js
+++ b/public/js/components/Calendar/Header.js
@@ -4,7 +4,8 @@ export default {
selected: this.mode,
modes:{
week:"Woche",
- month:"Monat",
+ month:"Monat",
+ day: "Tag",
},
}
},
@@ -52,6 +53,7 @@ export default {
diff --git a/public/js/components/Calendar/Month/Page.js b/public/js/components/Calendar/Month/Page.js
index 59bd6ea5a..d65c358b0 100644
--- a/public/js/components/Calendar/Month/Page.js
+++ b/public/js/components/Calendar/Month/Page.js
@@ -61,6 +61,10 @@ export default {
this.$emit('updateMode', 'week');
}
},
+ changeToDay(day) {
+ this.focusDate.set(day);
+ this.$emit('updateMode', 'day');
+ },
highlight(week, day){
this.highlightedWeek = week.no;
this.highlightedDay = day;
@@ -71,7 +75,8 @@ export default {
clickEvent(day,week) {
if(!this.noWeekView)
{
- this.changeToWeek(week);
+ //this.changeToWeek(week);
+ this.changeToDay(day);
}
this.selectDay(day);
}