mirror of
https://github.com/FH-Complete/FHC-Core.git
synced 2026-06-01 20:29:29 +00:00
Compare commits
306 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| fa91e204f0 | |||
| 23506430b1 | |||
| fa58635a22 | |||
| 7f630f24d5 | |||
| c0c57ba378 | |||
| 449537ef77 | |||
| d16120f650 | |||
| 12d8c8447b | |||
| 905cd46942 | |||
| 625ffe12ce | |||
| cb7a0f7669 | |||
| 68d97a5e97 | |||
| d27071528f | |||
| 17772c3738 | |||
| 772f35c6ba | |||
| 4b22f939b5 | |||
| 7b46a15752 | |||
| bf3d6275d4 | |||
| dd2fd6421b | |||
| 3b99a14b47 | |||
| 1d3d067b44 | |||
| d3ceed32c6 | |||
| 780890fbdd | |||
| 72aed76857 | |||
| 229882e8d8 | |||
| 1e184d36fc | |||
| 90e933de00 | |||
| 14372a6fce | |||
| bbb4f8a01c | |||
| 80306dadf7 | |||
| adba14f6e7 | |||
| 57e901be27 | |||
| d38641e312 | |||
| fdbb93a5c5 | |||
| b7e48633ab | |||
| 04dc1eb07b | |||
| 50b229090b | |||
| 86dc002fa6 | |||
| 2d27a998c4 | |||
| 090e535466 | |||
| c4d35181db | |||
| 453fc209b8 | |||
| 0ac6ef4599 | |||
| 7f13c128f1 | |||
| cb60ddcc94 | |||
| bd4ced9559 | |||
| a04d2acb86 | |||
| de2aabf00b | |||
| 685fc69e5d | |||
| 58a921b500 | |||
| af8814468f | |||
| c8a6e2f7cd | |||
| 2227c3ecf1 | |||
| c7526bd0d9 | |||
| 791f69b509 | |||
| 5592b69dc0 | |||
| fc1303affd | |||
| 863aaf62ec | |||
| 293352ac3c | |||
| 736e91224e | |||
| 9bc564dbf9 | |||
| 6d0ab0d4aa | |||
| 7ae34e0640 | |||
| e9b5438a24 | |||
| 51be318edc | |||
| ca79b0c4d8 | |||
| dfe05cbfa8 | |||
| 9109ead81c | |||
| 746f8bc736 | |||
| 9c03b89ab5 | |||
| 5798e960a2 | |||
| 98730ce612 | |||
| 552faefa51 | |||
| 5aded99999 | |||
| f780553773 | |||
| 804716edb2 | |||
| 332a47475e | |||
| 132edce701 | |||
| 6ce0cf6209 | |||
| 868599a7fe | |||
| 53bce69c6f | |||
| 20c68d675c | |||
| dfc8fdf44f | |||
| 4a26d7a89a | |||
| 16f57a1bce | |||
| 1cf3c18841 | |||
| 1dd9ff0daf | |||
| 011e93720e | |||
| 331381c94d | |||
| 478b23825c | |||
| ff876afbb3 | |||
| dd13c73415 | |||
| e89ab9b92f | |||
| 4e59173d6c | |||
| df28d7331b | |||
| 2d0a2f3024 | |||
| 781e145721 | |||
| e984425e36 | |||
| 2eb58e3346 | |||
| ab4039dbbd | |||
| 2c1702a20b | |||
| 72a5f35b0e | |||
| 076ae15abd | |||
| fbc5f95340 | |||
| ff3a25a5ec | |||
| 2dd5a95232 | |||
| 2a21bbf062 | |||
| d9a80e5ef7 | |||
| 2cadee1599 | |||
| 6c26fde210 | |||
| bc908b7fe9 | |||
| 26d468aa6f | |||
| 954397f028 | |||
| 80faa61c91 | |||
| 961ede66a9 | |||
| 0f7188a347 | |||
| 3e832f9526 | |||
| 392cfbdc4e | |||
| 0751aa5a0f | |||
| e57846566e | |||
| 6c818e5c30 | |||
| 20f043abc6 | |||
| 416451eb0b | |||
| 3ab7a61a47 | |||
| 5571353464 | |||
| 95d85c7f5b | |||
| d7e509979a | |||
| 91a5b2d4fc | |||
| 6fec8382b5 | |||
| 4eb076d115 | |||
| 5171a7b7b3 | |||
| 7427aa87ea | |||
| 85043e57db | |||
| b41c8acddd | |||
| 06bc1ebcd4 | |||
| 999827b3ec | |||
| 5beddbccb4 | |||
| 38ea481177 | |||
| dbf945dfe5 | |||
| 21065a3c95 | |||
| 79b5defb63 | |||
| e2ae9b88c8 | |||
| ca3abf9154 | |||
| 956b201757 | |||
| fac320bfce | |||
| 6c2820f900 | |||
| 9a113e2993 | |||
| 89e0326435 | |||
| f863c6d728 | |||
| 1a37273a9e | |||
| d14b9e2ab5 | |||
| d926e4165b | |||
| 8c88ae401b | |||
| 92a2053b42 | |||
| e5015f348b | |||
| 6792002c19 | |||
| 9890f6aade | |||
| 536e66eed9 | |||
| 6e103480cc | |||
| 6a53c9fae4 | |||
| 28d65ac114 | |||
| 239577e9cf | |||
| a8fb45adc6 | |||
| 9316016d24 | |||
| 8d815d40b6 | |||
| 33b5c370b1 | |||
| cdf63840b0 | |||
| cf14501311 | |||
| 187b4a6e4b | |||
| 4ab9056700 | |||
| 9a281dfa71 | |||
| 0b3f7d1fe3 | |||
| a9d82de25c | |||
| eb8b4986d7 | |||
| 70602be54e | |||
| dac71f597a | |||
| 3a646ffe77 | |||
| 6cc09969dd | |||
| afa765c4ba | |||
| 26db4a5e7a | |||
| 8f73489073 | |||
| 98a10a2f55 | |||
| e48b94b858 | |||
| ff08ca140c | |||
| 61a9feb8fd | |||
| 21fdf31518 | |||
| 3af9397689 | |||
| fef756f508 | |||
| 131edf1293 | |||
| 6787b9b553 | |||
| 1c2491385f | |||
| 97baaf6797 | |||
| 4e88765a83 | |||
| aac26f6720 | |||
| 3b3e75003f | |||
| ab699aafdc | |||
| 98bdb8c526 | |||
| 94f742187e | |||
| 70ebe34f1f | |||
| 992cb6b310 | |||
| 917a9ee707 | |||
| d577ac6d54 | |||
| 5b5f6ac0b9 | |||
| 2aecc6e0f2 | |||
| 4b064f566a | |||
| 2a86a70386 | |||
| 8ab83eaf41 | |||
| 262b170244 | |||
| e21f35b880 | |||
| 24c8a1c501 | |||
| cfe6e3c805 | |||
| d3b62daea0 | |||
| 35355b28c0 | |||
| 88c82a41ba | |||
| 910e960e4f | |||
| 354e1ccdf4 | |||
| d1911f0f96 | |||
| cdc279b5da | |||
| d003bfa7f1 | |||
| 343a82b89c | |||
| 09a5515121 | |||
| cc23fb0f39 | |||
| 7edddd0566 | |||
| ebafc4576f | |||
| 328fe4256e | |||
| c240eb4a4e | |||
| 38d9d91945 | |||
| 4669598dd9 | |||
| 3ce3eff022 | |||
| 7daaf79fcc | |||
| d68fa8ce95 | |||
| d61ee51d79 | |||
| a6f81006be | |||
| 5fa374259e | |||
| 9fd033b30e | |||
| 21d80905a2 | |||
| e98ed3c74f | |||
| ebe76821e4 | |||
| 3858e38a02 | |||
| 510c35e077 | |||
| a8f680810f | |||
| f1c3c8296f | |||
| 6c90ccfbaa | |||
| ea0a249612 | |||
| 653a320e6c | |||
| 57e7ad6903 | |||
| 290564fd2f | |||
| b9207b5efb | |||
| c58715d95b | |||
| 5c6a8b9966 | |||
| dd713a26db | |||
| fad293fbbf | |||
| 5a1b94f45b | |||
| 344c68bf08 | |||
| f06e59b362 | |||
| 8ca5849b14 | |||
| 01e6a1061c | |||
| 7eb888d2e3 | |||
| 26f67b6798 | |||
| e6eed4be4e | |||
| 4d9ff395e9 | |||
| 114a50ad4e | |||
| 298dbbf400 | |||
| 218f434e01 | |||
| 8a53c438e3 | |||
| 3fe15a302c | |||
| dec83bbd21 | |||
| 2354746d4f | |||
| d421b1ccb8 | |||
| 00e019d6fe | |||
| 5b0c115b10 | |||
| d37fac0ff7 | |||
| 91d656ff60 | |||
| 9fd73ca34d | |||
| 2681a85fa5 | |||
| 9a0716af44 | |||
| dc642cfbe7 | |||
| b98e831300 | |||
| 0d73824727 | |||
| 1a0a5c652b | |||
| f4f645b103 | |||
| 37395b70f6 | |||
| a65cb3b03c | |||
| 779641e8e7 | |||
| a5188ce24a | |||
| 39a96885d2 | |||
| 96dbec3218 | |||
| 4b29e7bf8d | |||
| ed69bd74ed | |||
| f0641ddd6d | |||
| 6c2a2e4665 | |||
| 5e929df966 | |||
| 38e8f91fdf | |||
| 455e0533fe | |||
| a8c4fc7607 | |||
| a26bdfe385 | |||
| df63b8c1b7 | |||
| 707d00b280 | |||
| 9c79d728e8 | |||
| 9c8a1f564e | |||
| 4014083238 | |||
| ba6224bc78 | |||
| f69016883c | |||
| c10baca137 | |||
| 60e403a28b | |||
| d542cf7720 |
@@ -64,6 +64,9 @@ $route['api/v1/system/[S|s]prache/(:any)'] = 'api/v1/system/sprache2/$1';
|
||||
$route['Cis/LvPlan/.*'] = 'Cis/LvPlan/index/$1';
|
||||
$route['Cis/MyLvPlan/.*'] = 'Cis/MyLvPlan/index/$1';
|
||||
$route['Cis/MyLv/.*'] = 'Cis/MyLv/index/$1';
|
||||
$route['Cis/OtherLvPlan/.*'] = 'Cis/OtherLvPlan/index/$1';
|
||||
//Route for LV Plan Stg/Semester/Verband/Gruppe
|
||||
$route['Cis/StgOrgLvPlan/.*'] = 'Cis/StgOrgLvPlan/index/$1';
|
||||
|
||||
$route['Abgabetool/Assistenz'] = 'Cis/Abgabetool/Assistenz';
|
||||
$route['Abgabetool/Assistenz/(:any)'] = 'Cis/Abgabetool/Assistenz/$1';
|
||||
|
||||
@@ -22,8 +22,9 @@ unset($config['student']['searchfields']['email']);
|
||||
unset($config['student']['searchfields']['tel']);
|
||||
$config['student']['resultfields'] = [
|
||||
"s.student_uid AS uid",
|
||||
"s.matrikelnr",
|
||||
"s.matrikelnr AS personenkennzeichen",
|
||||
"p.person_id",
|
||||
"p.matr_nr AS matrikelnummer",
|
||||
"(p.vorname || ' ' || p.nachname) AS name",
|
||||
"ARRAY[s.student_uid || '@' || '" . DOMAIN . "'] AS email",
|
||||
"CASE
|
||||
|
||||
@@ -31,12 +31,8 @@ class Abgabetool extends Auth_Controller
|
||||
{
|
||||
// TODO: routing from index based on berechtigung?
|
||||
|
||||
$viewData = array(
|
||||
'uid'=>getAuthUID(),
|
||||
);
|
||||
|
||||
if(defined('CIS4') && CIS4) {
|
||||
$this->load->view('CisRouterView/CisRouterView.php', ['viewData' => $viewData, 'route' => 'Abgabetool']);
|
||||
$this->load->view('CisRouterView/CisRouterView.php', ['route' => 'Abgabetool']);
|
||||
} else {
|
||||
$this->load->view('Cis/Abgabetool.php', ['uid' => getAuthUID(), 'route' => 'Abgabetool']);
|
||||
}
|
||||
@@ -44,12 +40,8 @@ class Abgabetool extends Auth_Controller
|
||||
|
||||
public function Student($student_uid_prop = '')
|
||||
{
|
||||
$viewData = array(
|
||||
'uid'=>getAuthUID(),
|
||||
);
|
||||
|
||||
if(defined('CIS4') && CIS4) {
|
||||
$this->load->view('CisRouterView/CisRouterView.php', ['viewData' => $viewData, 'route' => 'AbgabetoolStudent']);
|
||||
$this->load->view('CisRouterView/CisRouterView.php', ['route' => 'AbgabetoolStudent']);
|
||||
} else {
|
||||
$this->load->view('Cis/Abgabetool.php', ['uid' => getAuthUID(), 'route' => 'AbgabetoolStudent', 'student_uid_prop' => $student_uid_prop]);
|
||||
}
|
||||
@@ -57,12 +49,8 @@ class Abgabetool extends Auth_Controller
|
||||
|
||||
public function Mitarbeiter()
|
||||
{
|
||||
$viewData = array(
|
||||
'uid'=>getAuthUID(),
|
||||
);
|
||||
|
||||
if(defined('CIS4') && CIS4) {
|
||||
$this->load->view('CisRouterView/CisRouterView.php', ['viewData' => $viewData, 'route' => 'AbgabetoolMitarbeiter']);
|
||||
$this->load->view('CisRouterView/CisRouterView.php', ['route' => 'AbgabetoolMitarbeiter']);
|
||||
} else {
|
||||
$this->load->view('Cis/Abgabetool.php', ['uid' => getAuthUID(), 'route' => 'AbgabetoolMitarbeiter']);
|
||||
}
|
||||
@@ -70,13 +58,8 @@ class Abgabetool extends Auth_Controller
|
||||
|
||||
public function Assistenz($stg_kz_prop = '')
|
||||
{
|
||||
|
||||
$viewData = array(
|
||||
'uid'=>getAuthUID(),
|
||||
);
|
||||
|
||||
if(defined('CIS4') && CIS4) {
|
||||
$this->load->view('CisRouterView/CisRouterView.php', ['viewData' => $viewData, 'route' => 'AbgabetoolAssistenz']);
|
||||
$this->load->view('CisRouterView/CisRouterView.php', ['route' => 'AbgabetoolAssistenz']);
|
||||
} else {
|
||||
$this->load->view('Cis/Abgabetool.php', ['uid' => getAuthUID(), 'route' => 'AbgabetoolAssistenz', 'stg_kz_prop' => $stg_kz_prop]);
|
||||
}
|
||||
@@ -84,12 +67,8 @@ class Abgabetool extends Auth_Controller
|
||||
|
||||
public function Deadlines()
|
||||
{
|
||||
$viewData = array(
|
||||
'uid'=>getAuthUID(),
|
||||
);
|
||||
|
||||
if(defined('CIS4') && CIS4) {
|
||||
$this->load->view('CisRouterView/CisRouterView.php', ['viewData' => $viewData, 'route' => 'DeadlinesOverview']);
|
||||
$this->load->view('CisRouterView/CisRouterView.php', ['route' => 'DeadlinesOverview']);
|
||||
} else {
|
||||
$this->load->view('Cis/Abgabetool.php', ['uid' => getAuthUID(), 'route' => 'DeadlinesOverview']);
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ class Auth extends FHC_Controller
|
||||
|
||||
if ($this->form_validation->run())
|
||||
{
|
||||
redirect($this->authlib->getLandingPage('/CisVue/Dashboard'));
|
||||
redirect($this->authlib->getLandingPage('/Cis4'));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -28,12 +28,6 @@ class LvPlan extends Auth_Controller
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
|
||||
$viewData = array(
|
||||
'uid'=>getAuthUID(),
|
||||
'timezone' => $this->config->item('timezone')
|
||||
);
|
||||
|
||||
$this->load->view('CisRouterView/CisRouterView.php', ['viewData' => $viewData, 'route' => 'LvPlan']);
|
||||
$this->load->view('CisRouterView/CisRouterView.php', ['route' => 'LvPlan']);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,11 +26,6 @@ class MyLv extends Auth_Controller
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
|
||||
$viewData = array(
|
||||
|
||||
);
|
||||
|
||||
$this->load->view('CisRouterView/CisRouterView.php', ['viewData' => $viewData, 'route' => 'MyLv']);
|
||||
$this->load->view('CisRouterView/CisRouterView.php', ['route' => 'MyLv']);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,13 +27,7 @@ class MyLvPlan extends Auth_Controller
|
||||
* @return void
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
|
||||
$viewData = array(
|
||||
'uid'=>getAuthUID(),
|
||||
'timezone' => $this->config->item('timezone')
|
||||
);
|
||||
|
||||
$this->load->view('CisRouterView/CisRouterView.php', ['viewData' => $viewData, 'route' => 'MyLvPlan']);
|
||||
{
|
||||
$this->load->view('CisRouterView/CisRouterView.php', ['route' => 'MyLvPlan']);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
if (!defined('BASEPATH'))
|
||||
exit('No direct script access allowed');
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class OtherLvPlan extends Auth_Controller
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct([
|
||||
'index' => ['basis/other_lv_plan:r']
|
||||
]);
|
||||
|
||||
// Load Config
|
||||
$this->load->config('calendar');
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------------------
|
||||
// Public methods
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$this->load->view('CisRouterView/CisRouterView.php', ['route' => 'OtherLvPlan']);
|
||||
}
|
||||
}
|
||||
@@ -55,15 +55,7 @@ class Profil extends Auth_Controller
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
|
||||
$this->load->library('ProfilLib');
|
||||
$profil_data = $this->profillib->getView(getAuthUID());
|
||||
$profil_data = hasData($profil_data) ? getData($profil_data) : null;
|
||||
$viewData = array(
|
||||
'editable'=>true,
|
||||
'profil_data' => $profil_data,
|
||||
);
|
||||
$this->load->view('CisRouterView/CisRouterView.php',['viewData' => $viewData, 'route' => 'profilIndex']);
|
||||
$this->load->view('CisRouterView/CisRouterView.php', ['route' => 'profilIndex']);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -73,23 +65,13 @@ class Profil extends Auth_Controller
|
||||
*/
|
||||
public function View($uid)
|
||||
{
|
||||
$this->load->library('ProfilLib');
|
||||
$profil_data = $this->profillib->getView($uid);
|
||||
$profil_data = hasData($profil_data) ? getData($profil_data) : null;
|
||||
$viewData = array (
|
||||
'uid' => $uid,
|
||||
'profil_data'=>$profil_data,
|
||||
);
|
||||
if($uid == getAuthUID()){
|
||||
$viewData['editable'] = true;
|
||||
}
|
||||
$this->load->view('CisRouterView/CisRouterView.php',['viewData' => $viewData, 'route' => 'profilViewUid']);
|
||||
$this->load->view('CisRouterView/CisRouterView.php', ['route' => 'profilViewUid']);
|
||||
}
|
||||
|
||||
/**
|
||||
* checks whether a specific userID is a mitarbeiter or not (foreword declaration of the function isMitarbeiter in Mitarbeiter_model.php)
|
||||
* checks whether a specific userID is a student or not (foreword declaration of the function isStudent in Student_model.php)
|
||||
* @access public
|
||||
* @param $uid the userID used to check if it is a mitarbeiter
|
||||
* @param $uid the userID used to check if it is a student
|
||||
* @return boolean
|
||||
*/
|
||||
public function isStudent($uid)
|
||||
@@ -119,7 +101,7 @@ class Profil extends Auth_Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* gets the adressen that are marked as zustell from the currenlty logged in user
|
||||
* gets the adressen that are marked as zustell from the currently logged in user
|
||||
* @access public
|
||||
* @return array a list of adresse_id's
|
||||
*/
|
||||
@@ -262,23 +244,23 @@ class Profil extends Auth_Controller
|
||||
$this->GemeindeModel->addDistinct();
|
||||
$this->GemeindeModel->addSelect(["name"]);
|
||||
if ($nation == "A") {
|
||||
if (isset($zip) && $zip > 999 && $zip < 32000) {
|
||||
if (isset($zip) && $zip > 999 && $zip < 32000) {
|
||||
|
||||
$gemeinde_res = $this->GemeindeModel->loadWhere(['plz' => $zip]);
|
||||
if (isError($gemeinde_res)) {
|
||||
show_error("error while trying to query bis.tbl_gemeinde");
|
||||
}
|
||||
$gemeinde_res = hasData($gemeinde_res) ? getData($gemeinde_res) : null;
|
||||
$gemeinde_res = array_map(function ($obj) {
|
||||
return $obj->name;
|
||||
}, $gemeinde_res);
|
||||
echo json_encode($gemeinde_res);
|
||||
|
||||
} else {
|
||||
echo json_encode(error("ortschaftskennziffer code was not valid"));
|
||||
$gemeinde_res = $this->GemeindeModel->loadWhere(['plz' => $zip]);
|
||||
if (isError($gemeinde_res)) {
|
||||
show_error("error while trying to query bis.tbl_gemeinde");
|
||||
}
|
||||
$gemeinde_res = hasData($gemeinde_res) ? getData($gemeinde_res) : null;
|
||||
$gemeinde_res = array_map(function ($obj) {
|
||||
return $obj->name;
|
||||
}, $gemeinde_res);
|
||||
echo json_encode($gemeinde_res);
|
||||
|
||||
} else {
|
||||
echo json_encode(error("ortschaftskennziffer code was not valid"));
|
||||
}
|
||||
} else {
|
||||
echo json_encode(error("Nation was not 'A' (Austria)"));
|
||||
echo json_encode(error("Nation was not 'A' (Austria)"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -750,6 +732,4 @@ class Profil extends Auth_Controller
|
||||
$zutrittskarte_ausgegebenam = str_replace("-", ".", $zutrittskarte_ausgegebenam);
|
||||
return $zutrittskarte_ausgegebenam;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -25,11 +25,6 @@ class Raumsuche extends Auth_Controller
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
|
||||
$viewData = array(
|
||||
'uid'=>getAuthUID(),
|
||||
);
|
||||
|
||||
$this->load->view('CisRouterView/CisRouterView.php', ['viewData' => $viewData, 'route' => 'Raumsuche']);
|
||||
$this->load->view('CisRouterView/CisRouterView.php', ['route' => 'Raumsuche']);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
if (! defined('BASEPATH')) exit('No direct script access allowed');
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class StgOrgLvPlan extends Auth_Controller
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct([
|
||||
'index' => ['basis/cis:r']
|
||||
]);
|
||||
|
||||
// Load Config
|
||||
$this->load->config('calendar');
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------------------
|
||||
// Public methods
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$this->load->view('CisRouterView/CisRouterView.php', ['route' => 'StgOrgLvPlan']);
|
||||
}
|
||||
}
|
||||
@@ -29,10 +29,7 @@ class Studium extends Auth_Controller
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$viewData = array(
|
||||
|
||||
);
|
||||
$this->load->view('CisRouterView/CisRouterView.php',['viewData' => $viewData, 'route' => 'studium']);
|
||||
$this->load->view('CisRouterView/CisRouterView.php',['route' => 'studium']);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<?php
|
||||
|
||||
if (! defined('BASEPATH')) exit('No direct script access allowed');
|
||||
if (!defined('BASEPATH'))
|
||||
exit('No direct script access allowed');
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -13,9 +14,9 @@ class Cis4 extends Auth_Controller
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct(
|
||||
array(
|
||||
'index' => 'basis/cis:r'
|
||||
)
|
||||
array(
|
||||
'index' => 'basis/cis:r'
|
||||
)
|
||||
);
|
||||
|
||||
// Load Config
|
||||
@@ -30,16 +31,6 @@ class Cis4 extends Auth_Controller
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$this->load->model('person/Person_model', 'PersonModel');
|
||||
$personData = getData($this->PersonModel->getByUid(getAuthUID()))[0];
|
||||
|
||||
$viewData = array(
|
||||
'uid' => getAuthUID(),
|
||||
'name' => $personData->vorname,
|
||||
'person_id' => $personData->person_id,
|
||||
'timezone' => $this->config->item('timezone')
|
||||
);
|
||||
|
||||
$this->load->view('CisRouterView/CisRouterView.php', ['viewData' => $viewData, 'route' => 'FhcDashboard']);
|
||||
$this->load->view('CisRouterView/CisRouterView.php', ['route' => 'FhcDashboard']);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
<?php
|
||||
|
||||
if (! defined('BASEPATH')) exit('No direct script access allowed');
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class Dashboard extends Auth_Controller
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct(
|
||||
array(
|
||||
'index' => 'dashboard/benutzer:r'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------------------
|
||||
// Public methods
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
|
||||
$this->load->model('person/Person_model','PersonModel');
|
||||
$personData = getData($this->PersonModel->getByUid(getAuthUID()))[0];
|
||||
|
||||
$viewData = array(
|
||||
'uid' => getAuthUID(),
|
||||
'name' => $personData->vorname,
|
||||
'person_id' => $personData->person_id
|
||||
);
|
||||
|
||||
$this->load->view('CisRouterView/CisRouterView.php', ['viewData' => $viewData]);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -18,6 +18,8 @@
|
||||
|
||||
if (! defined('BASEPATH')) exit('No direct script access allowed');
|
||||
|
||||
use \DateTime as DateTime;
|
||||
|
||||
class Bookmark extends FHCAPI_Controller
|
||||
{
|
||||
|
||||
@@ -28,111 +30,162 @@ class Bookmark extends FHCAPI_Controller
|
||||
{
|
||||
parent::__construct([
|
||||
'getBookmarks' => self::PERM_LOGGED,
|
||||
'delete' => self::PERM_LOGGED,
|
||||
'insert' => self::PERM_LOGGED,
|
||||
'delete' => self::PERM_LOGGED,
|
||||
'insert' => self::PERM_LOGGED,
|
||||
'update' => self::PERM_LOGGED,
|
||||
]);
|
||||
'changeOrder' => self::PERM_LOGGED
|
||||
]);
|
||||
|
||||
$this->load->model('dashboard/Bookmark_model', 'BookmarkModel');
|
||||
|
||||
$this->uid = getAuthUID();
|
||||
$this->pid = getAuthPersonID();
|
||||
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------------
|
||||
// Public methods
|
||||
|
||||
|
||||
/**
|
||||
* gets the bookmarks associated to a user
|
||||
/**
|
||||
* gets the bookmarks associated to a user
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function getBookmarks()
|
||||
{
|
||||
$this->BookmarkModel->addOrder("bookmark_id");
|
||||
$this->BookmarkModel->addOrder("sort");
|
||||
$bookmarks = $this->BookmarkModel->loadWhere(["uid"=>$this->uid]);
|
||||
|
||||
$bookmarks = $this->getDataOrTerminateWithError($bookmarks);
|
||||
$bookmarks = $this->getDataOrTerminateWithError($bookmarks);
|
||||
|
||||
$this->terminateWithSuccess($bookmarks);
|
||||
}
|
||||
|
||||
/**
|
||||
* deletes bookmark from associated user
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function delete($bookmark_id)
|
||||
{
|
||||
$bookmark = $this->BookmarkModel->load($bookmark_id);
|
||||
|
||||
$bookmark = current($this->getDataOrTerminateWithError($bookmark));
|
||||
|
||||
// only delete bookmark if the user is the owner of the bookmark
|
||||
if($bookmark->uid == $this->uid || $this->permissionlib->isBerechtigt('admin')){
|
||||
|
||||
$delete_result = $this->BookmarkModel->delete($bookmark_id);
|
||||
|
||||
$delete_result = $this->getDataOrTerminateWithError($delete_result);
|
||||
|
||||
$this->terminateWithSuccess($delete_result);
|
||||
}else{
|
||||
$this->_outputAuthError(['delete' => ['admin:rw']]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* inserts new bookmark into the bookmark table
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function insert()
|
||||
{
|
||||
// form validation
|
||||
$this->load->library('form_validation');
|
||||
$this->form_validation->set_rules('url', 'URL', 'required|valid_url|max_length[511]');
|
||||
$this->form_validation->set_rules('title', 'Title', 'required|max_length[255]');
|
||||
if($this->form_validation->run() == FALSE) $this->terminateWithValidationErrors($this->form_validation->error_array());
|
||||
|
||||
$url = $this->input->post('url',true);
|
||||
$title = $this->input->post('title',true);
|
||||
$tag = $this->input->post('tag', true);
|
||||
|
||||
$insert_into_result = $this->BookmarkModel->insert(['uid'=>$this->uid, 'url'=>$url, 'title'=>$title,'tag'=>$tag, 'insertvon'=>$this->uid, 'updateamum'=>NULL, 'updatevon'=>NULL]);
|
||||
|
||||
$insert_into_result = $this->getDataOrTerminateWithError($insert_into_result);
|
||||
|
||||
$this->terminateWithSuccess($insert_into_result);
|
||||
|
||||
}
|
||||
$this->terminateWithSuccess($bookmarks);
|
||||
}
|
||||
|
||||
/**
|
||||
* updates bookmark in the bookmark table
|
||||
* deletes bookmark from associated user
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function update($bookmark_id)
|
||||
public function delete($bookmark_id)
|
||||
{
|
||||
// form validation
|
||||
$this->load->library('form_validation');
|
||||
$this->form_validation->set_rules('url', 'URL', 'required|valid_url|max_length[511]');
|
||||
$this->form_validation->set_rules('title', 'Title', 'required|max_length[255]');
|
||||
if($this->form_validation->run() == FALSE) $this->terminateWithValidationErrors($this->form_validation->error_array());
|
||||
$bookmark = $this->BookmarkModel->load($bookmark_id);
|
||||
|
||||
$url = $this->input->post('url',true);
|
||||
$title = $this->input->post('title',true);
|
||||
$bookmark = current($this->getDataOrTerminateWithError($bookmark));
|
||||
|
||||
// only delete bookmark if the user is the owner of the bookmark
|
||||
if ($bookmark->uid == $this->uid || $this->permissionlib->isBerechtigt('admin')) {
|
||||
$delete_result = $this->BookmarkModel->delete($bookmark_id);
|
||||
|
||||
$delete_result = $this->getDataOrTerminateWithError($delete_result);
|
||||
|
||||
$this->terminateWithSuccess($delete_result);
|
||||
} else {
|
||||
$this->_outputAuthError(['delete' => ['admin:rw']]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* inserts new bookmark into the bookmark table
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function insert()
|
||||
{
|
||||
// form validation
|
||||
$this->load->library('form_validation');
|
||||
$this->form_validation->set_rules('url', 'URL', 'required|valid_url|max_length[511]');
|
||||
$this->form_validation->set_rules('title', 'Title', 'required|max_length[255]');
|
||||
if (!$this->form_validation->run())
|
||||
$this->terminateWithValidationErrors($this->form_validation->error_array());
|
||||
|
||||
$url = $this->input->post('url', true);
|
||||
$title = $this->input->post('title', true);
|
||||
$tag = $this->input->post('tag', true);
|
||||
if (is_array($tag)) {
|
||||
$tag = json_encode($tag); // convert PHP array to JSON string
|
||||
}
|
||||
$sort = $this->input->post('sort', true);
|
||||
|
||||
$insert_into_result = $this->BookmarkModel->insert([
|
||||
'uid' => $this->uid,
|
||||
'url' => $url,
|
||||
'title' => $title,
|
||||
'tag' => $tag,
|
||||
'insertvon' => $this->uid,
|
||||
'updateamum' => null,
|
||||
'updatevon' => null,
|
||||
'sort' => $sort
|
||||
]);
|
||||
|
||||
$insert_into_result = $this->getDataOrTerminateWithError($insert_into_result);
|
||||
|
||||
$this->terminateWithSuccess($insert_into_result);
|
||||
}
|
||||
|
||||
/**
|
||||
* updates bookmark in the bookmark table
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function update($bookmark_id)
|
||||
{
|
||||
// form validation
|
||||
$this->load->library('form_validation');
|
||||
$this->form_validation->set_rules('url', 'URL', 'required|valid_url|max_length[511]');
|
||||
$this->form_validation->set_rules('title', 'Title', 'required|max_length[255]');
|
||||
if (!$this->form_validation->run())
|
||||
$this->terminateWithValidationErrors($this->form_validation->error_array());
|
||||
|
||||
$url = $this->input->post('url', true);
|
||||
$title = $this->input->post('title', true);
|
||||
$tag = $this->input->post('tag', true);
|
||||
if (is_array($tag)) {
|
||||
$tag = json_encode($tag);
|
||||
}
|
||||
|
||||
$now = new DateTime();
|
||||
$now = $now->format('Y-m-d H:i:s');
|
||||
|
||||
$update_result = $this->BookmarkModel->update($bookmark_id,['url'=>$url, 'title'=>$title,'updateamum'=>$now]);
|
||||
$update_result = $this->BookmarkModel->update($bookmark_id, [
|
||||
'url' => $url,
|
||||
'title' => $title,
|
||||
'tag' => $tag,
|
||||
'updateamum' => $now
|
||||
]);
|
||||
|
||||
$update_result = $this->getDataOrTerminateWithError($update_result);
|
||||
$update_result = $this->getDataOrTerminateWithError($update_result);
|
||||
|
||||
$this->terminateWithSuccess($update_result);
|
||||
$this->terminateWithSuccess($update_result);
|
||||
}
|
||||
|
||||
}
|
||||
/**
|
||||
* changes sort of two bookmarks in the bookmark table
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function changeOrder($bookmark_id1, $bookmark_id2)
|
||||
{
|
||||
$update_result = [];
|
||||
|
||||
$result1 = $this->BookmarkModel->load($bookmark_id1);
|
||||
$data1 = $this->getDataOrTerminateWithError($result1);
|
||||
$sort1 = current($data1)->sort;
|
||||
|
||||
$result2 = $this->BookmarkModel->load(["bookmark_id"=>$bookmark_id2]);
|
||||
$data2 = $this->getDataOrTerminateWithError($result2);
|
||||
$sort2 = current($data2)->sort;
|
||||
|
||||
$update_result1 = $this->BookmarkModel->update($bookmark_id1, [
|
||||
'sort' => $sort2
|
||||
]);
|
||||
$update_result[] = $this->getDataOrTerminateWithError($update_result1);
|
||||
|
||||
$update_result2 = $this->BookmarkModel->update($bookmark_id2, [
|
||||
'sort' => $sort1
|
||||
]);
|
||||
$update_result[] = $this->getDataOrTerminateWithError($update_result2);
|
||||
|
||||
$this->terminateWithSuccess($update_result);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ class Cis4FhcApi extends FHCAPI_Controller
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct([
|
||||
'getViewData' => self::PERM_LOGGED,
|
||||
'dashboardViewData' => self::PERM_LOGGED,
|
||||
]);
|
||||
|
||||
}
|
||||
@@ -36,17 +36,22 @@ class Cis4FhcApi extends FHCAPI_Controller
|
||||
// Public methods
|
||||
|
||||
/**
|
||||
* fetches ViewData
|
||||
*/
|
||||
public function getViewData()
|
||||
* retrieves view data for dashboard view
|
||||
* @access public
|
||||
* @param $uid the userID for which profile is being viewed, null or missing value implies one's own profile
|
||||
*/
|
||||
public function dashboardViewData()
|
||||
{
|
||||
$this->load->model('person/Person_model','PersonModel');
|
||||
$personData = getData($this->PersonModel->getByUid(getAuthUID()))[0];
|
||||
|
||||
$this->load->config('calendar');
|
||||
|
||||
$viewData = array(
|
||||
'uid' => getAuthUID(),
|
||||
'name' => $personData->vorname,
|
||||
'person_id' => $personData->person_id
|
||||
'person_id' => $personData->person_id,
|
||||
'timezone' => $this->config->item('timezone'),
|
||||
);
|
||||
|
||||
$this->terminateWithSuccess($viewData);
|
||||
|
||||
@@ -16,12 +16,13 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
if (! defined('BASEPATH')) exit('No direct script access allowed');
|
||||
if (!defined('BASEPATH'))
|
||||
exit('No direct script access allowed');
|
||||
|
||||
|
||||
class CisMenu extends FHCAPI_Controller
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* Object initialization
|
||||
*/
|
||||
@@ -31,28 +32,95 @@ class CisMenu extends FHCAPI_Controller
|
||||
'getMenu' => self::PERM_LOGGED,
|
||||
]);
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------------
|
||||
// Public methods
|
||||
|
||||
/**
|
||||
/**
|
||||
* fetches the menu for CIS from the database based on the userLanguage
|
||||
*/
|
||||
public function getMenu()
|
||||
public function getMenu()
|
||||
{
|
||||
$this->load->model('content/Content_model', 'ContentModel');
|
||||
$this->load->config('cis');
|
||||
$cis4_content_id =$this->config->item('cis_menu_root_content_id');
|
||||
$result = $this->ContentModel->getMenu($cis4_content_id, getAuthUID(),getUserLanguage());
|
||||
$cis4_content_id = $this->config->item('cis_menu_root_content_id');
|
||||
$result = $this->ContentModel->getMenu($cis4_content_id, getAuthUID(), getUserLanguage());
|
||||
$result = $this->getDataOrTerminateWithError($result);
|
||||
$menu = $result->childs ?? [];
|
||||
$this->terminateWithSuccess($menu);
|
||||
}
|
||||
|
||||
|
||||
|
||||
$menu = $this->generateUrlsForMenuItems($menu);
|
||||
$this->terminateWithSuccess($menu);
|
||||
}
|
||||
|
||||
private function generateUrlsForMenuItems($menuItems)
|
||||
{
|
||||
return array_map(
|
||||
function ($menuItem) {
|
||||
return $this->generateUrlForMenuItem($menuItem);
|
||||
},
|
||||
$menuItems
|
||||
);
|
||||
}
|
||||
|
||||
private function generateUrlForMenuItem($menuItem)
|
||||
{
|
||||
$menuItem->url = $this->menuItemUrlHelper($menuItem);
|
||||
unset($menuItem->content);
|
||||
|
||||
if ($menuItem->childs && count($menuItem->childs)) {
|
||||
$menuItem->childs = $this->generateUrlsForMenuItems($menuItem->childs);
|
||||
}
|
||||
|
||||
return $menuItem;
|
||||
}
|
||||
|
||||
private function menuItemUrlHelper($menuItem)
|
||||
{
|
||||
if ($menuItem->template_kurzbz !== 'redirect') {
|
||||
return site_url("/CisVue/Cms/content/" . $menuItem->content_id);
|
||||
}
|
||||
|
||||
if (!$menuItem->content || !mb_strlen($menuItem->content)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$doc = new DOMDocument();
|
||||
$doc->loadXML($menuItem->content);
|
||||
$urlElem = $doc->getElementsByTagName('url')->item(0);
|
||||
|
||||
if (!$urlElem) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$url = $urlElem->textContent;
|
||||
|
||||
if (strpos($url, '../cms/news.php') !== false) {
|
||||
$newsRegex = '/^\.\.\/cms\/news\.php/';
|
||||
$url = preg_replace($newsRegex, site_url("/CisVue/Cms/news"), $url);
|
||||
}
|
||||
|
||||
if (strpos($url, '../cms/content.php?') !== false) {
|
||||
$contentRegex = '/^\.\.\/cms\/content\.php\?content_id=([0-9]+)/';
|
||||
$matches = [];
|
||||
preg_match($contentRegex, $url, $matches);
|
||||
$url = site_url('/CisVue/Cms/content/' . $matches[1]);
|
||||
}
|
||||
|
||||
if (strpos($url, '../index.ci.php') !== false) {
|
||||
$indexRegex = '/^\.\.\/index\.ci\.php/';
|
||||
$url = preg_replace($indexRegex, site_url(), $url);
|
||||
}
|
||||
|
||||
if (strpos($url, '../') !== false) {
|
||||
$relativeRegex = '/^\.\.\//';
|
||||
$url = preg_replace($relativeRegex, base_url(), $url);
|
||||
}
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -38,7 +38,8 @@ class Lehre extends FHCAPI_Controller
|
||||
parent::__construct([
|
||||
'lvStudentenMail' => self::PERM_LOGGED,
|
||||
'LV' => self::PERM_LOGGED,
|
||||
'Pruefungen' => self::PERM_LOGGED
|
||||
'Pruefungen' => self::PERM_LOGGED,
|
||||
'semesterAverageGrade' => self::PERM_LOGGED,
|
||||
]);
|
||||
|
||||
}
|
||||
@@ -100,5 +101,49 @@ class Lehre extends FHCAPI_Controller
|
||||
|
||||
$this->terminateWithSuccess($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* calculates and returns the grade average and weighted average for a specific semester
|
||||
* @param string $studiensemester_kurzbz
|
||||
* @return void
|
||||
*/
|
||||
|
||||
public function semesterAverageGrade($studiensemester_kurzbz)
|
||||
{
|
||||
$this->load->model('education/Lehrveranstaltung_model', 'LehrveranstaltungModel');
|
||||
$semesterLvs = $this->LehrveranstaltungModel->getLvsByStudentWithGrades(getAuthUID(), $studiensemester_kurzbz, getUserLanguage());
|
||||
|
||||
if (isError($semesterLvs))
|
||||
return $this->outputJsonError(getError($semesterLvs));
|
||||
|
||||
$semesterLvsData = getData($semesterLvs);
|
||||
|
||||
$doGradesExist = false;
|
||||
$sum = 0;
|
||||
$count = 0;
|
||||
$sumWeighted = 0;
|
||||
$sumEcts = 0;
|
||||
|
||||
foreach ($semesterLvsData as $lv) {
|
||||
if (!$lv->znote || $lv->znote < 1 || $lv->znote > 5)
|
||||
continue;
|
||||
|
||||
$doGradesExist = true;
|
||||
|
||||
$sum += $lv->znote;
|
||||
$count++;
|
||||
$sumWeighted += $lv->znote * floatval($lv->ects);
|
||||
$sumEcts += floatval($lv->ects);
|
||||
}
|
||||
|
||||
$averageGrade = null;
|
||||
$weightedAverageGrade = null;
|
||||
if ($doGradesExist) {
|
||||
$averageGrade = $sum/$count;
|
||||
$weightedAverageGrade = $sumWeighted/$sumEcts;
|
||||
}
|
||||
|
||||
$this->terminateWithSuccess(['average_grade' => $averageGrade, 'weighted_average_grade' => $weightedAverageGrade]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,8 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
if (! defined('BASEPATH')) exit('No direct script access allowed');
|
||||
if (!defined('BASEPATH'))
|
||||
exit('No direct script access allowed');
|
||||
|
||||
use CI3_Events as Events;
|
||||
use \DateTime as DateTime;
|
||||
@@ -33,19 +34,25 @@ class LvPlan extends FHCAPI_Controller
|
||||
|
||||
parent::__construct([
|
||||
'getRoomplan' => self::PERM_LOGGED,
|
||||
'Stunden' => self::PERM_LOGGED,
|
||||
'getReservierungen' => self::PERM_LOGGED,
|
||||
'Stunden' => self::PERM_LOGGED,
|
||||
'getReservierungen' => self::PERM_LOGGED,
|
||||
'LvPlanEvents' => self::PERM_LOGGED,
|
||||
'eventsPersonal' => self::PERM_LOGGED,
|
||||
'eventsLv' => self::PERM_LOGGED,
|
||||
'getLehreinheitStudiensemester' => self::PERM_LOGGED,
|
||||
'studiensemesterDateInterval' => self::PERM_LOGGED,
|
||||
'getLvPlanForStudiensemester' => self::PERM_LOGGED,
|
||||
'getLv' => self::PERM_LOGGED
|
||||
'getLv' => self::PERM_LOGGED,
|
||||
'eventsStgOrg' => self::PERM_LOGGED,
|
||||
'fetchFerienEvents' => self::PERM_LOGGED,
|
||||
'getStudiengaenge' => self::PERM_LOGGED,
|
||||
'getLehrverband' => self::PERM_LOGGED,
|
||||
'permissionOtherLvPlan' => self::PERM_LOGGED,
|
||||
'compactibleEventTypes' => self::PERM_LOGGED,
|
||||
]);
|
||||
|
||||
$this->load->library('LogLib');
|
||||
$this->loglib->setConfigs(array(
|
||||
$this->load->library('LogLib');
|
||||
$this->loglib->setConfigs(array(
|
||||
'classIndex' => 5,
|
||||
'functionIndex' => 5,
|
||||
'lineIndex' => 4,
|
||||
@@ -53,17 +60,17 @@ class LvPlan extends FHCAPI_Controller
|
||||
'dbExecuteUser' => 'RESTful API'
|
||||
));
|
||||
|
||||
$this->load->library('form_validation');
|
||||
$this->load->library('form_validation');
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------------
|
||||
// Public methods
|
||||
|
||||
/**
|
||||
* fetches LvPlan and Moodle events together
|
||||
* @access public
|
||||
*
|
||||
*/
|
||||
* fetches LvPlan and Moodle events together
|
||||
* @access public
|
||||
*
|
||||
*/
|
||||
public function LvPlanEvents()
|
||||
{
|
||||
$hasLv = $this->input->post('lv_id');
|
||||
@@ -83,24 +90,30 @@ class LvPlan extends FHCAPI_Controller
|
||||
// form validation
|
||||
$this->form_validation->set_rules('start_date', "start_date", "required");
|
||||
$this->form_validation->set_rules('end_date', "end_date", "required");
|
||||
|
||||
|
||||
if (!$this->form_validation->run())
|
||||
$this->terminateWithValidationErrors($this->form_validation->error_array());
|
||||
|
||||
// storing the post parameter in local variables
|
||||
$start_date = $this->input->post('start_date', true);
|
||||
$end_date = $this->input->post('end_date', true);
|
||||
$uid = $this->input->post('uid', true);
|
||||
|
||||
// disallow accessing other user's events if missing permission
|
||||
if ($uid && $uid !== getAuthUID() && !$this->permissionlib->isBerechtigt('basis/other_lv_plan')) {
|
||||
$this->terminateWithError("Missing permission to view other users' timetables!");
|
||||
}
|
||||
|
||||
// fetching lvplan events
|
||||
$result = $this->stundenplanlib->getEventsUser($start_date, $end_date);
|
||||
$result = $this->stundenplanlib->getEventsUser($start_date, $end_date, $uid);
|
||||
$lvplanEvents = $this->getDataOrTerminateWithError($result);
|
||||
|
||||
// fetching moodle events
|
||||
$moodleEvents = $this->fetchMoodleEvents($start_date, $end_date);
|
||||
$moodleEvents = $this->fetchMoodleEvents($start_date, $end_date, $uid);
|
||||
|
||||
// fetching ferien events
|
||||
$ferienEvents = $this->fetchFerienEvents($start_date, $end_date);
|
||||
|
||||
$ferienEvents = $this->fetchFerienEvents($start_date, $end_date, $uid);
|
||||
|
||||
|
||||
$this->terminateWithSuccess(array_merge(
|
||||
$lvplanEvents,
|
||||
@@ -109,6 +122,45 @@ class LvPlan extends FHCAPI_Controller
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* fetches LvPlan for studiengang / semester / verband / gruppe
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function eventsStgOrg()
|
||||
{
|
||||
$this->load->library('StundenplanLib');
|
||||
|
||||
// form validation
|
||||
$this->form_validation->set_rules('start_date', "start_date", "required");
|
||||
$this->form_validation->set_rules('end_date', "end_date", "required");
|
||||
//$this->form_validation->set_rules('stg_kz', "stg_kz", "required"); //no validation show empty calendar
|
||||
|
||||
if (!$this->form_validation->run()) {
|
||||
$this->terminateWithValidationErrors($this->form_validation->error_array());
|
||||
$stgOrgEvents = [];
|
||||
$ferienEvents = [];
|
||||
} else {
|
||||
$start_date = $this->input->post('start_date', true);
|
||||
$end_date = $this->input->post('end_date', true);
|
||||
$stg_kz = $this->input->post('stg_kz', true);
|
||||
$sem = $this->input->post('sem', true);
|
||||
$verband = $this->input->post('verband', true);
|
||||
$gruppe = $this->input->post('gruppe', true);
|
||||
|
||||
$result = $this->stundenplanlib->getEventsStgOrg($start_date, $end_date, $stg_kz, $sem, $verband, $gruppe);
|
||||
$stgOrgEvents = $this->getDataOrTerminateWithError($result);
|
||||
|
||||
$result = $this->stundenplanlib->fetchFerienTageEvents($start_date, $end_date, $stg_kz);
|
||||
$ferienEvents = $this->getDataOrTerminateWithError($result);
|
||||
}
|
||||
|
||||
$this->terminateWithSuccess(array_merge(
|
||||
$stgOrgEvents,
|
||||
$ferienEvents
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* fetches LvPlan and Ferien events together for the lv
|
||||
*
|
||||
@@ -122,7 +174,7 @@ class LvPlan extends FHCAPI_Controller
|
||||
$this->form_validation->set_rules('start_date', "start_date", "required");
|
||||
$this->form_validation->set_rules('end_date', "end_date", "required");
|
||||
$this->form_validation->set_rules('lv_id', "lv_id", "required|integer");
|
||||
|
||||
|
||||
if (!$this->form_validation->run())
|
||||
$this->terminateWithValidationErrors($this->form_validation->error_array());
|
||||
|
||||
@@ -137,7 +189,6 @@ class LvPlan extends FHCAPI_Controller
|
||||
|
||||
// fetching ferien events
|
||||
$ferienEvents = $this->fetchFerienEvents($start_date, $end_date);
|
||||
|
||||
|
||||
$this->terminateWithSuccess(array_merge(
|
||||
$lvplanEvents,
|
||||
@@ -146,40 +197,42 @@ class LvPlan extends FHCAPI_Controller
|
||||
}
|
||||
|
||||
//TODO: delete this function if we don't use the old calendar export endpoints anymore
|
||||
public function studiensemesterDateInterval($date){
|
||||
$this->load->model('organisation/Studiensemester_model','StudiensemesterModel');
|
||||
$studiensemester =$this->StudiensemesterModel->getByDate(date_format(date_create($date),'Y-m-d'));
|
||||
$studiensemester =current($this->getDataOrTerminateWithError($studiensemester));
|
||||
public function studiensemesterDateInterval($date)
|
||||
{
|
||||
$this->load->model('organisation/Studiensemester_model', 'StudiensemesterModel');
|
||||
$studiensemester = $this->StudiensemesterModel->getByDate(date_format(date_create($date), 'Y-m-d'));
|
||||
$studiensemester = current($this->getDataOrTerminateWithError($studiensemester));
|
||||
$this->terminateWithSuccess($studiensemester);
|
||||
}
|
||||
|
||||
public function getLvPlanForStudiensemester($studiensemester,$lvid){
|
||||
public function getLvPlanForStudiensemester($studiensemester, $lvid)
|
||||
{
|
||||
$this->load->library('StundenplanLib');
|
||||
$this->load->model('organisation/Studiensemester_model','StudiensemesterModel');
|
||||
|
||||
$studiensemester_result = $this->StudiensemesterModel->loadWhere(["studiensemester_kurzbz"=>$studiensemester]);
|
||||
$this->load->model('organisation/Studiensemester_model', 'StudiensemesterModel');
|
||||
|
||||
$studiensemester_result = $this->StudiensemesterModel->loadWhere(["studiensemester_kurzbz" => $studiensemester]);
|
||||
$studiensemester_result = current($this->getDataOrTerminateWithError($studiensemester_result));
|
||||
$timespan_start = new DateTime($studiensemester_result->start);
|
||||
$timespan_ende = new DateTime($studiensemester_result->ende);
|
||||
$lvplan = $this->stundenplanlib->getStundenplan(date_format($timespan_start, 'Y-m-d'),date_format($timespan_ende, 'Y-m-d'), $lvid);
|
||||
$lvplan = $this->stundenplanlib->getStundenplan(date_format($timespan_start, 'Y-m-d'), date_format($timespan_ende, 'Y-m-d'), $lvid);
|
||||
$this->terminateWithSuccess($lvplan);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* fetches Stunden layout from database
|
||||
* @access public
|
||||
*
|
||||
*/
|
||||
public function Stunden()
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* fetches Stunden layout from database
|
||||
* @access public
|
||||
*
|
||||
*/
|
||||
public function Stunden()
|
||||
{
|
||||
$this->load->model('ressource/Stunde_model', 'StundeModel');
|
||||
|
||||
$this->StundeModel->addOrder('stunde', 'ASC');
|
||||
$stunden = $this->StundeModel->load();
|
||||
|
||||
$stunden = $this->getDataOrTerminateWithError($stunden);
|
||||
$stunden = $this->getDataOrTerminateWithError($stunden);
|
||||
|
||||
$this->terminateWithSuccess($stunden);
|
||||
}
|
||||
@@ -210,10 +263,10 @@ class LvPlan extends FHCAPI_Controller
|
||||
$roomplan_data = $this->stundenplanlib->getRoomplan($ort_kurzbz, $start_date, $end_date);
|
||||
|
||||
$roomplan_data = $this->getDataOrTerminateWithError($roomplan_data);
|
||||
|
||||
|
||||
$this->terminateWithSuccess($roomplan_data);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* gets the reservierungen of a room if the ort_kurzbz parameter is
|
||||
* supplied otherwise gets the reservierungen of the lvplan of a student
|
||||
@@ -226,25 +279,32 @@ class LvPlan extends FHCAPI_Controller
|
||||
{
|
||||
$this->form_validation->set_rules('start_date', "StartDate", "required");
|
||||
$this->form_validation->set_rules('end_date', "EndDate", "required");
|
||||
|
||||
|
||||
if (!$this->form_validation->run())
|
||||
$this->terminateWithValidationErrors($this->form_validation->error_array());
|
||||
|
||||
// storing the post parameter in local variables
|
||||
$start_date = $this->input->post('start_date', true);
|
||||
$end_date = $this->input->post('end_date', true);
|
||||
$uid = $this->input->post('uid', true);
|
||||
|
||||
// disallow accessing other user's reservierungen if missing permission
|
||||
if ($uid && $uid !== getAuthUID() && !$this->permissionlib->isBerechtigt('basis/other_lv_plan')) {
|
||||
$this->terminateWithError("Missing permission to view other users' timetables!");
|
||||
}
|
||||
|
||||
// get data
|
||||
$this->load->library('StundenplanLib');
|
||||
|
||||
$result = $this->stundenplanlib->getReservierungen($start_date, $end_date, $ort_kurzbz);
|
||||
$result = $this->stundenplanlib->getReservierungen($start_date, $end_date, $ort_kurzbz, $uid);
|
||||
|
||||
$result = $this->getDataOrTerminateWithError($result);
|
||||
|
||||
$this->terminateWithSuccess($result);
|
||||
}
|
||||
|
||||
public function getLehreinheitStudiensemester($lehreinheit_id){
|
||||
public function getLehreinheitStudiensemester($lehreinheit_id)
|
||||
{
|
||||
$this->load->model('education/Lehreinheit_model', 'LehreinheitModel');
|
||||
$this->LehreinheitModel->addSelect(["studiensemester_kurzbz"]);
|
||||
$result = $this->LehreinheitModel->load($lehreinheit_id);
|
||||
@@ -287,6 +347,68 @@ class LvPlan extends FHCAPI_Controller
|
||||
return $this->terminateWithSuccess(current($result));
|
||||
}
|
||||
|
||||
public function getStudiengaenge()
|
||||
{
|
||||
$this->load->model('organisation/Studiengang_model', 'StudiengangModel');
|
||||
|
||||
$this->StudiengangModel->addOrder('typ');
|
||||
$this->StudiengangModel->addOrder('kurzbz');
|
||||
$result = $this->StudiengangModel->loadWhere([
|
||||
'aktiv' => true
|
||||
]);
|
||||
|
||||
$data = $this->getDataOrTerminateWithError($result);
|
||||
|
||||
return $this->terminateWithSuccess($data);
|
||||
}
|
||||
|
||||
public function getLehrverband($studiengang_kz, $semester = null, $verband = null)
|
||||
{
|
||||
$this->load->model('organisation/Lehrverband_model', 'LehrverbandModel');
|
||||
|
||||
$where = [
|
||||
'aktiv' => true,
|
||||
'studiengang_kz' => $studiengang_kz,
|
||||
];
|
||||
|
||||
if ($semester !== null && $semester !== 'null' && $semester !== 'undefined') {
|
||||
$where['semester'] = $semester;
|
||||
}
|
||||
if ($verband !== null && $verband !== 'null' && $verband !== 'undefined') {
|
||||
$where['verband'] = $verband;
|
||||
}
|
||||
|
||||
$this->LehrverbandModel->addOrder('studiengang_kz');
|
||||
$this->LehrverbandModel->addOrder('semester');
|
||||
$this->LehrverbandModel->addOrder('verband');
|
||||
$this->LehrverbandModel->addOrder('gruppe');
|
||||
$result = $this->LehrverbandModel->loadWhere($where);
|
||||
|
||||
$data = $this->getDataOrTerminateWithError($result);
|
||||
|
||||
return $this->terminateWithSuccess($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the current user has permission to view other users' timetables
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function permissionOtherLvPlan()
|
||||
{
|
||||
$this->terminateWithSuccess($this->permissionlib->isBerechtigt('basis/other_lv_plan'));
|
||||
}
|
||||
|
||||
/**
|
||||
* get event types which can be compacted in lv plan display
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function compactibleEventTypes()
|
||||
{
|
||||
$this->terminateWithSuccess(["lehreinheit", "reservierung", "ferien", "moodle"]);
|
||||
}
|
||||
|
||||
/**
|
||||
* fetch moodle events
|
||||
*
|
||||
@@ -294,30 +416,30 @@ class LvPlan extends FHCAPI_Controller
|
||||
* @param string $end_date
|
||||
* @return array
|
||||
*/
|
||||
private function fetchMoodleEvents($start_date, $end_date)
|
||||
private function fetchMoodleEvents($start_date, $end_date, $uid = null)
|
||||
{
|
||||
$this->load->config('calendar');
|
||||
|
||||
$tz = new DateTimeZone($this->config->item('timezone'));
|
||||
|
||||
|
||||
$start = new DateTime($start_date);
|
||||
$start->setTimezone($tz);
|
||||
|
||||
|
||||
$end = new DateTime($end_date);
|
||||
$end->setTimezone($tz);
|
||||
$end->modify('+1 day -1 second');
|
||||
|
||||
|
||||
$moodle_events = [];
|
||||
|
||||
|
||||
Events::trigger(
|
||||
'moodleCalendarEvents',
|
||||
function & () use (&$moodle_events) {
|
||||
function &() use (&$moodle_events) {
|
||||
return $moodle_events;
|
||||
},
|
||||
[
|
||||
'start_date' => $start->format('c'),
|
||||
'end_date' => $end->format('c'),
|
||||
'username' => getAuthUID()
|
||||
'username' => $uid ?? getAuthUID()
|
||||
]
|
||||
);
|
||||
|
||||
@@ -331,23 +453,23 @@ class LvPlan extends FHCAPI_Controller
|
||||
* @param string $end_date
|
||||
* @return array
|
||||
*/
|
||||
private function fetchFerienEvents($start_date, $end_date)
|
||||
private function fetchFerienEvents($start_date, $end_date, $uid = null)
|
||||
{
|
||||
$this->load->model('organisation/Studiensemester_model', 'StudiensemesterModel');
|
||||
$this->load->model('education/Studentlehrverband_model', 'StudentLehrverbandModel');
|
||||
|
||||
$currentStudiensemester = $this->StudiensemesterModel->getByDate($start_date);
|
||||
$currentStudiensemester = $this->getDataOrTerminateWithError($currentStudiensemester);
|
||||
|
||||
|
||||
if ($currentStudiensemester) {
|
||||
$studentsemester_kurzbz = current($currentStudiensemester)->studiensemester_kurzbz;
|
||||
|
||||
$studiengang = $this->StudentLehrverbandModel->loadWhere([
|
||||
"student_uid" => getAuthUID(),
|
||||
"student_uid" => $uid ?? getAuthUID(),
|
||||
"studiensemester_kurzbz" => $studentsemester_kurzbz
|
||||
]);
|
||||
$studiengang = $this->getDataOrTerminateWithError($studiengang);
|
||||
|
||||
|
||||
if ($studiengang)
|
||||
$studiengang_kz = current($studiengang)->studiengang_kz;
|
||||
else
|
||||
@@ -357,7 +479,7 @@ class LvPlan extends FHCAPI_Controller
|
||||
}
|
||||
|
||||
$ferienEvents = $this->stundenplanlib->fetchFerienTageEvents($start_date, $end_date, $studiengang_kz);
|
||||
|
||||
|
||||
return $this->getDataOrTerminateWithError($ferienEvents);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2024 fhcomplete.org
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
if (!defined('BASEPATH'))
|
||||
exit('No direct script access allowed');
|
||||
|
||||
class OtherLvPlan extends FHCAPI_Controller
|
||||
{
|
||||
|
||||
/**
|
||||
* Object initialization
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct([
|
||||
'otherLvPlanViewData' => ['basis/other_lv_plan:r'],
|
||||
]);
|
||||
|
||||
$this->load->model('ressource/mitarbeiter_model', 'MitarbeiterModel');
|
||||
$this->load->model('person/Benutzer_model', 'BenutzerModel');
|
||||
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------------
|
||||
// Public methods
|
||||
|
||||
/**
|
||||
* retrieves viewData for other lv plan view
|
||||
* @access public
|
||||
* @param $uid the userID for which the other lv plan is being viewed
|
||||
*/
|
||||
public function otherLvPlanViewData($uid)
|
||||
{
|
||||
$isMitarbeiterResult = $this->MitarbeiterModel->isMitarbeiter($uid);
|
||||
$isMitarbeiter = getData($isMitarbeiterResult);
|
||||
$isStudent = !$isMitarbeiter;
|
||||
|
||||
$this->BenutzerModel->addSelect(["foto", "vorname", "nachname"]);
|
||||
$this->BenutzerModel->addJoin("tbl_person", "person_id");
|
||||
$personResult = $this->BenutzerModel->load([$uid]);
|
||||
$person = hasData($personResult) ? getData($personResult) : null;
|
||||
|
||||
$viewData = [
|
||||
"user_data" => [
|
||||
"username" => $uid,
|
||||
"is_student" => $isStudent,
|
||||
"is_mitarbeiter" => $isMitarbeiter,
|
||||
"foto" => $person[0]->foto,
|
||||
"vorname" => $person[0]->vorname,
|
||||
"nachname" => $person[0]->nachname,
|
||||
],
|
||||
];
|
||||
|
||||
$this->terminateWithSuccess($viewData);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------------------
|
||||
// Private methods
|
||||
|
||||
}
|
||||
|
||||
@@ -16,7 +16,8 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
if (! defined('BASEPATH')) exit('No direct script access allowed');
|
||||
if (!defined('BASEPATH'))
|
||||
exit('No direct script access allowed');
|
||||
|
||||
class Profil extends FHCAPI_Controller
|
||||
{
|
||||
@@ -27,13 +28,13 @@ class Profil extends FHCAPI_Controller
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct([
|
||||
'fotoSperre' => self::PERM_LOGGED,
|
||||
'fotoSperre' => self::PERM_LOGGED,
|
||||
'getGemeinden' => self::PERM_LOGGED,
|
||||
'getAllNationen' => self::PERM_LOGGED,
|
||||
'isMitarbeiter' => self::PERM_LOGGED,
|
||||
'profilViewData' => self::PERM_LOGGED,
|
||||
]);
|
||||
|
||||
|
||||
$this->load->library('PermissionLib');
|
||||
|
||||
$this->load->model('ressource/mitarbeiter_model', 'MitarbeiterModel');
|
||||
@@ -48,28 +49,37 @@ class Profil extends FHCAPI_Controller
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------------
|
||||
// Public methods
|
||||
public function profilViewData($uid=null){
|
||||
|
||||
/**
|
||||
* retrieves view data for profile view
|
||||
* @access public
|
||||
* @param $uid the userID for which profile is being viewed, null or missing value implies one's own profile
|
||||
*/
|
||||
public function profilViewData($uid = null)
|
||||
{
|
||||
$authUid = getAuthUID();
|
||||
$isProfilOfAuthUser = !$uid || $uid === $authUid;
|
||||
|
||||
$this->load->library('ProfilLib');
|
||||
$editable = false;
|
||||
if(isset($uid) && $uid != null){
|
||||
$profil_data = $this->profillib->getView($uid);
|
||||
if($uid == getAuthUID()){
|
||||
$editable = true;
|
||||
}
|
||||
}else{
|
||||
$editable = true;
|
||||
$profil_data = $this->profillib->getView(getAuthUID());
|
||||
$profileData = $this->profillib->getView($uid ?? $authUid);
|
||||
$profileData = hasData($profileData) ? getData($profileData) : null;
|
||||
|
||||
$viewData = [
|
||||
'editable' => $isProfilOfAuthUser,
|
||||
'profil_data' => $profileData,
|
||||
'permissions' => [
|
||||
'basis/other_lv_plan' => $this->permissionlib->isBerechtigt(('basis/other_lv_plan'))
|
||||
]
|
||||
];
|
||||
|
||||
if ($isProfilOfAuthUser) {
|
||||
$viewData['calendar_sync_urls'] = $this->getCalendarSyncUrlData();
|
||||
}
|
||||
|
||||
$profil_data = hasData($profil_data) ? getData($profil_data) : null;
|
||||
$viewData = array(
|
||||
'editable'=>$editable,
|
||||
'profil_data' => $profil_data,
|
||||
);
|
||||
|
||||
$this->terminateWithSuccess($viewData);
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* update column foto_sperre in public.tbl_person
|
||||
* @access public
|
||||
* @param boolean $value new value for the column
|
||||
@@ -77,9 +87,9 @@ class Profil extends FHCAPI_Controller
|
||||
*/
|
||||
public function fotoSperre($value)
|
||||
{
|
||||
if(!isset($value)){
|
||||
$this->terminateWithError("Missing parameter", self::ERROR_TYPE_GENERAL);
|
||||
}
|
||||
if (!isset($value)) {
|
||||
$this->terminateWithError("Missing parameter", self::ERROR_TYPE_GENERAL);
|
||||
}
|
||||
|
||||
$res = $this->PersonModel->update($this->pid, ["foto_sperre" => $value]);
|
||||
if (isError($res)) {
|
||||
@@ -87,10 +97,10 @@ class Profil extends FHCAPI_Controller
|
||||
}
|
||||
$this->PersonModel->addSelect("foto_sperre");
|
||||
$res = $this->PersonModel->load($this->pid);
|
||||
|
||||
$res = $this->getDataOrTerminateWithError($res);
|
||||
|
||||
$this->terminateWithSuccess(current($res));
|
||||
|
||||
$res = $this->getDataOrTerminateWithError($res);
|
||||
|
||||
$this->terminateWithSuccess(current($res));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -109,7 +119,7 @@ class Profil extends FHCAPI_Controller
|
||||
if (isError($nation_res)) {
|
||||
$this->terminateWithError("error while trying to query table codex.tbl_nation", self::ERROR_TYPE_GENERAL);
|
||||
}
|
||||
|
||||
|
||||
$nation_res = $this->getDataOrTerminateWithError($nation_res);
|
||||
|
||||
$this->terminateWithSuccess($nation_res);
|
||||
@@ -117,30 +127,30 @@ class Profil extends FHCAPI_Controller
|
||||
|
||||
public function getGemeinden($nation, $zip)
|
||||
{
|
||||
if(!isset($nation) || !isset($zip)){
|
||||
if (!isset($nation) || !isset($zip)) {
|
||||
echo json_encode(error("Missing parameters"));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
$this->load->model('codex/Gemeinde_model', "GemeindeModel");
|
||||
|
||||
|
||||
|
||||
$gemeinde_res = $this->GemeindeModel->getGemeindeByPlz($zip);
|
||||
|
||||
|
||||
if (isError($gemeinde_res)) {
|
||||
$this->terminateWithError(getError($gemeinde_res),self::ERROR_TYPE_GENERAL);
|
||||
$this->terminateWithError(getError($gemeinde_res), self::ERROR_TYPE_GENERAL);
|
||||
}
|
||||
$gemeinde_res = $this->getDataOrTerminateWithError($gemeinde_res);
|
||||
|
||||
|
||||
/* $gemeinde_res = array_map(function ($obj) {
|
||||
return $obj->ortschaftsname;
|
||||
}, $gemeinde_res); */
|
||||
|
||||
$this->terminateWithSuccess($gemeinde_res);
|
||||
|
||||
$this->terminateWithSuccess($gemeinde_res);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* checks whether a specific userID is a mitarbeiter or not (foreword declaration of the function isMitarbeiter in Mitarbeiter_model.php)
|
||||
* @access public
|
||||
@@ -150,23 +160,48 @@ class Profil extends FHCAPI_Controller
|
||||
public function isMitarbeiter($uid)
|
||||
{
|
||||
|
||||
if(!$uid) $this->terminateWithError("No uid provided", self::ERROR_TYPE_GENERAL);
|
||||
|
||||
|
||||
if (!$uid)
|
||||
$this->terminateWithError("No uid provided", self::ERROR_TYPE_GENERAL);
|
||||
|
||||
|
||||
$result = $this->MitarbeiterModel->isMitarbeiter($uid);
|
||||
|
||||
|
||||
if (isError($result)) {
|
||||
$this->terminateWithError("error when calling Mitarbeiter_model function isMitarbeiter with uid " . $uid, self::ERROR_TYPE_GENERAL);
|
||||
}
|
||||
|
||||
$result = $this->getDataOrTerminateWithError($result);
|
||||
|
||||
|
||||
$this->terminateWithSuccess($result);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------------------
|
||||
// Private methods
|
||||
|
||||
|
||||
/**
|
||||
* gets the identifier, phrase, and url for each calendar sync option
|
||||
* @access private
|
||||
* @return array array of arrays, where each child array is a sync option
|
||||
*/
|
||||
private function getCalendarSyncUrlData()
|
||||
{
|
||||
return [
|
||||
[
|
||||
"identifier" => "cal_dav",
|
||||
"labelPhrase" => "profil/calendar_sync_cal_dav",
|
||||
"url" => APP_ROOT . "webdav/lvplan.php/calendars/" . $this->uid . "/LVPlan-" . $this->uid,
|
||||
],
|
||||
[
|
||||
"identifier" => "cal_dav_principal",
|
||||
"labelPhrase" => "profil/calendar_sync_cal_dav_principal",
|
||||
"url" => APP_ROOT . "webdav/lvplan.php/principals/" . $this->uid,
|
||||
],
|
||||
[
|
||||
"identifier" => "i_cal",
|
||||
"labelPhrase" => "profil/calendar_sync_i_cal",
|
||||
"url" => APP_ROOT . "webdav/google.php?cal=" . encryptData($this->uid, LVPLAN_CYPHER_KEY) . "&" . microtime(true),
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2024 fhcomplete.org
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
if (!defined('BASEPATH'))
|
||||
exit('No direct script access allowed');
|
||||
|
||||
class StgOrgLvPlan extends FHCAPI_Controller
|
||||
{
|
||||
|
||||
/**
|
||||
* Object initialization
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct([
|
||||
'stgOrgLvPlanViewData' => self::PERM_LOGGED,
|
||||
]);
|
||||
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------------
|
||||
// Public methods
|
||||
|
||||
/**
|
||||
* fetches view data for stg org lv plan
|
||||
* @access public
|
||||
*/
|
||||
public function stgOrgLvPlanViewData()
|
||||
{
|
||||
$this->load->model('organisation/Studiengang_model', 'StudiengangModel');
|
||||
$this->StudiengangModel->addOrder('typ');
|
||||
$this->StudiengangModel->addOrder('kurzbz');
|
||||
$result = $this->StudiengangModel->loadWhere([
|
||||
'aktiv' => true
|
||||
]);
|
||||
$studiengaenge = $this->getDataOrTerminateWithError($result);
|
||||
|
||||
$viewData = array(
|
||||
'studiengaenge' => $studiengaenge,
|
||||
);
|
||||
|
||||
$this->terminateWithSuccess($viewData);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------------------
|
||||
// Private methods
|
||||
|
||||
}
|
||||
|
||||
@@ -62,21 +62,36 @@ class Studium extends FHCAPI_Controller
|
||||
|
||||
if($this->getDataOrTerminateWithError($this->StudentModel->isStudent(getAuthUID()))){
|
||||
$studentLehrverband =$this->StudentlehrverbandModel->loadWhere(["student_uid" => getAuthUID(), "studiensemester_kurzbz" => $aktuelles_studiensemester->studiensemester_kurzbz]);
|
||||
$studentLehrverband = current($this->getDataOrTerminateWithError($studentLehrverband));
|
||||
|
||||
$student_studiensemester = $studentLehrverband->studiensemester_kurzbz;
|
||||
$student_studiengang = $studentLehrverband->studiengang_kz;
|
||||
$student_semester = $studentLehrverband->semester;
|
||||
|
||||
//TODO(Manu) check if use Fallback or just comment out all paramschecks?
|
||||
//add Fallback: if no LehrverbandData of actual semester, get Data of previous one
|
||||
if(!hasData($studentLehrverband))
|
||||
{
|
||||
$result= $this->StudiensemesterModel->getPreviousFrom($aktuelles_studiensemester->studiensemester_kurzbz);
|
||||
|
||||
$data = $this->getDataOrTerminateWithError($result);
|
||||
$vorheriges_studiensemester = current($data)->studiensemester_kurzbz;
|
||||
$studentLehrverband =$this->StudentlehrverbandModel->loadWhere(["student_uid" => getAuthUID(), "studiensemester_kurzbz" => $vorheriges_studiensemester]);
|
||||
}
|
||||
$studentLehrverband = current(getData($studentLehrverband));
|
||||
|
||||
$student_studienplan = $this->getStudienPlanFromPrestudentStatus(getAuthPersonId())->studienplan_id;
|
||||
|
||||
if(!isset($parameter_studiensemester))
|
||||
$parameter_studiensemester = $student_studiensemester;
|
||||
if(!isset($parameter_studiengang))
|
||||
$parameter_studiengang = $student_studiengang;
|
||||
if(!isset($parameter_semester))
|
||||
$parameter_semester = $student_semester;
|
||||
if(!isset($parameter_studiensemester)) {
|
||||
$student_studiensemester = $studentLehrverband->studiensemester_kurzbz;
|
||||
$parameter_studiensemester = $student_studiensemester;
|
||||
}
|
||||
if(!isset($parameter_studiengang)) {
|
||||
$student_studiengang = $studentLehrverband->studiengang_kz;
|
||||
$parameter_studiengang = $student_studiengang;
|
||||
}
|
||||
if(!isset($parameter_semester)) {
|
||||
$student_semester = $studentLehrverband->semester;
|
||||
$parameter_semester = $student_semester;
|
||||
}
|
||||
if(!isset($parameter_studienplan))
|
||||
$parameter_studienplan = $student_studienplan;
|
||||
$parameter_studienplan = $student_studienplan;
|
||||
|
||||
}
|
||||
|
||||
if(isset($parameter_studiensemester)){
|
||||
@@ -96,8 +111,7 @@ class Studium extends FHCAPI_Controller
|
||||
|
||||
// fetch studiensemester
|
||||
$allStudienSemester = $this->getDataOrTerminateWithError($this->StudiensemesterModel->load());
|
||||
|
||||
|
||||
|
||||
if(isset($parameter_studiensemester) && !empty(array_filter($allStudienSemester, function($studiensemester) use($parameter_studiensemester){
|
||||
return $studiensemester->studiensemester_kurzbz == $parameter_studiensemester->studiensemester_kurzbz;
|
||||
}))){
|
||||
@@ -216,6 +230,8 @@ class Studium extends FHCAPI_Controller
|
||||
$studienplaene = array_map(function($studienplan){
|
||||
$orgform = current($this->getDataOrTerminateWithError($this->OrgformModel->loadWhere(["orgform_kurzbz" => $studienplan->orgform_kurzbz])));
|
||||
$studienplan->orgform_bezeichnung = $orgform->bezeichnung;
|
||||
// bezeichnung_mehrsprachig
|
||||
$studienplan->orgform_bezeichnung_english = $orgform->bezeichnung_mehrsprachig[1];
|
||||
return $studienplan;
|
||||
},$studienplaene);
|
||||
return $studienplaene;
|
||||
|
||||
@@ -40,11 +40,32 @@ class Board extends FHCAPI_Controller
|
||||
|
||||
public function list()
|
||||
{
|
||||
$this->DashboardModel->addSelect('dashboard_id');
|
||||
$this->DashboardModel->addSelect('dashboard_kurzbz');
|
||||
$this->DashboardModel->addSelect('tbl_dashboard.beschreibung');
|
||||
$this->DashboardModel->addSelect("(
|
||||
SELECT json_agg(w.*)
|
||||
FROM dashboard.tbl_widget w
|
||||
JOIN dashboard.tbl_dashboard_widget dw
|
||||
USING(widget_id)
|
||||
WHERE dw.dashboard_id=tbl_dashboard.dashboard_id
|
||||
) AS \"widgetSetup\"");
|
||||
|
||||
$result = $this->DashboardModel->load();
|
||||
|
||||
$data = $this->getDataOrTerminateWithError($result);
|
||||
|
||||
$this->terminateWithSuccess($result);
|
||||
$data = array_map(function ($dashboard) {
|
||||
$tmpSetups = json_decode($dashboard->widgetSetup);
|
||||
$tmpSetups = array_map(function ($widget) {
|
||||
$widget->setup->file = absoluteJsImportUrl($widget->setup->file);
|
||||
return $widget;
|
||||
}, $tmpSetups);
|
||||
$dashboard->widgetSetup = $tmpSetups;
|
||||
return $dashboard;
|
||||
}, $data);
|
||||
|
||||
$this->terminateWithSuccess($data);
|
||||
}
|
||||
|
||||
public function create()
|
||||
@@ -82,7 +103,7 @@ class Board extends FHCAPI_Controller
|
||||
|
||||
$data = $this->getDataOrTerminateWithError($result);
|
||||
|
||||
$this->terminateWithSuccess($result);
|
||||
$this->terminateWithSuccess($data);
|
||||
}
|
||||
|
||||
public function delete()
|
||||
@@ -116,6 +137,6 @@ class Board extends FHCAPI_Controller
|
||||
|
||||
$data = $this->getDataOrTerminateWithError($result);
|
||||
|
||||
$this->terminateWithSuccess($result);
|
||||
$this->terminateWithSuccess($data);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -120,10 +120,7 @@ class Preset extends FHCAPI_Controller
|
||||
$conf = $this->dashboardlib->getPreset($db, $funktion);
|
||||
if ($conf) {
|
||||
$preset = json_decode($conf->preset, true);
|
||||
if (!isset($preset[$funktion]) || !isset($preset[$funktion]['widgets']))
|
||||
$result[$funktion] = [];
|
||||
else
|
||||
$result[$funktion] = $preset[$funktion]['widgets'];
|
||||
$result[$funktion] = $preset;
|
||||
} else {
|
||||
$result[$funktion] = [];
|
||||
}
|
||||
@@ -154,7 +151,7 @@ class Preset extends FHCAPI_Controller
|
||||
|
||||
$preset_decoded = json_decode($preset->preset, true);
|
||||
|
||||
$this->dashboardlib->addWidgetsToWidgets($preset_decoded, $dashboard_kurzbz, $funktion_kurzbz, [$widget]);
|
||||
$preset_decoded[$widget['widgetid']] = $widget;
|
||||
|
||||
$preset->preset = json_encode($preset_decoded);
|
||||
|
||||
@@ -186,8 +183,10 @@ class Preset extends FHCAPI_Controller
|
||||
|
||||
$preset_decoded = json_decode($preset->preset, true);
|
||||
|
||||
if (!$this->dashboardlib->removeWidgetFromWidgets($preset_decoded, $funktion_kurzbz, $widgetid))
|
||||
if (!isset($preset_decoded[$widgetid]))
|
||||
show_404();
|
||||
|
||||
unset($preset_decoded[$widgetid]);
|
||||
|
||||
$preset->preset = json_encode($preset_decoded);
|
||||
|
||||
|
||||
@@ -48,25 +48,9 @@ class User extends FHCAPI_Controller
|
||||
|
||||
$uid = $this->authlib->getAuthObj()->username;
|
||||
|
||||
/*$mergedconfig = $this->dashboardlib->getMergedConfig($dashboard->dashboard_id, $uid);
|
||||
$mergedconfig = $this->dashboardlib->getMergedUserConfig($dashboard->dashboard_id, $uid);
|
||||
|
||||
$this->terminateWithSuccess([
|
||||
'general' => call_user_func_array(
|
||||
'array_merge_recursive',
|
||||
$mergedconfig
|
||||
)
|
||||
]);*/
|
||||
$defaultconfig = $this->dashboardlib->getDefaultConfig($dashboard->dashboard_id);
|
||||
$userconfig = $this->dashboardlib->getUserConfig($dashboard->dashboard_id, $uid);
|
||||
|
||||
$defaultconfig_squashed = $defaultconfig ? call_user_func_array('array_replace_recursive', $defaultconfig) : [];
|
||||
$userconfig_squashed = $userconfig ? call_user_func_array('array_replace_recursive', $userconfig) : [];
|
||||
|
||||
$mergedconfig = array_replace_recursive($defaultconfig_squashed, $userconfig_squashed);
|
||||
|
||||
$this->terminateWithSuccess([
|
||||
DashboardLib::SECTION_IF_FUNKTION_KURZBZ_IS_NULL => $mergedconfig
|
||||
]);
|
||||
$this->terminateWithSuccess($mergedconfig);
|
||||
}
|
||||
|
||||
public function addWidget()
|
||||
@@ -86,26 +70,15 @@ class User extends FHCAPI_Controller
|
||||
if (!isset($widget['widgetid']))
|
||||
$widget['widgetid'] = $this->dashboardlib->generateWidgetId($dashboard_kurzbz);
|
||||
|
||||
if (isset($widget['source']))
|
||||
unset($widget['source']);
|
||||
|
||||
$override = $this->dashboardlib->getOverrideOrCreateEmptyOverride($dashboard_kurzbz, $uid);
|
||||
|
||||
|
||||
$override_decoded = json_decode($override->override, true);
|
||||
|
||||
if (!isset($override_decoded['general']) || !is_array($override_decoded['general']))
|
||||
$override_decoded['general'] = [];
|
||||
$override_decoded[$widget['widgetid']] = $widget;
|
||||
|
||||
if (!isset($override_decoded['general']['widgets']))
|
||||
$override_decoded['general']['widgets'] = [];
|
||||
|
||||
$override_decoded['general']['widgets'][$widget['widgetid']] = $widget;
|
||||
|
||||
// NOTE(chris): remove doubles in other funktionen
|
||||
foreach ($override_decoded as $funktion => $array) {
|
||||
if ($funktion == 'general')
|
||||
continue;
|
||||
if (isset($array['widgets']) && isset($array['widgets'][$widget['widgetid']]))
|
||||
unset($override_decoded[$funktion]['widgets'][$widget['widgetid']]);
|
||||
}
|
||||
|
||||
$override->override = json_encode($override_decoded);
|
||||
|
||||
$result = $this->dashboardlib->insertOrUpdateOverride($override);
|
||||
@@ -135,18 +108,10 @@ class User extends FHCAPI_Controller
|
||||
|
||||
$override_decoded = json_decode($override->override, true);
|
||||
|
||||
foreach (array_keys($override_decoded) as $k) {
|
||||
if (!isset($override_decoded[$k]["widgets"])) {
|
||||
unset($override_decoded[$k]);
|
||||
continue;
|
||||
}
|
||||
if (isset($override_decoded[$k]["widgets"][$widget_id])) {
|
||||
unset($override_decoded[$k]["widgets"][$widget_id]);
|
||||
}
|
||||
if (!$override_decoded[$k]["widgets"]) {
|
||||
unset($override_decoded[$k]);
|
||||
}
|
||||
}
|
||||
if (!isset($override_decoded[$widget_id]))
|
||||
show_404();
|
||||
|
||||
unset($override_decoded[$widget_id]);
|
||||
|
||||
$override->override = json_encode($override_decoded);
|
||||
|
||||
|
||||
@@ -78,52 +78,32 @@ class Dokumente extends FHCAPI_Controller
|
||||
$this->terminateWithError($this->p->t('ui', 'errorMissingValue', ['value' => 'Studiengang_kz']), self::ERROR_TYPE_GENERAL);
|
||||
|
||||
$resultPreDoc = $this->_getPrestudentDokumente($prestudent_id);
|
||||
|
||||
$arrayAccepted = [];
|
||||
$person_id = $this->_getPersonId($prestudent_id);
|
||||
|
||||
$docNames = array_map(function ($item) {
|
||||
return $item->dokument_kurzbz;
|
||||
}, $resultPreDoc);
|
||||
$mergedArray = [];
|
||||
|
||||
foreach($docNames as $doc)
|
||||
foreach ($resultPreDoc as $pre)
|
||||
{
|
||||
$result = $this->AkteModel->getAktenFAS($person_id, $doc, $studiengang_kz, $prestudent_id, true);
|
||||
$result = $this->AkteModel->getAktenFAS($person_id, $pre->dokument_kurzbz, $studiengang_kz, $prestudent_id, true);
|
||||
|
||||
if (isError($result))
|
||||
{
|
||||
return $this->terminateWithError($result, self::ERROR_TYPE_GENERAL);
|
||||
}
|
||||
|
||||
if (hasData($result))
|
||||
{
|
||||
$data = getData($result);
|
||||
foreach ($data as $value)
|
||||
foreach (getData($result) as $doc)
|
||||
{
|
||||
array_push($arrayAccepted, $value);
|
||||
$merged = clone $doc;
|
||||
$merged->docdatum = $pre->docdatum;
|
||||
$merged->insertvonma = $pre->insertvonma;
|
||||
$merged->bezeichnung = $pre->bezeichnung;
|
||||
$mergedArray[] = $merged;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Mapping with document_kurzbz
|
||||
$preDocMap = [];
|
||||
foreach ($resultPreDoc as $pre) {
|
||||
$preDocMap[$pre->dokument_kurzbz] = $pre;
|
||||
}
|
||||
|
||||
$mergedArray = [];
|
||||
foreach ($arrayAccepted as $doc) {
|
||||
$merged = clone $doc;
|
||||
|
||||
if (isset($preDocMap[$doc->dokument_kurzbz])) {
|
||||
$merged->docdatum = $preDocMap[$doc->dokument_kurzbz]->docdatum;
|
||||
$merged->insertvonma = $preDocMap[$doc->dokument_kurzbz]->insertvonma;
|
||||
$merged->bezeichnung = $preDocMap[$doc->dokument_kurzbz]->bezeichnung;
|
||||
} else {
|
||||
$merged->akzeptiertdatum = null;
|
||||
$merged->akzeptiertvon = null;
|
||||
else
|
||||
{
|
||||
$mergedArray[] = $pre;
|
||||
}
|
||||
|
||||
$mergedArray[] = $merged;
|
||||
}
|
||||
|
||||
$this->terminateWithSuccess($mergedArray);
|
||||
|
||||
@@ -48,7 +48,8 @@ class Konto extends FHCAPI_Controller
|
||||
|
||||
// Load language phrases
|
||||
$this->loadPhrases([
|
||||
'konto'
|
||||
'konto',
|
||||
'lehre'
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -112,7 +113,7 @@ class Konto extends FHCAPI_Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function getBuchungstypen()
|
||||
public function getBuchungstypen($studiensemester_kurzbz = null)
|
||||
{
|
||||
$this->load->model('crm/Buchungstyp_model', 'BuchungstypModel');
|
||||
|
||||
@@ -122,6 +123,7 @@ class Konto extends FHCAPI_Controller
|
||||
|
||||
$data = $this->getDataOrTerminateWithError($result);
|
||||
|
||||
$this->_getOEHBeitrag($data, $studiensemester_kurzbz);
|
||||
$this->terminateWithSuccess($data);
|
||||
}
|
||||
|
||||
@@ -494,4 +496,43 @@ class Konto extends FHCAPI_Controller
|
||||
|
||||
$this->terminateWithSuccess();
|
||||
}
|
||||
|
||||
private function _getOEHBeitrag(&$data, $studiensemester_kurzbz = null)
|
||||
{
|
||||
if (is_null($studiensemester_kurzbz))
|
||||
{
|
||||
$this->load->library('VariableLib', ['uid' => getAuthUID()]);
|
||||
$studiensemester_akt = $this->variablelib->getVar('semester_aktuell');
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->load->model('organisation/Studiensemester_model', 'StudiensemesterModel');
|
||||
if ($this->StudiensemesterModel->isValidStudiensemester($studiensemester_kurzbz))
|
||||
$studiensemester_akt = $studiensemester_kurzbz;
|
||||
else
|
||||
$this->terminateWithError($this->p->t('lehre', 'error_noStudiensemester'));
|
||||
}
|
||||
|
||||
$this->load->model('codex/Oehbeitrag_model', 'OehbeitragModel');
|
||||
$oehBeitrag = $this->OehbeitragModel->getByStudiensemester($studiensemester_akt);
|
||||
|
||||
$oehStandardbetrag = null;
|
||||
if (hasData($oehBeitrag))
|
||||
{
|
||||
$oeh = getData($oehBeitrag)[0];
|
||||
$summe = ($oeh->studierendenbeitrag + $oeh->versicherung) * -1;
|
||||
$oehStandardbetrag = number_format((float)$summe, 2, '.', '');
|
||||
}
|
||||
|
||||
if ($oehStandardbetrag !== null)
|
||||
{
|
||||
$data = array_map(function ($buchungstyp) use ($oehStandardbetrag) {
|
||||
if (isset($buchungstyp->buchungstyp_kurzbz) && (strtolower($buchungstyp->buchungstyp_kurzbz) === 'oeh'))
|
||||
{
|
||||
$buchungstyp->standardbetrag = $oehStandardbetrag;
|
||||
}
|
||||
return $buchungstyp;
|
||||
}, $data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -417,6 +417,7 @@ abstract class Notiz_Controller extends FHCAPI_Controller
|
||||
$notiz_id = $this->input->post('notiz_id');
|
||||
|
||||
$this->NotizModel->addSelect('campus.tbl_dms_version.*');
|
||||
$this->NotizModel->addSelect($this->NotizModel->escape(base_url('content/notizdokdownload.php?id=')) . ' || public.tbl_notiz_dokument.dms_id AS preview');
|
||||
|
||||
$this->NotizModel->addJoin('public.tbl_notiz_dokument', 'ON (public.tbl_notiz_dokument.notiz_id = public.tbl_notiz.notiz_id)');
|
||||
$this->NotizModel->addJoin('campus.tbl_dms_version', 'ON (public.tbl_notiz_dokument.dms_id = campus.tbl_dms_version.dms_id)');
|
||||
|
||||
@@ -128,7 +128,7 @@ class AntragLib
|
||||
return $this->_ci->StudierendenantragstatusModel->resumeAntraegeForAbmeldungStgl($antrag_id);
|
||||
}
|
||||
// NOTE(chris): get last status that is not pause
|
||||
$this->_ci->StudierendenantragstatusModel->addOrder('insertamum');
|
||||
$this->_ci->StudierendenantragstatusModel->addOrder('insertamum', 'DESC');
|
||||
$this->_ci->StudierendenantragstatusModel->addLimit(1);
|
||||
$result = $this->_ci->StudierendenantragstatusModel->loadWhere([
|
||||
'studierendenantrag_id' => $antrag_id,
|
||||
|
||||
@@ -40,13 +40,16 @@ class StundenplanLib
|
||||
* @return stdClass
|
||||
* @access public
|
||||
*/
|
||||
public function getEventsUser($start, $end)
|
||||
public function getEventsUser($start, $end, $uid = null)
|
||||
{
|
||||
$this->_ci =& get_instance();
|
||||
|
||||
$this->_ci->load->model('ressource/Mitarbeiter_model', 'MitarbeiterModel');
|
||||
|
||||
$uid = getAuthUID();
|
||||
if (!$uid) {
|
||||
$uid = getAuthUID();
|
||||
}
|
||||
|
||||
if (is_null($uid))
|
||||
return error("No UID");
|
||||
|
||||
@@ -217,7 +220,7 @@ class StundenplanLib
|
||||
* @param string $ort_kurzbz
|
||||
* @return stdClass
|
||||
*/
|
||||
public function getReservierungen($start_date, $end_date, $ort_kurzbz = '')
|
||||
public function getReservierungen($start_date, $end_date, $ort_kurzbz = '', $uid = null)
|
||||
{
|
||||
$this->_ci =& get_instance();
|
||||
|
||||
@@ -228,14 +231,14 @@ class StundenplanLib
|
||||
$this->_ci->load->model('ressource/Reservierung_model', 'ReservierungModel');
|
||||
$this->_ci->load->model('ressource/Stundenplan_model', 'StundenplanModel');
|
||||
|
||||
$is_mitarbeiter = getData($this->_ci->MitarbeiterModel->isMitarbeiter(getAuthUID()));
|
||||
$is_mitarbeiter = getData($this->_ci->MitarbeiterModel->isMitarbeiter($uid ?? getAuthUID()));
|
||||
|
||||
if ($is_mitarbeiter && empty($ort_kurzbz)) {
|
||||
// request for personal lvplan show only reservations of logged in user
|
||||
$reservierungen = $this->_ci->ReservierungModel->getReservierungenMitarbeiter($start_date, $end_date);
|
||||
$reservierungen = $this->_ci->ReservierungModel->getReservierungenMitarbeiter($start_date, $end_date, $uid);
|
||||
} else {
|
||||
// querying the reservierungen
|
||||
$reservierungen = $this->_ci->ReservierungModel->getReservierungen($start_date, $end_date, $ort_kurzbz);
|
||||
$reservierungen = $this->_ci->ReservierungModel->getReservierungen($start_date, $end_date, $ort_kurzbz, $uid);
|
||||
}
|
||||
|
||||
if (isError($reservierungen))
|
||||
@@ -357,7 +360,10 @@ class StundenplanLib
|
||||
if (isError($ort_content_object)) {
|
||||
return error(getData($ort_content_object));
|
||||
}
|
||||
$ort_content_object = getData($ort_content_object)[0];
|
||||
$ort_content_object_data = getData($ort_content_object);
|
||||
$ort_content_object = (is_array($ort_content_object_data) && count($ort_content_object_data) > 0)
|
||||
? $ort_content_object_data[0]
|
||||
: null;
|
||||
if($ort_content_object) {
|
||||
$item->ort_content_id = $ort_content_object->content_id;
|
||||
}
|
||||
@@ -445,6 +451,24 @@ class StundenplanLib
|
||||
return success($ferienEventsFlattened);
|
||||
}
|
||||
|
||||
public function getEventsStgOrg( $start, $end, $stg_kz, $sem, $verband, $gruppe)
|
||||
{
|
||||
$this->_ci =& get_instance();
|
||||
|
||||
$this->_ci->load->model('ressource/Stundenplan_model', 'StundenplanModel');
|
||||
|
||||
$stundenplan_data = $this->_ci->StundenplanModel->getStundenplanStudiengang($start, $end, $stg_kz, $sem, $verband, $gruppe);
|
||||
if (isError($stundenplan_data))
|
||||
return $stundenplan_data;
|
||||
$stundenplan_data = getData($stundenplan_data) ?? [];
|
||||
|
||||
$function_error = $this->expandObjectInformation($stundenplan_data);
|
||||
if ($function_error)
|
||||
return $function_error;
|
||||
|
||||
return success($stundenplan_data);
|
||||
}
|
||||
|
||||
// start of the private functions ########################################################################################################
|
||||
|
||||
// function used to sort an array of studiensemester strings
|
||||
|
||||
@@ -37,7 +37,9 @@ class DashboardLib
|
||||
|
||||
public function getDashboardByKurzbz($dashboard_kurzbz)
|
||||
{
|
||||
$result = $this->_ci->DashboardModel->getDashboardByKurzbz($dashboard_kurzbz);
|
||||
$result = $this->_ci->DashboardModel->loadWhere([
|
||||
'dashboard_kurzbz' => $dashboard_kurzbz
|
||||
]);
|
||||
|
||||
if (hasData($result))
|
||||
{
|
||||
@@ -47,17 +49,21 @@ class DashboardLib
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getMergedConfig($dashboard_id, $uid)
|
||||
public function getMergedUserConfig($dashboard_id, $uid)
|
||||
{
|
||||
$defaultconfig = $this->getDefaultConfig($dashboard_id);
|
||||
$userconfig = $this->getUserConfig($dashboard_id, $uid);
|
||||
$defaultconfig = $this->getUserBaseConfig($dashboard_id);
|
||||
$userconfig = $this->getUserOverrideConfig($dashboard_id, $uid);
|
||||
|
||||
$mergedconfig = array_replace_recursive($defaultconfig, $userconfig);
|
||||
$sourceconfig = array_map(function ($value) {
|
||||
return ['source' => $value['source']];
|
||||
}, $defaultconfig);
|
||||
|
||||
$mergedconfig = array_replace_recursive($defaultconfig, $userconfig, $sourceconfig);
|
||||
|
||||
return $mergedconfig;
|
||||
}
|
||||
|
||||
public function getDefaultConfig($dashboard_id)
|
||||
protected function getUserBaseConfig($dashboard_id)
|
||||
{
|
||||
$funktion_kurzbzs = [];
|
||||
$rights = $this->_ci->permissionlib->getAccessRights();
|
||||
@@ -87,7 +93,11 @@ class DashboardLib
|
||||
$preset = json_decode($presetobj->preset, true);
|
||||
if (null !== $preset)
|
||||
{
|
||||
$defaultconfig = array_replace_recursive($defaultconfig, $preset);
|
||||
$preset = array_map(function ($value) use ($presetobj) {
|
||||
$value['source'] = $presetobj->funktion_kurzbz ?: self::SECTION_IF_FUNKTION_KURZBZ_IS_NULL;
|
||||
return $value;
|
||||
}, $preset);
|
||||
$defaultconfig = array_merge_recursive($defaultconfig, $preset);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -95,7 +105,7 @@ class DashboardLib
|
||||
return $defaultconfig;
|
||||
}
|
||||
|
||||
public function getUserConfig($dashboard_id, $uid)
|
||||
protected function getUserOverrideConfig($dashboard_id, $uid)
|
||||
{
|
||||
$res_userconfig = $this->_ci->DashboardOverrideModel->getOverride($dashboard_id, $uid);
|
||||
|
||||
@@ -124,7 +134,7 @@ class DashboardLib
|
||||
$emptyoverride = new stdClass();
|
||||
$emptyoverride->dashboard_id = $dashboard->dashboard_id;
|
||||
$emptyoverride->uid = $uid;
|
||||
$emptyoverride->override = '{"' . self::USEROVERRIDE_SECTION . '": {"widgets":{}}, "custom": { "widgets" : {}}}';
|
||||
$emptyoverride->override = '[]';
|
||||
|
||||
return $emptyoverride;
|
||||
}
|
||||
@@ -143,8 +153,7 @@ class DashboardLib
|
||||
$emptypreset = new stdClass();
|
||||
$emptypreset->dashboard_id = $dashboard->dashboard_id;
|
||||
$emptypreset->funktion_kurzbz = $funktion_kurzbz;
|
||||
$section = ($funktion_kurzbz !== null) ? $funktion_kurzbz : self::SECTION_IF_FUNKTION_KURZBZ_IS_NULL;
|
||||
$emptypreset->preset = '{"' . $section . '": { "widgets" : {}},"custom": { "widgets" : {}}}';
|
||||
$emptypreset->preset = '[]';
|
||||
|
||||
return $emptypreset;
|
||||
}
|
||||
@@ -209,44 +218,4 @@ class DashboardLib
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function addWidgetsToWidgets(&$widgets, $dashboard_kurzbz, $section, $addwigets)
|
||||
{
|
||||
foreach ($addwigets as $widget)
|
||||
{
|
||||
if(!isset($widget['widgetid']))
|
||||
{
|
||||
$widget['widgetid'] = $this->generateWidgetId($dashboard_kurzbz);
|
||||
}
|
||||
$this->addWidgetToWidgets($widgets, $section, $widget, $widget['widgetid']);
|
||||
}
|
||||
}
|
||||
|
||||
public function addWidgetToWidgets(&$widgets, $section, $widget, $widgetid)
|
||||
{
|
||||
$section = ($section !== null) ? $section : self::SECTION_IF_FUNKTION_KURZBZ_IS_NULL;
|
||||
if (!isset($widgets[$section]) || !isset($widgets[$section]["widgets"]) || !is_array($widgets[$section]))
|
||||
{
|
||||
$widgets[$section] = array();
|
||||
$widgets[$section]["widgets"] = array();
|
||||
}
|
||||
|
||||
$widgets[$section]["widgets"][$widgetid] = $widget;
|
||||
}
|
||||
|
||||
public function removeWidgetFromWidgets(&$widgets, $section, $widgetid)
|
||||
{
|
||||
$section = ($section !== null) ? $section : self::SECTION_IF_FUNKTION_KURZBZ_IS_NULL;
|
||||
if (isset($widgets[$section]) && isset($widgets[$section]["widgets"][$widgetid]))
|
||||
{
|
||||
unset($widgets[$section]["widgets"][$widgetid]);
|
||||
if(empty($widgets[$section]["widgets"]) && $section !== self::USEROVERRIDE_SECTION) {
|
||||
unset($widgets[$section]);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,7 +40,9 @@ abstract class AbstractBestandteil implements IValidation
|
||||
|
||||
if( is_bool($new_value) && ($old_value !== $new_value) ) {
|
||||
$this->modifiedcolumns[$columnname] = $columnname;
|
||||
} else if($old_value != $new_value) {
|
||||
} else if(is_null($old_value) xor is_null($new_value)) {
|
||||
$this->modifiedcolumns[$columnname] = $columnname;
|
||||
} else if($old_value != $new_value) {
|
||||
$this->modifiedcolumns[$columnname] = $columnname;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -137,19 +137,25 @@ EOTXT;
|
||||
return parent::__toString() . $txt;
|
||||
}
|
||||
|
||||
/* public function validate()
|
||||
public function validate()
|
||||
{
|
||||
if( !(filter_var($this->tage, FILTER_VALIDATE_INT,
|
||||
array(
|
||||
'options' => array(
|
||||
'min_range' => 1,
|
||||
'max_range' => 50
|
||||
)
|
||||
)
|
||||
)) ) {
|
||||
$this->validationerrors[] = 'Urlaubsanspruch muss eine Tagesanzahl im Bereich 1 bis 50 sein.';
|
||||
$value = $this->vordienstzeit;
|
||||
|
||||
if ($value === null || $value === '') {
|
||||
$result = null; // allow null value
|
||||
} else {
|
||||
$result = filter_var($value, FILTER_VALIDATE_INT, [
|
||||
'options' => [
|
||||
'min_range' => 0,
|
||||
'max_range' => 100
|
||||
]
|
||||
]);
|
||||
|
||||
if ($result === false) {
|
||||
$this->validationerrors[] = 'Vordienstjahre muss eine ganze Zahl (0 bis 100) enthalten oder leer sein.';
|
||||
}
|
||||
}
|
||||
|
||||
return parent::validate();
|
||||
} */
|
||||
}
|
||||
}
|
||||
|
||||
@@ -234,9 +234,9 @@ class Content_model extends DB_Model
|
||||
FROM
|
||||
campus.tbl_content c1
|
||||
LEFT JOIN
|
||||
campus.tbl_contentsprache s1 ON c1.content_id=s1.content_id AND s1.sprache=?
|
||||
campus.tbl_contentsprache s1 ON c1.content_id=s1.content_id AND s1.sprache=? AND sichtbar=true
|
||||
WHERE
|
||||
sichtbar=true
|
||||
c1.aktiv = true
|
||||
) s2
|
||||
LEFT JOIN
|
||||
campus.tbl_contentsprache s3 USING(content_id, sprache)
|
||||
@@ -277,7 +277,7 @@ class Content_model extends DB_Model
|
||||
JOIN
|
||||
campus.tbl_contentsprache s USING(contentsprache_id)
|
||||
LEFT JOIN
|
||||
campus.tbl_contentchild k ON(m.content_id=k.content_id)
|
||||
campus.tbl_contentchild k ON(m.content_id=k.content_id) and c.aktiv = true
|
||||
WHERE EXISTS (
|
||||
SELECT 1
|
||||
FROM campus.tbl_contentgruppe
|
||||
|
||||
@@ -11,8 +11,4 @@ class Bookmark_model extends DB_Model
|
||||
$this->dbTable = 'dashboard.tbl_bookmark';
|
||||
$this->pk = 'bookmark_id';
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -11,15 +11,4 @@ class Dashboard_model extends DB_Model
|
||||
$this->dbTable = 'dashboard.tbl_dashboard';
|
||||
$this->pk = 'dashboard_id';
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get Dashboard by kurzbz.
|
||||
* @param string dashboard_kurzbz
|
||||
* @return array
|
||||
*/
|
||||
public function getDashboardByKurzbz($dashboard_kurzbz)
|
||||
{
|
||||
return $this->loadWhere(array('dashboard_kurzbz' => $dashboard_kurzbz));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,10 +79,10 @@ class Paabgabe_model extends DB_Model
|
||||
JOIN public.tbl_benutzer ON (public.tbl_benutzer.uid = student_uid)
|
||||
JOIN public.tbl_person USING (person_id)
|
||||
|
||||
WHERE (campus.tbl_paabgabe.insertamum >= NOW() - INTERVAL ?
|
||||
OR campus.tbl_paabgabe.updateamum >= NOW() - INTERVAL ?)
|
||||
AND campus.tbl_paabgabe.paabgabetyp_kurzbz IN ?";
|
||||
|
||||
WHERE (campus.tbl_paabgabe.insertamum::date = CURRENT_DATE - INTERVAL ?
|
||||
OR campus.tbl_paabgabe.updateamum::date = CURRENT_DATE - INTERVAL ?)
|
||||
AND campus.tbl_paabgabe.paabgabetyp_kurzbz IN ?";
|
||||
|
||||
return $this->execQuery($query, [$interval, $interval, $relevantTypes]);
|
||||
}
|
||||
|
||||
@@ -108,7 +108,7 @@ class Paabgabe_model extends DB_Model
|
||||
JOIN public.tbl_person ON (public.tbl_benutzer.person_id = public.tbl_person.person_id)
|
||||
|
||||
WHERE campus.tbl_paabgabe.abgabedatum IS NOT NULL
|
||||
AND campus.tbl_paabgabe.abgabedatum >= NOW() - INTERVAL ?";
|
||||
AND campus.tbl_paabgabe.abgabedatum = CURRENT_DATE - INTERVAL ?";
|
||||
|
||||
if($relevantTypes !== null) {
|
||||
$query .= " AND campus.tbl_paabgabe.paabgabetyp_kurzbz IN ?";
|
||||
|
||||
@@ -594,7 +594,10 @@ class Studiengang_model extends DB_Model
|
||||
$this->addSelect('p.prestudent_id');
|
||||
$this->addSelect('pers.vorname');
|
||||
$this->addSelect('pers.nachname');
|
||||
$this->addSelect("CONCAT(UPPER(pers.nachname), ' ', pers.vorname, ' (', " . $this->dbTable . ".bezeichnung, ')') AS name");
|
||||
$this->addSelect("CONCAT(UPPER(pers.nachname), ' ', pers.vorname, ' (', "
|
||||
. $this->dbTable . ".bezeichnung, ', ', "
|
||||
. "UPPER(" . $this->dbTable . ".typ), "
|
||||
. "UPPER(" . $this->dbTable . ".kurzbz),')') AS name");
|
||||
|
||||
$this->addJoin('public.tbl_prestudent p', 'studiengang_kz');
|
||||
$this->addJoin(
|
||||
|
||||
@@ -18,10 +18,10 @@ class Reservierung_model extends DB_Model
|
||||
*
|
||||
* @return stdClass
|
||||
*/
|
||||
public function getReservierungen($start_date, $end_date, $ort_kurzbz = null)
|
||||
public function getReservierungen($start_date, $end_date, $ort_kurzbz = null, $uid = null)
|
||||
{
|
||||
|
||||
$lvplan_reservierungen_query="SELECT r.* , stund.beginn, stund.ende,
|
||||
|
||||
$lvplan_reservierungen_query = "SELECT r.* , stund.beginn, stund.ende,
|
||||
CASE
|
||||
WHEN r.gruppe_kurzbz IS NOT NULL THEN r.gruppe_kurzbz
|
||||
ELSE CONCAT(UPPER(studg.typ),UPPER(studg.kurzbz),'-',COALESCE(CAST(r.semester AS varchar),'/'),COALESCE(CAST(r.verband AS varchar),'/'))
|
||||
@@ -35,7 +35,7 @@ class Reservierung_model extends DB_Model
|
||||
LEFT JOIN public.tbl_studiensemester ss2 ON slv.studiensemester_kurzbz = ss2.studiensemester_kurzbz AND ss2.start <=r.datum AND ss2.ende >= r.datum
|
||||
WHERE datum >= ? AND datum <= ? AND (ss1.studiensemester_kurzbz IS NOT NULL
|
||||
OR ss2.studiensemester_kurzbz IS NOT NULL)";
|
||||
|
||||
|
||||
$raum_reservierungen_query = "SELECT res.*, beginn, ende,
|
||||
CASE
|
||||
WHEN res.gruppe_kurzbz IS NOT NULL THEN res.gruppe_kurzbz
|
||||
@@ -46,9 +46,9 @@ class Reservierung_model extends DB_Model
|
||||
JOIN lehre.tbl_stunde ON lehre.tbl_stunde.stunde = res.stunde
|
||||
WHERE res.ort_kurzbz = ? AND datum >= ? AND datum <= ?";
|
||||
|
||||
$subquery = is_null($ort_kurzbz)? $lvplan_reservierungen_query:$raum_reservierungen_query;
|
||||
|
||||
$query_result= $this->execReadOnlyQuery("
|
||||
$subquery = is_null($ort_kurzbz) ? $lvplan_reservierungen_query : $raum_reservierungen_query;
|
||||
|
||||
$query_result = $this->execReadOnlyQuery("
|
||||
SELECT
|
||||
'reservierung' as type, beginn, ende, datum,
|
||||
COALESCE(titel, beschreibung) as topic,
|
||||
@@ -59,15 +59,15 @@ class Reservierung_model extends DB_Model
|
||||
|
||||
FROM
|
||||
(
|
||||
". $subquery ."
|
||||
" . $subquery . "
|
||||
) AS subquery
|
||||
|
||||
GROUP BY datum, beginn, ende, ort_kurzbz, titel, beschreibung
|
||||
|
||||
ORDER BY datum, beginn
|
||||
", is_null($ort_kurzbz) ?[getAuthUID(), getAuthUID(),$start_date,$end_date]: [$ort_kurzbz, $start_date, $end_date]);
|
||||
", is_null($ort_kurzbz) ? [$uid ?? getAuthUID(), $uid ?? getAuthUID(), $start_date, $end_date] : [$ort_kurzbz, $start_date, $end_date]);
|
||||
|
||||
|
||||
|
||||
return $query_result;
|
||||
}
|
||||
|
||||
@@ -76,7 +76,7 @@ class Reservierung_model extends DB_Model
|
||||
*
|
||||
* @return stdClass
|
||||
*/
|
||||
public function getReservierungenMitarbeiter($start_date, $end_date)
|
||||
public function getReservierungenMitarbeiter($start_date, $end_date, $uid = null)
|
||||
{
|
||||
|
||||
$raum_reservierungen_query = "SELECT res.*, beginn, ende,
|
||||
@@ -91,8 +91,8 @@ class Reservierung_model extends DB_Model
|
||||
|
||||
$subquery = $raum_reservierungen_query;
|
||||
|
||||
|
||||
$query_result= $this->execReadOnlyQuery("
|
||||
|
||||
$query_result = $this->execReadOnlyQuery("
|
||||
SELECT
|
||||
'reservierung' as type, beginn, ende, datum,
|
||||
COALESCE(titel, beschreibung) as topic,
|
||||
@@ -103,13 +103,13 @@ class Reservierung_model extends DB_Model
|
||||
|
||||
FROM
|
||||
(
|
||||
". $subquery ."
|
||||
" . $subquery . "
|
||||
) AS subquery
|
||||
|
||||
GROUP BY datum, beginn, ende, ort_kurzbz, titel, beschreibung
|
||||
|
||||
ORDER BY datum, beginn
|
||||
", [getAuthUID(), $start_date, $end_date]);
|
||||
", [$uid ?? getAuthUID(), $start_date, $end_date]);
|
||||
|
||||
|
||||
return $query_result;
|
||||
@@ -129,9 +129,9 @@ class Reservierung_model extends DB_Model
|
||||
$this->addJoin('public.tbl_studiensemester ss2', 'slv.studiensemester_kurzbz=ss2.studiensemester_kurzbz AND ss2.start<=r.datum AND ss2.ende>=r.datum', 'LEFT');
|
||||
$this->db->or_where('ss1.studiensemester_kurzbz IS NOT NULL', null, false);
|
||||
$this->db->or_where('ss2.studiensemester_kurzbz IS NOT NULL', null, false);
|
||||
|
||||
|
||||
$query = $this->db->get_compiled_select('campus.vw_reservierung r');
|
||||
|
||||
|
||||
return $this->execQuery($query, [$uid, $uid]);
|
||||
}
|
||||
|
||||
|
||||
@@ -388,6 +388,84 @@ class Stundenplan_model extends DB_Model
|
||||
|
||||
ORDER BY datum, beginn", [$start_date, $end_date, $ma_uid]);
|
||||
}
|
||||
|
||||
/**
|
||||
* queries Stundenplan and filters by studiengang, semester, verband gruppe
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function getStundenplanStudiengang($start_date, $end_date, $stg_kz, $sem, $verband, $gruppe) {
|
||||
|
||||
$qry_params = [$start_date, $end_date, $stg_kz];
|
||||
|
||||
$qry = "
|
||||
SELECT
|
||||
'lehreinheit' as type, beginn, ende, datum,
|
||||
CONCAT(lehrfach,'-',lehrform) as topic,
|
||||
array_agg(DISTINCT lektor) as lektor,
|
||||
array_agg(DISTINCT (gruppe,verband,semester,studiengang_kz,gruppen_kuerzel)) as gruppe,
|
||||
string_agg(DISTINCT ort_kurzbz, '/') as ort_kurzbz,
|
||||
array_agg(DISTINCT lehreinheit_id) as lehreinheit_id,
|
||||
titel, lehrfach, lehrform, lehrfach_bez, organisationseinheit, farbe, lehrveranstaltung_id
|
||||
FROM
|
||||
(
|
||||
SELECT unr,datum,beginn, ende,
|
||||
CASE
|
||||
WHEN sp.mitarbeiter_kurzbz IS NOT NULL THEN sp.mitarbeiter_kurzbz
|
||||
ELSE sp.lektor
|
||||
END as lektor,
|
||||
CASE
|
||||
WHEN gruppe_kurzbz IS NOT NULL THEN gruppe_kurzbz
|
||||
ELSE CONCAT(UPPER(sp.stg_typ),UPPER(sp.stg_kurzbz),'-',COALESCE(CAST(sp.semester AS varchar),'/'),COALESCE(CAST(sp.verband AS varchar),'/'))
|
||||
END as gruppen_kuerzel,
|
||||
(SELECT bezeichnung
|
||||
FROM public.tbl_organisationseinheit
|
||||
WHERE oe_kurzbz IN(
|
||||
SELECT oe_kurzbz
|
||||
FROM lehre.tbl_lehrveranstaltung
|
||||
WHERE lehrveranstaltung_id = sp.lehrveranstaltung_id
|
||||
)) as organisationseinheit,
|
||||
sp.ort_kurzbz, sp.studiengang_kz, sp.titel,sp.lehreinheit_id,sp.lehrfach_id,sp.anmerkung,fix,lehrveranstaltung_id,stg_kurzbzlang,stg_bezeichnung,stg_typ,fachbereich_kurzbz,lehrfach,lehrfach_bez,farbe,lehrform,anmerkung_lehreinheit,gruppe, verband, semester,stg_kurzbz
|
||||
FROM (
|
||||
SELECT sp.*
|
||||
FROM lehre.vw_stundenplan sp
|
||||
WHERE
|
||||
sp.datum >= ?
|
||||
AND sp.datum <= ?
|
||||
) sp
|
||||
JOIN lehre.tbl_stunde ON lehre.tbl_stunde.stunde = sp.stunde
|
||||
WHERE studiengang_kz = ? ";
|
||||
|
||||
if($sem != NULL)
|
||||
{
|
||||
$qry_params[] = $sem;
|
||||
$qry .= " AND (semester = ? OR semester IS NULL)";
|
||||
}
|
||||
if($verband != NULL)
|
||||
{
|
||||
$qry_params[] = $verband;
|
||||
$qry .= " AND (verband = ? OR verband IS NULL OR verband = '0' OR verband = '')";
|
||||
}
|
||||
if($gruppe != NULL)
|
||||
{
|
||||
$qry_params[] = $gruppe;
|
||||
$qry .= " AND (gruppe = ? OR gruppe IS NULL OR gruppe = '0' OR gruppe = '') ";
|
||||
}
|
||||
$qry.= " AND (
|
||||
gruppe_kurzbz is null OR EXISTS(
|
||||
SELECT 1
|
||||
FROM
|
||||
public.tbl_gruppe WHERE gruppe_kurzbz = sp.gruppe_kurzbz AND direktinskription = false
|
||||
)
|
||||
)";
|
||||
|
||||
$qry.= " ) as subquery
|
||||
|
||||
GROUP BY unr, datum, beginn, ende, titel, lehrform, lehrfach, lehrfach_bez, organisationseinheit, farbe, lehrveranstaltung_id
|
||||
ORDER BY datum, beginn; ";
|
||||
|
||||
return $this->execReadOnlyQuery($qry, $qry_params);
|
||||
}
|
||||
|
||||
/**
|
||||
* NO STANDALONE FUNCTION - Generates a SQL query string to fetch 'stundenplan' events for a specific student within the current semester.
|
||||
|
||||
@@ -23,12 +23,14 @@ $includesArray = array(
|
||||
'public/css/components/FormUnderline.css',
|
||||
'public/css/components/abgabetool/abgabe.css',
|
||||
'public/css/Cis4/Cms.css',
|
||||
'public/css/Cis4/Studium.css',
|
||||
'public/css/Cis4/Studium.css'
|
||||
),
|
||||
'customJSs' => array(
|
||||
'vendor/npm-asset/primevue/accordion/accordion.min.js',
|
||||
'vendor/npm-asset/primevue/accordiontab/accordiontab.min.js',
|
||||
'vendor/npm-asset/primevue/checkbox/checkbox.min.js',
|
||||
'vendor/npm-asset/primevue/chips/chips.min.js',
|
||||
'vendor/npm-asset/primevue/multiselect/multiselect.min.js',
|
||||
'vendor/npm-asset/primevue/inputnumber/inputnumber.min.js',
|
||||
'vendor/npm-asset/primevue/speeddial/speeddial.min.js',
|
||||
'vendor/npm-asset/primevue/textarea/textarea.min.js',
|
||||
@@ -39,7 +41,7 @@ $includesArray = array(
|
||||
'vendor/moment/luxonjs/luxon.min.js'
|
||||
),
|
||||
'customJSModules' => array(
|
||||
'public/js/apps/Dashboard/Fhc.js',
|
||||
'public/js/apps/Cis/Cis.js',
|
||||
),
|
||||
|
||||
);
|
||||
@@ -47,8 +49,6 @@ $includesArray = array(
|
||||
$this->load->view('templates/CISVUE-Header', $includesArray);
|
||||
?>
|
||||
<div id="fhccontent" class="h-100" route=<?php echo $route ?>>
|
||||
<router-view
|
||||
:view-data='<?php echo json_encode($viewData) ?>'
|
||||
></router-view>
|
||||
<router-view></router-view>
|
||||
</div>
|
||||
<?php $this->load->view('templates/CISVUE-Footer', $includesArray); ?>
|
||||
|
||||
@@ -6,7 +6,7 @@ $includesArray = array(
|
||||
'fontawesome6' => true,
|
||||
'axios027' => true,
|
||||
'customJSModules' => array_merge([
|
||||
'public/js/apps/Cis.js'
|
||||
'public/js/apps/Cis/Menu.js'
|
||||
], $customJSModules ?? []),
|
||||
'customCSSs' => array_merge([
|
||||
'public/css/Cis4/Cis.css'
|
||||
|
||||
@@ -8,7 +8,7 @@ $includesArray = array(
|
||||
'axios027' => true,
|
||||
'primevue3' => true,
|
||||
'customJSModules' => array_merge([
|
||||
'public/js/apps/Cis.js'
|
||||
'public/js/apps/Cis/Menu.js'
|
||||
], $customJSModules ?? []),
|
||||
'customCSSs' => array_merge([
|
||||
'public/css/Cis4/Cis.css',
|
||||
|
||||
@@ -46,12 +46,13 @@ echo '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
|
||||
<link rel="stylesheet" href="../../../skin/tablesort.css" type="text/css"/>
|
||||
<link rel="stylesheet" href="../../../skin/style.css.php" type="text/css">
|
||||
<link rel="stylesheet" type="text/css" href="../../../skin/jquery-ui-1.9.2.custom.min.css">
|
||||
<script type="text/javascript" src="../../../vendor/jquery/jquery1/jquery-1.12.4.min.js"></script>
|
||||
<script type="text/javascript" src="../../../vendor/christianbach/tablesorter/jquery.tablesorter.min.js"></script>
|
||||
<script type="text/javascript" src="../../../vendor/components/jqueryui/jquery-ui.min.js"></script>
|
||||
<script type="text/javascript" src="../../../include/js/jquery.ui.datepicker.translation.js"></script>
|
||||
<script type="text/javascript" src="../../../vendor/jquery/sizzle/sizzle.js"></script>';
|
||||
|
||||
include('../../../include/meta/jquery.php');
|
||||
include('../../../include/meta/jquery-tablesorter.php');
|
||||
|
||||
const MOODLE_ADDON_KURZBZ = 'moodle';
|
||||
|
||||
// Load Addons to get Moodle_Path
|
||||
@@ -71,7 +72,7 @@ echo '
|
||||
$("#myTable").tablesorter(
|
||||
{
|
||||
sortList: [[0,0],[1,0]],
|
||||
widgets: [\'zebra\']
|
||||
widgets: [\'zebra\',\'filter\']
|
||||
});
|
||||
}
|
||||
);
|
||||
@@ -151,8 +152,9 @@ foreach($service->result as $row)
|
||||
$person = new person();
|
||||
$person->getPersonFromBenutzer($row->operativ_uid);
|
||||
$operativ = $person->nachname.' '.$person->vorname;
|
||||
$oeBez = new organisationseinheit($row->oe_kurzbz);
|
||||
echo '<tr>';
|
||||
echo '<td>',$row->oe_kurzbz,'</td>';
|
||||
echo '<td>',$oeBez->bezeichnung,'</td>';
|
||||
echo '<td><b>'.$row->bezeichnung.'</b></td>';
|
||||
echo '<td>',$row->beschreibung,'</td>';
|
||||
echo '<td><nobr><a href="../profile/index.php?uid='.$row->design_uid.'">',$design,'</a></nobr></td>';
|
||||
|
||||
@@ -293,7 +293,7 @@ else if (isset($_SESSION['pruefling_id']))
|
||||
}
|
||||
$lastsemester = $row->semester;
|
||||
|
||||
echo '<table border="0" cellspacing="0" cellpadding="0" id="Gebiet" style="display: visible; border-collapse: separate; border-spacing: 0 3px;">';
|
||||
echo '<table border="0" cellspacing="0" cellpadding="0" id="Gebiet" style="display: visible; border-collapse: separate; border-spacing: 0 3px; margin-top: 5px;">';
|
||||
echo '<tr><td class="HeaderTesttool">'. ($row->semester == '1' ? $p->t('testtool/basisgebiete') : $p->t('testtool/quereinstiegsgebiete')).'</td></tr>';
|
||||
}
|
||||
|
||||
|
||||
@@ -70,6 +70,18 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "package",
|
||||
"package": {
|
||||
"name": "drag-drop-touch-js/dragdroptouch",
|
||||
"version": "2.0.3",
|
||||
"source": {
|
||||
"url": "https://github.com/drag-drop-touch-js/dragdroptouch.git",
|
||||
"type": "git",
|
||||
"reference": "master"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "package",
|
||||
"package": {
|
||||
@@ -452,6 +464,8 @@
|
||||
|
||||
"easyrdf/easyrdf": "0.9.*",
|
||||
|
||||
"drag-drop-touch-js/dragdroptouch": "*",
|
||||
|
||||
"fgelinas/timepicker": "0.3.3",
|
||||
"fortawesome/font-awesome4": "4.7.*",
|
||||
"fortawesome/font-awesome6": "6.1.*",
|
||||
@@ -519,5 +533,9 @@
|
||||
"phpmetrics/phpmetrics": "2.*",
|
||||
"sebastian/phpcpd": "3.*",
|
||||
"phpunit/phpunit": "^6"
|
||||
},
|
||||
"scripts": {
|
||||
"post-install-cmd": "@symlink_vendor_to_public",
|
||||
"symlink_vendor_to_public": "ln -sfn ../vendor ./public/"
|
||||
}
|
||||
}
|
||||
|
||||
Generated
+11
-1
@@ -4,7 +4,7 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "f4f0af4586f46f97d8b6092c1ac0fb3a",
|
||||
"content-hash": "869cbc35bd1ba90ab90934fcb41b0f51",
|
||||
"packages": [
|
||||
{
|
||||
"name": "afarkas/html5shiv",
|
||||
@@ -804,6 +804,16 @@
|
||||
"abandoned": true,
|
||||
"time": "2018-03-09T06:07:41+00:00"
|
||||
},
|
||||
{
|
||||
"name": "drag-drop-touch-js/dragdroptouch",
|
||||
"version": "2.0.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/drag-drop-touch-js/dragdroptouch.git",
|
||||
"reference": "master"
|
||||
},
|
||||
"type": "library"
|
||||
},
|
||||
{
|
||||
"name": "easyrdf/easyrdf",
|
||||
"version": "0.9.1",
|
||||
|
||||
@@ -342,6 +342,8 @@ echo '<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>';
|
||||
<vbox>
|
||||
<checkbox id="mitarbeiter-entwicklungsteam-detail-checkbox-neu" checked="true" hidden="true" />
|
||||
<textbox id="mitarbeiter-entwicklungsteam-detail-textbox-studiengang" hidden="true" />
|
||||
<textbox id="mitarbeiter-entwicklungsteam-detail-entwicklungsteam_id" hidden="true" />
|
||||
|
||||
<groupbox id="mitarbeiter-entwicklungsteam-detail-groupbox" flex="1">
|
||||
<caption label="Details" />
|
||||
<grid id="mitarbeiter-entwicklungsteam-detail-grid" style="margin:4px;" flex="1">
|
||||
|
||||
@@ -1708,6 +1708,7 @@ function MitarbeiterEntwicklungsteamSelect()
|
||||
document.getElementById('mitarbeiter-entwicklungsteam-detail-textbox-studiengang').value=studiengang_kz;
|
||||
document.getElementById('mitarbeiter-entwicklungsteam-detail-datum-beginn').value=beginn;
|
||||
document.getElementById('mitarbeiter-entwicklungsteam-detail-datum-ende').value=ende;
|
||||
document.getElementById('mitarbeiter-entwicklungsteam-detail-entwicklungsteam_id').value=entwicklungsteam_id;
|
||||
MitarbeiterEntwicklungsteamDetailDisableFields(false);
|
||||
}
|
||||
|
||||
@@ -1725,6 +1726,7 @@ function MitarbeiterEntwicklungsteamSpeichern()
|
||||
studiengang_kz_old = document.getElementById('mitarbeiter-entwicklungsteam-detail-textbox-studiengang').value;
|
||||
beginn = document.getElementById('mitarbeiter-entwicklungsteam-detail-datum-beginn').value;
|
||||
ende = document.getElementById('mitarbeiter-entwicklungsteam-detail-datum-ende').value;
|
||||
entwicklungsteam_id = document.getElementById('mitarbeiter-entwicklungsteam-detail-entwicklungsteam_id').value;
|
||||
|
||||
if(studiengang_kz=='')
|
||||
{
|
||||
|
||||
@@ -3555,6 +3555,14 @@ function StudentZeugnisDokumentArchivieren()
|
||||
case 'microcredential_2':
|
||||
case 'microcredential_3':
|
||||
case 'microcredential_4':
|
||||
case 'microdegree_1':
|
||||
case 'microdegree_2':
|
||||
case 'microdegree_3':
|
||||
case 'microdegree_4':
|
||||
case 'microdegreeabschluss_1':
|
||||
case 'microdegreeabschluss_2':
|
||||
case 'microdegreeabschluss_3':
|
||||
case 'microdegreeabschluss_4':
|
||||
xml = 'microcredential.xml.php';
|
||||
break;
|
||||
|
||||
|
||||
@@ -364,9 +364,10 @@ class entwicklungsteam extends basis_db
|
||||
$bismeldung_jahr = $datetime->format('Y');
|
||||
|
||||
//laden des Datensatzes
|
||||
$qry = "SELECT *
|
||||
$qry = "SELECT tbl_entwicklungsteam.*, tbl_besqual.*, tbl_studiengang.studiengang_kz, tbl_studiengang.melderelevant
|
||||
FROM bis.tbl_entwicklungsteam
|
||||
JOIN bis.tbl_besqual USING(besqualcode)
|
||||
JOIN public.tbl_studiengang USING(studiengang_kz)
|
||||
WHERE mitarbeiter_uid=".$this->db_add_param($mitarbeiter_uid)."
|
||||
AND (beginn is NULL OR beginn <= make_date(". $this->db_add_param($bismeldung_jahr). "::INTEGER, 12, 31))
|
||||
AND (ende is NULL OR ende >= make_date(". $this->db_add_param($bismeldung_jahr). "::INTEGER, 1, 1))";
|
||||
@@ -394,6 +395,7 @@ class entwicklungsteam extends basis_db
|
||||
$obj->insertvon = $row->insertvon;
|
||||
$obj->ext_id = $row->ext_id;
|
||||
$obj->besqual = $row->besqualbez;
|
||||
$obj->melderelevant = $this->db_parse_bool($row->melderelevant);
|
||||
|
||||
$this->result[] = $obj;
|
||||
}
|
||||
|
||||
+49
-1
@@ -25,6 +25,7 @@
|
||||
*/
|
||||
require_once(dirname(__FILE__).'/basis_db.class.php');
|
||||
require_once(dirname(__FILE__).'/'.EXT_FKT_PATH.'/generateZahlungsreferenz.inc.php');
|
||||
require_once(dirname(__FILE__).'/variable.class.php');
|
||||
|
||||
class konto extends basis_db
|
||||
{
|
||||
@@ -432,6 +433,8 @@ class konto extends basis_db
|
||||
|
||||
$qry.=" ORDER BY beschreibung";
|
||||
|
||||
$oehBeitrag = $this->_getOEHBeitrag();
|
||||
|
||||
if($this->db_query($qry))
|
||||
{
|
||||
while($row = $this->db_fetch_object())
|
||||
@@ -440,7 +443,15 @@ class konto extends basis_db
|
||||
|
||||
$typ->buchungstyp_kurzbz = $row->buchungstyp_kurzbz;
|
||||
$typ->beschreibung = $row->beschreibung;
|
||||
$typ->standardbetrag = $row->standardbetrag;
|
||||
if (strtolower($typ->buchungstyp_kurzbz) === 'oeh' && $oehBeitrag)
|
||||
{
|
||||
$typ->standardbetrag = $oehBeitrag;
|
||||
}
|
||||
else
|
||||
{
|
||||
$typ->standardbetrag = $row->standardbetrag;
|
||||
}
|
||||
|
||||
$typ->standardtext = $row->standardtext;
|
||||
$typ->credit_points = $row->credit_points;
|
||||
$typ->aktiv = $this->db_parse_bool($row->aktiv);
|
||||
@@ -990,6 +1001,43 @@ class konto extends basis_db
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private function _getOEHBeitrag()
|
||||
{
|
||||
if(!is_user_logged_in())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
$variablen_obj = new variable();
|
||||
$variablen_obj->loadVariables(get_uid());
|
||||
|
||||
$qry = "WITH semstart AS (
|
||||
SELECT start FROM public.tbl_studiensemester
|
||||
WHERE studiensemester_kurzbz = '". $this->db_escape($variablen_obj->variable->semester_aktuell) . "'
|
||||
)
|
||||
SELECT * FROM bis.tbl_oehbeitrag oehb
|
||||
JOIN public.tbl_studiensemester semvon ON oehb.von_studiensemester_kurzbz = semvon.studiensemester_kurzbz
|
||||
LEFT JOIN public.tbl_studiensemester sembis ON oehb.bis_studiensemester_kurzbz = sembis.studiensemester_kurzbz
|
||||
JOIN semstart ON semstart.start::date >= semvon.start::date AND (sembis.studiensemester_kurzbz IS NULL OR semstart.start::date <= sembis.start::date)
|
||||
ORDER BY semvon.start
|
||||
LIMIT 1";
|
||||
|
||||
if ($this->db_query($qry))
|
||||
{
|
||||
if($row = $this->db_fetch_object())
|
||||
{
|
||||
$summe = ($row->studierendenbeitrag + $row->versicherung) * -1;
|
||||
return number_format((float)$summe, 2, '.', '');
|
||||
}
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->errormsg = 'Fehler bei der Abfrage aufgetreten';
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
@@ -584,8 +584,9 @@ class lehreinheitmitarbeiter extends basis_db
|
||||
|
||||
$qry = '
|
||||
WITH semester_sws_tbl AS (
|
||||
SELECT DISTINCT lehreinheit_id, studiensemester_kurzbz, lema.semesterstunden,
|
||||
stg.studiengang_kz, stg.melde_studiengang_kz, stg.lgartcode
|
||||
SELECT
|
||||
DISTINCT lehreinheit_id, studiensemester_kurzbz, lema.semesterstunden,
|
||||
stg.studiengang_kz, stg.melde_studiengang_kz, stg.lgartcode, stg.melderelevant
|
||||
FROM lehre.tbl_lehreinheitmitarbeiter lema
|
||||
JOIN lehre.tbl_lehreinheit USING (lehreinheit_id)
|
||||
JOIN lehre.tbl_lehrveranstaltung lv USING (lehrveranstaltung_id)
|
||||
@@ -598,6 +599,7 @@ class lehreinheitmitarbeiter extends basis_db
|
||||
AND ss.studiensemester_kurzbz IN ('.$this->implode4SQL($studiensemester_kurzbz_arr).')
|
||||
-- nur lehre, die bisgemeldet wird
|
||||
AND lema.bismelden
|
||||
AND stg.melderelevant
|
||||
-- keine lehreinheiten ohne semesterstunden
|
||||
AND lema.semesterstunden != 0
|
||||
)
|
||||
|
||||
Generated
+6
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"name": "FHC-Core",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {}
|
||||
}
|
||||
+28
-35
@@ -147,6 +147,8 @@ html {
|
||||
--fhc-cis-menu-lvl-5-color-hover: var(--fhc-text);
|
||||
--fhc-cis-grade-positive: var(--fhc-success);
|
||||
--fhc-cis-grade-negative: var(--fhc-danger);
|
||||
|
||||
--fhc-offcanvas-zindex: 1045;
|
||||
}
|
||||
|
||||
#themeSwitch i{
|
||||
@@ -375,7 +377,7 @@ html {
|
||||
/* searchbar */
|
||||
#nav-search {
|
||||
background-color: var(--fhc-primary);
|
||||
z-index: 1;
|
||||
z-index: calc(var(--fhc-offcanvas-zindex) + 1) !important;
|
||||
}
|
||||
#nav-search.me-3 {
|
||||
margin: 0 !important;
|
||||
@@ -386,12 +388,6 @@ html {
|
||||
#nav-search > .input-group > * {
|
||||
border-radius: 0 !important;
|
||||
}
|
||||
#nav-search .searchbar_results {
|
||||
top: 100% !important;
|
||||
left: 0;
|
||||
right: 0 !important;
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
/* frame */
|
||||
.in-frame {
|
||||
@@ -413,10 +409,18 @@ html {
|
||||
color: var(--fhc-link) !important;
|
||||
}
|
||||
|
||||
#nav-main {
|
||||
z-index: var(--fhc-offcanvas-zindex);
|
||||
}
|
||||
|
||||
#nav-main-sticky {
|
||||
max-height: calc(100vh - var(--fhc-cis-header-height));
|
||||
}
|
||||
|
||||
#nav-user-menu {
|
||||
z-index: calc(var(--fhc-offcanvas-zindex) + 1);
|
||||
}
|
||||
|
||||
#nav-user-menu img {
|
||||
object-fit: cover;
|
||||
height: calc( 3 * var(--fhc-cis-header-py));
|
||||
@@ -457,7 +461,14 @@ html {
|
||||
/* overflow: visible !important; */
|
||||
}
|
||||
#cis-header {
|
||||
z-index: 10;
|
||||
z-index: 10;
|
||||
}
|
||||
#cis-header-bar {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
height: var(--fhc-cis-header-height);
|
||||
width: 100%;
|
||||
background-color: var(--fhc-primary);
|
||||
}
|
||||
#cis-header nav {
|
||||
position: initial;
|
||||
@@ -473,12 +484,7 @@ html {
|
||||
display: none;
|
||||
}
|
||||
#nav-logo {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
height: var(--fhc-cis-header-height);
|
||||
width: var(--fhc-cis-menu-width);
|
||||
background-color: var(--fhc-primary);
|
||||
padding: var(--fhc-cis-header-py) var(--fhc-cis-header-px);
|
||||
z-index: 2;
|
||||
}
|
||||
@@ -493,37 +499,27 @@ html {
|
||||
top: var(--fhc-cis-header-height);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
#nav-main-sticky > :not(#nav-main-toggle) {
|
||||
overflow: auto;
|
||||
height: 100%;
|
||||
}
|
||||
#nav-main-toggle {
|
||||
width: 0;
|
||||
z-index: 1;
|
||||
}
|
||||
#nav-main-toggle .btn,
|
||||
#nav-main-toggle .fa-arrow-circle-left {
|
||||
#nav-main-toggle:hover {
|
||||
background-color: var(--fhc-secondary-highlight);
|
||||
}
|
||||
#nav-main-toggle .div,
|
||||
#nav-main-toggle .fa-chevron-left {
|
||||
transition: all 0.5s ease-in-out;
|
||||
}
|
||||
#nav-main-toggle .collapsed.btn {
|
||||
background-color: transparent !important;
|
||||
}
|
||||
#nav-main-toggle .collapsed .fa-arrow-circle-left {
|
||||
#nav-main-toggle .collapsed .fa-chevron-left {
|
||||
transform: scaleX(-1);
|
||||
color: var(--fhc-black-40);
|
||||
}
|
||||
#nav-search {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: var(--fhc-cis-menu-width);
|
||||
height: var(--fhc-cis-header-height);
|
||||
right: calc(var(--fhc-cis-header-height) + 2 * var(--fhc-cis-header-px) - 2 * var(--fhc-cis-header-py));
|
||||
width: auto !important;
|
||||
}
|
||||
#nav-user {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
position: relative;
|
||||
}
|
||||
#nav-user-btn {
|
||||
border-width: 0;
|
||||
@@ -558,7 +554,7 @@ html {
|
||||
|
||||
#nav-main-menu {
|
||||
height: 100%;
|
||||
background-color: var(--fhc-cis-menu-bg);
|
||||
background-color: var(--fhc-primary);
|
||||
}
|
||||
#nav-main-menu > div {
|
||||
width: var(--fhc-cis-menu-width);
|
||||
@@ -600,9 +596,6 @@ html {
|
||||
}
|
||||
#nav-user{
|
||||
position: relative;
|
||||
}
|
||||
#nav-user-btn {
|
||||
|
||||
}
|
||||
#nav-user-btn img {
|
||||
object-fit: cover;
|
||||
|
||||
@@ -197,10 +197,6 @@ html.fs_huge {
|
||||
margin-bottom: -1px;
|
||||
}
|
||||
|
||||
.tiny-90 div.tox.tox-tinymce {
|
||||
height: 90% !important;
|
||||
}
|
||||
|
||||
/* slim begin */
|
||||
.stv .form-label {
|
||||
margin-bottom: .15rem;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
@import './dashboard/news.css';
|
||||
@import './dashboard/LvPlan.css';
|
||||
|
||||
:root{
|
||||
:root {
|
||||
--fhc-dashboard-danger: var(--fhc-danger, #842029);
|
||||
--fhc-dashboard-grid-size: 4;
|
||||
--fhc-dashboard-link: var(--fhc-link, #0a57ca);
|
||||
@@ -17,22 +17,16 @@
|
||||
--fhc-dashboard-section-info-color-hover: var(--fhc-primary-highlight, #005585);
|
||||
}
|
||||
|
||||
@media(max-width: 577px) {
|
||||
:root {
|
||||
--fhc-dashboard-grid-size: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.core-dashboard a{
|
||||
.core-dashboard a {
|
||||
color: var(--fhc-dashboard-link);
|
||||
}
|
||||
|
||||
@media (max-width: 576px){
|
||||
@media (max-width: 576px) {
|
||||
.widget-icon {
|
||||
max-height: 250px;
|
||||
object-fit: cover;
|
||||
}
|
||||
.widget-icon-container{
|
||||
.widget-icon-container {
|
||||
max-width: 250px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
@@ -46,27 +40,36 @@
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
background-size: cover;
|
||||
cursor:pointer;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.dashboard-section > .newGridRow{
|
||||
position:absolute;
|
||||
width:20px;
|
||||
height:20px;
|
||||
padding:0;
|
||||
bottom:0;
|
||||
left:50%;
|
||||
transform:translate(-50%, 50%);
|
||||
.dashboard-section.edit-active {
|
||||
/**
|
||||
* replaces margin for extra row
|
||||
* 10% equals 0.1 of 100%
|
||||
* 1rem equals the padding of pb-3 that is overwritten here
|
||||
*/
|
||||
padding-bottom: calc(10% / var(--fhc-dashboard-grid-size) + 1rem) !important;
|
||||
}
|
||||
|
||||
.dashboard-section > .newGridRow {
|
||||
position: absolute;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
padding: 0;
|
||||
bottom: 0;
|
||||
left: 50%;
|
||||
transform: translate(-50%, 50%);
|
||||
background-color: var(--fhc-dashboard-gridrow-background);
|
||||
}
|
||||
|
||||
.newGridRow:hover {
|
||||
color:white;
|
||||
color: white;
|
||||
background-color: var(--fhc-dashboard-gridrow-background-highlight);
|
||||
}
|
||||
|
||||
.empty-tile-hover:hover {
|
||||
background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="-500 -500 1448 1512"><path fill="rgb(211, 211, 211)" d="M64 32C28.7 32 0 60.7 0 96V416c0 35.3 28.7 64 64 64H384c35.3 0 64-28.7 64-64V96c0-35.3-28.7-64-64-64H64zM200 344V280H136c-13.3 0-24-10.7-24-24s10.7-24 24-24h64V168c0-13.3 10.7-24 24-24s24 10.7 24 24v64h64c13.3 0 24 10.7 24 24s-10.7 24-24 24H248v64c0 13.3-10.7 24-24 24s-24-10.7-24-24z"/></svg>');
|
||||
background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="-500 -500 1448 1512"><path fill="rgb(211, 211, 211)" d="M64 32C28.7 32 0 60.7 0 96V416c0 35.3 28.7 64 64 64H384c35.3 0 64-28.7 64-64V96c0-35.3-28.7-64-64-64H64zM200 344V280H136c-13.3 0-24-10.7-24-24s10.7-24 24-24h64V168c0-13.3 10.7-24 24-24s24 10.7 24 24v64h64c13.3 0 24 10.7 24 24s-10.7 24-24 24H248v64c0 13.3-10.7 24-24 24s-24-10.7-24-24z"/></svg>');
|
||||
}
|
||||
|
||||
.alert-danger .form-check-input:checked {
|
||||
@@ -74,16 +77,6 @@
|
||||
background-color: var(--fhc-dashboard-danger);
|
||||
}
|
||||
|
||||
:root {
|
||||
--fhc-dashboard-grid-size: 4;
|
||||
}
|
||||
|
||||
@media(max-width: 1400px) {
|
||||
:root {
|
||||
--fhc-dashboard-grid-size: 4;
|
||||
}
|
||||
}
|
||||
|
||||
@media(max-width: 1200px) {
|
||||
:root {
|
||||
--fhc-dashboard-grid-size: 3;
|
||||
@@ -105,6 +98,7 @@
|
||||
@media(max-width: 577px) {
|
||||
:root {
|
||||
--fhc-dashboard-grid-size: 1;
|
||||
--fhc-dg-item-py: .75rem;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -132,50 +126,64 @@
|
||||
cursor: move !important;
|
||||
}
|
||||
|
||||
.draggedItem {
|
||||
.drop-grid-item-resize > .dashboard-item,
|
||||
.drop-grid-item-move > .dashboard-item {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
background-color: var(--fhc-dashboard-draggeditem-background);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.dashboard-item-overlay{
|
||||
.drop-grid-item-resize > .dashboard-item > *,
|
||||
.drop-grid-item-move > .dashboard-item > * {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.drop-grid-item-sizechanged > .dashboard-item,
|
||||
.drop-grid-item-move > .dashboard-item {
|
||||
background-color: var(--fhc-dashboard-item-overlay-background);
|
||||
}
|
||||
|
||||
.dashboard-item-overlay::before{
|
||||
position:absolute;
|
||||
content:"";
|
||||
top:0.25rem;
|
||||
left:0.25rem;
|
||||
right:0.25rem;
|
||||
bottom:0.25rem;
|
||||
border:4px dashed var(--fhc-dashboard-item-overly-border-color);
|
||||
opacity: 0.5;
|
||||
.drop-grid-item-sizechanged > .dashboard-item::before,
|
||||
.drop-grid-item-move > .dashboard-item::before {
|
||||
position: absolute;
|
||||
content: "";
|
||||
top: .25rem;
|
||||
left: .25rem;
|
||||
right: .25rem;
|
||||
bottom: .25rem;
|
||||
border: 4px dashed var(--fhc-dashboard-item-overly-border-color);
|
||||
opacity: .5;
|
||||
}
|
||||
|
||||
#deleteBookmark i{
|
||||
.drop-grid-item-oversized > .dashboard-item {
|
||||
/* Bootstrap: border-danger */
|
||||
--bs-border-opacity: 1;
|
||||
border-color: rgba(var(--bs-danger-rgb), var(--bs-border-opacity)) !important;
|
||||
}
|
||||
|
||||
#deleteBookmark i {
|
||||
color: var(--fhc-dashboard-danger);
|
||||
}
|
||||
|
||||
.pin:hover{
|
||||
.pin:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.pin[pinned]:hover{
|
||||
.pin[pinned]:hover {
|
||||
color: var(--fhc-dashboard-pin-pinned-hover-color);
|
||||
}
|
||||
|
||||
.section-info{
|
||||
.section-info {
|
||||
color: var(--fhc-dashboard-section-info-color);
|
||||
cursor:pointer;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.section-info:hover {
|
||||
color: var(--fhc-dashboard-section-info-color-hover);
|
||||
}
|
||||
|
||||
.denied-dragging-animation {
|
||||
.drop-grid-item-blocker [pinned='true'] {
|
||||
animation: wiggle 0.5s linear;
|
||||
color: var(--fhc-dashboard-denied-dragging-animation-color) !important;
|
||||
}
|
||||
@@ -204,13 +212,13 @@
|
||||
|
||||
}
|
||||
|
||||
.hiddenWidget{
|
||||
.hidden-widget {
|
||||
background: var(--fhc-disabled-background);
|
||||
opacity: 40%;
|
||||
}
|
||||
|
||||
.hiddenWidget .card,
|
||||
.hiddenWidget .card-body,
|
||||
.hiddenWidget .card-body *{
|
||||
.hidden-widget .card,
|
||||
.hidden-widget .card-body,
|
||||
.hidden-widget .card-body * {
|
||||
background: inherit !important;
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ export default {
|
||||
getViewData() {
|
||||
return {
|
||||
method: 'get',
|
||||
url: '/api/frontend/v1/Cis4FhcApi/getViewData'
|
||||
url: '/api/frontend/v1/Cis4FhcApi/dashboardViewData'
|
||||
};
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,26 @@
|
||||
/**
|
||||
* Copyright (C) 2026 fhcomplete.org
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
export default {
|
||||
getAllStudienSemester(studiensemester, studiengang, semester, studienplan) {
|
||||
return {
|
||||
method: 'get',
|
||||
url: 'api/frontend/v1/Studium/getStudienAllSemester/',
|
||||
params: {studiensemester, studiengang, semester, studienplan}
|
||||
};
|
||||
},
|
||||
}
|
||||
@@ -35,5 +35,11 @@ export default {
|
||||
method: 'get',
|
||||
url: `/api/frontend/v1/Lehre/Pruefungen/${lehrveranstaltung_id}`
|
||||
};
|
||||
},
|
||||
getSemesterAverageGrade(semester) {
|
||||
return {
|
||||
method: 'get',
|
||||
url: `/api/frontend/v1/Lehre/semesterAverageGrade/${semester}`
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -16,6 +16,12 @@
|
||||
*/
|
||||
|
||||
export default {
|
||||
getMyLvPlanViewData() {
|
||||
return {
|
||||
method: 'get',
|
||||
url: `/api/frontend/v1/LvPlan/myLvPlanViewData`,
|
||||
};
|
||||
},
|
||||
getRoomInfo(ort_kurzbz, start_date, end_date) {
|
||||
return {
|
||||
method: 'post',
|
||||
@@ -30,11 +36,11 @@ export default {
|
||||
params: { start_date, end_date, lv_id }
|
||||
};
|
||||
},
|
||||
eventsPersonal(start_date, end_date) {
|
||||
eventsPersonal(start_date, end_date, uid = null) {
|
||||
return {
|
||||
method: 'post',
|
||||
url: '/api/frontend/v1/lvPlan/eventsPersonal',
|
||||
params: { start_date, end_date }
|
||||
params: { start_date, end_date, uid }
|
||||
};
|
||||
},
|
||||
eventsLv(lv_id, start_date, end_date) {
|
||||
@@ -57,11 +63,11 @@ export default {
|
||||
params: { start_date, end_date }
|
||||
};
|
||||
},
|
||||
getLvPlanReservierungen(start_date, end_date) {
|
||||
getLvPlanReservierungen(start_date, end_date, uid = null) {
|
||||
return {
|
||||
method: 'post',
|
||||
url: '/api/frontend/v1/LvPlan/getReservierungen',
|
||||
params: { start_date, end_date }
|
||||
params: { start_date, end_date, uid }
|
||||
};
|
||||
},
|
||||
getLehreinheitStudiensemester(lehreinheit_id) {
|
||||
@@ -92,5 +98,42 @@ export default {
|
||||
method: 'get',
|
||||
url: '/api/frontend/v1/LvPlan/getLv/' + lehrveranstaltung_id
|
||||
};
|
||||
}
|
||||
},
|
||||
eventsStgOrg(start_date, end_date, stg_kz, sem, verband, gruppe) {
|
||||
return {
|
||||
method: 'post',
|
||||
url: '/api/frontend/v1/lvPlan/eventsStgOrg',
|
||||
params: { start_date, end_date, stg_kz, sem, verband, gruppe }
|
||||
};
|
||||
},
|
||||
getStudiengaenge(){
|
||||
return {
|
||||
method: 'get',
|
||||
url: '/api/frontend/v1/lvPlan/getStudiengaenge'
|
||||
}
|
||||
},
|
||||
getLehrverband(stg_kz, sem){
|
||||
return {
|
||||
method: 'get',
|
||||
url: `/api/frontend/v1/lvPlan/getLehrverband/${stg_kz}/${sem}`
|
||||
}
|
||||
},
|
||||
getGruppe(stg_kz, sem, verband){
|
||||
return {
|
||||
method: 'get',
|
||||
url: `/api/frontend/v1/lvPlan/getLehrverband/${stg_kz}/${sem}/${verband}`
|
||||
}
|
||||
},
|
||||
checkPermissionOtherLvPlan(){
|
||||
return {
|
||||
method: 'get',
|
||||
url: '/api/frontend/v1/lvPlan/permissionOtherLvPlan',
|
||||
}
|
||||
},
|
||||
getCompactibleEventTypes(){
|
||||
return {
|
||||
method: 'get',
|
||||
url: '/api/frontend/v1/lvPlan/compactibleEventTypes',
|
||||
}
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,25 @@
|
||||
/**
|
||||
* Copyright (C) 2025 fhcomplete.org
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
export default {
|
||||
getOtherLvPlanViewData(uid) {
|
||||
return {
|
||||
method: 'get',
|
||||
url: `/api/frontend/v1/OtherLvPlan/otherLvPlanViewData/${uid}`,
|
||||
};
|
||||
},
|
||||
};
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
export default {
|
||||
|
||||
profilViewData(uid) {
|
||||
getProfilViewData(uid = null) {
|
||||
let url = "/api/frontend/v1/Profil/profilViewData";
|
||||
if(uid){
|
||||
url += `/${uid}`;
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
/**
|
||||
* Copyright (C) 2025 fhcomplete.org
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
export default {
|
||||
getStgOrgLvPlanViewData(uid) {
|
||||
return {
|
||||
method: 'get',
|
||||
url: `/api/frontend/v1/StgOrgLvPlan/stgOrgLvPlanViewData`,
|
||||
};
|
||||
},
|
||||
};
|
||||
@@ -38,6 +38,10 @@ export default {
|
||||
};
|
||||
},
|
||||
insert(params) {
|
||||
if(params.betrag)
|
||||
{
|
||||
params.betrag = params.betrag.replace(',', '.');
|
||||
}
|
||||
return {
|
||||
method: 'post',
|
||||
url: 'api/frontend/v1/stv/konto/insert',
|
||||
@@ -52,6 +56,10 @@ export default {
|
||||
};
|
||||
},
|
||||
edit(params) {
|
||||
if(params.betrag)
|
||||
{
|
||||
params.betrag = params.betrag.replace(',', '.');
|
||||
}
|
||||
return {
|
||||
method: 'post',
|
||||
url: 'api/frontend/v1/stv/konto/update',
|
||||
@@ -65,10 +73,14 @@ export default {
|
||||
params: { buchungsnr }
|
||||
};
|
||||
},
|
||||
getBuchungstypen() {
|
||||
getBuchungstypen(studiensemester_kurzbz) {
|
||||
let url = 'api/frontend/v1/stv/konto/getBuchungstypen'
|
||||
if (!!studiensemester_kurzbz)
|
||||
url = url + '/' + encodeURIComponent(studiensemester_kurzbz);
|
||||
|
||||
return {
|
||||
method: 'get',
|
||||
url: 'api/frontend/v1/stv/konto/getBuchungstypen'
|
||||
url: url
|
||||
};
|
||||
}
|
||||
},
|
||||
};
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
export default {
|
||||
getBookmarks() {
|
||||
|
||||
return {
|
||||
method: 'get',
|
||||
url: '/api/frontend/v1/Bookmark/getBookmarks'
|
||||
@@ -28,18 +29,24 @@ export default {
|
||||
url: `/api/frontend/v1/Bookmark/delete/${bookmark_id}`
|
||||
};
|
||||
},
|
||||
update({ bookmark_id, url, title, tag=null }) {
|
||||
update({ bookmark_id, url, title, tag }) {
|
||||
return {
|
||||
method: 'post',
|
||||
url: `/api/frontend/v1/Bookmark/update/${bookmark_id}`,
|
||||
params: { url, title }
|
||||
params: { url, title, tag }
|
||||
};
|
||||
},
|
||||
insert({ url, title, tag }) {
|
||||
insert({ url, title, tag, sort }) {
|
||||
return {
|
||||
method: 'post',
|
||||
url: `/api/frontend/v1/Bookmark/insert`,
|
||||
params: { url, title, tag }
|
||||
params: { url, title, tag, sort }
|
||||
};
|
||||
},
|
||||
changeOrder(bookmark_id1, bookmark_id2) {
|
||||
return {
|
||||
method: 'post',
|
||||
url: `/api/frontend/v1/Bookmark/changeOrder/${bookmark_id1}/${bookmark_id2}`,
|
||||
};
|
||||
}
|
||||
};
|
||||
@@ -4,25 +4,27 @@ import Theme from '../../plugins/Theme.js';
|
||||
import contrast from '../../directives/contrast.js';
|
||||
import {setScrollbarWidth} from "../../helpers/CssVarCalcHelpers.js";
|
||||
import LvPlan from "../../components/Cis/LvPlan/Lehrveranstaltung.js";
|
||||
import MyLvPlan from "../../components/Cis/LvPlan/Personal.js";
|
||||
import MyLvPlan from "../../components/Cis/LvPlan/MyLvPlan.js";
|
||||
import MylvStudent from "../../components/Cis/Mylv/Student.js";
|
||||
import Profil from "../../components/Cis/Profil/Profil.js";
|
||||
import Raumsuche from "../../components/Cis/Raumsuche/Raumsuche.js";
|
||||
import CmsNews from "../../components/Cis/Cms/News.js";
|
||||
import CmsContent from "../../components/Cis/Cms/Content.js";
|
||||
import Info from "../../components/Cis/Mylv/Semester/Studiengang/Lv/Info.js";
|
||||
import RoomInformation, {DEFAULT_MODE_RAUMINFO} from "../../components/Cis/Mylv/RoomInformation.js";
|
||||
import RoomInformation, {DEFAULT_MODE_RAUMINFO_DESKTOP, DEFAULT_MODE_RAUMINFO_MOBILE} from "../../components/Cis/Mylv/RoomInformation.js";
|
||||
import AbgabetoolStudent from "../../components/Cis/Abgabetool/AbgabetoolStudent.js";
|
||||
import AbgabetoolMitarbeiter from "../../components/Cis/Abgabetool/AbgabetoolMitarbeiter.js";
|
||||
import AbgabetoolAssistenz from "../../components/Cis/Abgabetool/AbgabetoolAssistenz.js";
|
||||
import DeadlineOverview from "../../components/Cis/Abgabetool/DeadlineOverview.js";
|
||||
import Studium from "../../components/Cis/Studium/Studium.js";
|
||||
import StgOrgLvPlan from "../../components/Cis/LvPlan/StgOrg.js";
|
||||
import OtherLvPlan from "../../components/Cis/LvPlan/OtherLvPlan.js";
|
||||
|
||||
import ApiRenderers from '../../api/factory/renderers.js';
|
||||
import ApiRouteInfo from '../../api/factory/routeinfo.js';
|
||||
import {capitalize} from "../../helpers/StringHelpers.js";
|
||||
|
||||
const ciPath = FHC_JS_DATA_STORAGE_OBJECT.app_root.replace(/(https:|)(^|\/\/)(.*?\/)/g, '') + FHC_JS_DATA_STORAGE_OBJECT.ci_router;
|
||||
const isMobile = window.matchMedia("(max-width: 767px)").matches;
|
||||
|
||||
const router = VueRouter.createRouter({
|
||||
history: VueRouter.createWebHistory(`/${ciPath}`),
|
||||
@@ -85,7 +87,7 @@ const router = VueRouter.createRouter({
|
||||
name: "RoomInformation",
|
||||
params: { // in this case always populate other params since they are not optional
|
||||
ort_kurzbz: to.params.ort_kurzbz,
|
||||
mode: DEFAULT_MODE_RAUMINFO,
|
||||
mode: isMobile ? DEFAULT_MODE_RAUMINFO_MOBILE : DEFAULT_MODE_RAUMINFO_DESKTOP,
|
||||
focus_date: new Date().toISOString().split("T")[0]
|
||||
},
|
||||
};
|
||||
@@ -102,7 +104,7 @@ const router = VueRouter.createRouter({
|
||||
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;
|
||||
: (isMobile ? DEFAULT_MODE_RAUMINFO_MOBILE : DEFAULT_MODE_RAUMINFO_DESKTOP);
|
||||
|
||||
// default to today date if not provided
|
||||
const d = new Date(route.params.focus_date)
|
||||
@@ -197,6 +199,26 @@ const router = VueRouter.createRouter({
|
||||
};
|
||||
}
|
||||
},
|
||||
{
|
||||
path: `/Cis/StgOrgLvPlan/:mode?/:focus_date?/:stgkz?/:sem?/:verband?/:gruppe?`,
|
||||
name: 'StgOrgLvPlan',
|
||||
component: StgOrgLvPlan,
|
||||
props(route) {
|
||||
return {
|
||||
propsViewData: route.params
|
||||
};
|
||||
}
|
||||
},
|
||||
{
|
||||
path: `/Cis/OtherLvPlan/:otherUid/:mode?/:focus_date?`,
|
||||
name: "OtherLvPlan",
|
||||
component: OtherLvPlan,
|
||||
props(route) {
|
||||
return {
|
||||
propsViewData: route.params
|
||||
};
|
||||
}
|
||||
},
|
||||
{
|
||||
path: `/Cis4`,
|
||||
name: 'Cis4',
|
||||
@@ -227,24 +249,15 @@ const router = VueRouter.createRouter({
|
||||
})
|
||||
|
||||
const app = Vue.createApp({
|
||||
name: 'FhcApp',
|
||||
name: 'CisApp',
|
||||
data: () => ({
|
||||
appSideMenuEntries: {},
|
||||
renderers: null,
|
||||
windowWidth: 0,
|
||||
}),
|
||||
components: {},
|
||||
computed: {
|
||||
isMobile() {
|
||||
const smallScreen = window.matchMedia("(max-width: 767px)").matches;
|
||||
const touchCapable = ("ontouchstart" in window) || navigator.maxTouchPoints > 0;
|
||||
return smallScreen;// && touchCapable;
|
||||
},
|
||||
},
|
||||
provide() {
|
||||
return { // provide injectable & watchable language property
|
||||
language: Vue.computed(() => this.$p.user_language),
|
||||
renderers: Vue.computed(() => this.renderers),
|
||||
isMobile: this.isMobile,
|
||||
isMobile: Vue.computed(() => this.windowWidth < 767),
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
@@ -280,54 +293,21 @@ const app = Vue.createApp({
|
||||
this.$router.push(route);
|
||||
|
||||
}
|
||||
}
|
||||
},
|
||||
handleWindowResize() {
|
||||
this.windowWidth = window.innerWidth;
|
||||
},
|
||||
},
|
||||
async created(){
|
||||
|
||||
await this.$api
|
||||
.call(ApiRenderers.loadRenderers())
|
||||
.then(res => res.data)
|
||||
.then(data => {
|
||||
for (let rendertype of Object.keys(data)) {
|
||||
let modalTitle = null;
|
||||
let modalContent = null;
|
||||
let calendarEvent = null;
|
||||
if (data[rendertype].modalTitle)
|
||||
modalTitle = Vue.markRaw(Vue.defineAsyncComponent(() => import(data[rendertype].modalTitle)));
|
||||
if (data[rendertype].modalContent)
|
||||
modalContent = Vue.markRaw(Vue.defineAsyncComponent(() => import(data[rendertype].modalContent)));
|
||||
if (data[rendertype].calendarEvent)
|
||||
calendarEvent = Vue.markRaw(Vue.defineAsyncComponent(() => import(data[rendertype].calendarEvent)));
|
||||
|
||||
if (data[rendertype].calendarEventStyles){
|
||||
var head = document.head;
|
||||
if(!head.querySelector(`link[href="${data[rendertype].calendarEventStyles}"]`)){
|
||||
var link = document.createElement("link");
|
||||
link.type = "text/css";
|
||||
link.rel = "stylesheet";
|
||||
link.href = data[rendertype].calendarEventStyles;
|
||||
head.appendChild(link);
|
||||
}
|
||||
}
|
||||
|
||||
if(this.renderers === null) {
|
||||
this.renderers = {};
|
||||
}
|
||||
if (!this.renderers[rendertype]) {
|
||||
this.renderers[rendertype] = {}
|
||||
}
|
||||
this.renderers[rendertype].modalTitle = modalTitle;
|
||||
this.renderers[rendertype].modalContent = modalContent;
|
||||
this.renderers[rendertype].calendarEvent = calendarEvent;
|
||||
}
|
||||
});
|
||||
created() {
|
||||
this.windowWidth = window.innerWidth;
|
||||
},
|
||||
mounted() {
|
||||
async mounted() {
|
||||
document.addEventListener('click', this.handleClick);
|
||||
|
||||
window.addEventListener("resize", this.handleWindowResize);
|
||||
},
|
||||
beforeUnmount() {
|
||||
document.removeEventListener('click', this.handleClick);
|
||||
window.removeEventListener("resize", this.handleWindowResize);
|
||||
},
|
||||
});
|
||||
|
||||
@@ -353,4 +333,4 @@ app.mount('#fhccontent');
|
||||
|
||||
router.afterEach((to, from, failure) => {
|
||||
app.config.globalProperties.$api.call(ApiRouteInfo.info('cis4', to.fullPath));
|
||||
});
|
||||
});
|
||||
@@ -1,11 +1,12 @@
|
||||
import FhcSearchbar from "../components/searchbar/searchbar.js";
|
||||
import CisMenu from "../components/Cis/Menu.js";
|
||||
import PluginsPhrasen from '../plugins/Phrasen.js';
|
||||
import ApiSearchbar from '../api/factory/searchbar.js';
|
||||
import Theme from "../plugins/Theme.js";
|
||||
import FhcSearchbar from "../../components/searchbar/searchbar.js";
|
||||
import CisMenu from "../../components/Cis/Menu.js";
|
||||
import PluginsPhrasen from '../../plugins/Phrasen.js';
|
||||
import Theme from "../../plugins/Theme.js";
|
||||
import ApiSearchbar from '../../api/factory/searchbar.js';
|
||||
import ApiLvPlan from "../../api/factory/lvPlan.js";
|
||||
|
||||
const app = Vue.createApp({
|
||||
name: 'CisApp',
|
||||
name: 'CisMenuApp',
|
||||
components: {
|
||||
FhcSearchbar,
|
||||
CisMenu
|
||||
@@ -133,26 +134,61 @@ const app = Vue.createApp({
|
||||
childactions: []
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
windowWidth: 0,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
isMobile() {
|
||||
const smallScreen = window.matchMedia("(max-width: 767px)").matches;
|
||||
const touchCapable = ("ontouchstart" in window) || navigator.maxTouchPoints > 0;
|
||||
return smallScreen;// && touchCapable;
|
||||
},
|
||||
},
|
||||
provide() {
|
||||
return {
|
||||
isMobile: this.isMobile
|
||||
isNarrow: Vue.computed(() => this.windowWidth < 992),
|
||||
isMobile: Vue.computed(() => this.windowWidth < 767),
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
searchfunction: function(searchsettings) {
|
||||
return this.$api.call(ApiSearchbar.searchCis(searchsettings));
|
||||
}
|
||||
}
|
||||
},
|
||||
handleWindowResize() {
|
||||
this.windowWidth = window.innerWidth;
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.windowWidth = window.innerWidth;
|
||||
},
|
||||
async mounted() {
|
||||
const openOtherLvPlanAction = {
|
||||
label: Vue.computed(() => this.$p.t("lehre/stundenplan")),
|
||||
icon: "fas fa-calendar-days",
|
||||
type: "link",
|
||||
action: function (data) {
|
||||
const uid = JSON.parse(data.data).uid;
|
||||
const link =
|
||||
FHC_JS_DATA_STORAGE_OBJECT.app_root +
|
||||
FHC_JS_DATA_STORAGE_OBJECT.ci_router +
|
||||
"/Cis/OtherLvPlan/" +
|
||||
uid;
|
||||
return link;
|
||||
},
|
||||
};
|
||||
let checkPermissionOtherLvPlanResult = await this.$api.call(
|
||||
ApiLvPlan.checkPermissionOtherLvPlan(),
|
||||
);
|
||||
if (
|
||||
checkPermissionOtherLvPlanResult.meta.status === "success" &&
|
||||
checkPermissionOtherLvPlanResult.data
|
||||
) {
|
||||
this.searchbaroptions.actions.employee.childactions.push(
|
||||
openOtherLvPlanAction,
|
||||
);
|
||||
this.searchbaroptions.actions.student.childactions.push(
|
||||
openOtherLvPlanAction,
|
||||
);
|
||||
}
|
||||
window.addEventListener("resize", this.handleWindowResize);
|
||||
},
|
||||
beforeUnmount() {
|
||||
window.removeEventListener("resize", this.handleWindowResize);
|
||||
},
|
||||
});
|
||||
|
||||
FhcApps.makeExtendable(app);
|
||||
@@ -3,13 +3,10 @@ import DashboardAdmin from '../../components/Dashboard/Admin.js';
|
||||
|
||||
import PluginsPhrasen from '../../plugins/Phrasen.js';
|
||||
|
||||
import ApiRenderers from '../../api/factory/renderers.js';
|
||||
|
||||
const app = Vue.createApp({
|
||||
name: 'DashboardAdminApp',
|
||||
data: () => ({
|
||||
appSideMenuEntries: {},
|
||||
renderers: null
|
||||
appSideMenuEntries: {}
|
||||
}),
|
||||
components: {
|
||||
CoreNavigationCmpt,
|
||||
@@ -17,51 +14,16 @@ const app = Vue.createApp({
|
||||
},
|
||||
provide() {
|
||||
return {
|
||||
// TODO(chris): move those two into the components that need it
|
||||
renderers: Vue.computed(() => this.renderers),
|
||||
timezone: FHC_JS_DATA_STORAGE_OBJECT.timezone
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.$api
|
||||
.call(ApiRenderers.loadRenderers())
|
||||
.then(res => {
|
||||
for (let rendertype of Object.keys(res.data)) {
|
||||
let modalTitle = null;
|
||||
let modalContent = null;
|
||||
let calendarEvent = null;
|
||||
if (res.data[rendertype].modalTitle)
|
||||
modalTitle = Vue.markRaw(Vue.defineAsyncComponent(() => import(res.data[rendertype].modalTitle)));
|
||||
if (res.data[rendertype].modalContent)
|
||||
modalContent = Vue.markRaw(Vue.defineAsyncComponent(() => import(res.data[rendertype].modalContent)));
|
||||
if (res.data[rendertype].calendarEvent)
|
||||
calendarEvent = Vue.markRaw(Vue.defineAsyncComponent(() => import(res.data[rendertype].calendarEvent)));
|
||||
|
||||
if (res.data[rendertype].calendarEventStyles) {
|
||||
var head = document.head;
|
||||
if (!head.querySelector(`link[href="${res.data[rendertype].calendarEventStyles}"]`)) {
|
||||
var link = document.createElement("link");
|
||||
link.type = "text/css";
|
||||
link.rel = "stylesheet";
|
||||
link.href = res.data[rendertype].calendarEventStyles;
|
||||
head.appendChild(link);
|
||||
}
|
||||
}
|
||||
|
||||
if (this.renderers === null) {
|
||||
this.renderers = {};
|
||||
}
|
||||
if (!this.renderers[rendertype]) {
|
||||
this.renderers[rendertype] = {}
|
||||
}
|
||||
this.renderers[rendertype].modalTitle = modalTitle;
|
||||
this.renderers[rendertype].modalContent = modalContent;
|
||||
this.renderers[rendertype].calendarEvent = calendarEvent;
|
||||
}
|
||||
})
|
||||
.catch(this.$fhcAlert.handleSystemErrors);
|
||||
}
|
||||
});
|
||||
app.use(primevue.config.default, {
|
||||
zIndex: {
|
||||
overlay: 9000,
|
||||
tooltip: 8000
|
||||
}
|
||||
})
|
||||
app.use(PluginsPhrasen);
|
||||
app.directive('tooltip', primevue.tooltip);
|
||||
app.mount('#main');
|
||||
@@ -1,16 +0,0 @@
|
||||
import {CoreNavigationCmpt} from '../components/navigation/Navigation.js';
|
||||
import DashboardAdmin from '../components/Dashboard/Admin.js';
|
||||
import Phrases from "../plugin/Phrasen.js"
|
||||
|
||||
Vue.createApp({
|
||||
name: 'DashboardAdminApp',
|
||||
data: () => ({
|
||||
appSideMenuEntries: {}
|
||||
}),
|
||||
components: {
|
||||
CoreNavigationCmpt,
|
||||
DashboardAdmin
|
||||
},
|
||||
mounted() {
|
||||
}
|
||||
}).use(Phrases).mount('#main');
|
||||
@@ -20,7 +20,8 @@ export default {
|
||||
},
|
||||
inject: {
|
||||
mode: "mode",
|
||||
dropableEvents: "dropableEvents"
|
||||
dropableEvents: "dropableEvents",
|
||||
timezone: "timezone"
|
||||
},
|
||||
props: {
|
||||
events: Array,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import LineEvent from './Line/Event.js';
|
||||
import LineBackground from './Line/Background.js';
|
||||
import LineEvent from "./Line/Event.js";
|
||||
import LineBackground from "./Line/Background.js";
|
||||
|
||||
/**
|
||||
* TODO(chris):
|
||||
@@ -10,54 +10,117 @@ export default {
|
||||
name: "GridLine",
|
||||
components: {
|
||||
LineEvent,
|
||||
LineBackground
|
||||
},
|
||||
inject: {
|
||||
axisRow: "axisRow"
|
||||
LineBackground,
|
||||
},
|
||||
inject: ["axisRow", "shouldCompactEvents", "compactibleEventTypes"],
|
||||
props: {
|
||||
date: {
|
||||
type: luxon.DateTime,
|
||||
required: true
|
||||
required: true,
|
||||
},
|
||||
start: {
|
||||
type: luxon.DateTime,
|
||||
required: true
|
||||
required: true,
|
||||
},
|
||||
end: {
|
||||
type: luxon.DateTime,
|
||||
required: true
|
||||
required: true,
|
||||
},
|
||||
events: {
|
||||
type: Array,
|
||||
default: []
|
||||
default: [],
|
||||
},
|
||||
backgrounds: {
|
||||
type: Array,
|
||||
default: []
|
||||
}
|
||||
default: [],
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
eventsWithRowInfo() {
|
||||
const events = [];
|
||||
this.events.forEach(event => {
|
||||
const rows = [1, -1];
|
||||
formattedEvents() {
|
||||
let formattedEvents = this.events.map((event) => {
|
||||
event.rows = [1, -1];
|
||||
if (event.startsHere) {
|
||||
rows[0] = 't_' + event.start.diff(this.date).toMillis();
|
||||
event.rows[0] =
|
||||
"t_" + event.start.diff(this.date).toMillis();
|
||||
}
|
||||
if (event.endsHere) {
|
||||
rows[1] = 't_' + event.end.diff(this.date).toMillis();
|
||||
event.rows[1] = "t_" + event.end.diff(this.date).toMillis();
|
||||
}
|
||||
|
||||
events.push({
|
||||
...event,
|
||||
rows
|
||||
});
|
||||
return event;
|
||||
});
|
||||
return events;
|
||||
}
|
||||
|
||||
if (this.shouldCompactEvents && this.compactibleEventTypes?.length) {
|
||||
formattedEvents =
|
||||
this.compactEvents(formattedEvents, this.compactibleEventTypes);
|
||||
}
|
||||
|
||||
return formattedEvents;
|
||||
},
|
||||
},
|
||||
template: /* html */`
|
||||
methods: {
|
||||
compactEvents(events, compactibleEventTypes) {
|
||||
let formattedEvents = events
|
||||
.filter(
|
||||
(event) =>
|
||||
!compactibleEventTypes.includes(event.type),
|
||||
)
|
||||
.map((event) => {
|
||||
event.display = "default";
|
||||
return event;
|
||||
});
|
||||
let eventsToBeCompacted = events.filter((event) =>
|
||||
compactibleEventTypes.includes(event.type),
|
||||
);
|
||||
let compactedEvents = [];
|
||||
|
||||
eventsToBeCompacted.forEach((event) => {
|
||||
let existingCompactedEvent = compactedEvents.find(
|
||||
(compactedEvent) =>
|
||||
event.rows[0] === compactedEvent.rows[0] &&
|
||||
event.rows[1] === compactedEvent.rows[1],
|
||||
);
|
||||
|
||||
if (!existingCompactedEvent) {
|
||||
compactedEvents.push({
|
||||
events: [
|
||||
{
|
||||
farbe: event.orig.farbe,
|
||||
},
|
||||
],
|
||||
rows: event.rows,
|
||||
});
|
||||
} else {
|
||||
existingCompactedEvent.events.push({
|
||||
farbe: event.orig.farbe,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
compactedEvents.forEach((compactedEvent) => {
|
||||
if (compactedEvent.events.length < 4) {
|
||||
formattedEvents.push({
|
||||
display: "compacted",
|
||||
...compactedEvent,
|
||||
});
|
||||
} else {
|
||||
formattedEvents.push({
|
||||
display: "compacted",
|
||||
events: compactedEvent.events.slice(0, 3),
|
||||
rows: compactedEvent.rows,
|
||||
});
|
||||
formattedEvents.push({
|
||||
display: "compactedExtra",
|
||||
events: compactedEvent.events.slice(3),
|
||||
rows: compactedEvent.rows,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
return formattedEvents;
|
||||
},
|
||||
},
|
||||
template: /* html */ `
|
||||
<div
|
||||
class="fhc-calendar-base-grid-line"
|
||||
style="position:relative;display:grid;grid-auto-flow:dense"
|
||||
@@ -69,17 +132,38 @@ export default {
|
||||
:end="end"
|
||||
:background="bg"
|
||||
></line-background>
|
||||
<line-event
|
||||
v-for="(event, i) in eventsWithRowInfo"
|
||||
:key="i"
|
||||
:style="'grid-' + axisRow + ': ' + event.rows.join('/')"
|
||||
:event="event"
|
||||
>
|
||||
<template v-slot="slot">
|
||||
<slot name="event" v-bind="slot" />
|
||||
</template>
|
||||
</line-event>
|
||||
<template v-for="(event, i) in formattedEvents" :key="i">
|
||||
<line-event
|
||||
v-if="!event.display || event.display === 'default'"
|
||||
:style="'grid-' + axisRow + ': ' + event.rows.join('/')"
|
||||
:event="event"
|
||||
>
|
||||
<template v-slot="slot">
|
||||
<slot name="event" v-bind="slot" />
|
||||
</template>
|
||||
</line-event>
|
||||
<div
|
||||
v-else-if="event.display === 'compacted'"
|
||||
:style="'grid-' + axisRow + ': ' + event.rows.join('/')"
|
||||
class="d-flex flex-row justify-content-center gap-1 align-items-center"
|
||||
>
|
||||
<span
|
||||
v-for="(subEvent, subEventIndex) in event.events"
|
||||
:key="subEventIndex"
|
||||
:style="subEvent.farbe ? {'background-color': '#' + subEvent.farbe} : {}"
|
||||
style="height:10px; width:10px;"
|
||||
class="border border-dark rounded-circle"
|
||||
></span>
|
||||
</div>
|
||||
<div
|
||||
v-else-if="event.display === 'compactedExtra'"
|
||||
:style="'grid-' + axisRow + ': ' + event.rows.join('/')"
|
||||
class="w-100 d-flex flex-row justify-content-center"
|
||||
>
|
||||
{{"+" + event.events.length}}
|
||||
</div>
|
||||
</template>
|
||||
<slot name="dropzone" />
|
||||
</div>
|
||||
`
|
||||
}
|
||||
`,
|
||||
};
|
||||
|
||||
@@ -3,24 +3,20 @@ import FhcCalendar from "./Base.js";
|
||||
import ApiLvPlan from '../../api/factory/lvPlan.js';
|
||||
|
||||
import { useEventLoader } from '../../composables/EventLoader.js';
|
||||
import { useRenderers } from '../../composables/Renderers.js';
|
||||
|
||||
import ModeDay from './Mode/Day.js';
|
||||
import ModeWeek from './Mode/Week.js';
|
||||
import ModeMonth from './Mode/Month.js';
|
||||
import ModeList from './Mode/List.js';
|
||||
|
||||
export default {
|
||||
name: "CalendarLvPlan",
|
||||
components: {
|
||||
FhcCalendar
|
||||
},
|
||||
inject: [
|
||||
"renderers"
|
||||
],
|
||||
inject: ["isMobile"],
|
||||
props: {
|
||||
timezone: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
date: {
|
||||
type: [Date, String, Number, luxon.DateTime],
|
||||
default: luxon.DateTime.local()
|
||||
@@ -34,6 +30,16 @@ export default {
|
||||
required: true
|
||||
}
|
||||
},
|
||||
provide() {
|
||||
return {
|
||||
shouldCompactEvents: Vue.computed(
|
||||
() => this.$props.mode === "Month" && this.isMobile,
|
||||
),
|
||||
compactibleEventTypes: Vue.computed(
|
||||
() => this.compactibleEventTypes,
|
||||
),
|
||||
};
|
||||
},
|
||||
emits: [
|
||||
"update:date",
|
||||
"update:mode",
|
||||
@@ -41,11 +47,7 @@ export default {
|
||||
],
|
||||
data() {
|
||||
return {
|
||||
modes: {
|
||||
day: Vue.markRaw(ModeDay),
|
||||
week: Vue.markRaw(ModeWeek),
|
||||
month: Vue.markRaw(ModeMonth)
|
||||
},
|
||||
timezone: FHC_JS_DATA_STORAGE_OBJECT.timezone,
|
||||
modeOptions: {
|
||||
day: {
|
||||
emptyMessage: Vue.computed(() => this.$p.t('lehre/noLvFound')),
|
||||
@@ -53,9 +55,13 @@ export default {
|
||||
},
|
||||
week: {
|
||||
collapseEmptyDays: false
|
||||
}
|
||||
},
|
||||
list: {
|
||||
length: 7,
|
||||
},
|
||||
},
|
||||
teachingunits: null
|
||||
teachingunits: null,
|
||||
compactibleEventTypes: [],
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
@@ -77,7 +83,20 @@ export default {
|
||||
label: now.startOf('minute').toISOTime({ suppressSeconds: true, includeOffset: false })
|
||||
}
|
||||
];
|
||||
}
|
||||
},
|
||||
modes() {
|
||||
let modes = {
|
||||
day: Vue.markRaw(ModeDay),
|
||||
month: Vue.markRaw(ModeMonth),
|
||||
};
|
||||
if (this.isMobile) {
|
||||
modes.list = Vue.markRaw(ModeList);
|
||||
} else {
|
||||
modes.week = Vue.markRaw(ModeWeek);
|
||||
}
|
||||
|
||||
return modes;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
eventStyle(event) {
|
||||
@@ -88,33 +107,47 @@ export default {
|
||||
updateRange(rangeInterval) {
|
||||
this.rangeInterval = rangeInterval;
|
||||
this.$emit('update:range', rangeInterval);
|
||||
}
|
||||
},
|
||||
resetEventLoader() {
|
||||
this.reset();
|
||||
},
|
||||
async getStunden() {
|
||||
let stundenResponse = await this.$api.call(ApiLvPlan.getStunden());
|
||||
this.teachingunits = stundenResponse.data.map((el) => ({
|
||||
id: el.stunde,
|
||||
start: el.beginn,
|
||||
end: el.ende,
|
||||
}));
|
||||
},
|
||||
async getCompactibleEventTypes() {
|
||||
let compactibleEventTypesResponse = await this.$api.call(
|
||||
ApiLvPlan.getCompactibleEventTypes(),
|
||||
);
|
||||
this.compactibleEventTypes = compactibleEventTypesResponse.data;
|
||||
},
|
||||
},
|
||||
setup(props, context) {
|
||||
const rangeInterval = Vue.ref(null);
|
||||
|
||||
const { events, lv } = useEventLoader(rangeInterval, props.getPromiseFunc);
|
||||
const { events, lv, reset } = useEventLoader(rangeInterval, props.getPromiseFunc);
|
||||
|
||||
Vue.watch(lv, newValue => {
|
||||
context.emit('update:lv', newValue);
|
||||
});
|
||||
|
||||
const { renderers } = useRenderers();
|
||||
|
||||
return {
|
||||
rangeInterval,
|
||||
events,
|
||||
lv
|
||||
lv,
|
||||
reset,
|
||||
renderers
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.$api
|
||||
.call(ApiLvPlan.getStunden())
|
||||
.then(res => {
|
||||
return this.teachingunits = res.data.map(el => ({
|
||||
id: el.stunde,
|
||||
start: el.beginn,
|
||||
end: el.ende
|
||||
}));
|
||||
});
|
||||
async created() {
|
||||
await this.getStunden();
|
||||
await this.getCompactibleEventTypes();
|
||||
},
|
||||
template: /* html */`
|
||||
<fhc-calendar
|
||||
@@ -136,6 +169,13 @@ export default {
|
||||
>
|
||||
<template v-slot="{ event, mode }">
|
||||
<div
|
||||
v-if="!event"
|
||||
class="h-100 d-flex justify-content-center align-items-center"
|
||||
>
|
||||
{{ $p.t('lehre/noLvFound') }}
|
||||
</div>
|
||||
<div
|
||||
v-else
|
||||
:class="'event-type-' + event.type + ' ' + mode + 'PageContainer'"
|
||||
:type="mode == 'day' ? 'button' : undefined"
|
||||
:style="eventStyle(event)"
|
||||
@@ -154,6 +194,9 @@ export default {
|
||||
v-else
|
||||
:is="renderers[event.type]?.calendarEvent"
|
||||
:event="event"
|
||||
:timeSlotDisplayBehavior="
|
||||
$props.mode.toLowerCase() === 'list' ? 'always' : 'default'
|
||||
"
|
||||
></component>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -93,7 +93,7 @@ export default {
|
||||
mounted() {
|
||||
this.$emit('update:range', this.range);
|
||||
},
|
||||
template: `
|
||||
template: /*html*/ `
|
||||
<div
|
||||
class="fhc-calendar-mode-list flex-grow-1 position-relative"
|
||||
@cal-click-default.capture="handleClickDefaults"
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import FhcCalendar from "./Base.js";
|
||||
|
||||
import { useEventLoader } from '../../composables/EventLoader.js';
|
||||
import { useRenderers } from '../../composables/Renderers.js';
|
||||
|
||||
import ModeList from '../Calendar/Mode/List.js';
|
||||
|
||||
@@ -9,22 +10,17 @@ export default {
|
||||
components: {
|
||||
FhcCalendar
|
||||
},
|
||||
inject: [
|
||||
"renderers"
|
||||
],
|
||||
props: {
|
||||
timezone: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
getPromiseFunc: {
|
||||
type: Function,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
const timezone = FHC_JS_DATA_STORAGE_OBJECT.timezone;
|
||||
return {
|
||||
now: luxon.DateTime.now().setZone(this.timezone),
|
||||
timezone,
|
||||
now: luxon.DateTime.now().setZone(timezone),
|
||||
modes: {
|
||||
list: Vue.markRaw(ModeList)
|
||||
},
|
||||
@@ -59,10 +55,12 @@ export default {
|
||||
const rangeInterval = Vue.ref(null);
|
||||
|
||||
const { events } = useEventLoader(rangeInterval, props.getPromiseFunc);
|
||||
const { renderers } = useRenderers();
|
||||
|
||||
return {
|
||||
rangeInterval,
|
||||
events
|
||||
events,
|
||||
renderers
|
||||
};
|
||||
},
|
||||
template: /* html */`
|
||||
@@ -99,6 +97,7 @@ export default {
|
||||
<component
|
||||
:is="renderers[event.type]?.calendarEvent"
|
||||
:event="event"
|
||||
:timeSlotDisplayBehavior="'always'"
|
||||
></component>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -42,14 +42,6 @@ export const AbgabetoolAssistenz = {
|
||||
stg_kz_prop: {
|
||||
default: null
|
||||
},
|
||||
viewData: {
|
||||
type: Object,
|
||||
required: true,
|
||||
default: () => ({name: '', uid: ''}),
|
||||
validator(value) {
|
||||
return value && value.uid // && value.name -> extensive viewData use only for cis4 onwards
|
||||
}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
||||
@@ -31,16 +31,6 @@ export const AbgabetoolMitarbeiter = {
|
||||
old_abgabe_beurteilung_link: Vue.computed(() => this.old_abgabe_beurteilung_link)
|
||||
}
|
||||
},
|
||||
props: {
|
||||
viewData: {
|
||||
type: Object,
|
||||
required: true,
|
||||
default: () => ({name: '', uid: ''}),
|
||||
validator(value) {
|
||||
return value && value.uid // && value.name -> extensive viewData use only for cis4 onwards
|
||||
}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
tableData: null,
|
||||
|
||||
@@ -3,6 +3,7 @@ import ApiAbgabe from '../../../api/factory/abgabe.js'
|
||||
import BsModal from "../../Bootstrap/Modal.js";
|
||||
import FhcOverlay from "../../Overlay/FhcOverlay.js";
|
||||
import { getDateStyleClass} from "./getDateStyleClass.js";
|
||||
import ApiAuthinfo from "../../../api/factory/authinfo.js";
|
||||
|
||||
export const AbgabetoolStudent = {
|
||||
name: "AbgabetoolStudent",
|
||||
@@ -24,14 +25,6 @@ export const AbgabetoolStudent = {
|
||||
student_uid_prop: {
|
||||
default: null
|
||||
},
|
||||
viewData: {
|
||||
type: Object,
|
||||
required: true,
|
||||
default: () => ({uid: ''}),
|
||||
validator(value) {
|
||||
return value && value.uid
|
||||
}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
@@ -44,9 +37,18 @@ export const AbgabetoolStudent = {
|
||||
detail: null,
|
||||
projektarbeiten: null,
|
||||
selectedProjektarbeit: null,
|
||||
moodle_link: null
|
||||
moodle_link: null,
|
||||
uid: null,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
isViewMode() {
|
||||
return this.student_uid !== this.uid
|
||||
},
|
||||
student_uid() {
|
||||
return this.student_uid_prop || this.uid || null
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
checkQualityGatesStrict(termine) {
|
||||
let qgate1Passed = false
|
||||
@@ -258,18 +260,11 @@ export const AbgabetoolStudent = {
|
||||
},
|
||||
handleDownloadBeurteilung2(projektarbeit) {
|
||||
window.open(projektarbeit.beurteilung2)
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
|
||||
},
|
||||
computed: {
|
||||
isViewMode() {
|
||||
return this.student_uid !== this.viewData.uid
|
||||
},
|
||||
student_uid() {
|
||||
return this.student_uid_prop || this.viewData?.uid || null
|
||||
}
|
||||
async fetchAuthUID() {
|
||||
const authIdResponse = await this.$api.call(ApiAuthinfo.getAuthUID());
|
||||
this.uid = authIdResponse.data.uid;
|
||||
},
|
||||
},
|
||||
async created() {
|
||||
this.phrasenPromise = this.$p.loadCategory(['abgabetool', 'global'])
|
||||
@@ -302,6 +297,8 @@ export const AbgabetoolStudent = {
|
||||
}).catch(e => {
|
||||
this.loading = false
|
||||
})
|
||||
|
||||
await this.fetchAuthUID();
|
||||
},
|
||||
mounted() {
|
||||
this.setupMounted()
|
||||
|
||||
@@ -10,14 +10,6 @@ export const DeadlineOverview = {
|
||||
person_uid_prop: {
|
||||
default: null
|
||||
},
|
||||
viewData: {
|
||||
type: Object,
|
||||
required: true,
|
||||
default: () => ({name: '', uid: ''}),
|
||||
validator(value) {
|
||||
return value && value.name && value.uid
|
||||
}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
||||
@@ -2,115 +2,137 @@ import Pagination from "../../Pagination/Pagination.js";
|
||||
import StudiengangInformation from "./StudiengangInformation/StudiengangInformation.js";
|
||||
import BsConfirm from "../../Bootstrap/Confirm.js";
|
||||
|
||||
import ApiCms from '../../../api/factory/cms.js';
|
||||
import ApiCms from "../../../api/factory/cms.js";
|
||||
|
||||
export default {
|
||||
name: "NewsComponent",
|
||||
components: {
|
||||
Pagination,
|
||||
StudiengangInformation,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
content: null,
|
||||
maxPageCount: 0,
|
||||
page_size: 10,
|
||||
page:1,
|
||||
};
|
||||
},
|
||||
watch:{
|
||||
'$p.user_language.value':function(sprache){
|
||||
this.fetchNews();
|
||||
}
|
||||
},
|
||||
computed:{
|
||||
sprache: function(){
|
||||
return this.$p.user_language.value;
|
||||
components: {
|
||||
Pagination,
|
||||
StudiengangInformation,
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
fetchNews() {
|
||||
return this.$api
|
||||
.call(ApiCms.getNews(this.page, this.page_size, this.sprache))
|
||||
.then(res => res.data)
|
||||
.then(result => {
|
||||
this.content = result;
|
||||
inject: ["isMobile"],
|
||||
data() {
|
||||
return {
|
||||
content: null,
|
||||
maxPageCount: 0,
|
||||
page_size: 10,
|
||||
page: 1,
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
"$p.user_language.value": function (sprache) {
|
||||
this.fetchNews();
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
sprache: function () {
|
||||
return this.$p.user_language.value;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
async fetchNews() {
|
||||
let newsResponse = await this.$api.call(
|
||||
ApiCms.getNews(this.page, this.page_size, this.sprache),
|
||||
);
|
||||
this.content = newsResponse.data;
|
||||
|
||||
document.querySelectorAll("#cms [data-confirm]").forEach((el) => {
|
||||
el.addEventListener("click", (evt) => {
|
||||
evt.preventDefault();
|
||||
BsConfirm.popup(el.dataset.confirm)
|
||||
.then(() => {
|
||||
Axios.get(el.href)
|
||||
.then((res) => {
|
||||
// TODO(chris): check for success then show message and/or reload
|
||||
location = location;
|
||||
})
|
||||
.catch((err) => console.error("ERROR:", err));
|
||||
document.querySelectorAll("#cms [data-confirm]").forEach((el) => {
|
||||
el.addEventListener("click", (evt) => {
|
||||
evt.preventDefault();
|
||||
BsConfirm.popup(el.dataset.confirm)
|
||||
.then(() => {
|
||||
Axios.get(el.href)
|
||||
.then((res) => {
|
||||
// TODO(chris): check for success then show message and/or reload
|
||||
location = location;
|
||||
})
|
||||
.catch(() => {
|
||||
});
|
||||
});
|
||||
});
|
||||
document.querySelectorAll("#cms [data-href]").forEach((el) => {
|
||||
el.href = el.dataset.href.replace(
|
||||
/^ROOT\//,
|
||||
FHC_JS_DATA_STORAGE_OBJECT.app_root
|
||||
);
|
||||
});
|
||||
Vue.nextTick(()=>{
|
||||
document.querySelectorAll(".card-header").forEach((el) => {
|
||||
el.classList.add("fhc-primary");
|
||||
});
|
||||
document.querySelectorAll(".row").forEach((el) => {
|
||||
el.classList.add("w-100");
|
||||
el.classList.add("align-items-center");
|
||||
|
||||
});
|
||||
document.querySelectorAll(".row h2").forEach((el) => {
|
||||
el.classList.add("mb-0");
|
||||
});
|
||||
.catch((err) => console.error("ERROR:", err));
|
||||
})
|
||||
.catch(() => {});
|
||||
});
|
||||
});
|
||||
document.querySelectorAll("#cms [data-href]").forEach((el) => {
|
||||
el.href = el.dataset.href.replace(
|
||||
/^ROOT\//,
|
||||
FHC_JS_DATA_STORAGE_OBJECT.app_root,
|
||||
);
|
||||
});
|
||||
|
||||
})
|
||||
await this.$nextTick();
|
||||
this.formatExternalHtml();
|
||||
},
|
||||
async loadNewPageContent(data) {
|
||||
let newsResponse = await this.$api.call(
|
||||
ApiCms.getNews(data.page, data.rows),
|
||||
);
|
||||
this.content = newsResponse.data;
|
||||
|
||||
await this.$nextTick();
|
||||
|
||||
this.formatExternalHtml();
|
||||
},
|
||||
formatExternalHtml() {
|
||||
document
|
||||
.querySelectorAll(".news-list-item .card-header")
|
||||
.forEach((el) => {
|
||||
el.classList.add("fhc-primary");
|
||||
});
|
||||
document.querySelectorAll(".news-list-item .row").forEach((el) => {
|
||||
el.classList.add("w-100");
|
||||
el.classList.add("align-items-center");
|
||||
});
|
||||
document
|
||||
.querySelectorAll(".news-list-item .row h2")
|
||||
.forEach((el) => {
|
||||
el.classList.add("mb-0");
|
||||
});
|
||||
},
|
||||
loadNewPageContent(data) {
|
||||
this.$api
|
||||
.call(ApiCms.getNews(data.page, data.rows))
|
||||
.then(res => res.data)
|
||||
.then(result => {
|
||||
this.content = result;
|
||||
|
||||
});
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.fetchNews();
|
||||
afterPageUpdated(event) {
|
||||
this.page = event.page;
|
||||
this.page_size = event.rows;
|
||||
this.$refs.newsPageHeading.scrollIntoView({block: 'end'});
|
||||
this.loadNewPageContent(event);
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.fetchNews();
|
||||
|
||||
this.$api
|
||||
.call(ApiCms.getNewsRowCount())
|
||||
.then(res => res.data)
|
||||
.then(result => {
|
||||
.then((res) => res.data)
|
||||
.then((result) => {
|
||||
this.maxPageCount = result;
|
||||
});
|
||||
},
|
||||
template: /*html*/ `
|
||||
<h2 class="fhc-primary-color">News</h2>
|
||||
<hr/>
|
||||
<pagination v-show="content?true:false" :page_size="page_size" @page="page=$event.page; loadNewPageContent($event)" :maxPageCount="maxPageCount">
|
||||
</pagination>
|
||||
<div class="container-fluid mt-4">
|
||||
<div class="row">
|
||||
<div class="col" v-html="content">
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<div style="width:15rem">
|
||||
<studiengang-information></studiengang-information>
|
||||
},
|
||||
template: /*html*/ `
|
||||
<div :class="{'pb-3': isMobile}" class="overflow-x-hidden">
|
||||
<h2 ref="newsPageHeading" class="fhc-primary-color">News</h2>
|
||||
<hr/>
|
||||
<pagination
|
||||
v-if="content?true:false"
|
||||
:page="page"
|
||||
:page_size="page_size"
|
||||
@pageUpdated="afterPageUpdated($event)"
|
||||
:maxPageCount="maxPageCount"
|
||||
></pagination>
|
||||
<div class="container-fluid mt-4">
|
||||
<div class="row">
|
||||
<div class="col" v-html="content">
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<div style="width:15rem">
|
||||
<studiengang-information></studiengang-information>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<pagination
|
||||
v-if="content?true:false"
|
||||
:page="page"
|
||||
:page_size="page_size"
|
||||
@pageUpdated="afterPageUpdated($event)"
|
||||
:maxPageCount="maxPageCount"
|
||||
></pagination>
|
||||
</div>
|
||||
<pagination v-show="content?true:false" :page_size="page_size" @page="loadNewPageContent" :maxPageCount="maxPageCount">
|
||||
</pagination>
|
||||
`,
|
||||
};
|
||||
|
||||
@@ -29,51 +29,51 @@ components:{
|
||||
},
|
||||
template:/*html*/`
|
||||
<div id="fhc-studiengang-informationen">
|
||||
<template v-if="studiengang?.bezeichnung && semester">
|
||||
<div class="card card-body mb-3 border-0">
|
||||
<div class="mb-1">
|
||||
<h2 class="h4 mb-1 pb-0">{{$p.t('lehre','studiengang')}}:</h2>
|
||||
<span class="mb-1">{{studiengang?.bezeichnung}}</span>
|
||||
</div>
|
||||
<div class="mb-1">
|
||||
<h2 class="h4 mb-1 pb-0">Moodle:</h2>
|
||||
<a class="fhc-link-color mb-1" target="_blank" :href="moodleLink">{{studiengang?.kurzbzlang}}</a>
|
||||
</div>
|
||||
<div :class="{'mb-1':studiengang?.zusatzinfo_html}">
|
||||
<h2 class="h4 mb-1 pb-0">{{$p.t('lehre','studiensemester')}}: </h2>
|
||||
<span class="mb-1">{{semester}}</span>
|
||||
</div>
|
||||
<div class="zusatzinfo" v-if="studiengang?.zusatzinfo_html" v-html="studiengang?.zusatzinfo_html"></div>
|
||||
</div>
|
||||
</template>
|
||||
<template v-for="{title, collection} in collection_array">
|
||||
<template v-if="Array.isArray(collection) && collection.length !==0">
|
||||
<h2 class="h5 text-truncate">{{title}}</h2>
|
||||
<template v-if="displayWidget">
|
||||
<div class="d-flex flex-wrap flex-row mb-3 gap-2">
|
||||
<template v-for="person in collection">
|
||||
<studiengang-person displayWidget v-bind="person"></studiengang-person>
|
||||
</template>
|
||||
<template v-if="studiengang?.bezeichnung && semester">
|
||||
<div class="card card-body mb-3 border-0">
|
||||
<div class="mb-1">
|
||||
<h2 class="h4 mb-1 pb-0">{{$p.t('lehre','studiengang')}}:</h2>
|
||||
<span class="mb-1">{{studiengang?.bezeichnung}}</span>
|
||||
</div>
|
||||
</template>
|
||||
<template v-else>
|
||||
<template v-for="person in collection">
|
||||
<div class="mb-3">
|
||||
<studiengang-person v-bind="person"></studiengang-person>
|
||||
<div class="mb-1">
|
||||
<h2 class="h4 mb-1 pb-0">Moodle:</h2>
|
||||
<a class="fhc-link-color mb-1" target="_blank" :href="moodleLink">{{studiengang?.kurzbzlang}}</a>
|
||||
</div>
|
||||
<div :class="{'mb-1':studiengang?.zusatzinfo_html}">
|
||||
<h2 class="h4 mb-1 pb-0">{{$p.t('lehre','studiensemester')}}: </h2>
|
||||
<span class="mb-1">{{semester}}</span>
|
||||
</div>
|
||||
<div class="zusatzinfo" v-if="studiengang?.zusatzinfo_html" v-html="studiengang?.zusatzinfo_html"></div>
|
||||
</div>
|
||||
</template>
|
||||
<template v-for="{title, collection} in collection_array">
|
||||
<template v-if="Array.isArray(collection) && collection.length !==0">
|
||||
<h2 class="h5 text-truncate">{{title}}</h2>
|
||||
<template v-if="displayWidget">
|
||||
<div class="d-flex flex-wrap flex-row mb-3 gap-2">
|
||||
<template v-for="person in collection">
|
||||
<studiengang-person displayWidget v-bind="person"></studiengang-person>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
<template v-else>
|
||||
<template v-for="person in collection">
|
||||
<div class="mb-3">
|
||||
<studiengang-person v-bind="person"></studiengang-person>
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
</template>
|
||||
</template>
|
||||
</template>
|
||||
<template v-if="hochschulvertr && Array.isArray(hochschulvertr) && hochschulvertr.length >0">
|
||||
<studiengang-vertretung showBezeichnung :title="$p.t('studiengangInformation', 'Hochschulvertretung')" :vertretungsList="hochschulvertr"></studiengang-vertretung>
|
||||
</template>
|
||||
<template v-if="stdv && Array.isArray(stdv) && stdv.length >0">
|
||||
<studiengang-vertretung :title="$p.t('studiengangInformation', 'Studienvertretung').concat(studiengang.kurzbzlang??'')" :vertretungsList="stdv"></studiengang-vertretung>
|
||||
</template>
|
||||
<template v-if="jahrgangsvertr && Array.isArray(jahrgangsvertr) && jahrgangsvertr.length >0">
|
||||
<studiengang-vertretung :title="$p.t('studiengangInformation', 'Jahrgangsvertretung')" :vertretungsList="jahrgangsvertr"></studiengang-vertretung>
|
||||
</template>
|
||||
<template v-if="hochschulvertr && Array.isArray(hochschulvertr) && hochschulvertr.length >0">
|
||||
<studiengang-vertretung showBezeichnung :title="$p.t('studiengangInformation', 'Hochschulvertretung')" :vertretungsList="hochschulvertr"></studiengang-vertretung>
|
||||
</template>
|
||||
<template v-if="stdv && Array.isArray(stdv) && stdv.length >0">
|
||||
<studiengang-vertretung :title="$p.t('studiengangInformation', 'Studienvertretung').concat(studiengang?.kurzbzlang??'')" :vertretungsList="stdv"></studiengang-vertretung>
|
||||
</template>
|
||||
<template v-if="jahrgangsvertr && Array.isArray(jahrgangsvertr) && jahrgangsvertr.length >0">
|
||||
<studiengang-vertretung :title="$p.t('studiengangInformation', 'Jahrgangsvertretung')" :vertretungsList="jahrgangsvertr"></studiengang-vertretung>
|
||||
</template>
|
||||
</div>
|
||||
|
||||
`,
|
||||
|
||||
@@ -27,7 +27,7 @@ export default {
|
||||
|
||||
<dl class="stgkontaktinfo">
|
||||
<dt><i class="fa fa-phone me-2"></i></dt>
|
||||
<dd class="mb-3"><a class="fhc-link-color" :href="phone.link">{{phone.number}}</a></dd>
|
||||
<dd class="mb-3"><a class="fhc-link-color" :href="phone?.link">{{phone?.number}}</a></dd>
|
||||
|
||||
<dt><i class="fa fa-home me-2"></i></dt>
|
||||
<dd class="mb-3">{{ort}}</dd>
|
||||
|
||||
@@ -3,7 +3,8 @@ import FhcCalendar from "../../Calendar/LvPlan.js";
|
||||
import ApiLvPlan from '../../../api/factory/lvPlan.js';
|
||||
import ApiAuthinfo from '../../../api/factory/authinfo.js';
|
||||
|
||||
export const DEFAULT_MODE_LVPLAN = 'Week'
|
||||
export const DEFAULT_MODE_LVPLAN_MOBILE = 'List';
|
||||
export const DEFAULT_MODE_LVPLAN_DESKTOP = 'Week';
|
||||
|
||||
export default {
|
||||
name: 'LvPlanLehrveranstaltung',
|
||||
@@ -19,15 +20,21 @@ export default {
|
||||
lv: null
|
||||
};
|
||||
},
|
||||
inject: ["isMobile"],
|
||||
computed:{
|
||||
currentDay() {
|
||||
if (!this.propsViewData?.focus_date || isNaN(new Date(this.propsViewData?.focus_date)))
|
||||
return luxon.DateTime.now().setZone(this.viewData.timezone).toISODate();
|
||||
return luxon.DateTime.now().setZone(FHC_JS_DATA_STORAGE_OBJECT.timezone).toISODate();
|
||||
return this.propsViewData?.focus_date;
|
||||
},
|
||||
currentMode() {
|
||||
if (!this.propsViewData?.mode || !['day', 'week', 'month'].includes(this.propsViewData?.mode.toLowerCase()))
|
||||
return DEFAULT_MODE_LVPLAN;
|
||||
let validModes = ['day', 'month'];
|
||||
validModes.push(this.isMobile ? 'list' : 'week');
|
||||
|
||||
const defaultMode = this.isMobile ? DEFAULT_MODE_LVPLAN_MOBILE : DEFAULT_MODE_LVPLAN_DESKTOP;
|
||||
|
||||
if (!this.propsViewData?.mode || !validModes.includes(this.propsViewData?.mode.toLowerCase()))
|
||||
return defaultMode;
|
||||
return this.propsViewData?.mode;
|
||||
},
|
||||
currentLv() {
|
||||
@@ -47,6 +54,17 @@ export default {
|
||||
return this.lv.bezeichnung;
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
async isMobile() {
|
||||
await this.$nextTick();
|
||||
this.handleChangeMode(
|
||||
this.currentMode,
|
||||
luxon.DateTime.fromISO(this.currentDay, {
|
||||
zone: this.timezone,
|
||||
}),
|
||||
);
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
handleChangeDate(day, newMode) {
|
||||
return this.handleChangeMode(newMode, day);
|
||||
@@ -95,7 +113,6 @@ export default {
|
||||
<fhc-calendar
|
||||
v-else-if="lv"
|
||||
ref="calendar"
|
||||
:timezone="viewData.timezone"
|
||||
:get-promise-func="getPromiseFunc"
|
||||
:date="currentDay"
|
||||
:mode="currentMode"
|
||||
|
||||
@@ -3,7 +3,8 @@ import FhcCalendar from "../../Calendar/LvPlan.js";
|
||||
import ApiLvPlan from '../../../api/factory/lvPlan.js';
|
||||
import ApiAuthinfo from '../../../api/factory/authinfo.js';
|
||||
|
||||
export const DEFAULT_MODE_LVPLAN = 'Week'
|
||||
export const DEFAULT_MODE_LVPLAN_MOBILE = 'List';
|
||||
export const DEFAULT_MODE_LVPLAN_DESKTOP = 'Week';
|
||||
|
||||
export default {
|
||||
name: 'LvPlan',
|
||||
@@ -11,31 +12,32 @@ export default {
|
||||
FhcCalendar
|
||||
},
|
||||
props: {
|
||||
viewData: Object, // NOTE(chris): this is inherited from router-view
|
||||
propsViewData: Object
|
||||
},
|
||||
data() {
|
||||
const now = luxon.DateTime.now().setZone(this.viewData.timezone);
|
||||
return {
|
||||
studiensemester_kurzbz: null,
|
||||
studiensemester_start: null,
|
||||
studiensemester_ende: null,
|
||||
uid: null,
|
||||
lv: null
|
||||
lv: null,
|
||||
timezone: FHC_JS_DATA_STORAGE_OBJECT.timezone,
|
||||
};
|
||||
},
|
||||
inject: ["isMobile"],
|
||||
computed:{
|
||||
currentDay() {
|
||||
return this.propsViewData?.focus_date || luxon.DateTime.now().setZone(this.viewData.timezone).toISODate();
|
||||
return this.propsViewData?.focus_date || luxon.DateTime.now().setZone(this.timezone).toISODate();
|
||||
},
|
||||
currentMode() {
|
||||
return this.propsViewData?.mode || DEFAULT_MODE_LVPLAN;
|
||||
const defaultMode = this.isMobile ? DEFAULT_MODE_LVPLAN_MOBILE : DEFAULT_MODE_LVPLAN_DESKTOP;
|
||||
return this.propsViewData?.mode || defaultMode;
|
||||
},
|
||||
downloadLinks() {
|
||||
if (!this.studiensemester_start || !this.studiensemester_ende || !this.uid)
|
||||
return false;
|
||||
|
||||
const opts = { zone: this.viewData.timezone };
|
||||
const opts = { zone: this.timezone };
|
||||
const start = luxon.DateTime
|
||||
.fromISO(this.studiensemester_start, opts)
|
||||
.toUnixInteger();
|
||||
@@ -115,7 +117,7 @@ export default {
|
||||
<fhc-calendar
|
||||
ref="calendar"
|
||||
v-model:lv="lv"
|
||||
:timezone="viewData.timezone"
|
||||
:timezone="timezone"
|
||||
:get-promise-func="getPromiseFunc"
|
||||
:date="currentDay"
|
||||
:mode="currentMode"
|
||||
|
||||
+43
-17
@@ -3,7 +3,8 @@ import FhcCalendar from "../../Calendar/LvPlan.js";
|
||||
import ApiLvPlan from '../../../api/factory/lvPlan.js';
|
||||
import ApiAuthinfo from '../../../api/factory/authinfo.js';
|
||||
|
||||
export const DEFAULT_MODE_LVPLAN = 'Week'
|
||||
export const DEFAULT_MODE_LVPLAN_DESKTOP = "Week";
|
||||
export const DEFAULT_MODE_LVPLAN_MOBILE = "List";
|
||||
|
||||
export default {
|
||||
name: 'LvPlanPersonal',
|
||||
@@ -11,7 +12,6 @@ export default {
|
||||
FhcCalendar
|
||||
},
|
||||
props: {
|
||||
viewData: Object, // NOTE(chris): this is inherited from router-view
|
||||
propsViewData: Object
|
||||
},
|
||||
data() {
|
||||
@@ -21,18 +21,30 @@ export default {
|
||||
studiensemester_ende: null,
|
||||
uid: null,
|
||||
isMitarbeiter: false,
|
||||
isStudent: false
|
||||
isStudent: false,
|
||||
timezone: FHC_JS_DATA_STORAGE_OBJECT.timezone,
|
||||
};
|
||||
},
|
||||
inject: ["isMobile"],
|
||||
computed:{
|
||||
currentDay() {
|
||||
if (!this.propsViewData?.focus_date || isNaN(new Date(this.propsViewData?.focus_date)))
|
||||
return luxon.DateTime.now().setZone(this.viewData.timezone).toISODate();
|
||||
return luxon.DateTime.now().setZone(this.timezone).toISODate();
|
||||
return this.propsViewData?.focus_date;
|
||||
},
|
||||
currentMode() {
|
||||
if (!this.propsViewData?.mode || !['day', 'week', 'month'].includes(this.propsViewData?.mode.toLowerCase()))
|
||||
return DEFAULT_MODE_LVPLAN;
|
||||
let validModes = ["day", "month"];
|
||||
validModes.push(this.isMobile ? "list" : "week");
|
||||
|
||||
const defaultMode = this.isMobile
|
||||
? DEFAULT_MODE_LVPLAN_MOBILE
|
||||
: DEFAULT_MODE_LVPLAN_DESKTOP;
|
||||
|
||||
if (
|
||||
!this.propsViewData?.mode ||
|
||||
!validModes.includes(this.propsViewData?.mode.toLowerCase())
|
||||
)
|
||||
return defaultMode;
|
||||
return this.propsViewData?.mode;
|
||||
},
|
||||
downloadLinks() {
|
||||
@@ -47,7 +59,7 @@ export default {
|
||||
return;
|
||||
}
|
||||
|
||||
const opts = { zone: this.viewData.timezone };
|
||||
const opts = { zone: this.timezone };
|
||||
const start = luxon.DateTime
|
||||
.fromISO(this.studiensemester_start, opts)
|
||||
.toUnixInteger();
|
||||
@@ -70,6 +82,17 @@ export default {
|
||||
];
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
async isMobile() {
|
||||
await this.$nextTick();
|
||||
this.handleChangeMode(
|
||||
this.currentMode,
|
||||
luxon.DateTime.fromISO(this.currentDay, {
|
||||
zone: this.timezone,
|
||||
}),
|
||||
);
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
handleChangeDate(day, newMode) {
|
||||
return this.handleChangeMode(newMode, day);
|
||||
@@ -102,16 +125,18 @@ export default {
|
||||
this.$api.call(ApiLvPlan.eventsPersonal(start.toISODate(), end.toISODate())),
|
||||
this.$api.call(ApiLvPlan.getLvPlanReservierungen(start.toISODate(), end.toISODate()))
|
||||
];
|
||||
}
|
||||
},
|
||||
async fetchAuthInfo() {
|
||||
const authInfoResponse = await this.$api.call(ApiAuthinfo.getAuthInfo());
|
||||
|
||||
const authInfo = authInfoResponse.data;
|
||||
this.uid = authInfo.uid;
|
||||
this.isMitarbeiter = authInfo.isMitarbeiter;
|
||||
this.isStudent = authInfo.isStudent;
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.$api
|
||||
.call(ApiAuthinfo.getAuthInfo())
|
||||
.then(res => {
|
||||
this.uid = res.data.uid;
|
||||
this.isMitarbeiter = res.data.isMitarbeiter;
|
||||
this.isStudent = res.data.isStudent;
|
||||
});
|
||||
async created() {
|
||||
await this.fetchAuthInfo();
|
||||
},
|
||||
template: /*html*/`
|
||||
<div class="cis-lvplan-personal d-flex flex-column h-100">
|
||||
@@ -123,8 +148,9 @@ export default {
|
||||
</h2>
|
||||
<hr>
|
||||
<fhc-calendar
|
||||
v-if="timezone"
|
||||
ref="calendar"
|
||||
:timezone="viewData.timezone"
|
||||
:timezone="timezone"
|
||||
:get-promise-func="getPromiseFunc"
|
||||
:date="currentDay"
|
||||
:mode="currentMode"
|
||||
@@ -0,0 +1,278 @@
|
||||
import FormForm from "../../Form/Form.js";
|
||||
import FormInput from "../../Form/Input.js";
|
||||
import FhcCalendar from "../../Calendar/LvPlan.js";
|
||||
|
||||
import ApiLvPlan from "../.././../api/factory/lvPlan.js";
|
||||
import ApiOtherLvPlan from "../.././../api/factory/otherLvPlan.js";
|
||||
import ApiAuthinfo from "../../../api/factory/authinfo.js";
|
||||
|
||||
export const DEFAULT_MODE_LVPLAN_DESKTOP = "Week";
|
||||
export const DEFAULT_MODE_LVPLAN_MOBILE = "List";
|
||||
|
||||
export default {
|
||||
name: "OtherLvPlan",
|
||||
components: {
|
||||
FormForm,
|
||||
FormInput,
|
||||
FhcCalendar,
|
||||
},
|
||||
props: {
|
||||
propsViewData: Object,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
localProps: {},
|
||||
studiensemester_kurzbz: null,
|
||||
studiensemester_start: null,
|
||||
studiensemester_ende: null,
|
||||
isOtherPersonMitarbeiter: false,
|
||||
isOtherPersonStudent: false,
|
||||
currentStgBezeichnung: null,
|
||||
listVerband: [],
|
||||
listGroup: [],
|
||||
rangeIntervalFirst: null,
|
||||
otherPersonData: {
|
||||
fullName: "",
|
||||
photo: "",
|
||||
},
|
||||
timezone: FHC_JS_DATA_STORAGE_OBJECT.timezone,
|
||||
};
|
||||
},
|
||||
inject: ["isMobile"],
|
||||
computed: {
|
||||
currentDay() {
|
||||
if (
|
||||
!this.propsViewData?.focus_date ||
|
||||
isNaN(new Date(this.propsViewData?.focus_date))
|
||||
)
|
||||
return luxon.DateTime.now().setZone(this.timezone).toISODate();
|
||||
return this.propsViewData?.focus_date;
|
||||
},
|
||||
currentMode() {
|
||||
let validModes = ["day", "month"];
|
||||
validModes.push(this.isMobile ? "list" : "week");
|
||||
|
||||
const defaultMode = this.isMobile
|
||||
? DEFAULT_MODE_LVPLAN_MOBILE
|
||||
: DEFAULT_MODE_LVPLAN_DESKTOP;
|
||||
|
||||
if (
|
||||
!this.propsViewData?.mode ||
|
||||
!validModes.includes(this.propsViewData?.mode.toLowerCase())
|
||||
)
|
||||
return defaultMode;
|
||||
return this.propsViewData?.mode;
|
||||
},
|
||||
downloadLinks() {
|
||||
if (
|
||||
!this.studiensemester_start ||
|
||||
!this.studiensemester_ende ||
|
||||
!this.propsViewData.otherUid
|
||||
)
|
||||
return false;
|
||||
|
||||
const type = this.isOtherPersonStudent
|
||||
? "student"
|
||||
: this.isOtherPersonMitarbeiter
|
||||
? "lektor"
|
||||
: null;
|
||||
|
||||
if (!type) return;
|
||||
|
||||
const opts = { zone: this.timezone };
|
||||
const start = luxon.DateTime.fromISO(
|
||||
this.studiensemester_start,
|
||||
opts,
|
||||
).toUnixInteger();
|
||||
const ende = luxon.DateTime.fromISO(
|
||||
this.studiensemester_ende,
|
||||
opts,
|
||||
).toUnixInteger();
|
||||
|
||||
const download_link =
|
||||
FHC_JS_DATA_STORAGE_OBJECT.app_root +
|
||||
"cis/private/lvplan/stpl_kalender.php" +
|
||||
"?type=" +
|
||||
type +
|
||||
"&pers_uid=" +
|
||||
this.propsViewData.otherUid +
|
||||
"&begin=" +
|
||||
start +
|
||||
"&ende=" +
|
||||
ende;
|
||||
|
||||
return [
|
||||
{
|
||||
title: "excel",
|
||||
icon: "fa-solid fa-file-excel",
|
||||
link: download_link + "&format=excel",
|
||||
},
|
||||
{
|
||||
title: "csv",
|
||||
icon: "fa-solid fa-file-csv",
|
||||
link: download_link + "&format=csv",
|
||||
},
|
||||
{
|
||||
title: "ical1",
|
||||
icon: "fa-regular fa-calendar",
|
||||
link: download_link + "&format=ical&version=1&target=ical",
|
||||
},
|
||||
{
|
||||
title: "ical2",
|
||||
icon: "fa-regular fa-calendar",
|
||||
link: download_link + "&format=ical&version=2&target=ical",
|
||||
},
|
||||
];
|
||||
},
|
||||
get_image_base64_src: function () {
|
||||
if (!this.otherPersonData.photo?.length) {
|
||||
return "";
|
||||
}
|
||||
return "data:image/jpeg;base64," + this.otherPersonData.photo;
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
"propsViewData.otherUid": {
|
||||
handler() {
|
||||
this.$router.go();
|
||||
},
|
||||
},
|
||||
async isMobile() {
|
||||
await this.$nextTick();
|
||||
this.handleChangeMode(
|
||||
this.currentMode,
|
||||
luxon.DateTime.fromISO(this.currentDay, {
|
||||
zone: this.timezone,
|
||||
}),
|
||||
);
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
handleChangeDate(day, newMode) {
|
||||
return this.handleChangeMode(newMode, day);
|
||||
},
|
||||
handleChangeMode(newMode, day) {
|
||||
const mode = newMode[0].toUpperCase() + newMode.slice(1);
|
||||
const focus_date = day.toISODate();
|
||||
|
||||
this.$router.push({
|
||||
name: "OtherLvPlan",
|
||||
params: {
|
||||
mode,
|
||||
focus_date,
|
||||
},
|
||||
});
|
||||
},
|
||||
updateRange(rangeInterval) {
|
||||
this.$api
|
||||
.call(
|
||||
ApiLvPlan.studiensemesterDateInterval(
|
||||
rangeInterval.end.startOf("week").toISODate(),
|
||||
),
|
||||
)
|
||||
.then((res) => {
|
||||
this.studiensemester_kurzbz =
|
||||
res.data.studiensemester_kurzbz;
|
||||
this.studiensemester_start = res.data.start;
|
||||
this.studiensemester_ende = res.data.ende;
|
||||
});
|
||||
},
|
||||
getPromiseFunc(start, end) {
|
||||
return [
|
||||
this.$api.call(
|
||||
ApiLvPlan.eventsPersonal(
|
||||
start.toISODate(),
|
||||
end.toISODate(),
|
||||
this.propsViewData.otherUid,
|
||||
),
|
||||
),
|
||||
this.$api.call(
|
||||
ApiLvPlan.getLvPlanReservierungen(
|
||||
start.toISODate(),
|
||||
end.toISODate(),
|
||||
this.propsViewData.otherUid,
|
||||
),
|
||||
),
|
||||
];
|
||||
},
|
||||
async fetchViewData() {
|
||||
const viewDataResponse = await this.$api.call(
|
||||
ApiOtherLvPlan.getOtherLvPlanViewData(
|
||||
this.propsViewData.otherUid,
|
||||
),
|
||||
);
|
||||
|
||||
const viewData = viewDataResponse.data;
|
||||
|
||||
this.isOtherPersonMitarbeiter =
|
||||
!!viewData?.user_data?.is_mitarbeiter;
|
||||
this.isOtherPersonStudent = !!viewData?.user_data?.is_student;
|
||||
this.otherPersonData.fullName =
|
||||
viewData?.user_data?.vorname +
|
||||
" " +
|
||||
viewData?.user_data?.nachname;
|
||||
this.otherPersonData.photo = viewData?.user_data?.foto;
|
||||
},
|
||||
async redirectToMyLvPlanIfAuthUid() {
|
||||
const authInfoResponse = await this.$api.call(
|
||||
ApiAuthinfo.getAuthInfo(),
|
||||
);
|
||||
const authId = authInfoResponse.data.uid;
|
||||
if (authId === this.propsViewData.otherUid) {
|
||||
this.$router.push({ name: "MyLvPlan" });
|
||||
}
|
||||
},
|
||||
},
|
||||
async created() {
|
||||
await this.redirectToMyLvPlanIfAuthUid();
|
||||
await this.fetchViewData();
|
||||
},
|
||||
template: `
|
||||
<div class="d-flex flex-column h-100">
|
||||
<h2>
|
||||
<div class="d-flex flex-row justify-content-between align-items-center">
|
||||
<span>
|
||||
{{ $p.t('lehre/stundenplan') + (studiensemester_kurzbz ? " " + studiensemester_kurzbz : "") }}
|
||||
</span>
|
||||
<div @click="this.$router.push({name: 'ProfilView', params: {uid: propsViewData.otherUid}})" type="button" class="d-flex flex-row align-items-center gap-3">
|
||||
<span v-if="otherPersonData.fullName?.length">
|
||||
{{ otherPersonData.fullName }}
|
||||
</span>
|
||||
<img v-if="otherPersonData.photo?.length" alt="profile picture" class=" img-thumbnail " style=" max-height:60px; " :src="get_image_base64_src"/>
|
||||
</div>
|
||||
</div>
|
||||
</h2>
|
||||
<hr>
|
||||
<fhc-calendar
|
||||
v-if="timezone"
|
||||
ref="calendar"
|
||||
:timezone="timezone"
|
||||
:get-promise-func="getPromiseFunc"
|
||||
:date="currentDay"
|
||||
:mode="currentMode"
|
||||
@update:date="handleChangeDate"
|
||||
@update:mode="handleChangeMode"
|
||||
@update:range="updateRange"
|
||||
class="responsive-calendar"
|
||||
>
|
||||
<div
|
||||
v-if="downloadLinks"
|
||||
class="d-flex gap-1 justify-items-start"
|
||||
>
|
||||
<div v-for="{ title, icon, link } in downloadLinks">
|
||||
<a
|
||||
:href="link"
|
||||
:aria-label="title"
|
||||
class="py-1 btn btn-outline-secondary"
|
||||
>
|
||||
<div class="d-flex flex-column">
|
||||
<i aria-hidden="true" :class="icon"></i>
|
||||
<span style="font-size:.5rem">{{ title }}</span>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</fhc-calendar>
|
||||
</div>
|
||||
`,
|
||||
};
|
||||
@@ -0,0 +1,428 @@
|
||||
import FormForm from "../../Form/Form.js";
|
||||
import FormInput from "../../Form/Input.js";
|
||||
import FhcCalendar from "../../Calendar/LvPlan.js";
|
||||
|
||||
import ApiLvPlan from '../.././../api/factory/lvPlan.js';
|
||||
import ApiStgOrgLvPlan from '../.././../api/factory/stgOrgLvPlan.js';
|
||||
import ApiAuthinfo from '../../../api/factory/authinfo.js';
|
||||
|
||||
export const DEFAULT_MODE_LVPLAN_DESKTOP = "Week";
|
||||
export const DEFAULT_MODE_LVPLAN_MOBILE = "List";
|
||||
|
||||
export default {
|
||||
name: "LvPlanStgOrg",
|
||||
components: {
|
||||
FormForm,
|
||||
FormInput,
|
||||
FhcCalendar,
|
||||
},
|
||||
props: {
|
||||
propsViewData: Object
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
localProps: {},
|
||||
studiensemester_kurzbz: null,
|
||||
studiensemester_start: null,
|
||||
studiensemester_ende: null,
|
||||
uid: null,
|
||||
isMitarbeiter: false,
|
||||
isStudent: false,
|
||||
currentStgBezeichnung: null,
|
||||
formData: {
|
||||
stgkz: null,
|
||||
sem: null,
|
||||
verband: null,
|
||||
gruppe: null,
|
||||
},
|
||||
listStg: [],
|
||||
listSem: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
|
||||
listVerband: [],
|
||||
listGroup: [],
|
||||
rangeIntervalFirst: null,
|
||||
timezone: FHC_JS_DATA_STORAGE_OBJECT.timezone,
|
||||
};
|
||||
},
|
||||
inject: ["isMobile"],
|
||||
computed: {
|
||||
maxSemester() {
|
||||
const currentStg = this.listStg.find(
|
||||
(item) => item.studiengang_kz === this.formData.stgkz,
|
||||
);
|
||||
return currentStg?.max_semester;
|
||||
},
|
||||
currentDay() {
|
||||
if (!this.propsViewData?.focus_date || isNaN(new Date(this.propsViewData?.focus_date)))
|
||||
return luxon.DateTime.now().setZone(this.timezone).toISODate();
|
||||
return this.propsViewData?.focus_date;
|
||||
},
|
||||
currentMode() {
|
||||
let validModes = ["day", "month"];
|
||||
validModes.push(this.isMobile ? "list" : "week");
|
||||
|
||||
const defaultMode = this.isMobile
|
||||
? DEFAULT_MODE_LVPLAN_MOBILE
|
||||
: DEFAULT_MODE_LVPLAN_DESKTOP;
|
||||
|
||||
if (
|
||||
!this.propsViewData?.mode ||
|
||||
!validModes.includes(this.propsViewData?.mode.toLowerCase())
|
||||
)
|
||||
return defaultMode;
|
||||
return this.propsViewData?.mode;
|
||||
},
|
||||
downloadLinks() {
|
||||
if (
|
||||
!this.studiensemester_start ||
|
||||
!this.studiensemester_ende ||
|
||||
!this.uid
|
||||
)
|
||||
return false;
|
||||
|
||||
let type = false;
|
||||
type = this.isStudent ? "student" : type;
|
||||
type = this.isMitarbeiter ? "lektor" : type;
|
||||
if (false === type) {
|
||||
return;
|
||||
}
|
||||
|
||||
const opts = { zone: this.timezone };
|
||||
const start = luxon.DateTime
|
||||
.fromISO(this.studiensemester_start, opts)
|
||||
.toUnixInteger();
|
||||
const ende = luxon.DateTime
|
||||
.fromISO(this.studiensemester_ende, opts)
|
||||
.toUnixInteger();
|
||||
|
||||
const download_link =
|
||||
FHC_JS_DATA_STORAGE_OBJECT.app_root +
|
||||
"cis/private/lvplan/stpl_kalender.php" +
|
||||
"?type=" +
|
||||
type +
|
||||
"&pers_uid=" +
|
||||
this.uid +
|
||||
"&begin=" +
|
||||
start +
|
||||
"&ende=" +
|
||||
ende;
|
||||
|
||||
return [
|
||||
{
|
||||
title: "excel",
|
||||
icon: "fa-solid fa-file-excel",
|
||||
link: download_link + "&format=excel",
|
||||
},
|
||||
{
|
||||
title: "csv",
|
||||
icon: "fa-solid fa-file-csv",
|
||||
link: download_link + "&format=csv",
|
||||
},
|
||||
{
|
||||
title: "ical1",
|
||||
icon: "fa-regular fa-calendar",
|
||||
link: download_link + "&format=ical&version=1&target=ical",
|
||||
},
|
||||
{
|
||||
title: "ical2",
|
||||
icon: "fa-regular fa-calendar",
|
||||
link: download_link + "&format=ical&version=2&target=ical",
|
||||
},
|
||||
];
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
async isMobile() {
|
||||
await this.$nextTick();
|
||||
this.handleChangeMode(
|
||||
this.currentMode,
|
||||
luxon.DateTime.fromISO(this.currentDay, {
|
||||
zone: this.timezone,
|
||||
}),
|
||||
);
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
loadLvPlan() {
|
||||
if (!this.formData.stgkz) {
|
||||
this.$fhcAlert.alertError(this.$p.t("LvPlan", "chooseStg"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (
|
||||
!this.formData.sem &&
|
||||
(this.formData.verband || this.formData.gruppe)
|
||||
) {
|
||||
this.$fhcAlert.alertError(
|
||||
this.$p.t("LvPlan", "error_SemMissing"),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.formData.verband && this.formData.gruppe) {
|
||||
this.$fhcAlert.alertError(
|
||||
this.$p.t("LvPlan", "error_VerbandMissing"),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
const params = {
|
||||
mode: this.currentMode,
|
||||
focus_date: this.currentDay,
|
||||
stgkz: this.formData.stgkz,
|
||||
sem: this.formData.sem,
|
||||
verband: this.formData.verband,
|
||||
gruppe: this.formData.gruppe,
|
||||
};
|
||||
|
||||
//ensure logic: no value after a null value in route
|
||||
if (params.sem == null) {
|
||||
params.verband = null;
|
||||
params.gruppe = null;
|
||||
}
|
||||
if (params.verband == null) {
|
||||
params.gruppe = null;
|
||||
}
|
||||
|
||||
//delete all null values to avoid null in router
|
||||
Object.keys(params).forEach(
|
||||
(key) => params[key] == null && delete params[key],
|
||||
);
|
||||
|
||||
this.$router.push({
|
||||
name: "StgOrgLvPlan",
|
||||
params,
|
||||
});
|
||||
|
||||
this.$refs['calendar']?.resetEventLoader();
|
||||
},
|
||||
loadListSem(){
|
||||
if(!this.listSem)
|
||||
this.listSem = [...Array(this.maxSemester).keys()].map(i => i + 1);
|
||||
},
|
||||
loadListVerband() {
|
||||
this.$api
|
||||
.call(ApiLvPlan.getLehrverband(this.formData.stgkz, this.formData.sem, this.formData.verband))
|
||||
.then(result => {
|
||||
const data = result.data;
|
||||
const mappedData = data.map((item) => item.verband);
|
||||
this.listVerband = [
|
||||
...new Set(
|
||||
mappedData.filter(
|
||||
(v) =>
|
||||
v !== null &&
|
||||
v !== undefined &&
|
||||
String(v).trim() !== "",
|
||||
),
|
||||
),
|
||||
].sort();
|
||||
})
|
||||
.catch(this.$fhcAlert.handleSystemError);
|
||||
},
|
||||
loadListGroup() {
|
||||
this.$api
|
||||
.call(ApiLvPlan.getGruppe(this.formData.stgkz, this.formData.sem, this.formData.verband))
|
||||
.then(result => {
|
||||
const data = result.data;
|
||||
const mappedData = data.map((item) => item.gruppe);
|
||||
this.listGroup = [
|
||||
...new Set(
|
||||
mappedData.filter(
|
||||
(v) =>
|
||||
v !== null &&
|
||||
v !== undefined &&
|
||||
String(v).trim() !== "",
|
||||
),
|
||||
),
|
||||
].sort();
|
||||
})
|
||||
.catch(this.$fhcAlert.handleSystemError);
|
||||
},
|
||||
handleChangeDate(day, newMode) {
|
||||
return this.handleChangeMode(newMode, day);
|
||||
},
|
||||
handleChangeMode(newMode, day) {
|
||||
const mode = newMode[0].toUpperCase() + newMode.slice(1);
|
||||
const focus_date = day.toISODate();
|
||||
|
||||
this.$router.push({
|
||||
name: "StgOrgLvPlan",
|
||||
params: {
|
||||
mode,
|
||||
focus_date,
|
||||
stgkz: this.formData.stgkz,
|
||||
sem: this.formData.sem,
|
||||
verband: this.formData.verband,
|
||||
gruppe: this.formData.gruppe,
|
||||
},
|
||||
});
|
||||
},
|
||||
updateRange(rangeInterval) {
|
||||
this.$api
|
||||
.call(
|
||||
ApiLvPlan.studiensemesterDateInterval(
|
||||
rangeInterval.end.startOf("week").toISODate(),
|
||||
),
|
||||
)
|
||||
.then((res) => {
|
||||
this.studiensemester_kurzbz =
|
||||
res.data.studiensemester_kurzbz;
|
||||
this.studiensemester_start = res.data.start;
|
||||
this.studiensemester_ende = res.data.ende;
|
||||
});
|
||||
},
|
||||
getPromiseFunc(start, end) {
|
||||
return [
|
||||
this.$api.call(
|
||||
ApiLvPlan.eventsStgOrg(
|
||||
start,
|
||||
end,
|
||||
this.formData.stgkz,
|
||||
this.formData.sem,
|
||||
this.formData.verband,
|
||||
this.formData.gruppe,
|
||||
),
|
||||
),
|
||||
];
|
||||
},
|
||||
async fetchAuthInfo() {
|
||||
const authInfoResponse = await this.$api.call(ApiAuthinfo.getAuthInfo());
|
||||
|
||||
const authInfo = authInfoResponse.data;
|
||||
this.uid = authInfo.uid;
|
||||
this.isMitarbeiter = authInfo.isMitarbeiter;
|
||||
this.isStudent = authInfo.isStudent;
|
||||
},
|
||||
async fetchViewData() {
|
||||
const viewDataResponse = await this.$api.call(ApiStgOrgLvPlan.getStgOrgLvPlanViewData());
|
||||
|
||||
const viewData = viewDataResponse.data;
|
||||
this.listStg = viewData.studiengaenge;
|
||||
},
|
||||
},
|
||||
async created(){
|
||||
await this.fetchAuthInfo();
|
||||
await this.fetchViewData();
|
||||
|
||||
if (this.propsViewData) {
|
||||
this.formData.stgkz = this.propsViewData.stgkz ? this.propsViewData.stgkz: null;
|
||||
this.formData.sem = this.propsViewData.sem ? this.propsViewData.sem: null;
|
||||
this.formData.verband = this.propsViewData.verband ? this.propsViewData.verband: null;
|
||||
this.formData.gruppe = this.propsViewData.gruppe ? this.propsViewData.gruppe: null;
|
||||
|
||||
//ensure loading dropdown arrays for version propsView
|
||||
if(!this.listVerband.length && this.formData.sem)
|
||||
{
|
||||
this.loadListVerband();
|
||||
}
|
||||
if(!this.listGroup.length && this.formData.verband)
|
||||
{
|
||||
this.loadListGroup();
|
||||
}
|
||||
}
|
||||
|
||||
if (this.formData.stgkz) {
|
||||
this.loadLvPlan();
|
||||
}
|
||||
},
|
||||
template: `
|
||||
<div class="cis-lvplan-stg-org d-flex flex-column h-100">
|
||||
|
||||
<div class="mt-3">
|
||||
<form-form class="row row-cols-1 row-cols-md-2 row-cols-lg-4 row-cols-xl-5 g-3 mb-3">
|
||||
<form-input
|
||||
type="select"
|
||||
v-model="formData.stgkz"
|
||||
@change="loadListSem(formData.stgkz)"
|
||||
>
|
||||
<option :value="null" selected>{{ $p.t('LvPlan/chooseStg') }}</option>
|
||||
<option
|
||||
v-for="stg in listStg"
|
||||
:key="stg.studiengang_kz"
|
||||
:value="stg.studiengang_kz"
|
||||
>
|
||||
{{ stg.kurzbzlang }} ({{ stg.bezeichnung }})
|
||||
</option>
|
||||
</form-input>
|
||||
<form-input
|
||||
type="select"
|
||||
v-model="formData.sem"
|
||||
@change="loadListVerband()"
|
||||
@click="loadListSem(formData.stgkz)"
|
||||
>
|
||||
<option :value="null" selected>Semester</option>
|
||||
<option
|
||||
v-for="sem in listSem"
|
||||
:key="sem"
|
||||
:value="sem"
|
||||
>
|
||||
{{ sem }}
|
||||
</option>
|
||||
</form-input>
|
||||
<form-input
|
||||
type="select"
|
||||
v-model="formData.verband"
|
||||
@change="loadListGroup()"
|
||||
>
|
||||
<option :value="null" selected>{{ $p.t('lehre/verband') }} </option>
|
||||
<option
|
||||
v-for="verband in listVerband"
|
||||
:key="verband"
|
||||
:value="verband"
|
||||
>
|
||||
{{ verband }}
|
||||
</option>
|
||||
</form-input>
|
||||
<form-input
|
||||
type="select"
|
||||
v-model="formData.gruppe"
|
||||
>
|
||||
<option :value="null" selected>{{ $p.t('gruppenmanagement/gruppe') }}</option>
|
||||
<option
|
||||
v-for="group in listGroup"
|
||||
:key="group"
|
||||
:value="group"
|
||||
>
|
||||
{{ group }}
|
||||
</option>
|
||||
</form-input>
|
||||
<button type="button" class="btn btn-secondary" @click="loadLvPlan">{{ $p.t('LvPlan/loadLvPlan') }}</button>
|
||||
|
||||
</form-form>
|
||||
</div>
|
||||
|
||||
<template v-if="timezone">
|
||||
<fhc-calendar
|
||||
v-if="propsViewData && propsViewData.stgkz"
|
||||
ref="calendar"
|
||||
v-model:lv="formData"
|
||||
:timezone="timezone"
|
||||
:get-promise-func="getPromiseFunc"
|
||||
:date="currentDay"
|
||||
:mode="currentMode"
|
||||
@update:date="handleChangeDate"
|
||||
@update:mode="handleChangeMode"
|
||||
@update:range="updateRange"
|
||||
class="responsive-calendar"
|
||||
>
|
||||
<div
|
||||
v-if="downloadLinks"
|
||||
class="d-flex gap-1 justify-items-start"
|
||||
>
|
||||
<div v-for="{ title, icon, link } in downloadLinks">
|
||||
<a
|
||||
:href="link"
|
||||
:aria-label="title"
|
||||
class="py-1 btn btn-outline-secondary"
|
||||
>
|
||||
<div class="d-flex flex-column">
|
||||
<i aria-hidden="true" :class="icon"></i>
|
||||
<span style="font-size:.5rem">{{ title }}</span>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</fhc-calendar>
|
||||
</template>
|
||||
</div>
|
||||
`,
|
||||
};
|
||||
@@ -0,0 +1,187 @@
|
||||
import FhcCalendar from "../../Calendar/LvPlan.js";
|
||||
|
||||
import ApiLvPlan from '../.././../api/factory/lvPlan.js';
|
||||
import ApiAuthinfo from '../../../api/factory/authinfo.js';
|
||||
|
||||
export const DEFAULT_MODE_LVPLAN = 'Week';
|
||||
|
||||
export default {
|
||||
name: 'LvPlanStgOrg',
|
||||
inject: {
|
||||
cisRoot: {
|
||||
from: 'cisRoot'
|
||||
},
|
||||
},
|
||||
components: {
|
||||
FhcCalendar,
|
||||
},
|
||||
props: {
|
||||
viewData: Object,
|
||||
propsViewData: Object
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
studiensemester_kurzbz: null,
|
||||
studiensemester_start: null,
|
||||
studiensemester_ende: null,
|
||||
uid: null,
|
||||
isMitarbeiter: false,
|
||||
isStudent: false,
|
||||
listStg: [],
|
||||
currentStgBezeichnung: null
|
||||
};
|
||||
},
|
||||
computed:{
|
||||
currentDay() {
|
||||
if (!this.propsViewData?.focus_date || isNaN(new Date(this.propsViewData?.focus_date)))
|
||||
return luxon.DateTime.now().setZone(this.viewData.timezone).toISODate();
|
||||
return this.propsViewData?.focus_date;
|
||||
},
|
||||
currentMode() {
|
||||
if (!this.propsViewData?.mode || !['day', 'week', 'month'].includes(this.propsViewData?.mode.toLowerCase()))
|
||||
return DEFAULT_MODE_LVPLAN;
|
||||
return this.propsViewData?.mode;
|
||||
},
|
||||
downloadLinks() {
|
||||
if (!this.studiensemester_start || !this.studiensemester_ende || !this.uid)
|
||||
return false;
|
||||
|
||||
let type = false;
|
||||
type = this.isStudent ? 'student' : type;
|
||||
type = this.isMitarbeiter ? 'lektor' : type;
|
||||
if (false === type)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const opts = { zone: this.viewData.timezone };
|
||||
const start = luxon.DateTime
|
||||
.fromISO(this.studiensemester_start, opts)
|
||||
.toUnixInteger();
|
||||
const ende = luxon.DateTime
|
||||
.fromISO(this.studiensemester_ende, opts)
|
||||
.toUnixInteger();
|
||||
|
||||
const download_link = FHC_JS_DATA_STORAGE_OBJECT.app_root
|
||||
+ 'cis/private/lvplan/stpl_kalender.php'
|
||||
+ '?type=' + type
|
||||
+ '&pers_uid=' + this.uid
|
||||
+ '&begin=' + start
|
||||
+ '&ende=' + ende;
|
||||
|
||||
return [
|
||||
{ title: "excel", icon: 'fa-solid fa-file-excel', link: download_link + '&format=excel' },
|
||||
{ title: "csv", icon: 'fa-solid fa-file-csv', link: download_link + '&format=csv' },
|
||||
{ title: "ical1", icon: 'fa-regular fa-calendar', link: download_link + '&format=ical&version=1&target=ical' },
|
||||
{ title: "ical2", icon: 'fa-regular fa-calendar', link: download_link + '&format=ical&version=2&target=ical' }
|
||||
];
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleChangeDate(day, newMode) {
|
||||
return this.handleChangeMode(newMode, day);
|
||||
},
|
||||
handleChangeMode(newMode, day) {
|
||||
const mode = newMode[0].toUpperCase() + newMode.slice(1)
|
||||
const focus_date = day.toISODate();
|
||||
|
||||
this.$router.push({
|
||||
name: "StgOrgLvPlan",
|
||||
params: {
|
||||
mode,
|
||||
focus_date,
|
||||
stgkz: this.propsViewData.stgkz,
|
||||
sem: this.propsViewData.sem,
|
||||
verband: this.propsViewData.verband,
|
||||
gruppe: this.propsViewData.gruppe,
|
||||
}
|
||||
});
|
||||
},
|
||||
updateRange(rangeInterval) {
|
||||
this.$api
|
||||
.call(ApiLvPlan.studiensemesterDateInterval(
|
||||
rangeInterval.end.startOf('week').toISODate()
|
||||
))
|
||||
.then(res => {
|
||||
this.studiensemester_kurzbz = res.data.studiensemester_kurzbz;
|
||||
this.studiensemester_start = res.data.start;
|
||||
this.studiensemester_ende = res.data.ende;
|
||||
});
|
||||
},
|
||||
getPromiseFunc(start, end) {
|
||||
return [
|
||||
this.$api.call(ApiLvPlan.eventsStgOrg(start.toISODate(), end.toISODate(), this.propsViewData.stgkz, this.propsViewData.sem, this.propsViewData.verband, this.propsViewData.gruppe)),
|
||||
//local for test
|
||||
/* this.$api.call(ApiLvPlan.eventsStgOrg(start.toISODate(), end.toISODate(), this.stgkz, this.sem, this.verband, this.gruppe))*/
|
||||
];
|
||||
},
|
||||
backToDropdown(){
|
||||
this.$router.push({
|
||||
name: "OverviewLvPlan",
|
||||
});
|
||||
}
|
||||
},
|
||||
created(){
|
||||
this.$api
|
||||
.call(ApiAuthinfo.getAuthInfo())
|
||||
.then(res => {
|
||||
this.uid = res.data.uid;
|
||||
this.isMitarbeiter = res.data.isMitarbeiter;
|
||||
this.isStudent = res.data.isStudent;
|
||||
});
|
||||
|
||||
if(this.propsViewData.stgkz) {
|
||||
this.$api
|
||||
.call(ApiLvPlan.getStudiengaenge())
|
||||
.then(result => {
|
||||
const currentStg = result.data.find(
|
||||
item => item.studiengang_kz == this.propsViewData.stgkz
|
||||
);
|
||||
this.currentStgBezeichnung = currentStg.kurzbzlang + " - " + currentStg.bezeichnung;
|
||||
})
|
||||
.catch(this.$fhcAlert.handleSystemError);
|
||||
}
|
||||
},
|
||||
template: `
|
||||
<div class="cis-lvplan-stg-org d-flex flex-column h-100">
|
||||
<h2>{{ $p.t('LvPlan/headerLvPlanLvVerband') }}</h2>
|
||||
<p v-if="propsViewData.stgkz"><span><strong>{{currentStgBezeichnung}}</strong></span>
|
||||
<span v-if="propsViewData.sem" style="margin-left:10px;"> Semester: {{propsViewData.sem}} </span>
|
||||
<span v-if="propsViewData.verband" style="margin-left:10px;"> Verband: {{propsViewData.verband}} </span>
|
||||
<span v-if="propsViewData.gruppe" style="margin-left:10px;"> Gruppe: {{propsViewData.gruppe}} </span>
|
||||
<button class="py-1 btn btn-outline-secondary" :title="this.$p.t('LvPlan', 'backToDropdown')" style="margin-left:10px;"> <i class="fa fa-arrow-left fa-xs" @click="backToDropdown"></i></button>
|
||||
</p>
|
||||
<p v-else>{{ $p.t('LvPlan/noStgProvided') }}</p>
|
||||
|
||||
<fhc-calendar
|
||||
ref="calendar"
|
||||
:timezone="viewData.timezone"
|
||||
:get-promise-func="getPromiseFunc"
|
||||
:date="currentDay"
|
||||
:mode="currentMode"
|
||||
@update:date="handleChangeDate"
|
||||
@update:mode="handleChangeMode"
|
||||
@update:range="updateRange"
|
||||
class="responsive-calendar"
|
||||
>
|
||||
<div
|
||||
v-if="downloadLinks"
|
||||
class="d-flex gap-1 justify-items-start"
|
||||
>
|
||||
<div v-for="{ title, icon, link } in downloadLinks">
|
||||
<a
|
||||
:href="link"
|
||||
:aria-label="title"
|
||||
class="py-1 btn btn-outline-secondary"
|
||||
>
|
||||
<div class="d-flex flex-column">
|
||||
<i aria-hidden="true" :class="icon"></i>
|
||||
<span style="font-size:.5rem">{{ title }}</span>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</fhc-calendar>
|
||||
</div>
|
||||
`,
|
||||
};
|
||||
@@ -30,7 +30,7 @@ export default {
|
||||
menuOpen:true,
|
||||
};
|
||||
},
|
||||
inject: ["isMobile"],
|
||||
inject: ["isNarrow", "isMobile"],
|
||||
provide(){
|
||||
return{
|
||||
setActiveEntry: this.setActiveEntry,
|
||||
@@ -113,71 +113,101 @@ export default {
|
||||
});
|
||||
},
|
||||
template: /*html*/`
|
||||
<div
|
||||
id="header-options-collapsible"
|
||||
class="collapse multi-collapse collapse-horizontal show"
|
||||
>
|
||||
<div class="d-flex flex-row align-items-center gap-2 h-100" style="width: 79px">
|
||||
<button id="nav-main-btn" class="navbar-toggler rounded-0 px-2 border-0" type="button" data-bs-toggle="offcanvas" data-bs-target="#nav-main" aria-controls="nav-main" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<span v-if="isMobile" class="d-flex flex-row align-items-center">
|
||||
<theme-switch></theme-switch>
|
||||
</span>
|
||||
<div id="cis-header-bar" class="d-flex flex-row flex-grow-1">
|
||||
<div id="nav-logo" class="d-none d-lg-block">
|
||||
<div class="d-flex h-100 justify-content-between">
|
||||
<a :href="rootUrl">
|
||||
<img :src="logoUrl" alt="Corporate Identity Logo">
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<fhc-searchbar
|
||||
:searchoptions="searchbaroptions"
|
||||
:searchfunction="searchfunction"
|
||||
ref="searchbar"
|
||||
id="nav-search"
|
||||
class="fhc-searchbar w-100 py-1 py-lg-2"
|
||||
></fhc-searchbar>
|
||||
<div id="nav-logo" class="d-none d-lg-block">
|
||||
<div class="d-flex h-100 justify-content-between">
|
||||
<a :href="rootUrl">
|
||||
<img :src="logoUrl" alt="Corporate Identity Logo">
|
||||
</a>
|
||||
<theme-switch></theme-switch>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
id="header-usermenu-collapsible"
|
||||
class="collapse multi-collapse collapse-horizontal show"
|
||||
>
|
||||
<div
|
||||
:style="!isMobile ? '' : 'width: 51px'"
|
||||
id="nav-user"
|
||||
v-if="isNarrow"
|
||||
:class="{'collapse multi-collapse collapse-horizontal show': isMobile}"
|
||||
id="navbar-toggler-collapsible"
|
||||
>
|
||||
<button id="nav-user-btn" class="btn btn-link rounded-0" type="button" data-bs-toggle="collapse" data-bs-target="#nav-user-menu" aria-expanded="false" aria-controls="nav-user-menu">
|
||||
<img :src="avatarUrl" :alt="$p.t('profilUpdate/profilBild')" class="bg-dark avatar rounded-circle border border-dark"/>
|
||||
</button>
|
||||
<ul ref="navUserDropdown"
|
||||
@[\`shown.bs.collapse\`]="handleShowNavUser"
|
||||
@[\`hide.bs.collapse\`]="handleHideNavUser"
|
||||
id="nav-user-menu" class="top-100 end-0 collapse list-unstyled" aria-labelledby="nav-user-btn">
|
||||
<li><a class="fhc-dark-bg btn rounded-0 d-block" :href="site_url + '/Cis/Profil'" id="menu-profil">Profil</a></li>
|
||||
<li >
|
||||
<cis-sprachen @languageChanged="fetchMenu"></cis-sprachen>
|
||||
</li>
|
||||
<li><hr class="dropdown-divider m-0 "></li>
|
||||
<li ><a class="fhc-dark-bg btn rounded-0 d-block" :href="logoutUrl">Logout</a></li>
|
||||
</ul>
|
||||
<div class="d-flex flex-row align-items-center h-100" style="width: 35px">
|
||||
<button id="nav-main-btn" class="navbar-toggler rounded-0 px-2 border-0" type="button" data-bs-toggle="offcanvas" data-bs-target="#nav-main" aria-controls="nav-main" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<fhc-searchbar
|
||||
:searchoptions="searchbaroptions"
|
||||
:searchfunction="searchfunction"
|
||||
ref="searchbar"
|
||||
id="nav-search"
|
||||
class="fhc-searchbar flex-grow-1 py-1 py-lg-2"
|
||||
>
|
||||
<template #collapseToggler="{ isSearchShownInMobileView }">
|
||||
<span
|
||||
v-if="isMobile"
|
||||
type="button"
|
||||
data-bs-toggle="collapse"
|
||||
data-bs-target=".multi-collapse"
|
||||
aria-controls="searchbar-collapsible navbar-toggler-collapsible options-collapsible"
|
||||
aria-expanded="false"
|
||||
class="d-flex flex-row align-items-center pe-1"
|
||||
style="color: white"
|
||||
>
|
||||
<i v-if="isSearchShownInMobileView" class="fa-solid fa-chevron-left ps-3"></i>
|
||||
<i v-else class="fa-solid fa-magnifying-glass ps-2"></i>
|
||||
</span>
|
||||
</template>
|
||||
</fhc-searchbar>
|
||||
|
||||
<div
|
||||
id="options-collapsible"
|
||||
:class="{'collapse multi-collapse collapse-horizontal show': isMobile}"
|
||||
>
|
||||
<div :style="!isMobile ? '' : 'width: 105px'" class="d-flex flex-row ps-3 justify-content-end">
|
||||
<span class="d-flex flex-row align-items-center">
|
||||
<theme-switch></theme-switch>
|
||||
</span>
|
||||
<div id="nav-user">
|
||||
<button id="nav-user-btn" class="btn btn-link rounded-0" type="button" data-bs-toggle="collapse" data-bs-target="#nav-user-menu" aria-expanded="false" aria-controls="nav-user-menu">
|
||||
<img :src="avatarUrl" :alt="$p.t('profilUpdate/profilBild')" class="bg-dark avatar rounded-circle border border-dark"/>
|
||||
</button>
|
||||
<ul ref="navUserDropdown"
|
||||
@[\`shown.bs.collapse\`]="handleShowNavUser"
|
||||
@[\`hide.bs.collapse\`]="handleHideNavUser"
|
||||
id="nav-user-menu" class="top-100 end-0 collapse list-unstyled" aria-labelledby="nav-user-btn">
|
||||
<li><a class="fhc-dark-bg btn rounded-0 d-block" :href="site_url + '/Cis/Profil'" id="menu-profil">Profil</a></li>
|
||||
<li >
|
||||
<cis-sprachen @languageChanged="fetchMenu"></cis-sprachen>
|
||||
</li>
|
||||
<li><hr class="dropdown-divider m-0 "></li>
|
||||
<li ><a class="fhc-dark-bg btn rounded-0 d-block" :href="logoutUrl">Logout</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<nav id="nav-main" class="offcanvas offcanvas-start" tabindex="-1" aria-labelledby="nav-main-btn" data-bs-backdrop="false">
|
||||
<div id="nav-main-sticky">
|
||||
<div id="nav-main-toggle" class="position-static d-none d-lg-block ">
|
||||
<button :aria-label="menuCollapseAriaLabel" type="button" @click="menuOpen = !menuOpen" class="btn text-light rounded-0 p-1 d-flex align-items-center" data-bs-toggle="collapse" data-bs-target=".nav-menu-collapse" aria-expanded="true" aria-controls="nav-sprachen nav-main-menu">
|
||||
<i aria-hidden="true" class="fa fa-arrow-circle-left fhc-text"></i>
|
||||
</button>
|
||||
</div>
|
||||
<div class="offcanvas-body p-0">
|
||||
<div id="nav-main-menu" class="nav-menu-collapse collapse collapse-horizontal show">
|
||||
<div>
|
||||
<cis-menu-entry :highestMatchingUrlCount="highestMatchingUrlCount" :activeContent="activeEntry" v-for="entry in entries" :key="entry.content_id" :entry="entry" />
|
||||
<div class="d-flex flex-row h-100">
|
||||
<div class="offcanvas-body p-0">
|
||||
<div id="nav-main-menu" class="nav-menu-collapse collapse collapse-horizontal show">
|
||||
<div class="flex-grow-1">
|
||||
<cis-menu-entry :highestMatchingUrlCount="highestMatchingUrlCount" :activeContent="activeEntry" v-for="entry in entries" :key="entry.content_id" :entry="entry" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="nav-main-toggle" class="d-none d-lg-block">
|
||||
<div
|
||||
@click="menuOpen = !menuOpen"
|
||||
:aria-label="menuCollapseAriaLabel"
|
||||
type="button"
|
||||
class="h-100 d-flex align-items-center px-2"
|
||||
data-bs-toggle="collapse"
|
||||
data-bs-target=".nav-menu-collapse"
|
||||
aria-expanded="true"
|
||||
aria-controls="nav-sprachen nav-main-menu"
|
||||
>
|
||||
<i aria-hidden="true" class="fa-solid fa-chevron-left fhc-text"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -68,41 +68,8 @@ export default {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
link() {
|
||||
if (this.entry.template_kurzbz == 'redirect') {
|
||||
if (!this.entry.content)
|
||||
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
|
||||
url = url.childNodes[0].nodeValue + "";
|
||||
if (url.includes("../cms/news.php")) {
|
||||
let news_regex = new RegExp("^\.\./cms/news\.php");
|
||||
url = url.replace(news_regex, FHC_JS_DATA_STORAGE_OBJECT.app_root + FHC_JS_DATA_STORAGE_OBJECT.ci_router + '/CisVue/Cms/news');
|
||||
}
|
||||
else if (url.includes("../cms/content.php?")) {
|
||||
let content_regex = new RegExp("^\.\./cms/content.php\\?content_id=([0-9]+)");
|
||||
let content_regex_result = content_regex.exec(url);
|
||||
// content_regex_result[1] will be the first matched group
|
||||
return FHC_JS_DATA_STORAGE_OBJECT.app_root + FHC_JS_DATA_STORAGE_OBJECT.ci_router + '/CisVue/Cms/content/' + content_regex_result[1];
|
||||
}
|
||||
else if(url.includes("../index.ci.php")){
|
||||
let index_regex = new RegExp("^\.\./index\.ci\.php");
|
||||
url = url.replace(index_regex, FHC_JS_DATA_STORAGE_OBJECT.app_root + FHC_JS_DATA_STORAGE_OBJECT.ci_router);
|
||||
}
|
||||
else if (url.includes("../")) {
|
||||
let relative_regex = new RegExp("^\.\./");
|
||||
url = url.replace(relative_regex, FHC_JS_DATA_STORAGE_OBJECT.app_root);
|
||||
}
|
||||
return url;
|
||||
}
|
||||
return FHC_JS_DATA_STORAGE_OBJECT.app_root + FHC_JS_DATA_STORAGE_OBJECT.ci_router + '/CisVue/Cms/content/' + this.entry.content_id;
|
||||
},
|
||||
hasFullLink() {
|
||||
return this.link.startsWith(FHC_JS_DATA_STORAGE_OBJECT.app_root + FHC_JS_DATA_STORAGE_OBJECT.ci_router)
|
||||
return this.entry.url.startsWith(FHC_JS_DATA_STORAGE_OBJECT.app_root + FHC_JS_DATA_STORAGE_OBJECT.ci_router)
|
||||
},
|
||||
target() {
|
||||
if (this.entry.template_kurzbz == 'redirect') {
|
||||
@@ -145,7 +112,7 @@ export default {
|
||||
this.addUrlCount(count);
|
||||
},
|
||||
checkActiveUrl(url){
|
||||
this.getUrlMatchPoints(url,this.link);
|
||||
this.getUrlMatchPoints(url,this.entry.url);
|
||||
|
||||
let url_hash_spaceSymbol_regex = new RegExp("%20","gi");
|
||||
let url_hash_sharpSymbol_regex = new RegExp("^#");
|
||||
@@ -155,7 +122,7 @@ export default {
|
||||
// if the url hash contains the titel of the menu
|
||||
// or if the url equals the link of a menu
|
||||
// then set the menu active
|
||||
if (url_hash == this.entry.titel || url.href == this.link) {
|
||||
if (url_hash == this.entry.titel || url.href == this.entry.url) {
|
||||
this.setActiveEntry(this.entry.content_id);
|
||||
}
|
||||
},
|
||||
@@ -204,7 +171,7 @@ export default {
|
||||
<template v-if="hasChilds">
|
||||
<div class="btn-group w-100">
|
||||
<a :target="target"
|
||||
:href="(entry.menu_open && hasFullLink)?link:null"
|
||||
:href="(entry.menu_open && hasFullLink) ? entry.url : null"
|
||||
@click="toggleCollapse"
|
||||
:class="{
|
||||
'btn btn-default rounded-0 text-start': true,
|
||||
@@ -227,7 +194,7 @@ export default {
|
||||
</ul>
|
||||
</template>
|
||||
<a v-else
|
||||
:href="link"
|
||||
:href="entry.url"
|
||||
:target="target"
|
||||
:class="{
|
||||
'btn btn-default rounded-0 w-100 text-start': true,
|
||||
|
||||
@@ -100,7 +100,7 @@ export default {
|
||||
</template>
|
||||
<template v-else>
|
||||
<span v-if="event?.lehrfach_bez ">{{event?.lehrfach_bez + (event?.stg_kurzbzlang?' / ' + event?.stg_kurzbzlang:'')}}</span>
|
||||
<span v-else>Lehrveranstaltungs Übersicht</span>
|
||||
<span v-else>{{$p.t('lehre','lvUebersicht')}}</span>
|
||||
</template>
|
||||
|
||||
</template>
|
||||
|
||||
@@ -2,7 +2,8 @@ import FhcCalendar from "../../Calendar/LvPlan.js";
|
||||
|
||||
import ApiLvPlan from '../../../api/factory/lvPlan.js';
|
||||
|
||||
export const DEFAULT_MODE_RAUMINFO = 'Week'
|
||||
export const DEFAULT_MODE_RAUMINFO_MOBILE = 'List';
|
||||
export const DEFAULT_MODE_RAUMINFO_DESKTOP = 'Week';
|
||||
|
||||
export default {
|
||||
name: "RoomInformation",
|
||||
@@ -13,12 +14,14 @@ export default {
|
||||
viewData: Object, // NOTE(chris): this is inherited from router-view
|
||||
propsViewData: Object
|
||||
},
|
||||
inject: ["isMobile"],
|
||||
computed: {
|
||||
currentDay() {
|
||||
return this.propsViewData?.focus_date || luxon.DateTime.now().setZone(this.viewData.timezone).toISODate();
|
||||
return this.propsViewData?.focus_date || luxon.DateTime.now().setZone(FHC_JS_DATA_STORAGE_OBJECT.timezone).toISODate();
|
||||
},
|
||||
currentMode() {
|
||||
return this.propsViewData?.mode || DEFAULT_MODE_RAUMINFO;
|
||||
const defaultMode = this.isMobile ? DEFAULT_MODE_RAUMINFO_MOBILE : DEFAULT_MODE_RAUMINFO_DESKTOP;
|
||||
return this.propsViewData?.mode || defaultMode;
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
@@ -51,7 +54,6 @@ export default {
|
||||
<hr>
|
||||
<fhc-calendar
|
||||
ref="calendar"
|
||||
:timezone="viewData.timezone"
|
||||
:get-promise-func="getPromiseFunc"
|
||||
:date="currentDay"
|
||||
:mode="currentMode"
|
||||
|
||||
@@ -36,8 +36,9 @@ export default {
|
||||
return this.lvs.filter(lv => lv.studiengang_kz == studiengang.studiengang_kz && lv.semester == studiengang.semester);
|
||||
}
|
||||
},
|
||||
template: `<div class="mylv-semester" v-if="ready">
|
||||
<mylv-semester-studiengang v-for="studiengang in studiengaenge" :key="studiengang.studiengang_kz" v-bind="studiengang" :lvs="lvsForStudiengang(studiengang)"/>
|
||||
template: `
|
||||
<div class="mylv-semester" v-if="ready">
|
||||
<mylv-semester-studiengang v-for="studiengang in studiengaenge" :key="studiengang.studiengang_kz" v-bind="studiengang" :lvs="lvsForStudiengang(studiengang)" :semesterInfo="$props.semester" />
|
||||
</div>
|
||||
<div class="mylv-semester text-center" v-else>
|
||||
<i class="fa-solid fa-spinner fa-pulse fa-3x"></i>
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
import MylvSemesterStudiengangLv from "./Studiengang/Lv.js";
|
||||
import MylvSemesterStudiengangAverageGrade from "./Studiengang/AverageGrade.js";
|
||||
import Phrasen from "../../../../mixins/Phrasen.js";
|
||||
|
||||
export default {
|
||||
components: {
|
||||
MylvSemesterStudiengangLv
|
||||
MylvSemesterStudiengangLv,
|
||||
MylvSemesterStudiengangAverageGrade
|
||||
},
|
||||
mixins: [
|
||||
Phrasen
|
||||
@@ -12,6 +14,7 @@ export default {
|
||||
bezeichnung: String,
|
||||
kuerzel: String,
|
||||
semester: [String,Number],
|
||||
semesterInfo: [String,Number],
|
||||
lvs: Array,
|
||||
sg_bezeichnung_eng: String
|
||||
},
|
||||
@@ -29,9 +32,10 @@ export default {
|
||||
methods: {
|
||||
note(lv) {
|
||||
return lv.benotung ? lv.znote || lv.lvnote || null : null;
|
||||
}
|
||||
},
|
||||
},
|
||||
template: `<div class="card mb-3">
|
||||
|
||||
<div class="card-body">
|
||||
<h4 class="card-title mb-3">{{$p.user_language.value === 'English' ? sg_bezeichnung_eng : bezeichnung}} - {{kuerzel}}
|
||||
<small>{{semester}}.{{$p.t('lehre/semester')}}</small>
|
||||
@@ -41,6 +45,7 @@ export default {
|
||||
<mylv-semester-studiengang-lv v-bind="lv" class="text-center h-100"></mylv-semester-studiengang-lv>
|
||||
</div>
|
||||
</div>
|
||||
<mylv-semester-studiengang-average-grade :semesterInfo="$props.semesterInfo" />
|
||||
</div>
|
||||
</div>`
|
||||
};
|
||||
@@ -0,0 +1,86 @@
|
||||
import Phrasen from "../../../../../mixins/Phrasen.js";
|
||||
import ApiLehre from "../../../../../api/factory/lehre.js";
|
||||
|
||||
export default {
|
||||
mixins: [
|
||||
Phrasen
|
||||
],
|
||||
props: {
|
||||
semesterInfo: String,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
gradeAverage: null,
|
||||
gradeWeightedAverage: null,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async fetchAverageGrade() {
|
||||
this.gradeAverage = null;
|
||||
this.gradeWeightedAverage = null;
|
||||
if (!this.$props.semesterInfo) return;
|
||||
|
||||
let gradeAverageResponse = await this.$api.call(
|
||||
ApiLehre.getSemesterAverageGrade(this.$props.semesterInfo),
|
||||
);
|
||||
const gradeAverageResponseData = gradeAverageResponse.data;
|
||||
this.gradeAverage =
|
||||
gradeAverageResponseData.average_grade?.toFixed(2);
|
||||
this.gradeWeightedAverage =
|
||||
gradeAverageResponseData.weighted_average_grade?.toFixed(2);
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
semesterInfo() {
|
||||
this.fetchAverageGrade();
|
||||
},
|
||||
},
|
||||
async created() {
|
||||
await this.fetchAverageGrade();
|
||||
},
|
||||
template: /*html*/`
|
||||
<div class="card mylv-semester-studiengang-grades">
|
||||
|
||||
<div class="card-header text-center">
|
||||
<h6>{{$p.t('lehre/notenstatistik')}}</h6>
|
||||
</div>
|
||||
|
||||
<div v-if="gradeAverage && gradeWeightedAverage">
|
||||
<table class="card-body table w-auto mx-auto">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="text-end">
|
||||
{{$p.t('lehre/headerAverage')}}
|
||||
</td>
|
||||
<td class="text-start">
|
||||
{{ gradeAverage }}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="text-end">
|
||||
{{$p.t('lehre/headerWeightedAverage')}}
|
||||
</td>
|
||||
<td class="text-start">
|
||||
{{ gradeWeightedAverage }}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div v-else class="card-body text-center">
|
||||
<p>{{$p.t('lehre/info_noGradesYet')}}</p>
|
||||
</div>
|
||||
|
||||
<div v-if="gradeAverage && gradeWeightedAverage" class="card-footer d-flex align-items-start text-muted small">
|
||||
<i class="fa fa-circle-info me-2 mt-1"></i>
|
||||
<div>
|
||||
<strong>{{$p.t('ui', 'hinweis')}}</strong><br>
|
||||
* {{$p.t('lehre/noticeAverage')}}
|
||||
<br>
|
||||
** {{$p.t('lehre/noticeWeightedAverage')}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
`
|
||||
}
|
||||
@@ -24,9 +24,9 @@ export default {
|
||||
farbe: String,
|
||||
lvinfo: Boolean,
|
||||
benotung: Boolean,
|
||||
lvnote: String,
|
||||
lvnote: [String, Number],
|
||||
lvnotebez: Array,
|
||||
znote: String,
|
||||
znote: [String, Number],
|
||||
znotebez: Array,
|
||||
studiengang_kuerzel: String,
|
||||
semester: [String, Number],
|
||||
@@ -37,6 +37,11 @@ export default {
|
||||
positiv: Boolean,
|
||||
note_index: String
|
||||
},
|
||||
provide() {
|
||||
return {
|
||||
studium_studiensemester: Vue.computed(() => this.studien_semester),
|
||||
}
|
||||
},
|
||||
data: () => {
|
||||
return {
|
||||
pruefungenData: null,
|
||||
@@ -73,11 +78,11 @@ export default {
|
||||
},
|
||||
grade() {
|
||||
const languageIndex = this.$p.user_language.value === 'English' ? 1 : 0
|
||||
// no more showing of grade LV, if grade Zeugnis is not existing yet
|
||||
if(this.benotung && this.znotebez?.length) {
|
||||
return this.znotebez[languageIndex]
|
||||
} else if(this.benotung && this.lvnotebez?.length) {
|
||||
return this.lvnotebez[languageIndex]
|
||||
} else return null
|
||||
}
|
||||
else return null
|
||||
},
|
||||
LvHasPruefungenInformation(){
|
||||
return this.pruefungenData && this.pruefungenData.length > 0;
|
||||
@@ -119,7 +124,6 @@ export default {
|
||||
}
|
||||
},
|
||||
openPruefungen() {
|
||||
// early return if the pruefungenData is empty or not set
|
||||
if (!this.LvHasPruefungenInformation) return;
|
||||
|
||||
LvPruefungen.popup({
|
||||
@@ -205,21 +209,14 @@ export default {
|
||||
</template>
|
||||
</div>
|
||||
<div v-if="!emptyMenu" class="card-footer">
|
||||
<div class="row">
|
||||
<!-- template for the LV if there are multiple pruefungen -->
|
||||
<template v-if="LvHasPruefungenInformation">
|
||||
<a href="#" class="col-auto text-start text-decoration-none" @click.prevent="openPruefungen">
|
||||
<i class="fa fa-check text-success" v-if="positiv"></i>
|
||||
<span class="ps-1" :style="'color:'+gradeColor">{{ grade || $p.t('lehre/noGrades') }}</span>
|
||||
</a>
|
||||
</template>
|
||||
<!-- template for the LV with no pruefungen -->
|
||||
<template v-else>
|
||||
<span class="col-auto text-start text-decoration-none" >
|
||||
<i class="fa fa-check text-success" v-if="positiv"></i>
|
||||
<span class="ps-1" :style="'color:'+gradeColor">{{ grade || $p.t('lehre/noGrades') }}</span>
|
||||
</span>
|
||||
</template>
|
||||
<div
|
||||
@click.prevent="openPruefungen()"
|
||||
:type="LvHasPruefungenInformation ? 'button' : ''"
|
||||
class="d-flex flex-row align-items-center gap-1"
|
||||
>
|
||||
<i class="fa fa-check text-success" v-if="positiv"></i>
|
||||
<span :style="'color:'+gradeColor">{{ grade || $p.t('lehre/noGrades') }}</span>
|
||||
<i v-if="LvHasPruefungenInformation" class="fa fa-circle-info ms-1"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>`
|
||||
|
||||
@@ -96,34 +96,35 @@ export default {
|
||||
|
||||
},
|
||||
template: `
|
||||
|
||||
<h2>{{$p.t('lehre/myLV')}}</h2>
|
||||
<hr>
|
||||
<div class="mylv-student" v-if="ready">
|
||||
<div v-if="currentSemester" class="row justify-content-center mb-3">
|
||||
<div class="col-auto d-none">
|
||||
<label class="col-form-label">{{$p.t('lehre/studiensemester')}}</label>
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<div class="input-group">
|
||||
<button :aria-label="$p.t('lehre','previousStudSemester')" v-tooltip.top="{showDelay:1000, value:$p.t('lehre','previousStudSemester')}" class="btn btn-outline-secondary" type="button" :disabled="currentIsFirst" @click="prevSem">
|
||||
<i class="fa fa-caret-left" aria-hidden="true"></i>
|
||||
</button>
|
||||
<select ref="studiensemester" v-model="currentSemester" class="form-select" :aria-label="$p.t('global/studiensemester_auswaehlen')" @change="updateRouter($event.target.value)">
|
||||
<option v-for="semester in studiensemester" :key="semester.studiensemester_kurzbz">{{semester.studiensemester_kurzbz}}</option>
|
||||
</select>
|
||||
<button class="btn btn-outline-secondary" :aria-label="$p.t('lehre','nextStudSemester')" v-tooltip.top="{showDelay:1000, value:$p.t('lehre','nextStudSemester')}" type="button" :disabled="currentIsLast" @click="nextSem">
|
||||
<i class="fa fa-caret-right" aria-hidden="true"></i>
|
||||
</button>
|
||||
<div>
|
||||
<h2>{{$p.t('lehre/myLV')}}</h2>
|
||||
<hr>
|
||||
<div class="mylv-student" v-if="ready">
|
||||
<div v-if="currentSemester" class="row justify-content-center mb-3">
|
||||
<div class="col-auto d-none">
|
||||
<label class="col-form-label">{{$p.t('lehre/studiensemester')}}</label>
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<div class="input-group">
|
||||
<button :aria-label="$p.t('lehre','previousStudSemester')" v-tooltip.top="{showDelay:1000, value:$p.t('lehre','previousStudSemester')}" class="btn btn-outline-secondary" type="button" :disabled="currentIsFirst" @click="prevSem">
|
||||
<i class="fa fa-caret-left" aria-hidden="true"></i>
|
||||
</button>
|
||||
<select ref="studiensemester" v-model="currentSemester" class="form-select" :aria-label="$p.t('global/studiensemester_auswaehlen')" @change="updateRouter($event.target.value)">
|
||||
<option v-for="semester in studiensemester" :key="semester.studiensemester_kurzbz">{{semester.studiensemester_kurzbz}}</option>
|
||||
</select>
|
||||
<button class="btn btn-outline-secondary" :aria-label="$p.t('lehre','nextStudSemester')" v-tooltip.top="{showDelay:1000, value:$p.t('lehre','nextStudSemester')}" type="button" :disabled="currentIsLast" @click="nextSem">
|
||||
<i class="fa fa-caret-right" aria-hidden="true"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="alert alert-danger" role="alert" v-else>
|
||||
{{$p.t('lehre/noLvFound')}}
|
||||
</div>
|
||||
<mylv-semester v-bind="current"/>
|
||||
</div>
|
||||
<div class="alert alert-danger" role="alert" v-else>
|
||||
{{$p.t('lehre/noLvFound')}}
|
||||
<div class="mylv-student text-center" v-else>
|
||||
<i class="fa-solid fa-spinner fa-pulse fa-3x"></i>
|
||||
</div>
|
||||
<mylv-semester v-bind="current"/>
|
||||
</div>
|
||||
<div class="mylv-student text-center" v-else>
|
||||
<i class="fa-solid fa-spinner fa-pulse fa-3x"></i>
|
||||
</div>`
|
||||
};
|
||||
@@ -9,6 +9,7 @@ import QuickLinks from "./ProfilComponents/QuickLinks.js";
|
||||
import ProfilEmails from "./ProfilComponents/ProfilEmails.js";
|
||||
import RoleInformation from "./ProfilComponents/RoleInformation.js";
|
||||
import ProfilInformation from "./ProfilComponents/ProfilInformation.js";
|
||||
import CalendarSync from "./ProfilComponents/CalendarSync.js";
|
||||
|
||||
import ApiProfilUpdate from '../../../api/factory/profilUpdate.js';
|
||||
import { dateFilter } from '../../../tabulator/filters/Dates.js';
|
||||
@@ -26,6 +27,7 @@ export default {
|
||||
ProfilEmails,
|
||||
RoleInformation,
|
||||
ProfilInformation,
|
||||
CalendarSync,
|
||||
},
|
||||
|
||||
inject: ["sortProfilUpdates", "collapseFunction", "language","isEditable"],
|
||||
@@ -34,7 +36,7 @@ export default {
|
||||
return {
|
||||
showModal: false,
|
||||
editDataFilter: null,
|
||||
preloadedPhrasen:{},
|
||||
arePhrasesPreloaded: false,
|
||||
// tabulator options
|
||||
funktionen_table_options: {
|
||||
persistenceID: "filterTableMaProfilFunktionen",
|
||||
@@ -46,6 +48,7 @@ export default {
|
||||
responsiveLayout: "collapse",
|
||||
responsiveLayoutCollapseUseFormatters: false,
|
||||
responsiveLayoutCollapseFormatter: Vue.$collapseFormatter,
|
||||
responsiveLayoutCollapseStartOpen: false,
|
||||
columns: [
|
||||
{
|
||||
title:
|
||||
@@ -56,24 +59,27 @@ export default {
|
||||
formatter: "responsiveCollapse",
|
||||
maxWidth: 40,
|
||||
headerClick: this.collapseFunction,
|
||||
visible: true
|
||||
visible: true,
|
||||
responsive: 0,
|
||||
},
|
||||
{
|
||||
title: Vue.computed(() => this.preloadedPhrasen.bezeichnungPhrase),
|
||||
title: Vue.computed(() => this.$p.t('ui/bezeichnung')),
|
||||
field: "Bezeichnung",
|
||||
headerFilter: true,
|
||||
minWidth: 200,
|
||||
visible: true
|
||||
visible: true,
|
||||
responsive: 0,
|
||||
},
|
||||
{
|
||||
title: Vue.computed(() => this.preloadedPhrasen.organisationseinheitPhrase),
|
||||
title: Vue.computed(() => this.$p.t('lehre/organisationseinheit')),
|
||||
field: "Organisationseinheit",
|
||||
headerFilter: true,
|
||||
minWidth: 200,
|
||||
visible: true
|
||||
visible: true,
|
||||
responsive: 1,
|
||||
},
|
||||
{
|
||||
title: Vue.computed(() => this.preloadedPhrasen.gueltigVonPhrase),
|
||||
title: Vue.computed(() => this.$p.t('global/gueltigVon')),
|
||||
field: "Gültig_von",
|
||||
headerFilterFunc: 'dates',
|
||||
headerFilter: dateFilter,
|
||||
@@ -81,10 +87,11 @@ export default {
|
||||
minWidth: 200,
|
||||
visible: true,
|
||||
formatter:"datetime",
|
||||
formatterParams: this.datetimeFormatterParams()
|
||||
formatterParams: this.datetimeFormatterParams(),
|
||||
responsive: 4,
|
||||
},
|
||||
{
|
||||
title: Vue.computed(() => this.preloadedPhrasen.gueltigBisPhrase),
|
||||
title: Vue.computed(() => this.$p.t('global/gueltigBis')),
|
||||
field: "Gültig_bis",
|
||||
headerFilterFunc: 'dates',
|
||||
headerFilter: dateFilter,
|
||||
@@ -92,18 +99,19 @@ export default {
|
||||
minWidth: 200,
|
||||
visible: true,
|
||||
formatter:"datetime",
|
||||
formatterParams: this.datetimeFormatterParams()
|
||||
formatterParams: this.datetimeFormatterParams(),
|
||||
responsive: 3,
|
||||
},
|
||||
{
|
||||
title: Vue.computed(() => this.preloadedPhrasen.wochenstundenPhrase),
|
||||
title: Vue.computed(() => this.$p.t('profil/wochenstunden')),
|
||||
field: "Wochenstunden",
|
||||
headerFilter: true,
|
||||
minWidth: 200,
|
||||
visible: true
|
||||
visible: true,
|
||||
responsive: 2,
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
betriebsmittel_table_options: {
|
||||
persistenceID: "filterTableMaProfilBetriebsmittel",
|
||||
persistence: {
|
||||
@@ -115,6 +123,7 @@ export default {
|
||||
responsiveLayoutCollapseUseFormatters: false,
|
||||
responsiveLayoutCollapseFormatter: Vue.$collapseFormatter,
|
||||
data: [{betriebsmittel: "", Nummer: "", Ausgegeben_am: ""}],
|
||||
responsiveLayoutCollapseStartOpen: false,
|
||||
columns: [
|
||||
{
|
||||
title:
|
||||
@@ -125,32 +134,36 @@ export default {
|
||||
formatter: "responsiveCollapse",
|
||||
maxWidth: 40,
|
||||
headerClick: this.collapseFunction,
|
||||
visible: true
|
||||
visible: true,
|
||||
responsive: 0,
|
||||
},
|
||||
{
|
||||
title: Vue.computed(() => this.preloadedPhrasen.entlehnteBetriebsmittelPhrase),
|
||||
title: Vue.computed(() => this.$p.t('profil/entlehnteBetriebsmittel')),
|
||||
field: "betriebsmittel",
|
||||
headerFilter: true,
|
||||
minWidth: 200,
|
||||
visible: true
|
||||
visible: true,
|
||||
responsive: 0,
|
||||
},
|
||||
{
|
||||
title: Vue.computed(() => this.preloadedPhrasen.inventarnummerPhrase),
|
||||
title: Vue.computed(() => this.$p.t('profil/inventarnummer')),
|
||||
field: "Nummer",
|
||||
headerFilter: true,
|
||||
resizable: true,
|
||||
minWidth: 200,
|
||||
visible: true
|
||||
visible: true,
|
||||
responsive: 2,
|
||||
},
|
||||
{
|
||||
title: Vue.computed(() => this.preloadedPhrasen.ausgabedatumPhrase),
|
||||
title: Vue.computed(() => this.$p.t('profil/ausgabedatum')),
|
||||
field: "Ausgegeben_am",
|
||||
headerFilterFunc: 'dates',
|
||||
headerFilter: dateFilter,
|
||||
minWidth: 200,
|
||||
visible: true,
|
||||
formatter:"datetime",
|
||||
formatterParams: this.datetimeFormatterParams()
|
||||
formatterParams: this.datetimeFormatterParams(),
|
||||
responsive: 1,
|
||||
},
|
||||
],
|
||||
}
|
||||
@@ -160,15 +173,14 @@ export default {
|
||||
props: {
|
||||
data: Object,
|
||||
editData: Object,
|
||||
calendarSyncUrls: Array,
|
||||
},
|
||||
|
||||
methods: {
|
||||
betriebsmittelTableBuilt: function () {
|
||||
this.$refs.betriebsmittelTable.tabulator.setColumns(this.betriebsmittel_table_options.columns)
|
||||
this.$refs.betriebsmittelTable.tabulator.setData(this.data.mittel);
|
||||
},
|
||||
funktionenTableBuilt: function () {
|
||||
this.$refs.funktionenTable.tabulator.setColumns(this.funktionen_table_options.columns)
|
||||
this.$refs.funktionenTable.tabulator.setData(this.data.funktionen);
|
||||
},
|
||||
hideEditProfilModal: function () {
|
||||
@@ -219,8 +231,8 @@ export default {
|
||||
});
|
||||
},
|
||||
setTableColumnTitles() { // reevaluates computed phrasen
|
||||
if(this.$refs.betriebsmittelTable) this.$refs.betriebsmittelTable.tabulator.setColumns(this.betriebsmittel_table_options.columns)
|
||||
if(this.$refs.funktionenTable) this.$refs.funktionenTable.tabulator.setColumns(this.funktionen_table_options.columns)
|
||||
if(this.$refs.betriebsmittelTable) this.$refs.betriebsmittelTable.tabulator.setColumns(this.betriebsmittel_table_options.columns);
|
||||
if(this.$refs.funktionenTable) this.$refs.funktionenTable.tabulator.setColumns(this.funktionen_table_options.columns);
|
||||
},
|
||||
datetimeFormatterParams: function() {
|
||||
const params = {
|
||||
@@ -296,24 +308,20 @@ export default {
|
||||
}
|
||||
};
|
||||
},
|
||||
quickLinks() {
|
||||
let quickLinks = [];
|
||||
//
|
||||
return quickLinks;
|
||||
},
|
||||
},
|
||||
|
||||
created() {
|
||||
// preload phrasen
|
||||
this.$p.loadCategory(["ui","lehre","global","profil"]).then(() => {
|
||||
this.preloadedPhrasen.bezeichnungPhrase = this.$p.t('ui/bezeichnung');
|
||||
this.preloadedPhrasen.organisationseinheitPhrase = this.$p.t('lehre/organisationseinheit');
|
||||
this.preloadedPhrasen.gueltigVonPhrase = this.$p.t('global/gueltigVon');
|
||||
this.preloadedPhrasen.gueltigBisPhrase = this.$p.t('global/gueltigBis');
|
||||
this.preloadedPhrasen.wochenstundenPhrase = this.$p.t('profil/wochenstunden');
|
||||
this.preloadedPhrasen.entlehnteBetriebsmittelPhrase = this.$p.t('profil/entlehnteBetriebsmittel');
|
||||
this.preloadedPhrasen.inventarnummerPhrase = this.$p.t('profil/inventarnummer');
|
||||
this.preloadedPhrasen.ausgabedatumPhrase = this.$p.t('profil/ausgabedatum');
|
||||
this.preloadedPhrasen.loaded=true;
|
||||
this.arePhrasesPreloaded = true;
|
||||
});
|
||||
//? sorts the profil Updates: pending -> accepted -> rejected
|
||||
this.data.profilUpdates?.sort(this.sortProfilUpdates);
|
||||
|
||||
},
|
||||
watch: {
|
||||
'data.funktionen'(newVal) {
|
||||
@@ -330,14 +338,8 @@ export default {
|
||||
<div class="container-fluid text-break fhc-form" >
|
||||
<edit-profil v-if="showModal" ref="editModal" :isMitarbeiter="true" @hideBsModal="hideEditProfilModal" :value="JSON.parse(JSON.stringify(filteredEditData))" :titel="$p.t('profil','profilBearbeiten')"></edit-profil>
|
||||
<div class="row">
|
||||
<div class="d-md-none col-12 ">
|
||||
<!--TODO: uncomment when implemented
|
||||
<div class="row mb-3">
|
||||
<div class="col">
|
||||
<quick-links :title="$p.t('profil','quickLinks')" :mobile="true"></quick-links>
|
||||
</div>
|
||||
</div>-->
|
||||
<!-- Bearbeiten Button -->
|
||||
<div class="d-md-none col-12">
|
||||
<!-- Bearbeiten Button -->
|
||||
<div v-if="isEditable" class="row mb-3 ">
|
||||
<div class="col">
|
||||
<button @click="()=>showEditProfilModal()" type="button" class="text-start card w-100 btn btn-outline-secondary" >
|
||||
@@ -350,9 +352,9 @@ export default {
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- MOBILE PROFIL UPDATES -->
|
||||
<div v-if="data.profilUpdates" class="row mb-3">
|
||||
<div class="col">
|
||||
<!-- MOBILE PROFIL UPDATES -->
|
||||
<fetch-profil-updates v-if="data.profilUpdates && data.profilUpdates.length" @fetchUpdates="fetchProfilUpdates" :data="data.profilUpdates" ></fetch-profil-updates>
|
||||
</div>
|
||||
</div>
|
||||
@@ -365,30 +367,42 @@ export default {
|
||||
<!-- ROW WITH THE PROFIL INFORMATION -->
|
||||
<div class="row mb-4">
|
||||
<div class="col-lg-12 col-xl-6 ">
|
||||
<!-- PROFIL INFORMATION -->
|
||||
<div class="row mb-4">
|
||||
<div class="col">
|
||||
<!-- PROFIL INFORMATION -->
|
||||
<profil-information @showEditProfilModal="showEditProfilModal" :title="$p.t('profil','mitarbeiterIn')" :data="profilInformation" :fotoStatus="fotoStatus"></profil-information>
|
||||
</div>
|
||||
</div>
|
||||
<!-- QUICK LINKS, MOBILE VIEW (HIDDEN IF VIEWPORT >= MD BREAKPOINT) -->
|
||||
<div v-if="quickLinks.length" class="row mb-4 d-md-none">
|
||||
<div class="col">
|
||||
<quick-links :title="$p.t('profil/quickLinks')" :links="quickLinks" />
|
||||
</div>
|
||||
</div>
|
||||
<!-- CALENDAR SYNC OPTIONS, MOBILE VIEW (HIDDEN IF VIEWPORT >= MD BREAKPOINT) -->
|
||||
<div class="row mb-4 d-md-none">
|
||||
<div class="col">
|
||||
<calendar-sync :uid="$props.data.username" :calendarSyncUrls="$props.calendarSyncUrls"></calendar-sync>
|
||||
</div>
|
||||
</div>
|
||||
<!-- MITARBEITER INFO -->
|
||||
<div class="row mb-4">
|
||||
<div class=" col-lg-12">
|
||||
<!-- MITARBEITER INFO -->
|
||||
<role-information :title="$p.t('profil','mitarbeiterInformation')" :data="roleInformation"></role-information>
|
||||
</div>
|
||||
</div>
|
||||
<!-- START OF SECOND PROFIL INFORMATION COLUMN -->
|
||||
</div>
|
||||
<div class="col-xl-6 col-lg-12 ">
|
||||
<!-- EMAILS -->
|
||||
<div class="row mb-4">
|
||||
<div class="col">
|
||||
<!-- EMAILS -->
|
||||
<profil-emails :title="this.$p.t('person','email')" :data="data.emails" ></profil-emails>
|
||||
</div>
|
||||
</div>
|
||||
<!-- PRIVATE KONTAKTE-->
|
||||
<div class="row mb-4 ">
|
||||
<div class="col">
|
||||
<!-- PRIVATE KONTAKTE-->
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<div class="row">
|
||||
@@ -410,9 +424,9 @@ export default {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- PRIVATE ADRESSEN-->
|
||||
<div class="row mb-4">
|
||||
<div class="col">
|
||||
<!-- PRIVATE ADRESSEN-->
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<div class="row">
|
||||
@@ -437,10 +451,10 @@ export default {
|
||||
</div>
|
||||
</div >
|
||||
<div class="row">
|
||||
<!-- FUNKTIONEN TABELLE -->
|
||||
<div class="col-12 mb-4" >
|
||||
<!-- FUNKTIONEN TABELLE -->
|
||||
<core-filter-cmpt
|
||||
v-if="preloadedPhrasen.loaded"
|
||||
v-if="arePhrasesPreloaded"
|
||||
@tableBuilt="funktionenTableBuilt"
|
||||
:title="$p.t('person','funktionen')"
|
||||
ref="funktionenTable"
|
||||
@@ -449,10 +463,10 @@ export default {
|
||||
:sideMenu="false"
|
||||
/>
|
||||
</div>
|
||||
<!-- BETRIEBSMITTEL TABELLE -->
|
||||
<div class="col-12 mb-4" >
|
||||
<!-- BETRIEBSMITTEL TABELLE -->
|
||||
<core-filter-cmpt
|
||||
v-if="preloadedPhrasen.loaded"
|
||||
v-if="arePhrasesPreloaded"
|
||||
@tableBuilt="betriebsmittelTableBuilt"
|
||||
:title="$p.t('profil','entlehnteBetriebsmittel')"
|
||||
ref="betriebsmittelTable"
|
||||
@@ -465,17 +479,6 @@ export default {
|
||||
</div>
|
||||
<!-- START OF SIDE PANEL -->
|
||||
<div class="col-md-4 col-xxl-3 col-sm-12 text-break" >
|
||||
<!--TODO: uncomment when implemented
|
||||
<div class="row d-none d-md-block mb-3">
|
||||
|
||||
<div class="col">
|
||||
|
||||
<quick-links :title="$p.t('profil','quickLinks')"></quick-links>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</div>-->
|
||||
<!-- Bearbeiten Button -->
|
||||
<div class="row d-none d-md-block ">
|
||||
<div class="col mb-3">
|
||||
@@ -489,21 +492,33 @@ export default {
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- QUICK LINKS, HIDDEN IF VIEWPORT < MD BREAKPOINT -->
|
||||
<div v-if="quickLinks.length" class="row mb-3 d-none d-md-block">
|
||||
<div class="col">
|
||||
<quick-links :title="$p.t('profil/quickLinks')" :links="quickLinks" />
|
||||
</div>
|
||||
</div>
|
||||
<!-- CALENDAR SYNC OPTIONS, HIDDEN IF VIEWPORT < MD BREAKPOINT -->
|
||||
<div class="row mb-3 d-none d-md-block">
|
||||
<div class="col">
|
||||
<calendar-sync :uid="$props.data.username" :calendarSyncUrls="$props.calendarSyncUrls"></calendar-sync>
|
||||
</div>
|
||||
</div>
|
||||
<!-- PROFIL UPDATES -->
|
||||
<div v-if="data.profilUpdates" class="row d-none d-md-block mb-3">
|
||||
<div class="col mb-3">
|
||||
<!-- PROFIL UPDATES -->
|
||||
<fetch-profil-updates v-if="data.profilUpdates && data.profilUpdates.length" @fetchUpdates="fetchProfilUpdates" :data="data.profilUpdates"></fetch-profil-updates>
|
||||
</div>
|
||||
</div>
|
||||
<!-- AUSWEIS STATUS -->
|
||||
<div class="row mb-3" >
|
||||
<div class="col-12">
|
||||
<!-- AUSWEIS STATUS -->
|
||||
<ausweis-status :data="data.zutrittsdatum"></ausweis-status>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<!-- MAILVERTEILER -->
|
||||
<div class="row mb-3">
|
||||
<div class="col">
|
||||
<!-- MAILVERTEILER -->
|
||||
<mailverteiler :data="data?.mailverteiler" :title="$p.t('profil','mailverteiler')"></mailverteiler>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,30 +1,30 @@
|
||||
import {CoreFilterCmpt} from "../../../components/filter/Filter.js";
|
||||
import { CoreFilterCmpt } from "../../../components/filter/Filter.js";
|
||||
import Mailverteiler from "./ProfilComponents/Mailverteiler.js";
|
||||
import QuickLinks from "./ProfilComponents/QuickLinks.js";
|
||||
import RoleInformation from "./ProfilComponents/RoleInformation.js";
|
||||
import ProfilEmails from "./ProfilComponents/ProfilEmails.js";
|
||||
import ProfilInformation from "./ProfilComponents/ProfilInformation.js";
|
||||
import QuickLinks from "./ProfilComponents/QuickLinks.js";
|
||||
|
||||
import { dateFilter } from '../../../tabulator/filters/Dates.js';
|
||||
import { dateFilter } from "../../../tabulator/filters/Dates.js";
|
||||
|
||||
export default {
|
||||
components: {
|
||||
CoreFilterCmpt,
|
||||
Mailverteiler,
|
||||
QuickLinks,
|
||||
RoleInformation,
|
||||
ProfilEmails,
|
||||
ProfilInformation,
|
||||
QuickLinks,
|
||||
},
|
||||
inject: ["collapseFunction", "language"],
|
||||
data() {
|
||||
return {
|
||||
collapseIconFunktionen: true,
|
||||
preloadedPhrasen:{},
|
||||
arePhrasesPreloaded: false,
|
||||
funktionen_table_options: {
|
||||
persistenceID: "filterTableMaViewProfilFunktionen",
|
||||
persistence: {
|
||||
columns: false
|
||||
columns: false,
|
||||
},
|
||||
minHeight: 300,
|
||||
layout: "fitColumns",
|
||||
@@ -35,58 +35,65 @@ export default {
|
||||
//? option when wanting to hide the collapsed list
|
||||
|
||||
{
|
||||
title:
|
||||
"<i id='collapseIconFunktionen' role='button' class='fa-solid fa-angle-down '></i>",
|
||||
title: "<i id='collapseIconFunktionen' role='button' class='fa-solid fa-angle-down '></i>",
|
||||
field: "collapse",
|
||||
headerSort: false,
|
||||
headerFilter: false,
|
||||
formatter: "responsiveCollapse",
|
||||
maxWidth: 40,
|
||||
headerClick: this.collapseFunction,
|
||||
visible: true
|
||||
visible: true,
|
||||
},
|
||||
{
|
||||
title: Vue.computed(() => this.$p.t('ui/bezeichnung')),
|
||||
title: Vue.computed(() => this.$p.t("ui/bezeichnung")),
|
||||
field: "Bezeichnung",
|
||||
headerFilter: true,
|
||||
minWidth: 200,
|
||||
visible: true
|
||||
visible: true,
|
||||
},
|
||||
{
|
||||
title: Vue.computed(() => this.$p.t('lehre/organisationseinheit')),
|
||||
title: Vue.computed(() =>
|
||||
this.$p.t("lehre/organisationseinheit"),
|
||||
),
|
||||
field: "Organisationseinheit",
|
||||
headerFilter: true,
|
||||
minWidth: 200,
|
||||
visible: true
|
||||
visible: true,
|
||||
},
|
||||
{
|
||||
title: Vue.computed(() => this.$p.t('global/gueltigVon')),
|
||||
title: Vue.computed(() =>
|
||||
this.$p.t("global/gueltigVon"),
|
||||
),
|
||||
field: "Gültig_von",
|
||||
headerFilterFunc: 'dates',
|
||||
headerFilterFunc: "dates",
|
||||
headerFilter: dateFilter,
|
||||
resizable: true,
|
||||
minWidth: 200,
|
||||
visible: true,
|
||||
formatter:"datetime",
|
||||
formatterParams: this.datetimeFormatterParams()
|
||||
formatter: "datetime",
|
||||
formatterParams: this.datetimeFormatterParams(),
|
||||
},
|
||||
{
|
||||
title: Vue.computed(() => this.$p.t('global/gueltigBis')),
|
||||
title: Vue.computed(() =>
|
||||
this.$p.t("global/gueltigBis"),
|
||||
),
|
||||
field: "Gültig_bis",
|
||||
headerFilterFunc: 'dates',
|
||||
headerFilterFunc: "dates",
|
||||
headerFilter: dateFilter,
|
||||
resizable: true,
|
||||
minWidth: 200,
|
||||
visible: true,
|
||||
formatter:"datetime",
|
||||
formatterParams: this.datetimeFormatterParams()
|
||||
formatter: "datetime",
|
||||
formatterParams: this.datetimeFormatterParams(),
|
||||
},
|
||||
{
|
||||
title: Vue.computed(() => this.$p.t('profil/wochenstunden')),
|
||||
title: Vue.computed(() =>
|
||||
this.$p.t("profil/wochenstunden"),
|
||||
),
|
||||
field: "Wochenstunden",
|
||||
headerFilter: true,
|
||||
minWidth: 200,
|
||||
visible: true
|
||||
visible: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -94,47 +101,56 @@ export default {
|
||||
},
|
||||
|
||||
//? this is the prop passed to the dynamic component with the custom data of the view
|
||||
props: ["data"],
|
||||
props: ["data", "permissions"],
|
||||
methods: {
|
||||
funktionenTableBuilt: function () {
|
||||
this.$refs.funktionenTable.tabulator.setData(this.data.funktionen);
|
||||
},
|
||||
datetimeFormatterParams: function() {
|
||||
datetimeFormatterParams: function () {
|
||||
const params = {
|
||||
inputFormat:"yyyy-MM-dd",
|
||||
outputFormat:"dd.MM.yyyy",
|
||||
invalidPlaceholder:"(invalid date)",
|
||||
timezone:FHC_JS_DATA_STORAGE_OBJECT.timezone
|
||||
inputFormat: "yyyy-MM-dd",
|
||||
outputFormat: "dd.MM.yyyy",
|
||||
invalidPlaceholder: "(invalid date)",
|
||||
timezone: FHC_JS_DATA_STORAGE_OBJECT.timezone,
|
||||
};
|
||||
return params;
|
||||
}
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
'data.funktionen'(newVal) {
|
||||
if(this.$refs.funktionenTable) this.$refs.funktionenTable.tabulator.setData(newVal);
|
||||
"data.funktionen"(newVal) {
|
||||
if (this.$refs.funktionenTable)
|
||||
this.$refs.funktionenTable.tabulator.setData(newVal);
|
||||
},
|
||||
"language.value"(newVal) {
|
||||
// reevaluates computed phrasen
|
||||
if (this.$refs.funktionenTable)
|
||||
this.$refs.funktionenTable.tabulator.setColumns(
|
||||
this.funktionen_table_options.columns,
|
||||
);
|
||||
},
|
||||
'language.value'(newVal) { // reevaluates computed phrasen
|
||||
if(this.$refs.funktionenTable) this.$refs.funktionenTable.tabulator.setColumns(this.funktionen_table_options.columns)
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
getTelefonValue() {
|
||||
if(this.data.standort_telefon?.kontakt) {
|
||||
return this.data.standort_telefon.kontakt + " " + this.data.telefonklappe
|
||||
} else if(this.data.standort_telefon) {
|
||||
return this.data.standort_telefon + " " + this.data.telefonklappe
|
||||
if (this.data.standort_telefon?.kontakt) {
|
||||
return (
|
||||
this.data.standort_telefon.kontakt +
|
||||
" " +
|
||||
this.data.telefonklappe
|
||||
);
|
||||
} else if (this.data.standort_telefon) {
|
||||
return (
|
||||
this.data.standort_telefon + " " + this.data.telefonklappe
|
||||
);
|
||||
} else {
|
||||
return this.data.telefonklappe
|
||||
return this.data.telefonklappe;
|
||||
}
|
||||
},
|
||||
fotoStatus() {
|
||||
return this.data?.fotoStatus ?? null;
|
||||
},
|
||||
|
||||
personEmails() {
|
||||
return this.data?.emails ? this.data.emails : [];
|
||||
},
|
||||
|
||||
profilInformation() {
|
||||
if (!this.data) {
|
||||
return {};
|
||||
@@ -151,43 +167,56 @@ export default {
|
||||
foto: this.data.foto,
|
||||
};
|
||||
},
|
||||
|
||||
roleInformation() {
|
||||
if (!this.data) {
|
||||
return {};
|
||||
}
|
||||
return {
|
||||
geburtsdatum: {
|
||||
label: `${this.$p.t('profil','Geburtsdatum')}`,
|
||||
value: this.data.gebdatum
|
||||
label: `${this.$p.t("profil", "Geburtsdatum")}`,
|
||||
value: this.data.gebdatum,
|
||||
},
|
||||
geburtsort: {
|
||||
label: `${this.$p.t('profil','Geburtsort')}`,
|
||||
value: this.data.gebort
|
||||
label: `${this.$p.t("profil", "Geburtsort")}`,
|
||||
value: this.data.gebort,
|
||||
},
|
||||
personenkennzeichen: {
|
||||
label: `${this.$p.t('profil','Kurzzeichen')}`,
|
||||
value: this.data.kurzbz
|
||||
label: `${this.$p.t("profil", "Kurzzeichen")}`,
|
||||
value: this.data.kurzbz,
|
||||
},
|
||||
telefon: {
|
||||
label: `${this.$p.t('profil','Telefon')}`,
|
||||
value: this.getTelefonValue
|
||||
label: `${this.$p.t("profil", "Telefon")}`,
|
||||
value: this.getTelefonValue,
|
||||
},
|
||||
office: {
|
||||
label: `${this.$p.t('profil','Büro')}`,
|
||||
value: this.data.ort_kurzbz
|
||||
}
|
||||
label: `${this.$p.t("profil", "Büro")}`,
|
||||
value: this.data.ort_kurzbz,
|
||||
},
|
||||
};
|
||||
},
|
||||
quickLinks() {
|
||||
let quickLinks = [];
|
||||
if (
|
||||
this.$props.permissions &&
|
||||
this.$props.permissions["basis/other_lv_plan"]
|
||||
) {
|
||||
quickLinks.push({
|
||||
icon: "fa-calendar-days",
|
||||
phrase: "lehre/stundenplan",
|
||||
action: () => {
|
||||
this.$router.push({
|
||||
name: "OtherLvPlan",
|
||||
params: { otherUid: this.$props.data.username },
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
||||
return quickLinks;
|
||||
},
|
||||
},
|
||||
created(){
|
||||
created() {
|
||||
this.$p.loadCategory(["ui", "lehre", "global", "profil"]).then(() => {
|
||||
this.preloadedPhrasen.bezeichnungPhrase = this.$p.t('ui/bezeichnung');
|
||||
this.preloadedPhrasen.organisationseinheitPhrase = this.$p.t('lehre/organisationseinheit');
|
||||
this.preloadedPhrasen.gueltigVonPhrase = this.$p.t('global/gueltigVon');
|
||||
this.preloadedPhrasen.gueltigBisPhrase = this.$p.t('global/gueltigBis');
|
||||
this.preloadedPhrasen.wochenstundenPhrase = this.$p.t('profil/wochenstunden');
|
||||
this.preloadedPhrasen.loaded = true;
|
||||
this.arePhrasesPreloaded = true;
|
||||
});
|
||||
},
|
||||
|
||||
@@ -196,15 +225,6 @@ export default {
|
||||
<div class="container-fluid text-break fhc-form" >
|
||||
<!-- ROW -->
|
||||
<div class="row">
|
||||
<!-- HIDDEN QUICK LINKS -->
|
||||
<!-- TODO: uncomment when implemented
|
||||
<div class="d-md-none col-12 ">
|
||||
|
||||
<quick-links :title="$p.t('profil','quickLinks')" :mobile="true" ></quick-links>
|
||||
|
||||
</div>
|
||||
-->
|
||||
<!-- END OF HIDDEN QUCK LINKS -->
|
||||
<!-- MAIN PANNEL -->
|
||||
<div class="col-sm-12 col-md-8 col-xxl-9 ">
|
||||
<!-- ROW WITH PROFIL IMAGE AND INFORMATION -->
|
||||
@@ -213,27 +233,33 @@ export default {
|
||||
<div class="row mb-4">
|
||||
<!-- FIRST KAESTCHEN -->
|
||||
<div class="col-lg-12 col-xl-6 ">
|
||||
<!-- Profil Informationen -->
|
||||
<div class="row mb-4">
|
||||
<div class="col">
|
||||
<!-- Profil Informationen -->
|
||||
<profil-information :title="$p.t('profil','mitarbeiterIn')" :data="profilInformation" :fotoStatus="fotoStatus"></profil-information>
|
||||
</div>
|
||||
</div>
|
||||
<!-- QUICK LINKS, MOBILE VIEW (HIDDEN IF VIEWPORT >= MD BREAKPOINT) -->
|
||||
<div v-if="quickLinks.length" class="row mb-4 d-md-none">
|
||||
<div class="col">
|
||||
<quick-links :title="$p.t('profil/quickLinks')" :links="quickLinks" />
|
||||
</div>
|
||||
</div>
|
||||
<!-- START OF SECOND PROFIL INFORMATION COLUMN -->
|
||||
<!-- END OF PROFIL INFORMATION ROW -->
|
||||
<!-- INFORMATION CONTENT END -->
|
||||
</div>
|
||||
<div class="col-xl-6 col-lg-12 ">
|
||||
<!-- EMAILS -->
|
||||
<div class="row mb-4">
|
||||
<div class="col">
|
||||
<!-- EMAILS -->
|
||||
<profil-emails :title="this.$p.t('person','email')" :data="personEmails"></profil-emails>
|
||||
</div>
|
||||
</div>
|
||||
<!-- SECOND ROW OF SECOND COLUMN IN MAIN CONTENT -->
|
||||
<!-- roleInformation -->
|
||||
<div class="row mb-4">
|
||||
<div class=" col-lg-12">
|
||||
<!-- roleInformation -->
|
||||
<role-information :data="roleInformation" :title="$p.t('profil','mitarbeiterInformation')"></role-information>
|
||||
</div>
|
||||
</div>
|
||||
@@ -242,12 +268,12 @@ export default {
|
||||
</div>
|
||||
<!-- START OF THE SECOND PROFIL INFORMATION ROW -->
|
||||
<!-- ROW WITH PROFIL IMAGE AND INFORMATION END -->
|
||||
</div >
|
||||
</div>
|
||||
<!-- SECOND ROW UNDER THE PROFIL IMAGE AND INFORMATION WITH THE TABLES -->
|
||||
<div class="row">
|
||||
<!-- FIRST TABLE -->
|
||||
<div class="col-12 mb-4" >
|
||||
<core-filter-cmpt v-if="preloadedPhrasen.loaded" @tableBuilt="funktionenTableBuilt" :title="$p.t('person','funktionen')" ref="funktionenTable" :tabulator-options="funktionen_table_options" tableOnly :sideMenu="false" />
|
||||
<core-filter-cmpt v-if="arePhrasesPreloaded" @tableBuilt="funktionenTableBuilt" :title="$p.t('person','funktionen')" ref="funktionenTable" :tabulator-options="funktionen_table_options" tableOnly :sideMenu="false" />
|
||||
</div>
|
||||
<!-- END OF THE ROW WITH THE TABLES UNDER THE PROFIL INFORMATION -->
|
||||
</div>
|
||||
@@ -255,27 +281,23 @@ export default {
|
||||
</div>
|
||||
<!-- START OF SIDE PANEL -->
|
||||
<div class="col-md-4 col-xxl-3 col-sm-12 text-break" >
|
||||
<!-- VISIBLE UNTIL VIEWPORT MD -->
|
||||
<!--TODO: uncomment when implemented
|
||||
<div class="row d-none d-md-block mb-3">
|
||||
<div class="col">
|
||||
|
||||
<quick-links :title="$p.t('profil','quickLinks')" ></quick-links>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
-->
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<!-- MAILVERTEILER -->
|
||||
<mailverteiler :data="data?.mailverteiler" :title="$p.t('profil','mailverteiler')"></mailverteiler>
|
||||
</div>
|
||||
</div>
|
||||
<!-- END OF SIDE PANEL -->
|
||||
</div>
|
||||
<!-- QUICK LINKS, HIDDEN IF VIEWPORT < MD BREAKPOINT -->
|
||||
<div v-if="quickLinks.length" class="row mb-3 d-none d-md-block">
|
||||
<div class="col">
|
||||
<quick-links :title="$p.t('profil/quickLinks')" :links="quickLinks" />
|
||||
</div>
|
||||
</div>
|
||||
<!-- MAILVERTEILER -->
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<mailverteiler :data="data?.mailverteiler" :title="$p.t('profil','mailverteiler')"></mailverteiler>
|
||||
</div>
|
||||
</div>
|
||||
<!-- END OF SIDE PANEL -->
|
||||
</div>
|
||||
<!-- END OF CONTAINER ROW-->
|
||||
</div>
|
||||
<!-- END OF CONTAINER -->
|
||||
</div>
|
||||
<!-- END OF CONTAINER -->
|
||||
</div>
|
||||
`,
|
||||
};
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user