diff --git a/application/config/routes.php b/application/config/routes.php index 923503082..af39aa8fc 100644 --- a/application/config/routes.php +++ b/application/config/routes.php @@ -72,6 +72,17 @@ $route['Abgabetool/Student'] = 'Cis/Abgabetool/Student'; $route['Abgabetool/Student/(:any)'] = 'Cis/Abgabetool/Student/$1'; $route['Abgabetool/Deadlines'] = 'Cis/Abgabetool/Deadlines'; +// Studierendenverwaltung App Routes +$route['studvw'] = 'studentenverwaltung/index'; +$route['studvw/.*'] = 'studentenverwaltung/index'; +// Old routes +$route['studentenverwaltung'] = 'redirect/301/studvw'; +$route['studentenverwaltung/(:any)'] = 'redirect/301/studvw/stdsem/$1'; +$route['studentenverwaltung/(:any)/(prestudent|student|person|search)/(:any)'] = 'redirect/301/studvw/stdsem/$1/$2/$3'; +$route['studentenverwaltung/(:any)/prestudent/(:any)/tab/:any'] = 'redirect/301/studvw/stdsem/$1/prestudent/$2'; +$route['studentenverwaltung/(:any)/search/(:any)/(:any)'] = 'redirect/301/studvw/stdsem/$1/search/$2/$3'; +$route['studentenverwaltung/(:any)/(:any)'] = 'redirect/301/studvw/stdsem/$1/stg/$2'; + // Studierendenverwaltung List Routes $route['api/frontend/v1/treemenudata/stv/stdsem/(:any)/inout/1/incoming/1'] = 'api/frontend/v1/stv/students/getIncoming/$1'; $route['api/frontend/v1/treemenudata/stv/stdsem/(:any)/inout/1/outgoing/1'] = 'api/frontend/v1/stv/students/getOutgoing/$1'; diff --git a/application/controllers/Redirect.php b/application/controllers/Redirect.php new file mode 100644 index 000000000..f4a9f4cd7 --- /dev/null +++ b/application/controllers/Redirect.php @@ -0,0 +1,44 @@ +. + */ + +if (! defined('BASEPATH')) exit('No direct script access allowed'); + +/** + * This controller redirects urls to another location. This is mainly used + * with the $routes config + */ +class Redirect extends CI_Controller +{ + public function __construct() + { + parent::__construct(); + } + + /** + * Main function to handle all redirects. + * + * @param string $method - the redirect code (30x) + * @param array $params - the url to redirect to + * + * @return void + */ + public function _remap($method, $params) + { + redirect($params, 'location', $method); + } +} diff --git a/public/js/apps/Studentenverwaltung.js b/public/js/apps/Studentenverwaltung.js index 47490bfdd..f977f5044 100644 --- a/public/js/apps/Studentenverwaltung.js +++ b/public/js/apps/Studentenverwaltung.js @@ -24,167 +24,26 @@ import PluginsPhrasen from "../plugins/Phrasen.js"; 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(), + history: VueRouter.createWebHistory('/' + ciPath), routes: [ { name: 'index', - path: `/${ciPath}/studentenverwaltung`, - component: FhcStudentenverwaltung - }, - { - name: 'studiensemester', - path: `/${ciPath}/studentenverwaltung/:studiensemester_kurzbz`, + path: '/studvw', component: FhcStudentenverwaltung, - props: (route) => { - return { - url_studiensemester_kurzbz: route.params.studiensemester_kurzbz - }; - }, - beforeEnter: (to, from, next) => { - const isSemester = /^[WS]S\d{4}$/.test(to.params.studiensemester_kurzbz); - if (!isSemester) { - return next({name: 'index'}); + children: [ + { + name: 'stdsem', + path: 'stdsem/:stdsem', + children: [ + { name: 'search', path: 'search/:query' }, + { name: 'searchtypes', path: 'search/:types/:query' }, + { name: 'prestudent', path: 'prestudent/:prestudent_id' }, + { name: 'student', path: 'student/:student_uid' }, + { name: 'person', path: 'person/:person_id' }, + { name: 'treemenu', path: ':treemenu(.*)*' } + ] } - next(); - } - }, - { - name: 'studiengang', - path: `/${ciPath}/studentenverwaltung/:studiensemester_kurzbz/:studiengang`, - component: FhcStudentenverwaltung, - props: (route) => { - return { - url_studiensemester_kurzbz: route.params.studiensemester_kurzbz, - url_studiengang: route.params.studiengang, - }; - }, - beforeEnter: (to, from, next) => { - const isSemester = /^[WS]S\d{4}$/.test(to.params.studiensemester_kurzbz); - if (!isSemester) { - return next({name: 'index'}); - } - const isStudiengang = /^[A-Z]{3}/.test(to.params.studiengang); - if (!isStudiengang) { - return next({ - name: 'studiensemester', - params: { - studiensemester_kurzbz: to.params.studiensemester_kurzbz - } - }); - } - next(); - } - }, - { - path: `/${ciPath}/studentenverwaltung/:studiensemester_kurzbz/prestudent/:prestudent_id`, - component: FhcStudentenverwaltung, - props: (route) => { - return { - url_studiensemester_kurzbz: route.params.studiensemester_kurzbz, - url_mode: 'prestudent', - url_prestudent_id: route.params.prestudent_id - }; - }, - beforeEnter: (to, from, next) => { - const isSemester = /^[WS]S\d{4}$/.test(to.params.studiensemester_kurzbz); - if (!isSemester) { - return next({name: 'index'}); - } - next(); - } - }, - { - path: `/${ciPath}/studentenverwaltung/:studiensemester_kurzbz/prestudent/:prestudent_id/:tab`, - component: FhcStudentenverwaltung, - props: (route) => { - return { - url_studiensemester_kurzbz: route.params.studiensemester_kurzbz, - url_mode: 'prestudent', - url_prestudent_id: route.params.prestudent_id, - url_tab: route.params.tab - }; - }, - beforeEnter: (to, from, next) => { - const isSemester = /^[WS]S\d{4}$/.test(to.params.studiensemester_kurzbz); - if (!isSemester) { - return next({name: 'index'}); - } - next(); - } - }, - { - path: `/${ciPath}/studentenverwaltung/:studiensemester_kurzbz/student/:id`, - component: FhcStudentenverwaltung, - props: (route) => { - return { - url_studiensemester_kurzbz: route.params.studiensemester_kurzbz, - url_mode: 'student', - url_student_id: route.params.id - }; - }, - beforeEnter: (to, from, next) => { - const isSemester = /^[WS]S\d{4}$/.test(to.params.studiensemester_kurzbz); - if (!isSemester) { - return next({name: 'index'}); - } - next(); - } - }, - { - path: `/${ciPath}/studentenverwaltung/:studiensemester_kurzbz/person/:person_id`, - component: FhcStudentenverwaltung, - props: (route) => { - return { - url_studiensemester_kurzbz: route.params.studiensemester_kurzbz, - url_mode: 'person', - url_prestudent_id: route.params.person_id - }; - }, - beforeEnter: (to, from, next) => { - const isSemester = /^[WS]S\d{4}$/.test(to.params.studiensemester_kurzbz); - if (!isSemester) { - return next({name: 'index'}); - } - next(); - } - }, - { - name: 'search', - path: `/${ciPath}/studentenverwaltung/:studiensemester_kurzbz/search/:searchstr`, - component: FhcStudentenverwaltung, - props(route) { - return { - url_studiensemester_kurzbz: route.params.studiensemester_kurzbz, - url_mode: 'search', - url_prestudent_id: route.params.searchstr - }; - }, - beforeEnter(to, from, next) { - const isSemester = /^[WS]S\d{4}$/.test(to.params.studiensemester_kurzbz); - if (!isSemester) { - return next({name: 'index'}); - } - next(); - } - }, - { - name: 'search_w_types', - path: `/${ciPath}/studentenverwaltung/:studiensemester_kurzbz/search/:types/:searchstr`, - component: FhcStudentenverwaltung, - props(route) { - return { - url_studiensemester_kurzbz: route.params.studiensemester_kurzbz, - url_mode: 'search', - url_prestudent_id: route.params.type + '/' + route.params.searchstr - }; - }, - beforeEnter(to, from, next) { - const isSemester = /^[WS]S\d{4}$/.test(to.params.studiensemester_kurzbz); - if (!isSemester) { - return next({name: 'index'}); - } - next(); - } + ] }, { path: '/:pathMatch(.*)*', @@ -197,11 +56,16 @@ const router = VueRouter.createRouter({ router.afterEach((to, from, failure) => { let title = 'Studierendenverwaltung FH-Complete'; - if (to.params.studiengang) { - title = to.params.studiengang + ' ' + title; + if (to.params.treemenu) { + const index = to.params.treemenu.findIndex( + (e, i) => i%2 == 0 && e == 'stg' + ); + if (index >= 0) { + title = to.params.treemenu[index + 1].toUpperCase() + ' ' + title; + } } - if (to.params.studiensemester_kurzbz) { - title = to.params.studiensemester_kurzbz + ' ' + title; + if (to.params.stdsem) { + title = to.params.stdsem.toUpperCase() + ' ' + title; } document.title = title; }); diff --git a/public/js/components/Base/Treemenu.js b/public/js/components/Base/Treemenu.js index 465b91ac2..7347260e0 100644 --- a/public/js/components/Base/Treemenu.js +++ b/public/js/components/Base/Treemenu.js @@ -23,7 +23,7 @@ export default { required: true, }, preselectedKey: { - type: String, + type: Array, default: null } }, @@ -156,18 +156,17 @@ export default { }, async setPreselection() { - if (!this.preselectedKey) + if (!this.preselectedKey || !this.preselectedKey.length) { this.selectedKey = null; return; } - let rawKey = this.preselectedKey - - if (!rawKey || typeof rawKey !== 'string') + if (!this.preselectedKey || !Array.isArray(this.preselectedKey)) return; - const parts = this.preselectedKey.split('/'); + // [1, 2, 3, 4, ...] => ['1-2', '3-4', ...] + const parts = this.preselectedKey.reduce((r, c, i, a) => (i%2 && r.push(a[i-1] + '-' + c), r), []); let currentKey = parts[0]; let currentNode = this.findNodeByKey(currentKey); diff --git a/public/js/components/Stv/Studentenverwaltung.js b/public/js/components/Stv/Studentenverwaltung.js index 382041224..35933f1e3 100644 --- a/public/js/components/Stv/Studentenverwaltung.js +++ b/public/js/components/Stv/Studentenverwaltung.js @@ -53,12 +53,7 @@ export default { cisRoot: String, avatarUrl: String, logoutUrl: String, - activeAddons: String, // semicolon separated list of active addons - url_studiensemester_kurzbz: String, - url_mode: String, - url_prestudent_id: String, - url_tab: String, - url_studiengang: String + activeAddons: String // semicolon separated list of active addons }, provide() { return { @@ -141,7 +136,6 @@ export default { mergeResults: 'person' }, studiengangKz: undefined, - studiengangKuerzel: '', studiensemesterKurzbz: this.defaultSemester, selected_semester: undefined, selected_orgform: undefined, @@ -193,34 +187,52 @@ export default { } return extraItems; + }, + listEndpoint() { + if (['index', 'stdsem'].includes(this.$route.name)) + return null; + + if (this.$route.params.query) { + return ApiStv.students.search({ + searchstr: this.$route.params.query, + types: this.$route.params.types?.split('+') || [] + }, this.$route.params.stdsem); + } + + let url = 'stdsem/' + this.$route.params.stdsem + '/'; + + if (this.$route.params.treemenu) { + url += this.$route.params.treemenu.join('/'); + return ApiTreemenu.data('stv', url); + } + + const paramName = Object.keys(this.$route.params).find(k => k != 'stdsem'); + if (paramName) { + url += this.$route.name + '/' + this.$route.params[paramName]; + return ApiTreemenu.data('stv', url); + } + + return null; + }, + studiengangKuerzel() { + if (!this.lists?.stgs) + return ''; + + const stg = this.lists.stgs + .find(stg => stg.studiengang_kz == this.studiengangKz); + + if (stg) + return (stg.typ + stg.kurzbz).toUpperCase(); + + return ''; } }, watch: { - 'url_studiensemester_kurzbz': function (newVal, oldVal) { - if (newVal !== oldVal) { - this.studiensemesterKurzbz = newVal; - if(this.$route.name === 'search') - { - this.handleSearchUrl(); - } - else - { - this.$refs.stvList.updateUrl(); - this.$refs.details.reload(); - } + listEndpoint(n, o) { + if (n != o) { + this.$refs.stvList.updateUrl(n || []); } }, - 'url_studiengang': function (newVal, oldVal) { - if (newVal !== oldVal) { - this.checkUrlStudiengang(); - } - }, - 'url_mode': function () { - this.handlePersonUrl(); - }, - url_prestudent_id() { - this.handlePersonUrl(); - }, 'appconfig.font_size'() { // add to html class const classList = Object.keys(this.$refs.config.setup.font_size.options); @@ -273,161 +285,66 @@ export default { ); }, onSelectVerband({ link, studiengang_kz, semester, orgform_kurzbz }) { - let urlpath = String(link); - /*if (!urlpath.match(/\/prestudent/)) - { - urlpath = 'CURRENT_SEMESTER' + '/' + urlpath; - }*/ - urlpath = 'stdsem/' + this.studiensemesterKurzbz + '/' + urlpath; - this.$refs.stvList.updateUrl(ApiTreemenu.data('stv', urlpath)); - this.studiengangKz = studiengang_kz; this.selected_semester = semester; this.selected_orgform = orgform_kurzbz; - const stg = this.lists.stgs.find((element) => { - return (element.studiengang_kz === this.studiengangKz); - }); - if (stg) - { - this.studiengangKuerzel = (stg.typ + stg.kurzbz).toUpperCase() - this.$router.push({ - name: 'studiengang', - params: { - studiensemester_kurzbz: this.studiensemesterKurzbz, - studiengang: this.studiengangKuerzel - } - }); - } else - { - this.studiengangKuerzel = ''; - this.$router.push({ - name: 'studiensemester', - params: { - studiensemester_kurzbz: this.studiensemesterKurzbz - } - }); - } - }, - studiensemesterChanged(v) { - this.studiensemesterKurzbz = v; this.$router.push({ + name: 'treemenu', params: { - studiensemester_kurzbz: v + treemenu: link.split('/') } }); }, + studiensemesterChanged(stdsem) { + if (!stdsem) { + // no valid studiensemester in url + this.$router.replace({ + params: { + stdsem: this.defaultSemester.toLowerCase() + } + }); + return; + } + if (stdsem.toLowerCase() != this.studiensemesterKurzbz?.toLowerCase()) { + this.$router.push({ + params: { + stdsem: stdsem.toLowerCase() + } + }); + } + this.studiensemesterKurzbz = stdsem; + }, reloadList() { this.$refs.stvList.reload(); }, searchfunction(params, config) { return this.$api.call(ApiSearchbar.searchStv(params), config); }, - handlePersonUrl() { - if (this.$route.params.id) { - this.$refs.stvList.updateUrl( - ApiStv.students.uid(this.$route.params.id, 'CURRENT_SEMESTER'), - true - ); - } else if (this.$route.params.prestudent_id) { - this.$refs.stvList.updateUrl( - ApiStv.students.prestudent(this.$route.params.prestudent_id, 'CURRENT_SEMESTER'), - true - ); - } else if (this.$route.params.person_id) { - this.$refs.stvList.updateUrl( - ApiStv.students.person(this.$route.params.person_id, 'CURRENT_SEMESTER'), - true - ); - } else if (this.$route.params.searchstr) { - this.handleSearchUrl(); - } - else - { - this.clearTabulator(); - } - }, - handleSearchUrl() { - const searchsettings = { - searchstr: this.$route.params.searchstr, - types: this.$route.params.types?.split('+') || [] - }; - - // init into student list - this.$refs.stvList.updateUrl( - ApiStv.students.search(searchsettings, this.studiensemesterKurzbz) - ); - - // init into searchbar - this.$refs.searchbar.searchsettings.searchstr = searchsettings.searchstr; - this.$refs.searchbar.searchsettings.types = searchsettings.types; - this.$nextTick(this.blurSearchbar); - }, - clearTabulator() { - if(['index', 'studiensemester'].includes(this.$route.name)) - { - if(this.$refs?.stvList?.$refs?.table?.tabulator) - { - this.$refs.stvList.$refs.table.tabulator.setData([]); - } - } - }, - checkUrlStudiengang() { - if (this.url_studiengang) { - const stg = this.lists.stgs.find((element) => { - const kuerzel = (element.typ + element.kurzbz).toUpperCase(); - return (this.url_studiengang === kuerzel); - }); - if (stg) { - this.studiengangKz = stg.studiengang_kz; - this.studiengangKuerzel = (stg.typ + stg.kurzbz).toUpperCase(); - } else { - this.$router.replace({ - name: 'studiensemester', - params: { - studiensemester_kurzbz: this.studiensemesterKurzbz - } - }); - } - } - else - { - this.studiengangKz = undefined; - this.studiengangKuerzel = ''; - this.clearTabulator(); - } - }, onSearch(e) { - this.deleteCustomFilter(); const searchsettings = { ...this.$refs.searchbar.searchsettings }; + if (searchsettings.searchstr.length >= 2) { - this.blurSearchbar(); + this.deleteCustomFilter(); if (!searchsettings.types.length || searchsettings.types.length == this.$refs.searchbar.types.length) { this.$router.push({ name: 'search', params: { - studiensemester_kurzbz: this.studiensemesterKurzbz, - searchstr: searchsettings.searchstr + query: searchsettings.searchstr } }); } else { this.$router.push({ - name: 'search_w_types', + name: 'searchtypes', params: { - studiensemester_kurzbz: this.studiensemesterKurzbz, - searchstr: searchsettings.searchstr, + query: searchsettings.searchstr, types: searchsettings.types.join('+') } }); } } }, - blurSearchbar() { - this.$refs.searchbar.$refs.input.blur(); - this.$refs.searchbar.abort(); - this.$refs.searchbar.hideresult(); - }, handleCustomFilter(filter){ this.filter = filter; }, @@ -436,15 +353,13 @@ export default { } }, created() { - if (!this.url_studiensemester_kurzbz) { + if (!this.$route.params.stdsem) { this.$router.replace({ - name: 'studiensemester', + name: 'stdsem', params: { - studiensemester_kurzbz: this.defaultSemester + stdsem: this.defaultSemester.toLowerCase() } }); - } else { - this.studiensemesterKurzbz = this.url_studiensemester_kurzbz; } this.$api @@ -480,7 +395,6 @@ export default { .then(result => { this.lists.stgs = result.data; this.lists.active_stgs = this.lists.stgs.filter(stg => stg.aktiv); - this.checkUrlStudiengang(); }) .catch(this.$fhcAlert.handleSystemError); @@ -507,7 +421,8 @@ export default { .catch(this.$fhcAlert.handleSystemError); }, mounted() { - this.handlePersonUrl(); + if (this.listEndpoint) + this.$refs.stvList.updateUrl(this.listEndpoint); }, template: /* html */`
@@ -638,13 +553,13 @@ export default {
- - + +