mirror of
https://github.com/FH-Complete/FHC-Core.git
synced 2026-07-19 16:02:15 +00:00
Merge branch 'feature-25999/C4_cleanup' into merge_FHC4_C4
This commit is contained in:
@@ -61,7 +61,17 @@ $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/null/null/null';
|
||||
$route['Cis/Stundenplan/(:num)'] = 'Cis/Stundenplan/index/null/null/$1';
|
||||
$route['Cis/Stundenplan/(:num)/(:any)'] = 'Cis/Stundenplan/index/null/$2/$1';
|
||||
|
||||
// Specific route (for mode: month|week|day, focusdate, lv_id optional)
|
||||
$route['Cis/Stundenplan/([M|m]onth|[W|w]eek|[D|d]ay)'] = 'Cis/Stundenplan/index/$1';
|
||||
$route['Cis/Stundenplan/([M|m]onth|[W|w]eek|[D|d]ay)(/(:any))?'] = 'Cis/Stundenplan/index/$1/$3';
|
||||
$route['Cis/Stundenplan/([M|m]onth|[W|w]eek|[D|d]ay)(/(:any))?(/(:num))?'] = 'Cis/Stundenplan/index/$1/$3/$5';
|
||||
|
||||
|
||||
|
||||
|
||||
// load routes from extensions
|
||||
$subdir = 'application/config/extensions';
|
||||
|
||||
@@ -23,9 +23,18 @@ class Stundenplan extends Auth_Controller
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function index($lv_id = null)
|
||||
public function index($mode = 'Week', $focus_date = null, $lv_id = null)
|
||||
{
|
||||
// convert string "null" to actual null values -> ci3 reroute fix
|
||||
$mode = ($mode === 'null') ? 'Week' : ucfirst(strtolower($mode));
|
||||
$focus_date = ($focus_date === 'null') ? date('Y-m-d') : $focus_date;
|
||||
$lv_id = ($lv_id === 'null') ? null : $lv_id;
|
||||
|
||||
if($mode) $mode = ucfirst(strtolower($mode));
|
||||
|
||||
$viewData = array(
|
||||
'mode' => $mode,
|
||||
'focus_date' => $focus_date,
|
||||
'lv_id' => $lv_id,
|
||||
'uid'=>getAuthUID(),
|
||||
);
|
||||
|
||||
@@ -403,6 +403,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
|
||||
@@ -478,6 +479,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)
|
||||
);
|
||||
@@ -492,6 +494,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)
|
||||
);
|
||||
|
||||
@@ -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";
|
||||
import Stundenplan from "../../components/Cis/Stundenplan/Stundenplan";
|
||||
import Stundenplan, {DEFAULT_MODE_STUNDENPLAN} from "../../components/Cis/Stundenplan/Stundenplan";
|
||||
import MylvStudent from "../../components/Cis/Mylv/Student";
|
||||
import Profil from "../../components/Cis/Profil/Profil";
|
||||
import CmsNews from "../../components/Cis/Cms/News";
|
||||
import CmsContent from "../../components/Cis/Cms/Content";
|
||||
import Info from "../../components/Cis/Mylv/Semester/Studiengang/Lv/Info";
|
||||
import RoomInformation from "../../components/Cis/Mylv/RoomInformation";
|
||||
import RoomInformation, {DEFAULT_MODE_RAUMINFO} from "../../components/Cis/Mylv/RoomInformation";
|
||||
|
||||
const ciPath = FHC_JS_DATA_STORAGE_OBJECT.app_root.replace(/(https:|)(^|\/\/)(.*?\/)/g, '') + FHC_JS_DATA_STORAGE_OBJECT.ci_router;
|
||||
|
||||
@@ -28,11 +28,62 @@ 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: {
|
||||
ort_kurzbz: to.params.ort_kurzbz
|
||||
},
|
||||
};
|
||||
},
|
||||
},
|
||||
{
|
||||
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 focus_date = 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 +109,67 @@ 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
|
||||
const focus_date = 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,11 +178,19 @@ 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'
|
||||
},
|
||||
};
|
||||
},
|
||||
},
|
||||
]
|
||||
})
|
||||
|
||||
|
||||
@@ -62,6 +62,9 @@ export default {
|
||||
noMonthView: Boolean
|
||||
},
|
||||
watch:{
|
||||
mode(newVal) {
|
||||
this.$emit('change:mode', newVal)
|
||||
},
|
||||
selectedEvent:{
|
||||
handler(newSelectedEvent) {
|
||||
this.$emit('selectedEvent', newSelectedEvent);
|
||||
@@ -161,12 +164,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 +190,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,7 +234,6 @@ export default {
|
||||
}
|
||||
}).observe(this.$refs.container);
|
||||
}
|
||||
|
||||
},
|
||||
unmounted(){
|
||||
CalendarDates.cleanup();
|
||||
|
||||
@@ -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 {
|
||||
<div ref="viewButtons" v-if="!noWeekView && !noMonthView" :class="getHeaderClassSide" class="d-flex justify-content-center justify-content-md-end align-items-center" style="pointer-events: none;">
|
||||
<div style="pointer-events: all;">
|
||||
<div role="group" aria-label="Kalender Modus">
|
||||
<button type="button" :class="{'active':mode_kurzbz === mode}" style="margin-right: 4px;" @click.prevent="$emit('updateMode',mode_kurzbz)" class="btn btn-outline-secondary" v-for="({mode_bezeichnung,icon,condition},mode_kurzbz) in modes">
|
||||
<button type="button" :class="{'active':mode_kurzbz.toLowerCase() === mode.toLowerCase()}" style="margin-right: 4px;" @click.prevent="$emit('updateMode',mode_kurzbz)" class="btn btn-outline-secondary" v-for="({mode_bezeichnung,icon,condition},mode_kurzbz) in modes">
|
||||
<i v-if="condition" class="fa" :class="icon" ></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -273,6 +273,7 @@ export default {
|
||||
}
|
||||
},
|
||||
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) {
|
||||
|
||||
@@ -3,13 +3,14 @@ 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
|
||||
}
|
||||
},
|
||||
components: {
|
||||
FhcCalendar,
|
||||
@@ -19,9 +20,10 @@ export default{
|
||||
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 +45,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 +63,36 @@ 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;
|
||||
},
|
||||
handleChangeMode(mode) {
|
||||
const modeCapitalized = mode.charAt(0).toUpperCase() + mode.slice(1)
|
||||
|
||||
this.$router.push({
|
||||
name: "RoomInformation",
|
||||
params: {
|
||||
mode: modeCapitalized,
|
||||
focus_date: this.currentDay.toISOString().split("T")[0],
|
||||
ort_kurzbz: this.propsViewData.ort_kurzbz
|
||||
}
|
||||
})
|
||||
|
||||
this.calendarMode = mode
|
||||
},
|
||||
showModal: function (event) {
|
||||
this.currentlySelectedEvent = event;
|
||||
Vue.nextTick(() => {
|
||||
@@ -86,8 +126,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 +160,21 @@ export default{
|
||||
this.loadEvents();
|
||||
},
|
||||
template: /*html*/`
|
||||
<h2>Room Information {{ ort_kurzbz }}</h2>
|
||||
<h2>{{ $p.t('rauminfo/rauminfo') }} {{ propsViewData.ort_kurzbz }}</h2>
|
||||
<hr>
|
||||
<lv-modal v-if="currentlySelectedEvent" :showMenu="false" :event="currentlySelectedEvent" ref="lvmodal" />
|
||||
<fhc-calendar @selectedEvent="setSelectedEvent" :initial-date="currentDay" @change:range="updateRange" :events="events" initial-mode="week" show-weeks @select:day="selectDay" v-model:minimized="minimized">
|
||||
<fhc-calendar
|
||||
ref="calendar"
|
||||
@selectedEvent="setSelectedEvent"
|
||||
:initial-date="currentDay"
|
||||
@change:range="updateRange"
|
||||
:events="events"
|
||||
:initial-mode="propsViewData.mode"
|
||||
show-weeks
|
||||
@select:day="selectDay"
|
||||
@change:mode="handleChangeMode"
|
||||
v-model:minimized="minimized"
|
||||
>
|
||||
<template #monthPage="{event,day}">
|
||||
<span >
|
||||
{{event.topic}}
|
||||
@@ -139,15 +190,15 @@ export default{
|
||||
<template #dayPage="{event,day,mobile}">
|
||||
<div @click="mobile? showModal(event?.orig):null" type="button" class="fhc-entry border border-secondary border row h-100 justify-content-center align-items-center text-center">
|
||||
<div class="col ">
|
||||
<p>Lehrveranstaltung:</p>
|
||||
<p>{{ $p.t('lehre/lehrveranstaltung') }}:</p>
|
||||
<p class="m-0">{{event?.orig.topic}}</p>
|
||||
</div>
|
||||
<div class="col ">
|
||||
<p>Lektor:</p>
|
||||
<p>{{ $p.t('lehre/lektor') }}:</p>
|
||||
<p class="m-0" v-for="lektor in event?.orig.lektor">{{lektor.kurzbz}}</p>
|
||||
</div>
|
||||
<div class="col ">
|
||||
<p>Ort: </p>
|
||||
<p>{{ $p.t('profil/Ort') }}: </p>
|
||||
<p class="m-0">{{event?.orig.ort_kurzbz}}</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -155,12 +206,14 @@ export default{
|
||||
<template #pageMobilContent>
|
||||
<h3 >{{$p.t('lvinfo','lehrveranstaltungsinformationen')}}</h3>
|
||||
<div class="w-100">
|
||||
<lv-info :event="currentlySelectedEvent" />
|
||||
<lv-info :event="currentlySelectedEvent" />
|
||||
</div>
|
||||
</template>
|
||||
<template #pageMobilContentEmpty >
|
||||
<h3>Keine Raum Reservierung</h3>
|
||||
<h3>{{$p.t('rauminfo','keineRaumReservierung')}}</h3>
|
||||
</template>
|
||||
</fhc-calendar>
|
||||
`,
|
||||
};
|
||||
};
|
||||
|
||||
export default RoomInformation
|
||||
@@ -177,7 +177,7 @@ export default {
|
||||
:class="{'link-dark':menuItem.c4_link, 'unavailable':!menuItem.c4_link, 'dropdown-toggle':menuItem.c4_moodle_links?.length }"
|
||||
:target="menuItem.c4_target"
|
||||
:href="c4_link(menuItem) ? c4_link(menuItem) : null">
|
||||
{{menuItem.name}}
|
||||
{{ menuItem.phrase ? $p.t(menuItem.phrase) : menuItem.name}}
|
||||
</a>
|
||||
</div>
|
||||
<ul v-if="menuItem.c4_moodle_links?.length" class="dropdown-menu p-0" :aria-labelledby="'moodle_links_'+lehrveranstaltung_id">
|
||||
|
||||
@@ -4,25 +4,28 @@ import LvModal from "../Mylv/LvModal.js";
|
||||
import LvInfo from "../Mylv/LvInfo.js"
|
||||
import LvMenu from "../Mylv/LvMenu.js"
|
||||
|
||||
export const Stundenplan = {
|
||||
export const DEFAULT_MODE_STUNDENPLAN = 'Week'
|
||||
|
||||
const Stundenplan = {
|
||||
name: 'Stundenplan',
|
||||
data() {
|
||||
return {
|
||||
events: null,
|
||||
calendarMode: DEFAULT_MODE_STUNDENPLAN,
|
||||
calendarDate: new CalendarDate(new Date()),
|
||||
eventCalendarDate: new CalendarDate(new Date()),
|
||||
currentlySelectedEvent: null,
|
||||
currentDay: new Date(),
|
||||
currentDay: this.propsViewData?.focus_date ? new Date(this.propsViewData.focus_date) : new Date(),
|
||||
minimized: false,
|
||||
studiensemester_kurzbz:null,
|
||||
studiensemester_start:null,
|
||||
studiensemester_ende:null,
|
||||
uid:null,
|
||||
studiensemester_kurzbz: null,
|
||||
studiensemester_start: null,
|
||||
studiensemester_ende: null,
|
||||
uid: null
|
||||
}
|
||||
},
|
||||
props: [
|
||||
"viewData",
|
||||
],
|
||||
props: {
|
||||
propsViewData: Object
|
||||
},
|
||||
watch: {
|
||||
weekFirstDay: {
|
||||
handler: async function (newValue) {
|
||||
@@ -33,6 +36,16 @@ export const Stundenplan = {
|
||||
this.studiensemester_ende = ende;
|
||||
},
|
||||
immediate: true,
|
||||
},
|
||||
// forward/backward on history entries happening in stundenplan
|
||||
'propsViewData.lv_id'(newVal) {
|
||||
// relevant if lv_id 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)
|
||||
}
|
||||
},
|
||||
components: {
|
||||
@@ -49,11 +62,6 @@ export const Stundenplan = {
|
||||
let download_link = (format, version = "", target = "") => `${FHC_JS_DATA_STORAGE_OBJECT.app_root}cis/private/lvplan/stpl_kalender.php?type=student&pers_uid=${this.uid}&begin=${start}&ende=${ende}&format=${format}${version ? '&version=' + version : ''}${target ? '&target=' + target : ''}`;
|
||||
return [{ title: "excel", icon: 'fa-solid fa-file-excel', link: download_link('excel') }, { title: "csv", icon: 'fa-solid fa-file-csv', link: download_link('csv') }, { title: "ical1", icon: 'fa-regular fa-calendar', link: download_link('ical', '1', 'ical') }, { title: "ical2", icon: 'fa-regular fa-calendar', link: download_link('ical', '2', 'ical') }];
|
||||
},
|
||||
lv_id() { // computed so we can theoretically change path/lva selection and reload without page refresh
|
||||
const pathParts = window.location.pathname.split('/').filter(Boolean);
|
||||
const id = pathParts[pathParts.length - 1];
|
||||
return id && !isNaN(Number(id)) ? id : null; // only return id if it is a number string since the path might contain invalid elements
|
||||
},
|
||||
weekFirstDay: function () {
|
||||
return this.calendarDateToString(this.calendarDate.cdFirstDayOfWeek);
|
||||
},
|
||||
@@ -66,7 +74,6 @@ export const Stundenplan = {
|
||||
monthLastDay: function () {
|
||||
return this.calendarDateToString(this.eventCalendarDate.cdLastDayOfCalendarMonth);
|
||||
},
|
||||
|
||||
},
|
||||
methods:{
|
||||
fetchStudiensemesterDetails: async function (date) {
|
||||
@@ -84,8 +91,35 @@ export const Stundenplan = {
|
||||
this.currentlySelectedEvent = event;
|
||||
},
|
||||
selectDay: function(day){
|
||||
const date = day.getFullYear() + "-" +
|
||||
String(day.getMonth() + 1).padStart(2, "0") + "-" +
|
||||
String(day.getDate()).padStart(2, "0");
|
||||
|
||||
this.$router.push({
|
||||
name: "Stundenplan",
|
||||
params: {
|
||||
mode: this.calendarMode,
|
||||
focus_date: date,
|
||||
lv_id: this.propsViewData?.lv_id || null
|
||||
}
|
||||
})
|
||||
|
||||
this.currentDay = day;
|
||||
},
|
||||
handleChangeMode(mode) {
|
||||
const modeCapitalized = mode.charAt(0).toUpperCase() + mode.slice(1)
|
||||
|
||||
this.$router.push({
|
||||
name: "Stundenplan",
|
||||
params: {
|
||||
mode: modeCapitalized,
|
||||
focus_date: this.currentDay.toISOString().split("T")[0],
|
||||
lv_id: this.propsViewData?.lv_id ?? null
|
||||
}
|
||||
})
|
||||
|
||||
this.calendarMode = mode
|
||||
},
|
||||
showModal: function(event){
|
||||
this.currentlySelectedEvent = event;
|
||||
Vue.nextTick(() => {
|
||||
@@ -117,7 +151,7 @@ export const Stundenplan = {
|
||||
},
|
||||
loadEvents: function(){
|
||||
Promise.allSettled([
|
||||
this.$fhcApi.factory.stundenplan.getStundenplan(this.monthFirstDay, this.monthLastDay, this.viewData.lv_id),
|
||||
this.$fhcApi.factory.stundenplan.getStundenplan(this.monthFirstDay, this.monthLastDay, this.propsViewData.lv_id),
|
||||
this.$fhcApi.factory.stundenplan.getStundenplanReservierungen(this.monthFirstDay, this.monthLastDay)
|
||||
]).then((result) => {
|
||||
let promise_events = [];
|
||||
@@ -163,7 +197,18 @@ export const Stundenplan = {
|
||||
<h2>{{$p.t('lehre/stundenplan')}}</h2>
|
||||
<hr>
|
||||
<lv-modal v-if="currentlySelectedEvent" :event="currentlySelectedEvent" ref="lvmodal" />
|
||||
<fhc-calendar @selectedEvent="setSelectedEvent" :initial-date="currentDay" @change:range="updateRange" :events="events" initial-mode="week" show-weeks @select:day="selectDay" v-model:minimized="minimized">
|
||||
<fhc-calendar
|
||||
ref="calendar"
|
||||
@selectedEvent="setSelectedEvent"
|
||||
:initial-date="currentDay"
|
||||
@change:range="updateRange"
|
||||
:events="events"
|
||||
:initial-mode="propsViewData.mode"
|
||||
show-weeks
|
||||
@select:day="selectDay"
|
||||
@change:mode="handleChangeMode"
|
||||
v-model:minimized="minimized"
|
||||
>
|
||||
<template #calendarDownloads>
|
||||
<div v-for="{title,icon,link} in downloadLinks">
|
||||
<a :href="link" :title="title" class="py-1 px-2 m-1 btn btn-outline-secondary">
|
||||
@@ -230,8 +275,7 @@ export const Stundenplan = {
|
||||
<template #pageMobilContentEmpty >
|
||||
<h3>{{ $p.t('lehre/noLvFound') }}</h3>
|
||||
</template>
|
||||
</fhc-calendar>
|
||||
`
|
||||
</fhc-calendar>`
|
||||
}
|
||||
|
||||
export default Stundenplan
|
||||
@@ -159,11 +159,11 @@ export default {
|
||||
template: /*html*/ `
|
||||
<div class="widgets-url w-100 h-100 overflow-scroll" style="padding: 1rem 1rem;">
|
||||
<div class="d-flex flex-column justify-content-between">
|
||||
<!-- todo: widgetTag ?? -->
|
||||
<button v-if="editModeIsActive" class="btn btn-outline-secondary btn-sm w-100 mt-2" @click="openCreateModal" type="button">{{$p.t('bookmark','newLink')}}</button>
|
||||
|
||||
<template v-if="shared">
|
||||
|
||||
<template v-if="!emptyBookmarks">
|
||||
<button v-if="editModeIsActive" class="btn btn-outline-secondary btn-sm w-100 mt-2" @click="openCreateModal" type="button">{{$p.t('bookmark','newLink')}}</button>
|
||||
<div v-for="link in shared" :key="link.id" class="d-flex mt-2">
|
||||
<a target="_blank" :href="link.url">
|
||||
<i class="fa fa-solid fa-arrow-up-right-from-square me-1"></i>{{ link.title }}
|
||||
@@ -208,7 +208,7 @@ export default {
|
||||
<form-input id="editUrl" v-model="url_input" name="url"></form-input>
|
||||
</template>
|
||||
<template #footer>
|
||||
<button @click="editBookmark" class="btn btn-primary">{{$p.t('bookmark','editLink')}}</button>
|
||||
<button @click="editBookmark" class="btn btn-primary">{{$p.t('bookmark','saveLink')}}</button>
|
||||
</template>
|
||||
</bs-modal>
|
||||
</core-form>
|
||||
|
||||
@@ -20284,6 +20284,46 @@ array(
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'rauminfo',
|
||||
'phrase' => 'rauminfo',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => "Raum Informationen",
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => "Room Information",
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'rauminfo',
|
||||
'phrase' => 'keineRaumReservierung',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => "Keine Raum Reservierungen gefunden",
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => "No Room Reservations found",
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'lehre',
|
||||
|
||||
Reference in New Issue
Block a user