From f60f735fa84ab77dbb7e15068bc46a0f1e99f676 Mon Sep 17 00:00:00 2001 From: Johann Hoffmann Date: Wed, 15 Jan 2025 14:10:08 +0100 Subject: [PATCH] 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; --- application/controllers/Cis/MyLv.php | 2 + application/controllers/Cis4.php | 2 +- application/controllers/CisVue/Dashboard.php | 4 +- .../views/CisRouterView/CisRouterView.php | 32 ++++ application/views/CisVue/Dashboard.php | 26 --- public/js/apps/Cis.js | 1 - public/js/apps/Dashboard/Fhc.js | 53 +++++- public/js/components/Cis/Menu.js | 7 + public/js/components/Cis/Menu/Entry.js | 19 +- .../components/Cis/Stundenplan/Stundenplan.js | 163 ++++++++++++++++++ public/js/components/Dashboard/Dashboard.js | 2 +- 11 files changed, 274 insertions(+), 37 deletions(-) create mode 100644 application/views/CisRouterView/CisRouterView.php delete mode 100644 application/views/CisVue/Dashboard.php create mode 100644 public/js/components/Cis/Stundenplan/Stundenplan.js diff --git a/application/controllers/Cis/MyLv.php b/application/controllers/Cis/MyLv.php index 08bf843b5..aa489d113 100644 --- a/application/controllers/Cis/MyLv.php +++ b/application/controllers/Cis/MyLv.php @@ -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) diff --git a/application/controllers/Cis4.php b/application/controllers/Cis4.php index 9197fd388..ef0113387 100644 --- a/application/controllers/Cis4.php +++ b/application/controllers/Cis4.php @@ -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]); } } \ No newline at end of file diff --git a/application/controllers/CisVue/Dashboard.php b/application/controllers/CisVue/Dashboard.php index 45838eb76..ee830cb8b 100644 --- a/application/controllers/CisVue/Dashboard.php +++ b/application/controllers/CisVue/Dashboard.php @@ -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]); } } \ No newline at end of file diff --git a/application/views/CisRouterView/CisRouterView.php b/application/views/CisRouterView/CisRouterView.php new file mode 100644 index 000000000..75c7c69b6 --- /dev/null +++ b/application/views/CisRouterView/CisRouterView.php @@ -0,0 +1,32 @@ + '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); +?> +
+ +
+load->view('templates/CISVUE-Footer', $includesArray); ?> \ No newline at end of file diff --git a/application/views/CisVue/Dashboard.php b/application/views/CisVue/Dashboard.php deleted file mode 100644 index f97af8b07..000000000 --- a/application/views/CisVue/Dashboard.php +++ /dev/null @@ -1,26 +0,0 @@ - '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); -?> - -
- -
- -load->view('templates/CISVUE-Footer', $includesArray); ?> - diff --git a/public/js/apps/Cis.js b/public/js/apps/Cis.js index 35aa5c6b2..da658dc47 100644 --- a/public/js/apps/Cis.js +++ b/public/js/apps/Cis.js @@ -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, diff --git a/public/js/apps/Dashboard/Fhc.js b/public/js/apps/Dashboard/Fhc.js index 24459759f..1748340db 100644 --- a/public/js/apps/Dashboard/Fhc.js +++ b/public/js/apps/Dashboard/Fhc.js @@ -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'); \ No newline at end of file +app.mount('#fhccontent'); \ No newline at end of file diff --git a/public/js/components/Cis/Menu.js b/public/js/components/Cis/Menu.js index 9b834d51a..2cbf67dbf 100644 --- a/public/js/components/Cis/Menu.js +++ b/public/js/components/Cis/Menu.js @@ -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, diff --git a/public/js/components/Cis/Menu/Entry.js b/public/js/components/Cis/Menu/Entry.js index 9b9560633..07aa58efd 100644 --- a/public/js/components/Cis/Menu/Entry.js +++ b/public/js/components/Cis/Menu/Entry.js @@ -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 { { + 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*/` +

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

+
+ + + + + + + + + ` +} + +export default Stundenplan \ No newline at end of file diff --git a/public/js/components/Dashboard/Dashboard.js b/public/js/components/Dashboard/Dashboard.js index b96c0f20c..6fb7dfe48 100644 --- a/public/js/components/Dashboard/Dashboard.js +++ b/public/js/components/Dashboard/Dashboard.js @@ -15,7 +15,7 @@ export default { return { sections: [], widgets: null, - viewData: JSON.parse(this.viewDataString), + viewData: JSON.parse(this.viewDataString ?? '{}'), editMode: false } },