From ad080e61b290aad48f5a906ff2e011a1aeadf201 Mon Sep 17 00:00:00 2001 From: chfhtw Date: Tue, 22 Jul 2025 13:14:56 +0200 Subject: [PATCH] Implementation CIS => RoomInformation --- application/controllers/CisVue/Cms.php | 9 +- .../controllers/api/frontend/v1/LvPlan.php | 82 +++-- application/libraries/StundenplanLib.php | 63 +++- public/js/api/factory/lvPlan.js | 10 +- public/js/api/lvPlan.js | 10 +- .../js/components/Cis/Mylv/RoomInformation.js | 345 +++++++----------- 6 files changed, 256 insertions(+), 263 deletions(-) diff --git a/application/controllers/CisVue/Cms.php b/application/controllers/CisVue/Cms.php index a9ff13c53..aa07b919f 100644 --- a/application/controllers/CisVue/Cms.php +++ b/application/controllers/CisVue/Cms.php @@ -87,9 +87,14 @@ class Cms extends Auth_Controller $this->load->view('CisRouterView/CisRouterView.php', ['viewData'=>$viewData, 'route' => 'News']); } - public function getRoomInformation($ort_kurzbz){ + public function getRoomInformation($ort_kurzbz) + { + // Load Config + $this->load->config('calendar'); + $viewData = array( - 'ort_kurzbz' => $ort_kurzbz + 'ort_kurzbz' => $ort_kurzbz, + 'timezone' => $this->config->item('timezone') ); $this->load->view('CisRouterView/CisRouterView.php', ['viewData' => $viewData, 'route' => 'CmsRoom']); } diff --git a/application/controllers/api/frontend/v1/LvPlan.php b/application/controllers/api/frontend/v1/LvPlan.php index 69d08110a..0ccf65a0e 100644 --- a/application/controllers/api/frontend/v1/LvPlan.php +++ b/application/controllers/api/frontend/v1/LvPlan.php @@ -32,7 +32,7 @@ class LvPlan extends FHCAPI_Controller parent::__construct([ 'getRoomplan' => self::PERM_LOGGED, 'Stunden' => self::PERM_LOGGED, - 'Reservierungen' => self::PERM_LOGGED, + 'getReservierungen' => self::PERM_LOGGED, 'LvPlanEvents' => self::PERM_LOGGED, 'getLehreinheitStudiensemester' => self::PERM_LOGGED, 'studiensemesterDateInterval' => self::PERM_LOGGED, @@ -177,55 +177,69 @@ class LvPlan extends FHCAPI_Controller $this->terminateWithSuccess($stunden); } - /** - * fetches room events from a certain date - * @access public - * - */ + /** + * fetches room events from a certain date + * @access public + * + * @return void + */ public function getRoomplan() { + // form validation + $this->load->library('form_validation'); + + $this->form_validation->set_rules('ort_kurzbz', "Ort", "required"); + $this->form_validation->set_rules('start_date', "start_date", "required"); + $this->form_validation->set_rules('end_date', "end_date", "required"); + + if (!$this->form_validation->run()) + $this->terminateWithValidationErrors($this->form_validation->error_array()); + + // storing the post parameter in local variables + $ort_kurzbz = $this->input->post('ort_kurzbz', true); + $start_date = $this->input->post('start_date', true); + $end_date = $this->input->post('end_date', true); + + // get data $this->load->library('StundenplanLib'); - // form validation - $this->load->library('form_validation'); - $this->form_validation->set_data($_GET); - $this->form_validation->set_rules('ort_kurzbz',"Ort","required"); - $this->form_validation->set_rules('start_date',"start_date","required"); - $this->form_validation->set_rules('end_date',"end_date","required"); - if($this->form_validation->run() === FALSE) $this->terminateWithValidationErrors($this->form_validation->error_array()); - // storing the get parameter in local variables - $ort_kurzbz = $this->input->get('ort_kurzbz', TRUE); - $start_date = $this->input->get('start_date', TRUE); - $end_date = $this->input->get('end_date', TRUE); - - $roomplan_data = $this->LvPlan->lvPlanGruppierung($this->LvPlan->getRoomQuery($ort_kurzbz, $start_date, $end_date)); - - $roomplan_data = $this->getDataOrTerminateWithError($roomplan_data); - $this->stundenplanlib->expand_object_information($roomplan_data); + $roomplan_data = $this->stundenplanlib->getRoomplan($ort_kurzbz, $start_date, $end_date); + $roomplan_data = $this->getDataOrTerminateWithError($roomplan_data); + $this->terminateWithSuccess($roomplan_data); - } - // gets the reservierungen of a room if the ort_kurzbz parameter is supplied otherwise gets the reservierungen of the lvplan of a student - public function Reservierungen($ort_kurzbz = null) + /** + * gets the reservierungen of a room if the ort_kurzbz parameter is + * supplied otherwise gets the reservierungen of the lvplan of a student + * @access public + * + * @param string $ort_kurzbz + * @return void + */ + public function getReservierungen($ort_kurzbz = null) { - $this->load->library('StundenplanLib'); //form validation $this->load->library('form_validation'); - $this->form_validation->set_data($_GET); + $this->form_validation->set_rules('start_date', "StartDate", "required"); $this->form_validation->set_rules('end_date', "EndDate", "required"); - if($this->form_validation->run() == FALSE) $this->terminateWithValidationErrors($this->form_validation->error_array()); + + if (!$this->form_validation->run()) + $this->terminateWithValidationErrors($this->form_validation->error_array()); - $this->load->model('ressource/Mitarbeiter_model','MitarbeiterModel'); + // storing the post parameter in local variables + $start_date = $this->input->post('start_date', true); + $end_date = $this->input->post('end_date', true); - // storing the get parameter in local variables - $start_date = $this->input->get('start_date', TRUE); - $end_date = $this->input->get('end_date', TRUE); + // get data + $this->load->library('StundenplanLib'); + + $result = $this->stundenplanlib->getReservierungen($start_date, $end_date, $ort_kurzbz); + + $result = $this->getDataOrTerminateWithError($result); - $result = $this->stundenplanlib->getReservierungen($start_date,$end_date,$ort_kurzbz); - $result = $this->getDataOrTerminateWithError($result); $this->terminateWithSuccess($result); } diff --git a/application/libraries/StundenplanLib.php b/application/libraries/StundenplanLib.php index 868d73a24..0107ceef1 100644 --- a/application/libraries/StundenplanLib.php +++ b/application/libraries/StundenplanLib.php @@ -130,30 +130,69 @@ class StundenplanLib{ } - public function getReservierungen($start_date, $end_date, $ort_kurzbz){ + /** + * Get stundenplan for a room + * + * @param string $ort_kurzbz + * @param string $start_date + * @param string $end_date + * @return stdClass + */ + public function getRoomplan($ort_kurzbz, $start_date, $end_date) + { $this->_ci =& get_instance(); // Load Config $this->_ci->load->config('calendar'); + // Load Models + $this->_ci->load->model('ressource/Stundenplan_model', 'StundenplanModel'); + + $query = $this->_ci->StundenplanModel->getRoomQuery($ort_kurzbz, $start_date, $end_date); + $roomplan_data = $this->_ci->StundenplanModel->stundenplanGruppierung($query); + + if (isError($roomplan_data)) + return $roomplan_data; + + $this->expand_object_information($roomplan_data->retval); + + return $roomplan_data; + } + + /** + * Get reservations (for a room or all) + * + * @param string $start_date + * @param string $end_date + * @param string $ort_kurzbz + * @return stdClass + */ + public function getReservierungen($start_date, $end_date, $ort_kurzbz = '') + { + $this->_ci =& get_instance(); + + // Load Config + $this->_ci->load->config('calendar'); + // Load Models + $this->_ci->load->model('ressource/Mitarbeiter_model', 'MitarbeiterModel'); $is_mitarbeiter = getData($this->_ci->MitarbeiterModel->isMitarbeiter(getAuthUID())); - if($is_mitarbeiter) - { + + if ($is_mitarbeiter) { $reservierungen = $this->_ci->ReservierungModel->getReservierungenMitarbeiter($start_date, $end_date, $ort_kurzbz); } else { // querying the reservierungen $reservierungen = $this->_ci->ReservierungModel->getReservierungen($start_date, $end_date, $ort_kurzbz); } - if(isError($reservierungen)) - { - return error(getData($reservierungen)); - } - $reservierungen = getData($reservierungen) ?? []; - $function_error = $this->expand_object_information($reservierungen); - if(!is_null($function_error)){ + + if (isError($reservierungen)) + return $reservierungen; + + $function_error = $this->expand_object_information($reservierungen->retval); + + if (!is_null($function_error)) return $function_error; - } - return success($reservierungen); + + return $reservierungen; } public function getLektorenFromLehrveranstaltung($lehrveranstaltung_id, $semester, $studiengang_kz, $studiensemester_kurzbz){ diff --git a/public/js/api/factory/lvPlan.js b/public/js/api/factory/lvPlan.js index d8cad1c01..99f7961f6 100644 --- a/public/js/api/factory/lvPlan.js +++ b/public/js/api/factory/lvPlan.js @@ -18,7 +18,7 @@ export default { getRoomInfo(ort_kurzbz, start_date, end_date) { return { - method: 'get', + method: 'post', url: '/api/frontend/v1/LvPlan/getRoomplan', params: { ort_kurzbz, start_date, end_date } }; @@ -39,15 +39,15 @@ export default { }, getOrtReservierungen(ort_kurzbz, start_date, end_date) { return { - method: 'get', - url: `/api/frontend/v1/LvPlan/Reservierungen/${ort_kurzbz}`, + method: 'post', + url: `/api/frontend/v1/LvPlan/getReservierungen/${ort_kurzbz}`, params: { start_date, end_date } }; }, getLvPlanReservierungen(start_date, end_date) { return { - method: 'get', - url: '/api/frontend/v1/LvPlan/Reservierungen', + method: 'post', + url: '/api/frontend/v1/LvPlan/getReservierungen', params: { start_date, end_date } }; }, diff --git a/public/js/api/lvPlan.js b/public/js/api/lvPlan.js index a1d34b37c..2939b688c 100644 --- a/public/js/api/lvPlan.js +++ b/public/js/api/lvPlan.js @@ -1,7 +1,7 @@ export default { getRoomInfo(ort_kurzbz, start_date, end_date) { - return this.$fhcApi.get( + return this.$fhcApi.post( '/api/frontend/v1/LvPlan/getRoomplan', { ort_kurzbz, start_date, end_date} ); @@ -13,14 +13,14 @@ export default { ); }, getOrtReservierungen(ort_kurzbz, start_date, end_date) { - return this.$fhcApi.get( - `/api/frontend/v1/LvPlan/Reservierungen/${ort_kurzbz}`, + return this.$fhcApi.post( + `/api/frontend/v1/LvPlan/getReservierungen/${ort_kurzbz}`, { start_date, end_date} ); }, getLvPlanReservierungen(start_date, end_date) { - return this.$fhcApi.get( - '/api/frontend/v1/LvPlan/Reservierungen', + return this.$fhcApi.post( + '/api/frontend/v1/LvPlan/getReservierungen', { start_date, end_date } ); }, diff --git a/public/js/components/Cis/Mylv/RoomInformation.js b/public/js/components/Cis/Mylv/RoomInformation.js index 6a9a7dbcd..b604ef2bb 100644 --- a/public/js/components/Cis/Mylv/RoomInformation.js +++ b/public/js/components/Cis/Mylv/RoomInformation.js @@ -1,259 +1,194 @@ -import FhcCalendar from "../../Calendar/Calendar.js"; +import FhcCalendar from "../../Calendar/Base.js"; import CalendarDate from "../../../composables/CalendarDate.js"; -import LvModal from "../../../components/Cis/Mylv/LvModal.js"; import LvInfo from "../../../components/Cis/Mylv/LvInfo.js" import ApiStudenplan from '../../../api/factory/lvPlan.js'; +import { useEventLoader } from '../../../composables/EventLoader.js'; + +import ModeDay from '../../Calendar/Mode/Day.js'; +import ModeWeek from '../../Calendar/Mode/Week.js'; +import ModeMonth from '../../Calendar/Mode/Month.js'; + export const DEFAULT_MODE_RAUMINFO = 'Week' -const RoomInformation = { +export default { name: "RoomInformation", - props:{ - propsViewData: { - type: Object - }, - rowMinHeight: { - type: String, - default: '100px' - }, - eventMaxHeight: { - type: String, - default: '125px' - } - }, components: { FhcCalendar, - LvModal, - LvInfo, + LvInfo }, - provide() { - return { - rowMinHeight: this.rowMinHeight, - eventMaxHeight: this.eventMaxHeight - } + inject: [ + "renderers" + ], + props:{ + viewData: Object, // NOTE(chris): this is inherited from router-view + propsViewData: Object }, data() { + const now = luxon.DateTime.now().setZone(this.viewData.timezone); return { - events: null, - calendarMode: DEFAULT_MODE_RAUMINFO, - calendarDate: new CalendarDate(new Date()), - currentlySelectedEvent: null, - currentDay: this.propsViewData?.focus_date ? new Date(this.propsViewData.focus_date) : new Date(), - minimized: false, - - } + modes: { + day: Vue.markRaw(ModeDay), + week: Vue.markRaw(ModeWeek), + month: Vue.markRaw(ModeMonth) + }, + modeOptions: { + day: { + emptyMessage: Vue.computed(() => this.$p.t('rauminfo/keineRaumReservierung')), + emptyMessageDetails: Vue.computed(() => this.$p.t('rauminfo/keineRaumReservierung')), + compact: false + }, + week: { + collapseEmptyDays: false + } + }, + currentDay: this.propsViewData?.focus_date, + calendarMode: this.propsViewData?.mode ?? DEFAULT_MODE_RAUMINFO, + backgrounds: [ + { + class: 'background-past', + end: now, + label: now.startOf('minute').toISOTime({ suppressSeconds: true, includeOffset: false }) + } + ] + } }, - computed:{ - currentDate: function(){ - return new Date(this.calendarWeek.y, this.calendarWeek.m, this.calendarWeek.d); - }, - weekFirstDay: function () { - return this.calendarDateToString(this.calendarDate.cdFirstDayOfWeek); + methods:{ + eventStyle(event) { + if (!event.farbe) + return undefined; + return '--event-bg:#' + event.farbe; }, - weekLastDay: function () { - return this.calendarDateToString(this.calendarDate.cdLastDayOfWeek); - }, - monthFirstDay: function () { - return this.calendarDateToString(this.calendarDate.cdFirstDayOfCalendarMonth); - }, - monthLastDay: function () { - return this.calendarDateToString(this.calendarDate.cdLastDayOfCalendarMonth); - }, - }, - watch: { - 'propsViewData.ort_kurzbz'(newVal) { - // relevant if ort_kurzbz can be changed from within this component - }, - 'propsViewData.mode'(newVal) { - if(this.$refs.calendar) this.$refs.calendar.setMode(newVal) - }, - 'propsViewData.focus_date'(newVal) { - this.currentDate = new Date(newVal) - } - }, - methods:{ - setSelectedEvent: function(event){ - this.currentlySelectedEvent = event; - }, - getLvID: function () { - this.lv_id = window.location.pathname - }, - selectDay: function(day){ - const date = day.getFullYear() + "-" + - String(day.getMonth() + 1).padStart(2, "0") + "-" + - String(day.getDate()).padStart(2, "0"); + handleChangeDate(day) { + const focus_date = day.toISODate(); + const mode = this.calendarMode[0].toUpperCase() + this.calendarMode.slice(1); this.$router.push({ name: "RoomInformation", params: { - mode: this.calendarMode, - focus_date: date, + mode, + focus_date, ort_kurzbz: this.propsViewData.ort_kurzbz } }) - + this.currentDay = day; }, - handleOffset: function(offset) { - this.currentDay = new Date( - this.currentDay.getFullYear() + offset.y, - this.currentDay.getMonth() + offset.m, - this.currentDay.getDate() + offset.d - ) + handleChangeMode(newMode) { + const mode = newMode[0].toUpperCase() + newMode.slice(1) + const focus_date = (this.currentDay instanceof luxon.DateTime) + ? this.currentDay.toISODate() + : this.currentDay; - const date = this.currentDay.getFullYear() + "-" + - String(this.currentDay.getMonth() + 1).padStart(2, "0") + "-" + - String(this.currentDay.getDate()).padStart(2, "0"); - - this.$router.push({ - name: "LvPlan", - params: { - mode: this.calendarMode, - focus_date: date, - lv_id: this.propsViewData?.lv_id || null - } - }) - }, - handleChangeMode(mode) { - const modeCapitalized = mode.charAt(0).toUpperCase() + mode.slice(1) - const date = this.currentDay.getFullYear() + "-" + - String(this.currentDay.getMonth() + 1).padStart(2, "0") + "-" + - String(this.currentDay.getDate()).padStart(2, "0"); - this.$router.push({ name: "RoomInformation", params: { - mode: modeCapitalized, - focus_date: date, + mode, + focus_date, ort_kurzbz: this.propsViewData.ort_kurzbz } }) this.calendarMode = mode }, - showModal: function (event) { - this.currentlySelectedEvent = event; - Vue.nextTick(() => { - this.$refs.lvmodal.show(); - }); - - }, - 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 (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 = new CalendarDate(end); - Vue.nextTick(() => { - this.loadEvents(); - }); - } - }, - calendarDateToString: function (calendarDate) { - return calendarDate instanceof CalendarDate ? - [calendarDate.y, calendarDate.m + 1, calendarDate.d].join('-') : - null; - - }, - loadEvents: function(){ - - // bundles the room_events and the reservierungen together into the this.events array - Promise.allSettled([ - this.$api.call(ApiStudenplan.getRoomInfo(this.propsViewData.ort_kurzbz, this.monthFirstDay, this.monthLastDay)), - this.$api.call(ApiStudenplan.getOrtReservierungen(this.propsViewData.ort_kurzbz, this.monthFirstDay, this.monthLastDay)) - ]).then((result) => { - let promise_events = []; - result.forEach((promise_result) => { - if(promise_result.status === 'fulfilled' && promise_result.value.meta.status === "success"){ - - let data = promise_result.value.data; - // adding additional information to the events - if (data && data.forEach) { - data.forEach((el, i) => { - el.id = i; - if (el.type === 'reservierung') { - el.color = '#' + (el.farbe || 'FFFFFF'); - } else { - el.color = '#' + (el.farbe || 'CCCCCC'); - } - - el.start = new Date(el.datum + ' ' + el.beginn); - el.end = new Date(el.datum + ' ' + el.ende); - - }); - } - promise_events = promise_events.concat(data); - } - }) - this.events = promise_events; - }) - }, - }, - created() { - this.loadEvents(); + updateRange(rangeInterval) { + this.rangeInterval = rangeInterval; + } }, - template: /*html*/` + setup(props) { + const $api = Vue.inject('$api'); + + const rangeInterval = Vue.ref(null); + + const { events } = useEventLoader(rangeInterval, (start, end) => { + return [ + $api.call(ApiStudenplan.getRoomInfo(props.propsViewData.ort_kurzbz, start.toISODate(), end.toISODate())), + $api.call(ApiStudenplan.getOrtReservierungen(props.propsViewData.ort_kurzbz, start.toISODate(), end.toISODate())) + ]; + }); + + return { + rangeInterval, + events + }; + }, + template: /*html*/` +

{{ $p.t('rauminfo/rauminfo') }} {{ propsViewData.ort_kurzbz }}


- - -