diff --git a/application/config/routes.php b/application/config/routes.php index 8acf9b5ea..eb4c267ce 100644 --- a/application/config/routes.php +++ b/application/config/routes.php @@ -61,7 +61,7 @@ $route['api/v1/organisation/[O|o]rganisationseinheit/(:any)'] = 'api/v1/organisa $route['api/v1/ressource/[B|b]etriebsmittelperson/(:any)'] = 'api/v1/ressource/betriebsmittelperson2/$1'; $route['api/v1/system/[S|s]prache/(:any)'] = 'api/v1/system/sprache2/$1'; -$route['Cis/Stundenplan/(:any)?'] = 'Cis/Stundenplan/index/$1'; +$route['Cis/Stundenplan/.*'] = 'Cis/Stundenplan/index/$1'; // load routes from extensions $subdir = 'application/config/extensions'; diff --git a/application/controllers/Cis/Stundenplan.php b/application/controllers/Cis/Stundenplan.php index f6fb0bd67..71e01be8b 100644 --- a/application/controllers/Cis/Stundenplan.php +++ b/application/controllers/Cis/Stundenplan.php @@ -23,10 +23,10 @@ class Stundenplan extends Auth_Controller /** * @return void */ - public function index($lv_id = null) + public function index() { + $viewData = array( - 'lv_id' => $lv_id, 'uid'=>getAuthUID(), ); diff --git a/application/controllers/api/frontend/v1/Stundenplan.php b/application/controllers/api/frontend/v1/Stundenplan.php index 0a56dac71..2ec02fea9 100644 --- a/application/controllers/api/frontend/v1/Stundenplan.php +++ b/application/controllers/api/frontend/v1/Stundenplan.php @@ -153,6 +153,11 @@ class Stundenplan extends FHCAPI_Controller $stundenplan_data = $this->StundenplanModel->getStundenplanLVA($start_date, $end_date, $lv_id); $stundenplan_data = $this->getDataOrTerminateWithError($stundenplan_data) ?? []; $this->expand_object_information($stundenplan_data); + + // query lv itself in case its Stundenplan is being queried and it has no entries + $this->load->model('education/Lehrveranstaltung_model','LehrveranstaltungModel'); + $lv = getData($this->LehrveranstaltungModel->load($lv_id))[0]; + $this->addMeta('lv', $lv); $this->terminateWithSuccess($stundenplan_data); } diff --git a/application/models/education/Lehrveranstaltung_model.php b/application/models/education/Lehrveranstaltung_model.php index 8044fa9de..44f9834d8 100644 --- a/application/models/education/Lehrveranstaltung_model.php +++ b/application/models/education/Lehrveranstaltung_model.php @@ -556,16 +556,6 @@ class Lehrveranstaltung_model extends DB_Model */ public function getLvsByStudentWithGrades($student_uid, $studiensemester_kurzbz, $sprache = null, $lvid=null) { - if ($sprache) { - $sprache_qry = $this->db->compile_binds('SELECT index FROM public.tbl_sprache WHERE sprache = ?', [$sprache]); - $bezeichnung = 'bezeichnung_mehrsprachig[(' . $sprache_qry . ')]'; - $sgbezeichnung = $sprache == 'English' ? 'COALESCE(sg.english, sg.bezeichnung)' : 'sg.bezeichnung'; - $lvbezeichnung = $sprache == 'English' ? 'COALESCE(v.bezeichnung_english, v.bezeichnung)' : 'v.bezeichnung'; - } else { - $bezeichnung = 'bezeichnung'; - $sgbezeichnung = 'sg.bezeichnung'; - $lvbezeichnung = 'v.bezeichnung'; - } $this->addDistinct(); // TODO(chris): selects @@ -605,16 +595,20 @@ class Lehrveranstaltung_model extends DB_Model $this->addSelect('znn.positiv'); #$this->addSelect('splv.module'); - $this->addSelect($lvbezeichnung . ' AS bezeichnung'); - $this->addSelect($sgbezeichnung . ' AS sg_bezeichnung'); + $this->addSelect('v.bezeichnung AS bezeichnung'); + $this->addSelect('v.bezeichnung_english AS bezeichnung_eng'); + $this->addSelect('sg.bezeichnung AS sg_bezeichnung'); + $this->addSelect('sg.english AS sg_bezeichnung_eng'); $this->addSelect('UPPER(sg.typ::VARCHAR(1) || sg.kurzbz) AS studiengang_kuerzel'); //also adds returns the index of the grade //TODO: ist zeugnissnote immer gleich wie die lvgesamtnote $this->addSelect('COALESCE(zn.note::numeric,gn.note::numeric) as note_index'); $this->addSelect('COALESCE(znn.positiv,gnn.positiv) as positiv'); - $this->addSelect('COALESCE(gnn.' . $bezeichnung . ', gnn.bezeichnung, gn.note::text) AS lvnote'); - $this->addSelect('COALESCE(znn.' . $bezeichnung . ', znn.bezeichnung, zn.note::text) AS znote'); + $this->addSelect('gnn.bezeichnung_mehrsprachig AS lvnotebez'); + $this->addSelect('gnn.note AS lvnote'); + $this->addSelect('znn.bezeichnung_mehrsprachig AS znotebez'); + $this->addSelect('znn.note AS znote'); // TODO(chris): Potentielle Anpassung "Eine UID" $this->addJoin('campus.vw_student_lehrveranstaltung v', 'lehrveranstaltung_id'); diff --git a/include/tw/cis_menu_lv.inc.php b/include/tw/cis_menu_lv.inc.php index a18af4bde..fa35362bd 100644 --- a/include/tw/cis_menu_lv.inc.php +++ b/include/tw/cis_menu_lv.inc.php @@ -402,6 +402,7 @@ function checkZeilenUmbruch() 'id'=>'core_menu_mailanstudierende', 'position'=>'100', 'name'=>$p->t('lehre/mail'), + 'phrase'=>'lehre/mail', 'icon'=>'../../../skin/images/button_feedback.png', 'link'=>$mailto, 'link_onclick'=>$link_onclick @@ -477,6 +478,7 @@ function checkZeilenUmbruch() 'id'=>'core_menu_anerkennungNachgewiesenerKenntnisse', 'position'=>'128', 'name'=>$p->t('lehre/anrechnung'), + 'phrase'=>'lehre/anrechnung', 'icon'=>'../../../skin/images/button_listen.png', 'link' => APP_ROOT. 'index.ci.php/lehre/anrechnung/RequestAnrechnung?studiensemester='.urlencode($angezeigtes_stsem).'&lv_id='.urlencode($lvid) ); @@ -491,6 +493,7 @@ if((!defined('CIS_LEHRVERANSTALTUNG_ANRECHNUNG_ANZEIGEN') || CIS_LEHRVERANSTALTU 'id'=>'core_menu_anerkennungNachgewiesenerKenntnisse_empfehlen', 'position'=>'128', 'name'=>$p->t('lehre/anrechnungen'), + 'phrase'=>'lehre/anrechnung', 'icon'=>'../../../skin/images/button_listen.png', 'link' => APP_ROOT. 'index.ci.php/lehre/anrechnung/ReviewAnrechnungUebersicht?studiensemester='.urlencode($angezeigtes_stsem) ); diff --git a/public/js/apps/Dashboard/Fhc.js b/public/js/apps/Dashboard/Fhc.js index 19f6b3a2b..d49195399 100644 --- a/public/js/apps/Dashboard/Fhc.js +++ b/public/js/apps/Dashboard/Fhc.js @@ -3,13 +3,13 @@ import FhcApi from '../../plugin/FhcApi.js'; import Phrasen from '../../plugin/Phrasen.js'; import contrast from '../../directives/contrast.js'; import {setScrollbarWidth} from "../../helpers/CssVarCalcHelpers.js"; -import Stundenplan from "../../components/Cis/Stundenplan/Stundenplan.js"; +import Stundenplan, {DEFAULT_MODE_STUNDENPLAN} from "../../components/Cis/Stundenplan/Stundenplan.js"; import MylvStudent from "../../components/Cis/Mylv/Student.js"; import Profil from "../../components/Cis/Profil/Profil.js"; import CmsNews from "../../components/Cis/Cms/News.js"; import CmsContent from "../../components/Cis/Cms/Content.js"; import Info from "../../components/Cis/Mylv/Semester/Studiengang/Lv/Info.js"; -import RoomInformation from "../../components/Cis/Mylv/RoomInformation.js"; +import RoomInformation, { DEFAULT_MODE_RAUMINFO } from "../../components/Cis/Mylv/RoomInformation.js"; const ciPath = FHC_JS_DATA_STORAGE_OBJECT.app_root.replace(/(https:|)(^|\/\/)(.*?\/)/g, '') + FHC_JS_DATA_STORAGE_OBJECT.ci_router; @@ -28,11 +28,65 @@ const router = VueRouter.createRouter({ component: Profil, props: true }, + + // Redirect old links to new format { - path: `/CisVue/Cms/getRoomInformation/:ort_kurzbz`, + path: "/CisVue/Cms/getRoomInformation/:ort_kurzbz", + name: "RoomInformationOld", + component: RoomInformation, + redirect: (to) => { + return { // redirect to longer Rauminfo url and map params + name: "RoomInformation", + params: { // in this case always populate other params since they are not optional + ort_kurzbz: to.params.ort_kurzbz, + mode: DEFAULT_MODE_RAUMINFO, + focus_date: new Date().toISOString().split("T")[0] + }, + }; + }, + }, + { + path: `/CisVue/Cms/getRoomInformation/:mode/:focus_date/:ort_kurzbz`, name: 'RoomInformation', component: RoomInformation, - props: true + props: (route) => { // validate and set mode/focus date if for some reason missing + const validModes = ["Month", "Week", "Day"]; + + // check mode string + const mode = route.params.mode && + validModes.includes(route.params.mode.charAt(0).toUpperCase() + route.params.mode.slice(1).toLowerCase()) + ? route.params.mode.charAt(0).toUpperCase() + route.params.mode.slice(1).toLowerCase() + : DEFAULT_MODE_RAUMINFO; + + // default to today date if not provided + const d = new Date(route.params.focus_date) + const focus_date = !isNaN(d) ? route.params.focus_date : new Date().toISOString().split("T")[0]; + + // for consistency reasons format the props into one object but actually use a new name to we dont collide with + // existing viewData declaration written from codeigniter 3 into routerview tag + return { + propsViewData: { + mode, + focus_date, + ort_kurzbz: route.params.ort_kurzbz + } + }; + }, + beforeEnter: (to, from, next) => { + // missing mode or focus_date -> set defaults + if (!to.params.mode || !to.params.focus_date) { + next({ + name: "RoomInformation", + params: { + mode: to.params.mode || DEFAULT_MODE_RAUMINFO, + focus_date: to.params.focus_date || new Date().toISOString().split("T")[0], + ort_kurzbz: route.params.ort_kurzbz + } + }); + } else { + next(); + } + } }, { path: `/CisVue/Cms/Content/:content_id`, @@ -58,10 +112,68 @@ const router = VueRouter.createRouter({ component: Info, props: true }, + // Redirect old links to new format { - path: `/Cis/Stundenplan/:lv_id?`, + // only trigger on first param being numeric to avoid paths like "Stundenplan/Month" entering here + path: "/Cis/Stundenplan/:lv_id(\\d+)", + name: "StundenplanOld", + component: Stundenplan, + redirect: (to) => { + return { // redirect to longer Stundenplan url and map params + name: "Stundenplan", + params: { + lv_id: to.params.lv_id + }, + }; + }, + }, + { + path: `/Cis/Stundenplan/:mode?/:focus_date?/:lv_id?`, name: 'Stundenplan', - component: Stundenplan + component: Stundenplan, + props: (route) => { // validate and set mode/focus date if for some reason missing + const validModes = ["Month", "Week", "Day"]; + + // check mode string + const mode = route.params.mode && + validModes.includes(route.params.mode.charAt(0).toUpperCase() + route.params.mode.slice(1).toLowerCase()) + ? route.params.mode.charAt(0).toUpperCase() + route.params.mode.slice(1).toLowerCase() + : DEFAULT_MODE_STUNDENPLAN; + + // default to today date if not provided or string forms invalid date + const d = new Date(route.params.focus_date) + const focus_date = !isNaN(d) ? route.params.focus_date : new Date().toISOString().split("T")[0]; + // for consistency reasons format the props into one object but actually use a new name to we dont collide with + // existing viewData declaration written from codeigniter 3 into routerview tag + return { + propsViewData: { + mode, + focus_date, + lv_id: route.params.lv_id + } + }; + }, + beforeEnter: (to, from, next) => { + // missing mode or focus_date -> set defaults + if (!to.params.mode || !to.params.focus_date) { + next({ + name: "Stundenplan", + params: { + mode: to.params.mode || DEFAULT_MODE_STUNDENPLAN, + focus_date: to.params.focus_date || new Date().toISOString().split("T")[0], + lv_id: to.params.lv_id + } + }); + } else { + next(); + } + } + }, + { + path: `/Cis4`, + name: 'Cis4', + component: FhcDashboard, + props: {dashboard: 'CIS'}, }, { path: `/`, @@ -70,14 +182,32 @@ const router = VueRouter.createRouter({ props: {dashboard: 'CIS'}, }, { - path: `/Cis4`, - name: 'Cis4', + path: '/:pathMatch(.*)*', + name: 'Fallback', component: FhcDashboard, props: {dashboard: 'CIS'}, - } + redirect: () => { + return { + name: "Cis4", + params: { + dashboard: 'CIS' + }, + }; + }, + }, ] }) +router.beforeEach((to, from) => { + // this avoids redundant routing navigation in place due to router.replace on a route with param function and + // beforeEnter navigation guard + + // TODO: manage the infinite forward navigation issue somehow + if (to.fullPath === from.fullPath) { + return false + } +}) + const app = Vue.createApp({ name: 'FhcApp', data: () => ({ @@ -111,7 +241,7 @@ const app = Vue.createApp({ // let click event propagate normally if we dont route internally const res = this.$router.resolve(route) - if(!res?.matched?.length) return + if(!res?.matched?.length || res.name === 'Fallback') return event.preventDefault(); // Prevent browser navigation diff --git a/public/js/components/Calendar/Calendar.js b/public/js/components/Calendar/Calendar.js index c3515df45..cdceb38db 100644 --- a/public/js/components/Calendar/Calendar.js +++ b/public/js/components/Calendar/Calendar.js @@ -62,6 +62,9 @@ export default { noMonthView: Boolean }, watch:{ + mode(newVal) { + this.$emit('change:mode', newVal) + }, selectedEvent:{ handler(newSelectedEvent) { this.$emit('selectedEvent', newSelectedEvent); @@ -92,7 +95,8 @@ export default { 'select:event', 'change:range', 'update:minimized', - 'selectedEvent' + 'selectedEvent', + 'change:offset' ], data() { return { @@ -161,12 +165,12 @@ export default { if (this.events && Array.isArray(this.events) && this.events.length > 0) { let filteredEvents = this.events.filter(event => { let eventDate = new CalendarDate(new Date(event.datum)); - if (this.mode == 'week') + if (this.mode == 'week' || this.mode == 'Week') { // week view filters the elements only for the same week return this.focusDate.w == eventDate.w; } - else if (this.mode == 'day') + else if (this.mode == 'day' || this.mode == 'Day') { // day view filters the elements for the same day and the same week return this.focusDate.d == eventDate.d && this.focusDate.w == eventDate.w; @@ -187,17 +191,21 @@ export default { }, }, methods: { + setMode(mode) { + this.mode = mode + }, handleInput(day) { this.$emit(day[0], day[1]); }, }, created() { - const allowedInitialModes = ['years']; + const initMode = this.initialMode.toLowerCase() + const allowedInitialModes = ['day']; if (!this.noWeekView) allowedInitialModes.push('week'); if (!this.noMonthView) allowedInitialModes.push('month'); - this.mode = allowedInitialModes[allowedInitialModes.indexOf(this.initialMode)] || allowedInitialModes.pop(); + this.mode = allowedInitialModes[allowedInitialModes.indexOf(initMode)] || allowedInitialModes.pop(); this.date.set(new Date(this.initialDate)); this.focusDate.set(this.date); }, @@ -227,14 +235,14 @@ export default { } }).observe(this.$refs.container); } - }, unmounted(){ CalendarDates.cleanup(); }, template: /*html*/`
- + diff --git a/public/js/components/Calendar/Day.js b/public/js/components/Calendar/Day.js index b85615f3e..13128a520 100644 --- a/public/js/components/Calendar/Day.js +++ b/public/js/components/Calendar/Day.js @@ -22,21 +22,23 @@ export default { this.focusDate.d += dir; this.emitRangeChanged(previousDate); }, - emitRangeChanged(previousDate) { + emitRangeChanged(previousDate, mounted) { this.$emit('change:range', { start: previousDate, end:this.focusDate }); }, prev() { this.$refs.pane.prev(); + this.$emit('change:offset', { y: 0, m: 0, d: -1 }); }, next() { this.$refs.pane.next(); + this.$emit('change:offset', { y: 0, m: 0, d: 1 }); }, selectEvent(event) { this.$emit('input', ['select:event', event]); } }, - created() { - this.emitRangeChanged(); + mounted() { + this.emitRangeChanged(new CalendarDate(this.focusDate.y, this.focusDate.m, this.focusDate.d -1), true); }, template: /*html*/`
diff --git a/public/js/components/Calendar/Day/Page.js b/public/js/components/Calendar/Day/Page.js index 44aadb837..e8c6f4a56 100644 --- a/public/js/components/Calendar/Day/Page.js +++ b/public/js/components/Calendar/Day/Page.js @@ -36,6 +36,7 @@ export default { 'calendarClientHeight', 'setSelectedEvent', 'selectedEvent', + 'rowMinHeight' ], props: { year: Number, @@ -398,7 +399,7 @@ export default {
-

Keine Lehrveranstaltungen

+

{{ $p.t('lehre/noLvFound') }}

@@ -412,12 +413,13 @@ export default {
-
{{hour}}:00
+
{{hour}}:00
-
+
diff --git a/public/js/components/Calendar/Header.js b/public/js/components/Calendar/Header.js index 5d92304c6..5ee3d51e7 100644 --- a/public/js/components/Calendar/Header.js +++ b/public/js/components/Calendar/Header.js @@ -3,9 +3,9 @@ export default { return{ selected: this.mode, modes:{ - day: { mode_bezeichnung: "Tag", icon: "fa-calendar-day" , condition:true}, - week: { mode_bezeichnung: "Woche", icon: "fa-calendar-week", condition: !this.noWeekView }, - month: { mode_bezeichnung: "Monat", icon: "fa-calendar-days", condition: !this.noMonthView }, + day: { mode_bezeichnung: "day", icon: "fa-calendar-day" , condition:true}, + week: { mode_bezeichnung: "week", icon: "fa-calendar-week", condition: !this.noWeekView }, + month: { mode_bezeichnung: "month", icon: "fa-calendar-days", condition: !this.noMonthView }, }, headerPadding:null, } @@ -62,7 +62,7 @@ export default {
-
diff --git a/public/js/components/Calendar/Month.js b/public/js/components/Calendar/Month.js index 79fc1bf23..d427304b8 100644 --- a/public/js/components/Calendar/Month.js +++ b/public/js/components/Calendar/Month.js @@ -28,16 +28,23 @@ export default { } else { this.focusDate.moveMonthInDirection(dir) } + this.emitRangeChanged() + }, + emitRangeChanged(mounted = false) { + this.$emit('change:range', { - start: new Date(this.focusDate.y, this.focusDate.m, 1), - end: new Date(this.focusDate.y, this.focusDate.m+1, 0) + start: new Date(this.focusDate.y, this.focusDate.m, 1), + end: new Date(this.focusDate.y, this.focusDate.m+1, 0), + mounted }); }, prev() { this.$refs.pane.prev(); + this.$emit('change:offset', { y: 0, m: -1, d: 0 }); }, next() { this.$refs.pane.next(); + this.$emit('change:offset', { y: 0, m: 1, d: 0 }); }, selectDay(day) { let m = day.getMonth(); @@ -53,11 +60,8 @@ export default { this.$emit('input', ['select:day',day]) } }, - created() { - this.$emit('change:range', { - start: new Date(this.focusDate.y, this.focusDate.m, 1), - end: new Date(this.focusDate.y, this.focusDate.m+1, 0) - }); + mounted() { + this.emitRangeChanged(true) }, template: `
diff --git a/public/js/components/Calendar/Month/Page.js b/public/js/components/Calendar/Month/Page.js index 896be61bc..27c649f1b 100644 --- a/public/js/components/Calendar/Month/Page.js +++ b/public/js/components/Calendar/Month/Page.js @@ -63,6 +63,10 @@ export default { }, methods: { + handleEventClick(e, day) { + this.selectDay(day) + e.stopPropagation() + }, getDayClass(week, day) { let classstring = 'fhc-calendar-month-page-day text-decoration-none overflow-hidden' const isHighlightedWeek = this.isHighlightedWeek(week) @@ -150,10 +154,11 @@ export default { :key="day" :class="getDayClass(week, day)" > - {{day.getDate()}} + {{day.getDate()}} -
+

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

diff --git a/public/js/components/Calendar/Week.js b/public/js/components/Calendar/Week.js index 858af0733..132660d78 100644 --- a/public/js/components/Calendar/Week.js +++ b/public/js/components/Calendar/Week.js @@ -20,23 +20,25 @@ export default { this.focusDate.d += dir * 7; this.emitRangeChanged(); }, - emitRangeChanged() { + emitRangeChanged(mounted = false) { let start = this.focusDate.firstDayOfWeek; let end = this.focusDate.lastDayOfWeek; - this.$emit('change:range', { start, end }); + this.$emit('change:range', { start, end, mounted }); }, prev() { this.$refs.pane.prev(); + this.$emit('change:offset', { y: 0, m: 0, d: -7 }); }, next() { this.$refs.pane.next(); + this.$emit('change:offset', { y: 0, m: 0, d: 7 }); }, selectEvent(event) { this.$emit('input', ['select:event',event]); } }, - created() { - this.emitRangeChanged(); + mounted() { + this.emitRangeChanged(true); }, template: /*html*/`
diff --git a/public/js/components/Calendar/Week/Page.js b/public/js/components/Calendar/Week/Page.js index a6bc221fe..999369313 100644 --- a/public/js/components/Calendar/Week/Page.js +++ b/public/js/components/Calendar/Week/Page.js @@ -23,7 +23,8 @@ export default { 'noMonthView', 'isSliding', 'selectedEvent', - 'setSelectedEvent' + 'setSelectedEvent', + 'rowMinHeight' ], props: { year: Number, @@ -49,7 +50,7 @@ export default { }, getGridStyle() { return { - 'min-height': '100px', + 'min-height': this.rowMinHeight, // this.size is the magic number anyway which directs font-size, // which in turn influences a lot of layout width: '42px' @@ -299,7 +300,13 @@ export default { this.$emit('updateMode', 'month'); } }, + changeToDay(day) { + this.date.set(day); + this.focusDate.set(day); + this.$emit('updateMode', 'day'); + }, dateToMinutesOfDay(day) { + // subtract 7 from the total hours because the hours range from 7 to 24 return Math.floor(((day.getHours()-7) * 60 + day.getMinutes()) / this.smallestTimeFrame) + 1; }, weekPageClick(event, day) { @@ -346,7 +353,7 @@ export default {
-
+
{{dayText[day]?.tag}}
{{dayText[day]?.datum}}
diff --git a/public/js/components/Calendar/Weeks.js b/public/js/components/Calendar/Weeks.js index 530cfe90e..76243c67b 100644 --- a/public/js/components/Calendar/Weeks.js +++ b/public/js/components/Calendar/Weeks.js @@ -8,8 +8,6 @@ export default { 'size', 'focusDate' ], - data() { - }, computed: { weeks(){ return [...Array(this.focusDate.numWeeks).keys()].map(i => i + 1); @@ -34,7 +32,7 @@ export default { }, }, template: ` -
+
diff --git a/public/js/components/Calendar/Years.js b/public/js/components/Calendar/Years.js index 6cda6cfe9..baff2eb6c 100644 --- a/public/js/components/Calendar/Years.js +++ b/public/js/components/Calendar/Years.js @@ -41,9 +41,11 @@ export default { }, prev() { this.$refs.pane.prev(); + this.$emit('change:offset', { y: -1, m: 0, d: 0 }); }, next() { this.$refs.pane.next(); + this.$emit('change:offset', { y: 1, m: 0, d: 0 }); } }, created() { diff --git a/public/js/components/Calendar/Years/Page.js b/public/js/components/Calendar/Years/Page.js index c6efe0ffc..3d78fc38d 100644 --- a/public/js/components/Calendar/Years/Page.js +++ b/public/js/components/Calendar/Years/Page.js @@ -18,6 +18,13 @@ export default { return [...Array(this.end - this.start).keys()].map(i => i + this.start); } }, + mounted() { + const container = document.getElementById("calendarContainer") + if(container) { + container.style['overflow-y'] = 'scroll' + container.style['overflow-x'] = 'auto' + } + }, template: `
diff --git a/public/js/components/Cis/Mylv/LvMenu.js b/public/js/components/Cis/Mylv/LvMenu.js index d6a84527a..fc6a3a723 100644 --- a/public/js/components/Cis/Mylv/LvMenu.js +++ b/public/js/components/Cis/Mylv/LvMenu.js @@ -56,11 +56,11 @@ export default { }, }, template:/*html*/` -
No Menu available
+
{{$p.t('lehre','lehrveranstaltungsUnavailable')}}
-
+
diff --git a/public/js/components/Cis/Mylv/LvModal.js b/public/js/components/Cis/Mylv/LvModal.js index 4be4e5c79..63ac069c9 100644 --- a/public/js/components/Cis/Mylv/LvModal.js +++ b/public/js/components/Cis/Mylv/LvModal.js @@ -68,7 +68,7 @@ export default { return BsModal.popup.bind(this)(null, options); }, template: /*html*/ ` - + @@ -95,4 +95,4 @@ export default { `, -}; \ No newline at end of file +}; diff --git a/public/js/components/Cis/Mylv/RoomInformation.js b/public/js/components/Cis/Mylv/RoomInformation.js index 10308673c..8a7354305 100644 --- a/public/js/components/Cis/Mylv/RoomInformation.js +++ b/public/js/components/Cis/Mylv/RoomInformation.js @@ -3,25 +3,41 @@ import CalendarDate from "../../../composables/CalendarDate.js"; import LvModal from "../../../components/Cis/Mylv/LvModal.js"; import LvInfo from "../../../components/Cis/Mylv/LvInfo.js" -export default{ +export const DEFAULT_MODE_RAUMINFO = 'Week' + +const RoomInformation = { name: "RoomInformation", props:{ - ort_kurzbz: { - type: String, - required: true, - } + propsViewData: { + type: Object + }, + rowMinHeight: { + type: String, + default: '100px' + }, + eventMaxHeight: { + type: String, + default: '125px' + } }, components: { FhcCalendar, LvModal, LvInfo, }, + provide() { + return { + rowMinHeight: this.rowMinHeight, + eventMaxHeight: this.eventMaxHeight + } + }, data() { return { events: null, + calendarMode: DEFAULT_MODE_RAUMINFO, calendarDate: new CalendarDate(new Date()), currentlySelectedEvent: null, - currentDay: new Date(), + currentDay: this.propsViewData?.focus_date ? new Date(this.propsViewData.focus_date) : new Date(), minimized: false, } @@ -43,6 +59,17 @@ export default{ 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; @@ -50,9 +77,59 @@ export default{ getLvID: function () { this.lv_id = window.location.pathname }, - selectDay: function (day) { + selectDay: function(day){ + const date = day.getFullYear() + "-" + + String(day.getMonth() + 1).padStart(2, "0") + "-" + + String(day.getDate()).padStart(2, "0"); + + this.$router.push({ + name: "RoomInformation", + params: { + mode: this.calendarMode, + focus_date: 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 + ) + + const date = this.currentDay.getFullYear() + "-" + + String(this.currentDay.getMonth() + 1).padStart(2, "0") + "-" + + String(this.currentDay.getDate()).padStart(2, "0"); + + this.$router.push({ + name: "Stundenplan", + 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, + ort_kurzbz: this.propsViewData.ort_kurzbz + } + }) + + this.calendarMode = mode + }, showModal: function (event) { this.currentlySelectedEvent = event; Vue.nextTick(() => { @@ -86,8 +163,8 @@ export default{ // bundles the room_events and the reservierungen together into the this.events array Promise.allSettled([ - this.$fhcApi.factory.stundenplan.getRoomInfo(this.ort_kurzbz, this.monthFirstDay, this.monthLastDay), - this.$fhcApi.factory.stundenplan.getOrtReservierungen(this.ort_kurzbz, this.monthFirstDay, this.monthLastDay) + this.$fhcApi.factory.stundenplan.getRoomInfo(this.propsViewData.ort_kurzbz, this.monthFirstDay, this.monthLastDay), + this.$fhcApi.factory.stundenplan.getOrtReservierungen(this.propsViewData.ort_kurzbz, this.monthFirstDay, this.monthLastDay) ]).then((result) => { let promise_events = []; result.forEach((promise_result) => { @@ -120,10 +197,22 @@ export default{ this.loadEvents(); }, template: /*html*/` -

Room Information {{ ort_kurzbz }}

+

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


- +