diff --git a/application/config/routes.php b/application/config/routes.php index b07497ae7..8acf9b5ea 100644 --- a/application/config/routes.php +++ b/application/config/routes.php @@ -61,8 +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['CisVue'] = 'CisVue/dashboard'; -$route['Cis/Stundenplan/(:any)'] = 'Cis/Stundenplan'; +$route['Cis/Stundenplan/(:any)?'] = 'Cis/Stundenplan/index/$1'; // load routes from extensions $subdir = 'application/config/extensions'; diff --git a/application/controllers/Cis/MyLv.php b/application/controllers/Cis/MyLv.php index aa489d113..49a938553 100644 --- a/application/controllers/Cis/MyLv.php +++ b/application/controllers/Cis/MyLv.php @@ -26,9 +26,12 @@ class MyLv extends Auth_Controller */ public function index() { - $this->load->view('Cis/MyLv'); -// $this->load->view('Cis/CisRouterView'); + $viewData = array( + + ); + + $this->load->view('CisRouterView/CisRouterView.php', ['viewData' => $viewData, 'route' => 'MyLv']); } public function Info($studien_semester,$lvid) diff --git a/application/controllers/Cis/Stundenplan.php b/application/controllers/Cis/Stundenplan.php index 3e4e1a070..a9f89f172 100644 --- a/application/controllers/Cis/Stundenplan.php +++ b/application/controllers/Cis/Stundenplan.php @@ -23,8 +23,13 @@ class Stundenplan extends Auth_Controller /** * @return void */ - public function index() + public function index($lv_id = null) { - $this->load->view('Cis/Stundenplan'); + + $viewData = array( + 'lv_id' => $lv_id + ); + + $this->load->view('CisRouterView/CisRouterView.php', ['viewData' => $viewData, 'route' => 'Stundenplan']); } } diff --git a/application/controllers/Cis4.php b/application/controllers/Cis4.php index ef0113387..c0ca8d503 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('CisRouterView/CisRouterView.php',['viewData' => $viewData]); + $this->load->view('CisRouterView/CisRouterView.php',['viewData' => $viewData, 'route' => 'FhcDashboard']); } } \ No newline at end of file diff --git a/application/views/Cis/MyLv.php b/application/views/Cis/MyLv.php deleted file mode 100644 index 3bac4e294..000000000 --- a/application/views/Cis/MyLv.php +++ /dev/null @@ -1,16 +0,0 @@ - 'MyLv', - 'primevue3' => true, - 'customJSModules' => ['public/js/apps/Cis/MyLv/Student.js'], - 'customCSSs' => ['public/css/components/MyLv.css'] -); - -$this->load->view('templates/CISVUE-Header', $includesArray); -?> - -
- -
- -load->view('templates/CISVUE-Footer', $includesArray); ?> diff --git a/application/views/Cis/Stundenplan.php b/application/views/Cis/Stundenplan.php deleted file mode 100644 index 965707205..000000000 --- a/application/views/Cis/Stundenplan.php +++ /dev/null @@ -1,16 +0,0 @@ - 'Stundenplan', - 'primevue3' => true, - 'customJSModules' => ['public/js/apps/Cis/Stundenplan.js'], - 'customCSSs' => ['public/css/components/calendar.css'] -); - -$this->load->view('templates/CISVUE-Header', $includesArray); -?> - -
- -
- -load->view('templates/CISVUE-Footer', $includesArray); ?> diff --git a/application/views/CisRouterView/CisRouterView.php b/application/views/CisRouterView/CisRouterView.php index 75c7c69b6..d8990a103 100644 --- a/application/views/CisRouterView/CisRouterView.php +++ b/application/views/CisRouterView/CisRouterView.php @@ -12,7 +12,12 @@ $includesArray = array( 'public/css/components/verticalsplit.css', 'public/css/components/searchbar.css', 'public/css/Fhc.css', - 'public/css/components/dashboard.css' + 'public/css/components/dashboard.css', + 'public/css/components/calendar.css', + 'public/css/components/MyLv.css', + 'public/css/components/FilterComponent.css', + 'public/css/components/Profil.css', + 'public/css/components/FormUnderline.css' ), 'customJSs' => array( 'vendor/npm-asset/primevue/accordion/accordion.js', @@ -26,7 +31,7 @@ $includesArray = array( $this->load->view('templates/CISVUE-Header', $includesArray); ?> -
+
>
load->view('templates/CISVUE-Footer', $includesArray); ?> \ No newline at end of file diff --git a/public/js/apps/Cis/Cms.js b/public/js/apps/Cis/Cms.js index c3c60f1bf..e198cfd09 100644 --- a/public/js/apps/Cis/Cms.js +++ b/public/js/apps/Cis/Cms.js @@ -28,43 +28,10 @@ const router = VueRouter.createRouter({ const app = Vue.createApp({ name: 'CmsApp', - data() { - return { - interceptHandler: this.intercept - } - }, components: { CmsNews, CmsContent, }, - methods: { - intercept(e) { - // TODO: maybe a more sophisticated menu link click detection is possible? - if (e.target.tagName === "A" && e.target.pathname?.includes(ciPath) && e.target.pathname.includes('Cms/content')) { - const pathParts = e.target.pathname.split('/').filter(Boolean); - const idString = pathParts[pathParts.length - 1]; - const content_id = idString && !isNaN(Number(idString)) ? idString : null; // only return id if it is a number string since the path might contain invalid elements - - e.preventDefault() // prevents normal browser page load - this.$router.push({ - name: 'Content', - params: { - content_id - } - }) - - } else if(e.target.tagName === "A" && e.target.pathname?.includes(ciPath) && e.target.pathname.includes('Cms/news')) { - //handle news content - - e.preventDefault() // prevents normal browser page load - this.$router.push({ - name: 'News', - - }) - } - - } - }, mounted() { document.querySelectorAll("#cms [data-confirm]").forEach((el) => { el.addEventListener("click", (evt) => { @@ -88,16 +55,13 @@ const app = Vue.createApp({ FHC_JS_DATA_STORAGE_OBJECT.app_root ); }); - document.addEventListener("click", this.interceptHandler, {capture: true, passive: false}) - }, - unmounted() { - document.removeEventListener('click', this.interceptHandler) } }); setScrollbarWidth(); app.use(router); +window.cmsRouter = router; app.use(FhcApi); app.use(primevue.config.default, { zIndex: { overlay: 9999 } }); app.use(Phrasen); diff --git a/public/js/apps/Cis/MyLv/Student.js b/public/js/apps/Cis/MyLv/Student.js deleted file mode 100644 index 70759216a..000000000 --- a/public/js/apps/Cis/MyLv/Student.js +++ /dev/null @@ -1,14 +0,0 @@ -import MylvStudent from "../../../components/Cis/Mylv/Student.js"; -import Phrasen from "../../../plugin/Phrasen.js"; -import {setScrollbarWidth} from "../../../helpers/CssVarCalcHelpers"; - -const app = Vue.createApp({ - name: 'MyLvStudentApp', - components: { - MylvStudent - } -}) - -setScrollbarWidth(); - -app.use(Phrasen).mount('#content'); \ No newline at end of file diff --git a/public/js/apps/Cis/Stundenplan.js b/public/js/apps/Cis/Stundenplan.js deleted file mode 100644 index 198e8a765..000000000 --- a/public/js/apps/Cis/Stundenplan.js +++ /dev/null @@ -1,167 +0,0 @@ -import FhcCalendar from "../../components/Calendar/Calendar.js"; -import Phrasen from "../../plugin/Phrasen.js"; -import CalendarDate from "../../composables/CalendarDate.js"; -import LvModal from "../../components/Cis/Mylv/LvModal.js"; -import LvInfo from "../../components/Cis/Mylv/LvInfo.js" -import LvMenu from "../../components/Cis/Mylv/LvMenu.js" -import Json from "../../helpers/Json.js" - - -const app = Vue.createApp({ - name: 'StundenplanApp', - 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*/` -

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

-
- - - - - - - - - ` -}); -app.use(Phrasen); -app.component('json', Json); -app.mount('#content'); \ No newline at end of file diff --git a/public/js/apps/Dashboard.js b/public/js/apps/Dashboard.js deleted file mode 100644 index 9f42092f4..000000000 --- a/public/js/apps/Dashboard.js +++ /dev/null @@ -1,18 +0,0 @@ -import {CoreNavigationCmpt} from '../components/navigation/Navigation.js'; -import CoreDashboard from '../components/Dashboard/Dashboard.js'; -import FhcApi from '../../plugin/FhcApi.js'; -import Phrasen from '../../plugin/Phrasen.js'; - -const app = Vue.createApp({ - name: 'DashboardApp', - data: () => ({ - appSideMenuEntries: {} - }), - components: { - CoreNavigationCmpt, - CoreDashboard - } -}) -app.use(FhcApi); -app.use(Phrasen); -app.mount('#main'); \ No newline at end of file diff --git a/public/js/apps/Dashboard/Fhc.js b/public/js/apps/Dashboard/Fhc.js index 1748340db..e07b64b1b 100644 --- a/public/js/apps/Dashboard/Fhc.js +++ b/public/js/apps/Dashboard/Fhc.js @@ -1,61 +1,119 @@ 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 {setScrollbarWidth} from "../../helpers/CssVarCalcHelpers"; import Stundenplan from "../../components/Cis/Stundenplan/Stundenplan"; +import MylvStudent from "../../components/Cis/Mylv/Student"; +import Profil from "../../components/Cis/Profil/Profil"; + 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 - } - ] + history: VueRouter.createWebHistory(`/${ciPath}`), + routes: [ + // { + // path: `/Cis/News`, + // name: 'Profil', + // component: Profil, + // props: true + // }, + // { + // path: `/Cis/Profil`, + // name: 'Profil', + // component: Profil, + // props: true + // }, + { + path: `/Cis/MyLv`, + name: 'MyLv', + component: MylvStudent, + props: true + }, + { + path: `/Cis/Stundenplan/:lv_id?`, + name: 'Stundenplan', + component: Stundenplan + }, + { + path: `/`, + name: 'FhcDashboard', + component: FhcDashboard, + props: {dashboard: 'CIS'} + }, + { + path: '/:catchAll(.*)', + redirect: {name: 'FhcDashboard'}, + props: true + } + ] }) -router.beforeEach((from, to) => { - console.log('from', from) - console.log('to', to) +router.beforeEach((to, from) => { + console.log('from', from) + console.log('to', to) + +}) + +router.beforeResolve(async to => { + // TODO: check if necessary viewData params have been provided + // if (to.meta.requiresCamera) { + // try { + // await askForCameraPermission() + // } catch (error) { + // if (error instanceof NotAllowedError) { + // // ... handle the error and then cancel the navigation + // return false + // } else { + // // unexpected error, cancel the navigation and pass the error to the global handler + // throw error + // } + // } + // } }) const app = Vue.createApp({ - name: 'FhcApp', - data: () => ({ - appSideMenuEntries: {} - }), - components: { - 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); - }, + name: 'FhcApp', + data: () => ({ + appSideMenuEntries: {} + }), + components: {}, + methods: { + isInternalRoute(href) { + const internalBase = window.location.origin + return href.startsWith(internalBase); + }, + handleClick(event) { + const target = event.target.closest('a'); + // TODO: handle case of is internalRoute but not defined in vue router + if (target && this.isInternalRoute(target.href)) { + event.preventDefault(); // Prevent browser navigation + const path = new URL(target.href).pathname + const base = this.$router.options.history.base + const route = path.replace(base, '') || '/' + + this.$router.push(route); + } + }, + tryCis4Navigate(e) { + this.$router.push({name: e.detail}); + }, + getInitialRoute() { + const el = document.getElementById('fhccontent') + const r = el?.getAttribute('route') + if (r) return r + return 'FhcDashboard' + } + }, + mounted() { + // window.addEventListener('beforeunload', this.beforeUnloadListener) + document.addEventListener('click', this.handleClick); + window.addEventListener('fhcnavigate', this.tryCis4Navigate); + this.$router.push({name: this.getInitialRoute()}); + }, + beforeUnmount() { + document.removeEventListener('click', this.handleClick); + }, }); setScrollbarWidth(); @@ -63,10 +121,10 @@ app.use(router); window.fhcVueRouter = router app.use(FhcApi); app.use(primevue.config.default, { - zIndex: { - overlay: 9000, - tooltip: 8000 - } + zIndex: { + overlay: 9000, + tooltip: 8000 + } }) app.use(Phrasen); 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 2cbf67dbf..9b834d51a 100644 --- a/public/js/components/Cis/Menu.js +++ b/public/js/components/Cis/Menu.js @@ -2,12 +2,6 @@ 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, @@ -34,7 +28,6 @@ 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 07aa58efd..b04875ad2 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', 'routeMap'], + inject: ['makeParentContentActive', 'setActiveEntry','addUrlCount'], watch:{ highestMatchingUrlCount: function(newValue) { @@ -55,11 +55,8 @@ export default { this.makeParentContentActive(this.entry.content_id); } } - // debugging helpers - console.log(this.entry.titel, newValue ? "open" : "close") - }, }, - computed: { active: function () { if (this.entry.menu_open){ @@ -185,19 +182,7 @@ 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) { @@ -215,7 +200,9 @@ export default {