mirror of
https://github.com/FH-Complete/FHC-Core.git
synced 2026-06-17 12:09:28 +00:00
FhcApp uses vueRouter4; CisApp checks for global router instance and routes internally as long as a path/routename/component setup is defined, if that is not the case use the provided href link; WIP moving apps like Profil, MyLv etc into components to be navigated by FhcApp;
This commit is contained in:
@@ -27,6 +27,8 @@ class MyLv extends Auth_Controller
|
||||
public function index()
|
||||
{
|
||||
$this->load->view('Cis/MyLv');
|
||||
|
||||
// $this->load->view('Cis/CisRouterView');
|
||||
}
|
||||
|
||||
public function Info($studien_semester,$lvid)
|
||||
|
||||
@@ -36,6 +36,6 @@ class Cis4 extends Auth_Controller
|
||||
'person_id' => $personData->person_id
|
||||
);
|
||||
|
||||
$this->load->view('CisVue/Dashboard.php',['viewData' => $viewData]);
|
||||
$this->load->view('CisRouterView/CisRouterView.php',['viewData' => $viewData]);
|
||||
}
|
||||
}
|
||||
@@ -36,8 +36,8 @@ class Dashboard extends Auth_Controller
|
||||
'name' => $personData->vorname,
|
||||
'person_id' => $personData->person_id
|
||||
);
|
||||
|
||||
$this->load->view('CisVue/Dashboard.php',['viewData' => $viewData]);
|
||||
|
||||
$this->load->view('CisRouterView/CisRouterView.php', ['viewData' => $viewData]);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
$includesArray = array(
|
||||
'title' => 'Cis4',
|
||||
'axios027' => true,
|
||||
'bootstrap5' => true,
|
||||
'fontawesome6' => true,
|
||||
'tabulator5' => true,
|
||||
'vue3' => true,
|
||||
'primevue3' => true,
|
||||
'customCSSs' => array(
|
||||
'public/css/components/verticalsplit.css',
|
||||
'public/css/components/searchbar.css',
|
||||
'public/css/Fhc.css',
|
||||
'public/css/components/dashboard.css'
|
||||
),
|
||||
'customJSs' => array(
|
||||
'vendor/npm-asset/primevue/accordion/accordion.js',
|
||||
'vendor/npm-asset/primevue/accordiontab/accordiontab.js'
|
||||
),
|
||||
'customJSModules' => array(
|
||||
'public/js/apps/Dashboard/Fhc.js'
|
||||
),
|
||||
|
||||
);
|
||||
|
||||
$this->load->view('templates/CISVUE-Header', $includesArray);
|
||||
?>
|
||||
<div id="fhccontent">
|
||||
<router-view view-data-string='<?php echo json_encode($viewData) ?>'></router-view>
|
||||
</div>
|
||||
<?php $this->load->view('templates/CISVUE-Footer', $includesArray); ?>
|
||||
@@ -1,26 +0,0 @@
|
||||
<?php
|
||||
$includesArray = array(
|
||||
'title' => 'Dashboard',
|
||||
'tabulator5'=>true,
|
||||
'primevue3' => true,
|
||||
'customJSModules' => [
|
||||
'public/js/apps/Dashboard/Fhc.js'
|
||||
],
|
||||
'customJSs' => [
|
||||
'vendor/npm-asset/primevue/accordion/accordion.js',
|
||||
'vendor/npm-asset/primevue/accordiontab/accordiontab.js'
|
||||
],
|
||||
'customCSSs' => [
|
||||
'public/css/components/dashboard.css'
|
||||
],
|
||||
);
|
||||
|
||||
$this->load->view('templates/CISVUE-Header', $includesArray);
|
||||
?>
|
||||
|
||||
<div id="content">
|
||||
<fhc-dashboard dashboard="CIS" view-data-string='<?php echo json_encode($viewData) ?>' />
|
||||
</div>
|
||||
|
||||
<?php $this->load->view('templates/CISVUE-Footer', $includesArray); ?>
|
||||
|
||||
@@ -119,7 +119,6 @@ const app = Vue.createApp({
|
||||
}
|
||||
});
|
||||
app.use(FhcApi);
|
||||
//TODO: EVERY View that uses CISVUE-HEADER includes Cis.js and needs to import primevue.js even if they don't use it (might be needed for Vue Router)
|
||||
app.use(primevue.config.default, {
|
||||
zIndex: {
|
||||
overlay: 9000,
|
||||
|
||||
@@ -2,6 +2,38 @@ import FhcDashboard from '../../components/Dashboard/Dashboard.js';
|
||||
import FhcApi from '../../plugin/FhcApi.js';
|
||||
import Phrasen from '../../plugin/Phrasen.js';
|
||||
import { setScrollbarWidth } from "../../helpers/CssVarCalcHelpers";
|
||||
import Stundenplan from "../../components/Cis/Stundenplan/Stundenplan";
|
||||
|
||||
const ciPath = FHC_JS_DATA_STORAGE_OBJECT.app_root.replace(/(https:|)(^|\/\/)(.*?\/)/g, '') + FHC_JS_DATA_STORAGE_OBJECT.ci_router;
|
||||
|
||||
const router = VueRouter.createRouter({
|
||||
history: VueRouter.createWebHistory(`/${ciPath}`),
|
||||
routes: [
|
||||
{
|
||||
path: `/Cis/Stundenplan`,
|
||||
name: 'Stundenplan',
|
||||
component: Stundenplan,
|
||||
props: true
|
||||
},
|
||||
{
|
||||
path: `/`,
|
||||
name: 'FhcDashboard',
|
||||
component: FhcDashboard,
|
||||
props: {dashboard: 'CIS'},
|
||||
alias: ['/Cis4']
|
||||
},
|
||||
{
|
||||
path: '/:catchAll(.*)',
|
||||
redirect: { name: 'FhcDashboard'},
|
||||
props: true
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
router.beforeEach((from, to) => {
|
||||
console.log('from', from)
|
||||
console.log('to', to)
|
||||
})
|
||||
|
||||
const app = Vue.createApp({
|
||||
name: 'FhcApp',
|
||||
@@ -9,11 +41,26 @@ const app = Vue.createApp({
|
||||
appSideMenuEntries: {}
|
||||
}),
|
||||
components: {
|
||||
FhcDashboard
|
||||
}
|
||||
FhcDashboard,
|
||||
Stundenplan
|
||||
},
|
||||
methods: {
|
||||
tryCis4Navigate(e) {
|
||||
this.$router.push({ name: e.detail });
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
window.addEventListener('fhcnavigate', this.tryCis4Navigate);
|
||||
this.$router.push({ name: 'FhcDashboard' });
|
||||
},
|
||||
beforeUnmount() {
|
||||
window.removeEventListener('fhcnavigate', this.tryCis4Navigate);
|
||||
},
|
||||
});
|
||||
|
||||
setScrollbarWidth();
|
||||
app.use(router);
|
||||
window.fhcVueRouter = router
|
||||
app.use(FhcApi);
|
||||
app.use(primevue.config.default, {
|
||||
zIndex: {
|
||||
@@ -22,4 +69,4 @@ app.use(primevue.config.default, {
|
||||
}
|
||||
})
|
||||
app.use(Phrasen);
|
||||
app.mount('#content');
|
||||
app.mount('#fhccontent');
|
||||
@@ -2,6 +2,12 @@ import CisMenuEntry from "./Menu/Entry.js";
|
||||
import FhcSearchbar from "../searchbar/searchbar.js";
|
||||
import CisSprachen from "./Sprachen.js"
|
||||
|
||||
// TODO: maybe get this from global vue router variable
|
||||
const routeMap = [
|
||||
{ routeName: 'FhcDashboard', paths: ['', '/', 'Cis4']},
|
||||
{ routeName: 'Stundenplan', paths: ['Stundenplan']}
|
||||
]
|
||||
|
||||
export default {
|
||||
components: {
|
||||
CisMenuEntry,
|
||||
@@ -28,6 +34,7 @@ export default {
|
||||
},
|
||||
provide(){
|
||||
return{
|
||||
routeMap,
|
||||
setActiveEntry: this.setActiveEntry,
|
||||
addUrlCount: this.addUrlCount,
|
||||
makeParentContentActive: this.makeParentContentActive,
|
||||
|
||||
@@ -15,7 +15,7 @@ export default {
|
||||
urlCount:0,
|
||||
}
|
||||
},
|
||||
inject: ['makeParentContentActive', 'setActiveEntry','addUrlCount'],
|
||||
inject: ['makeParentContentActive', 'setActiveEntry','addUrlCount', 'routeMap'],
|
||||
watch:{
|
||||
highestMatchingUrlCount: function(newValue)
|
||||
{
|
||||
@@ -77,6 +77,7 @@ export default {
|
||||
return '';
|
||||
let xmlDoc = (new DOMParser()).parseFromString(this.entry.content,"text/xml");
|
||||
let url = xmlDoc.getElementsByTagName('url')[0];
|
||||
|
||||
if (!url)
|
||||
return '';
|
||||
// TODO(chris): replace get params
|
||||
@@ -184,7 +185,19 @@ export default {
|
||||
{
|
||||
this.setActiveEntry(this.entry.content_id);
|
||||
}
|
||||
}
|
||||
},
|
||||
handleClick(e) {
|
||||
// TODO: this needs to be done more resilient
|
||||
const linkParts = this.link.split('/')
|
||||
const routePath = linkParts.reverse()[0]
|
||||
const r = this.routeMap.find(route => route.paths.includes(routePath))
|
||||
if(window.fhcVueRouter && r) {
|
||||
const re = new CustomEvent("fhcnavigate", { detail: r.routeName })
|
||||
window.dispatchEvent(re)
|
||||
} else {
|
||||
location.href = this.link
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
if (this.$refs.children) {
|
||||
@@ -224,7 +237,7 @@ export default {
|
||||
</ul>
|
||||
</template>
|
||||
<a v-else
|
||||
:href="link"
|
||||
@click="handleClick"
|
||||
:target="target"
|
||||
:class="{
|
||||
'btn btn-default rounded-0 w-100 text-start': true,
|
||||
|
||||
@@ -0,0 +1,163 @@
|
||||
import FhcCalendar from "../../Calendar/Calendar.js";
|
||||
import CalendarDate from "../../../composables/CalendarDate.js";
|
||||
import LvModal from "../Mylv/LvModal.js";
|
||||
import LvInfo from "../Mylv/LvInfo.js"
|
||||
import LvMenu from "../Mylv/LvMenu.js"
|
||||
|
||||
export const Stundenplan = {
|
||||
name: 'Stundenplan',
|
||||
data() {
|
||||
return {
|
||||
events: null,
|
||||
calendarDate: new CalendarDate(new Date()),
|
||||
currentlySelectedEvent: null,
|
||||
currentDay: new Date(),
|
||||
minimized: false,
|
||||
}
|
||||
},
|
||||
components: {
|
||||
FhcCalendar, LvModal, LvMenu, LvInfo
|
||||
},
|
||||
computed:{
|
||||
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);
|
||||
},
|
||||
weekLastDay: function () {
|
||||
return this.calendarDateToString(this.calendarDate.cdLastDayOfWeek);
|
||||
},
|
||||
monthFirstDay: function () {
|
||||
return this.calendarDateToString(this.calendarDate.cdFirstDayOfCalendarMonth);
|
||||
},
|
||||
monthLastDay: function () {
|
||||
return this.calendarDateToString(this.calendarDate.cdLastDayOfCalendarMonth);
|
||||
},
|
||||
|
||||
},
|
||||
methods:{
|
||||
setSelectedEvent: function (event) {
|
||||
this.currentlySelectedEvent = event;
|
||||
},
|
||||
selectDay: function(day){
|
||||
this.currentDay = day;
|
||||
},
|
||||
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(){
|
||||
Promise.allSettled([
|
||||
this.$fhcApi.factory.stundenplan.getStundenplan(this.monthFirstDay, this.monthLastDay, this.lv_id),
|
||||
this.$fhcApi.factory.stundenplan.getStundenplanReservierungen(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();
|
||||
},
|
||||
template:/*html*/`
|
||||
<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">
|
||||
<template #monthPage="{event,day,isSelected}">
|
||||
<span class="fhc-entry" :class="{'selectedEvent':isSelected}" style="color:white" :style="{'background-color': event.color}">
|
||||
{{event.topic}}
|
||||
</span>
|
||||
</template>
|
||||
<template #weekPage="{event,day,isSelected}">
|
||||
<div @click="showModal(event?.orig)" type="button" :class="{'selectedEvent':isSelected}"
|
||||
class="fhc-entry border border-secondary border d-flex flex-column align-items-center
|
||||
justify-content-evenly h-100" style="max-height: 75px; overflow: auto;">
|
||||
<span>{{event?.orig.topic}}</span>
|
||||
<span v-for="lektor in event?.orig.lektor">{{lektor.kurzbz}}</span>
|
||||
<span>{{event?.orig.ort_kurzbz}}</span>
|
||||
</div>
|
||||
</template>
|
||||
<template #dayPage="{event,day,mobile}">
|
||||
<div @click="mobile? showModal(event?.orig):null" type="button" class="fhc-entry border border-secondary border row m-0 h-100 justify-content-center align-items-center text-center">
|
||||
<div class="col ">
|
||||
<p>Lehrveranstaltung:</p>
|
||||
<p class="m-0">{{event?.orig.topic}}</p>
|
||||
</div>
|
||||
<div class="col ">
|
||||
<p>Lektor:</p>
|
||||
<p class="m-0" v-for="lektor in event?.orig.lektor">{{lektor.kurzbz}}</p>
|
||||
</div>
|
||||
<div class="col ">
|
||||
<p>Ort: </p>
|
||||
<p class="m-0">{{event?.orig.ort_kurzbz}}</p>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #pageMobilContent="{lvMenu}">
|
||||
<h3 >{{$p.t('lvinfo','lehrveranstaltungsinformationen')}}</h3>
|
||||
<div class="w-100">
|
||||
<lv-info :event="currentlySelectedEvent" />
|
||||
</div>
|
||||
<h3 >Lehrveranstaltungs Menu</h3>
|
||||
<lv-menu :containerStyles="['p-0']" :rowStyles="['m-0']" v-show="lvMenu" :menu="lvMenu" />
|
||||
</template>
|
||||
<template #pageMobilContentEmpty >
|
||||
<h3>Keine Lehrveranstaltungen</h3>
|
||||
</template>
|
||||
</fhc-calendar>
|
||||
`
|
||||
}
|
||||
|
||||
export default Stundenplan
|
||||
@@ -15,7 +15,7 @@ export default {
|
||||
return {
|
||||
sections: [],
|
||||
widgets: null,
|
||||
viewData: JSON.parse(this.viewDataString),
|
||||
viewData: JSON.parse(this.viewDataString ?? '{}'),
|
||||
editMode: false
|
||||
}
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user