diff --git a/application/controllers/api/frontend/v1/lv/StgTree.php b/application/controllers/api/frontend/v1/lv/StgTree.php index 8272da978..792775833 100644 --- a/application/controllers/api/frontend/v1/lv/StgTree.php +++ b/application/controllers/api/frontend/v1/lv/StgTree.php @@ -25,7 +25,25 @@ class StgTree extends FHCAPI_Controller return $this->_outputAuthError([$method => ['admin:r', 'assistenz:r']]); } - return $this->getStudiengang($method); + $count = count($params); + if (!$count) + return $this->getStudiengang($method); + + if ($count == 1) { + if (is_numeric($params[0])) + return $this->getSemester($method, $params[0]); + else + return $this->getStudiengang($method, $params[0]); + } + if ($count == 2) { + if (is_numeric($params[0])) + return $this->getVerband($method, $params[0], $params[1]); + else + return $this->getSemester($method, $params[1], $params[0]); + } + + + show_404(); } @@ -64,16 +82,27 @@ class StgTree extends FHCAPI_Controller $this->terminateWithSuccess($list); } - protected function getStudiengang($studiengang_kz) + protected function getStudiengang($studiengang_kz, $org_form = null) { $link = $studiengang_kz . '/'; + if ($org_form !== null) + $link .= $org_form . '/'; $this->StudiengangModel->addJoin('public.tbl_lehrverband v', 'studiengang_kz'); $this->StudiengangModel->addDistinct(); $this->StudiengangModel->addSelect("CONCAT(" . $this->StudiengangModel->escape($link) . ", semester) AS link", false); - $this->StudiengangModel->addSelect("CONCAT(UPPER(CONCAT(typ, kurzbz)), '-', semester, (SELECT CASE WHEN bezeichnung IS NULL OR bezeichnung='' THEN ''::TEXT ELSE CONCAT(' (', bezeichnung, ')') END FROM public.tbl_lehrverband WHERE studiengang_kz=v.studiengang_kz AND semester=v.semester ORDER BY verband, gruppe LIMIT 1)) AS name", false); - $this->StudiengangModel->addSelect("TRUE AS leaf", false); + $this->StudiengangModel->addSelect("CONCAT( + UPPER(CONCAT(typ, kurzbz)), + '-', + semester, + ( + SELECT CASE WHEN bezeichnung IS NULL OR bezeichnung='' THEN ''::TEXT ELSE CONCAT(' (', bezeichnung, ')') END + FROM public.tbl_lehrverband + WHERE studiengang_kz=v.studiengang_kz AND semester=v.semester + ORDER BY verband, gruppe LIMIT 1 + ) + ) AS name", false); $this->StudiengangModel->addSelect('semester'); $this->StudiengangModel->addSelect($this->StudiengangModel->escape($studiengang_kz) . '::integer AS stg_kz', false); @@ -97,6 +126,8 @@ class StgTree extends FHCAPI_Controller $this->StudienordnungModel->addDistinct(); $this->StudienordnungModel->addSelect("CONCAT(studiengang_kz, '/', p.orgform_kurzbz) AS link"); $this->StudienordnungModel->addSelect("p.orgform_kurzbz AS name"); + $this->StudienordnungModel->addSelect("p.orgform_kurzbz AS orgform_kurzbz"); + $this->StudienordnungModel->addSelect("studiengang_kz AS stg_kz"); $this->StudienordnungModel->addSelect("TRUE as leaf", false); $this->StudienordnungModel->addJoin('lehre.tbl_studienplan p', 'studienordnung_id'); @@ -111,6 +142,115 @@ class StgTree extends FHCAPI_Controller $list = array_merge($list, $result); } } + $this->terminateWithSuccess($list); + } + + protected function getSemester($studiengang_kz, $semester, $org_form = null) + { + $link = $studiengang_kz . '/'; + if ($org_form !== null) + $link .= $org_form . '/'; + $link .= $semester . '/'; + + + $this->load->model('organisation/Gruppe_model', 'GruppeModel'); + + $this->GruppeModel->addDistinct(); + $this->GruppeModel->addSelect("CONCAT(" . $this->GruppeModel->escape($link . 'grp/') . ", gruppe_kurzbz) AS link", false); + $this->GruppeModel->addSelect("CONCAT(gruppe_kurzbz, ' (', bezeichnung, ')') AS name", false); + $this->GruppeModel->addSelect("TRUE AS leaf", false); + + $this->GruppeModel->addSelect('sort'); + $this->GruppeModel->addSelect('gruppe_kurzbz'); + $this->GruppeModel->addSelect($this->GruppeModel->escape($studiengang_kz) . '::integer AS stg_kz', false); + + $this->GruppeModel->addOrder('sort'); + $this->GruppeModel->addOrder('gruppe_kurzbz'); + + $where = [ + 'studiengang_kz' => $studiengang_kz, + 'semester' => $semester, + 'lehre' => true, + 'sichtbar' => true, + 'aktiv' => true, + 'direktinskription' => false + ]; + + if ($org_form !== null) + $where['orgform_kurzbz'] = $org_form; + + $result = $this->GruppeModel->loadWhere($where); + + $list = $this->getDataOrTerminateWithError($result); + + $this->StudiengangModel->addJoin('public.tbl_lehrverband v', 'studiengang_kz'); + + $this->StudiengangModel->addSelect("CONCAT(" . $this->StudiengangModel->escape($link) . ", verband) AS link", false); + $this->StudiengangModel->addSelect("CONCAT(UPPER(CONCAT(typ, kurzbz)), '-', semester, verband, (SELECT CASE WHEN bezeichnung IS NULL OR bezeichnung='' THEN ''::TEXT ELSE CONCAT(' (', bezeichnung, ')') END FROM public.tbl_lehrverband WHERE studiengang_kz=v.studiengang_kz AND semester=v.semester AND verband=v.verband ORDER BY gruppe LIMIT 1)) AS name", false); + $this->StudiengangModel->addSelect("CASE WHEN MAX(gruppe)='' OR MAX(gruppe)=' ' THEN TRUE ELSE FALSE END AS leaf"); + + $this->StudiengangModel->addSelect($this->StudiengangModel->escape($semester) . ' AS semester'); + $this->StudiengangModel->addSelect('verband'); + $this->StudiengangModel->addSelect($this->StudiengangModel->escape($studiengang_kz) . '::integer AS stg_kz', false); + + $this->StudiengangModel->addOrder('verband'); + + $this->StudiengangModel->addGroupBy('link, name, verband'); + + $where = [ + 'v.studiengang_kz' => $studiengang_kz, + 'v.semester' => $semester, + 'v.verband !=' => '', + 'v.aktiv' => true + ]; + + if ($org_form !== null && $semester) // NOTE(chris): on semester 0 show all? + $where['v.orgform_kurzbz'] = $org_form; + + $result = $this->StudiengangModel->loadWhere($where); + $result = $this->getDataOrTerminateWithError($result); + + $list = array_merge($list, $result); + + $this->terminateWithSuccess($list); + } + + protected function getVerband($studiengang_kz, $semester, $verband, $org_form = null) + { + $link = $studiengang_kz . '/'; + if ($org_form !== null) + $link .= $org_form . '/'; + $link .= $semester . '/'. $verband . '/'; + + + $this->StudiengangModel->addJoin('public.tbl_lehrverband v', 'studiengang_kz'); + + $this->StudiengangModel->addDistinct(); + $this->StudiengangModel->addSelect("CONCAT(" . $this->StudiengangModel->escape($link) . ", gruppe) AS link", false); + $this->StudiengangModel->addSelect("CONCAT(UPPER(CONCAT(typ, kurzbz)), '-', semester, verband, gruppe, (SELECT CASE WHEN bezeichnung IS NULL OR bezeichnung='' THEN ''::TEXT ELSE CONCAT(' (', bezeichnung, ')') END FROM public.tbl_lehrverband WHERE studiengang_kz=v.studiengang_kz AND semester=v.semester AND verband=v.verband AND gruppe=v.gruppe ORDER BY gruppe LIMIT 1)) AS name", false); + $this->StudiengangModel->addSelect("TRUE AS leaf", false); + + $this->StudiengangModel->addSelect('v.semester'); + $this->StudiengangModel->addSelect('v.verband'); + $this->StudiengangModel->addSelect('gruppe'); + $this->StudiengangModel->addSelect($this->StudiengangModel->escape($studiengang_kz) . '::integer AS stg_kz', false); + + $this->StudiengangModel->addOrder('gruppe'); + + $where = [ + 'v.studiengang_kz' => $studiengang_kz, + 'v.semester' => $semester, + 'v.verband' => $verband, + 'v.gruppe !=' => '', + 'v.aktiv' => true + ]; + + if ($org_form !== null && $semester) + $where['v.orgform_kurzbz'] = $org_form; + + $result = $this->StudiengangModel->loadWhere($where); + + $list = $this->getDataOrTerminateWithError($result); $this->terminateWithSuccess($list); } diff --git a/application/controllers/api/frontend/v1/tempus/Coursepicker.php b/application/controllers/api/frontend/v1/tempus/Coursepicker.php index 18de39a4e..2d0eecd94 100644 --- a/application/controllers/api/frontend/v1/tempus/Coursepicker.php +++ b/application/controllers/api/frontend/v1/tempus/Coursepicker.php @@ -94,11 +94,15 @@ class Coursepicker extends FHCAPI_Controller public function getByStg() { - //TODO check einbauen ob studiensemester und stg vorhanden ist - $stg = $this->input->get('stg'); - $studiensemester_kurzbz = $this->input->get('studiensemester_kurzbz'); - if (is_null($stg) || is_null($studiensemester_kurzbz)) - $this->terminateWithError($this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL); + $this->_ci->form_validation->set_data($_POST); + $this->_ci->form_validation->set_rules('studiengaenge[]',"studiengaenge","required"); + $this->_ci->form_validation->set_rules('studiensemester_kurzbz',"studiensemester_kurzbz","required"); + + if($this->_ci->form_validation->run() === FALSE) + $this->terminateWithValidationErrors($this->_ci->form_validation->error_array()); + + $studiengaenge = $this->input->post('studiengaenge'); + $studiensemester_kurzbz = $this->input->post('studiensemester_kurzbz'); $this->_ci->LehreinheitModel->addSelect(' tbl_lehreinheit.lehreinheit_id, @@ -131,15 +135,39 @@ class Coursepicker extends FHCAPI_Controller $this->_ci->LehreinheitModel->addJoin('lehre.tbl_lehreinheitmitarbeiter lema', 'tbl_lehreinheit.lehreinheit_id = lema.lehreinheit_id'); $this->_ci->LehreinheitModel->addJoin('lehre.tbl_lehreinheitgruppe lvb', 'tbl_lehreinheit.lehreinheit_id = lvb.lehreinheit_id'); $this->_ci->LehreinheitModel->addJoin('public.tbl_studiengang', 'lvb.studiengang_kz = tbl_studiengang.studiengang_kz'); + $this->_ci->LehreinheitModel->addJoin('lehre.tbl_lehrveranstaltung', 'tbl_lehreinheit.lehrveranstaltung_id = tbl_lehrveranstaltung.lehrveranstaltung_id'); $this->_ci->LehreinheitModel->addJoin('lehre.tbl_lehrveranstaltung lehrfach', 'tbl_lehreinheit.lehrfach_id = lehrfach.lehrveranstaltung_id'); $this->_ci->LehreinheitModel->addJoin('public.tbl_mitarbeiter ma', 'lema.mitarbeiter_uid = ma.mitarbeiter_uid'); $this->_ci->LehreinheitModel->addJoin('lehre.tbl_lehrform', 'tbl_lehrform.lehrform_kurzbz = tbl_lehreinheit.lehrform_kurzbz'); $this->_ci->LehreinheitModel->addJoin('public.tbl_benutzer', 'ma.mitarbeiter_uid = tbl_benutzer.uid'); $this->_ci->LehreinheitModel->addJoin('public.tbl_person', 'tbl_benutzer.person_id = tbl_person.person_id'); + $this->_ci->LehreinheitModel->db->group_start(); + $first = true; + foreach ($studiengaenge as $studiengang) + { + if ($first) + $this->_ci->LehreinheitModel->db->group_start(); + else + { + $this->_ci->LehreinheitModel->db->or_group_start(); + } + $first = false; + + $this->_ci->LehreinheitModel->db->where('tbl_lehrveranstaltung.studiengang_kz', $studiengang['studiengang_kz']); + + if (isset($studiengang['semester'])) + $this->_ci->LehreinheitModel->db->where('tbl_lehrveranstaltung.semester', $studiengang['semester']); + + if (isset($studiengang['orgform_kurzbz'])) + $this->_ci->LehreinheitModel->db->where('tbl_lehrveranstaltung.orgform_kurzbz', $studiengang['orgform_kurzbz']); + + $this->_ci->LehreinheitModel->db->group_end(); + } + $this->_ci->LehreinheitModel->db->group_end(); + $result = $this->_ci->LehreinheitModel->loadWhere(array( 'tbl_lehrform.verplanen' => true, - 'tbl_studiengang.studiengang_kz' => $stg, 'tbl_lehreinheit.studiensemester_kurzbz' => $studiensemester_kurzbz )); diff --git a/application/controllers/api/frontend/v1/tempus/Favorites.php b/application/controllers/api/frontend/v1/tempus/Favorites.php new file mode 100644 index 000000000..94ee39707 --- /dev/null +++ b/application/controllers/api/frontend/v1/tempus/Favorites.php @@ -0,0 +1,47 @@ + self::PERM_LOGGED, + 'set' => self::PERM_LOGGED + ]); + + // Load models + $this->load->model('system/Variable_model', 'VariableModel'); + } + + public function index() + { + $result = $this->VariableModel->getVariables(getAuthUID(), ['tempus_favorites']); + + $data = $this->getDataOrTerminateWithError($result); + + if (!$data) + $this->terminateWithSuccess(null); + else + $this->terminateWithSuccess(isset($data['tempus_favorites']) ? $data['tempus_favorites'] : null); + } + + public function set() + { + $this->load->library('form_validation'); + + $this->form_validation->set_rules('favorites', 'Favorites', 'required'); + + if (!$this->form_validation->run()) + $this->terminateWithValidationErrors($this->form_validation->error_array()); + + $favorites = $this->input->post('favorites'); + + $result = $this->VariableModel->setVariable(getAuthUID(), 'tempus_favorites', $favorites); + + $this->getDataOrTerminateWithError($result); + + $this->terminateWithSuccess(true); + } +} diff --git a/application/controllers/api/frontend/v1/tempus/Info.php b/application/controllers/api/frontend/v1/tempus/Info.php new file mode 100644 index 000000000..b8ab2b9b0 --- /dev/null +++ b/application/controllers/api/frontend/v1/tempus/Info.php @@ -0,0 +1,37 @@ + self::PERM_LOGGED, + ]); + + $this->_ci =& get_instance(); + + $this->load->model('organisation/Studiengang_model', 'StudiengangModel'); + + $this->loadPhrases([ + 'ui' + ]); + + } + + public function getStudiengaenge() + { + $this->_ci->StudiengangModel->addDistinct(); + $this->_ci->StudiengangModel->addSelect('studiengang_kz'); + $this->_ci->StudiengangModel->addSelect("CONCAT(kurzbzlang, ' (', UPPER(CONCAT(typ, kurzbz)), ') - ', tbl_studiengang.bezeichnung) AS name"); + + $result = $this->getDataOrTerminateWithError($this->_ci->StudiengangModel->load()); + $this->terminateWithSuccess($result); + } +} diff --git a/application/controllers/api/frontend/v1/tempus/Kalender.php b/application/controllers/api/frontend/v1/tempus/Kalender.php index ba7eec4d0..7a65a5211 100644 --- a/application/controllers/api/frontend/v1/tempus/Kalender.php +++ b/application/controllers/api/frontend/v1/tempus/Kalender.php @@ -33,7 +33,6 @@ class Kalender extends FHCAPI_Controller 'calculateMultiWeekPlan' => 'lehre/lvplan:rw', 'confirmMultiWeekPlan' => 'lehre/lvplan:rw', 'addToKalenderEvent' => 'lehre/lvplan:rw', - 'addReservierung' => 'lehre/lvplan:rw', 'sync' => 'lehre/lvplan:rw', ]); @@ -90,15 +89,15 @@ class Kalender extends FHCAPI_Controller public function getPlan() { - $this->_ci->form_validation->set_data($_GET); + $this->_ci->form_validation->set_data($_POST); $this->_ci->form_validation->set_rules('start_date',"start_date","required"); $this->_ci->form_validation->set_rules('end_date',"end_date","required"); if($this->_ci->form_validation->run() === FALSE) $this->terminateWithValidationErrors($this->_ci->form_validation->error_array()); - $start_date = $this->_ci->input->get('start_date', TRUE); - $end_date = $this->_ci->input->get('end_date', TRUE); + $start_date = $this->_ci->input->post('start_date', TRUE); + $end_date = $this->_ci->input->post('end_date', TRUE); $filter = $this->_checkFilter(self::ALLOWED_PLAN_FILTER); @@ -230,7 +229,7 @@ class Kalender extends FHCAPI_Controller public function getRaumvorschlag() { - $this->_ci->form_validation->set_data($_GET); + $this->_ci->form_validation->set_data($_POST); $filter = $this->_checkFilter(self::ALLOWED_ROOM_FILTER); $this->terminateWithSuccess($this->_ci->raumvorschlaglib->getVorschlaege($filter->kalender_id)); @@ -396,32 +395,6 @@ class Kalender extends FHCAPI_Controller $this->terminateWithSuccess(getData($result)); } - public function addReservierung() - { - $this->_ci->form_validation->set_data($_POST); - $this->_ci->form_validation->set_rules('titel',"titel","required"); - $this->_ci->form_validation->set_rules('beschreibung',"beschreibung","required"); - $this->_ci->form_validation->set_rules('ort_kurzbz',"ort_kurzbz","required"); - $this->_ci->form_validation->set_rules('start_date',"start_date","required"); - $this->_ci->form_validation->set_rules('end_date',"end_date","required"); - - if($this->_ci->form_validation->run() === FALSE) - $this->terminateWithValidationErrors($this->_ci->form_validation->error_array()); - - $titel = $this->_ci->input->post('titel', TRUE); - $beschreibung = $this->_ci->input->post('beschreibung', TRUE); - $ort_kurzbz = $this->_ci->input->post('ort_kurzbz', TRUE); - $start_date = $this->_ci->input->post('start_date', TRUE); - $end_date = $this->_ci->input->post('end_date', TRUE); - - - $result = $this->_ci->kalenderlib->addReservierung($titel, $beschreibung, $ort_kurzbz, $start_date, $end_date); - - if (isError($result)) - $this->terminateWithError(getError($result)); - - $this->terminateWithSuccess(getData($result)); - } private function _checkFilter($filters) { @@ -429,10 +402,10 @@ class Kalender extends FHCAPI_Controller $filter_object = new stdClass(); foreach ($filters as $filter) { - if ($this->_ci->input->get($filter)) + if ($this->_ci->input->post($filter)) { $filter_valid = true; - $filter_object->$filter = $this->_ci->input->get($filter); + $filter_object->$filter = $this->_ci->input->post($filter); } } diff --git a/application/controllers/api/frontend/v1/tempus/Reservierung.php b/application/controllers/api/frontend/v1/tempus/Reservierung.php index c1030d8ee..be22d96e9 100644 --- a/application/controllers/api/frontend/v1/tempus/Reservierung.php +++ b/application/controllers/api/frontend/v1/tempus/Reservierung.php @@ -158,7 +158,7 @@ class Reservierung extends FHCAPI_Controller $this->_ci->form_validation->set_data($_POST); $this->_ci->form_validation->set_rules('titel',"titel","required"); $this->_ci->form_validation->set_rules('beschreibung',"beschreibung","required"); - $this->_ci->form_validation->set_rules('ort_kurzbz',"ort_kurzbz","required"); + $this->_ci->form_validation->set_rules('ort_kurzbz[]',"ort_kurzbz","required"); $this->_ci->form_validation->set_rules('start_date',"start_date","required"); $this->_ci->form_validation->set_rules('end_date',"end_date","required"); diff --git a/application/libraries/KalenderLib.php b/application/libraries/KalenderLib.php index 95cff42ba..c4c72c167 100644 --- a/application/libraries/KalenderLib.php +++ b/application/libraries/KalenderLib.php @@ -345,12 +345,12 @@ class KalenderLib $data = $this->_ci->KalenderModel->load(); return $this->_mapEvents($data); } - public function getPlanForPlanner($start_date, $end_date, $ort = null, $uids = null, $stg = null) + public function getPlanForPlanner($start_date, $end_date, $ort = null, $uids = null, $studiengaenge = null) { $this->_getBasePlan($start_date, $end_date); if (!is_null($ort)) - $this->_ci->KalenderModel->db->where('tbl_kalender_ort.ort_kurzbz', $ort); + $this->_ci->KalenderModel->db->where_in('tbl_kalender_ort.ort_kurzbz', $ort); if (!is_null($uids)) { @@ -361,8 +361,33 @@ class KalenderLib $this->_ci->KalenderModel->db->group_end(); } - if (!is_null($stg)) - $this->_ci->KalenderModel->db->where('tbl_lehrveranstaltung.studiengang_kz', $stg); + if (!is_null($studiengaenge)) + { + + $this->_ci->KalenderModel->db->group_start(); + $first = true; + foreach ($studiengaenge as $studiengang) + { + if ($first) + $this->_ci->KalenderModel->db->group_start(); + else + { + $this->_ci->KalenderModel->db->or_group_start(); + } + $first = false; + + $this->_ci->KalenderModel->db->where('tbl_lehrveranstaltung.studiengang_kz', $studiengang['studiengang_kz']); + + if (isset($studiengang['semester'])) + $this->_ci->KalenderModel->db->where('tbl_lehrveranstaltung.semester', $studiengang['semester']); + + if (isset($studiengang['orgform_kurzbz'])) + $this->_ci->KalenderModel->db->where('tbl_lehrveranstaltung.orgform_kurzbz', $studiengang['orgform_kurzbz']); + + $this->_ci->KalenderModel->db->group_end(); + } + $this->_ci->KalenderModel->db->group_end(); + } $this->_ci->KalenderModel->db->where('NOT EXISTS ( SELECT 1 FROM lehre.tbl_kalender nachfolger @@ -828,10 +853,10 @@ class KalenderLib { $this->_ci->KalenderModel->addSelect('1'); $this->_ci->KalenderModel->addJoin('lehre.tbl_kalender_ort', 'kalender_id'); + $this->_ci->KalenderModel->db->where_in('ort_kurzbz', $ort_kurzbz); $reservierung_vorhanden = $this->_ci->KalenderModel->load(array ( 'von <=' => $end_date, 'bis >=' => $start_date, - 'ort_kurzbz' => $ort_kurzbz, )); if (hasData($reservierung_vorhanden) && !$this->_ci->permissionlib->isBerechtigt('lehre/reservierungAdvanced')) @@ -1085,12 +1110,20 @@ class KalenderLib } private function _addKalenderOrt($kalender_id, $ort_kurzbz) { - return $this->_ci->KalenderOrtModel->insert( - array ( - 'kalender_id' => $kalender_id, - 'ort_kurzbz' => $ort_kurzbz - ) - ); + foreach ((array) $ort_kurzbz as $ort) + { + $ortresult = $this->_ci->KalenderOrtModel->insert( + array ( + 'kalender_id' => $kalender_id, + 'ort_kurzbz' => $ort + ) + ); + + if (!isSuccess($ortresult)) + return $ortresult; + } + + return success(); } public function updateKalenderEvent($kalender_id, $ort_kurzbz = null, $start_time = null, $end_time = null) diff --git a/public/js/api/factory/tempus/coursepicker.js b/public/js/api/factory/tempus/coursepicker.js index 82e1a6965..92ff4fa6b 100644 --- a/public/js/api/factory/tempus/coursepicker.js +++ b/public/js/api/factory/tempus/coursepicker.js @@ -6,11 +6,11 @@ export default { params: { query } }; }, - getByStg(stg, studiensemester_kurzbz) { + getByStg(studiengaenge, studiensemester_kurzbz) { return { - method: 'get', + method: 'post', url: 'api/frontend/v1/tempus/coursepicker/getByStg', - params: { stg, studiensemester_kurzbz } + params: { studiengaenge, studiensemester_kurzbz } }; }, diff --git a/public/js/api/factory/tempus/info.js b/public/js/api/factory/tempus/info.js new file mode 100644 index 000000000..849b81545 --- /dev/null +++ b/public/js/api/factory/tempus/info.js @@ -0,0 +1,8 @@ +export default { + getStudiengaenge() { + return { + method: 'get', + url: '/api/frontend/v1/tempus/Info/getStudiengaenge', + }; + }, +}; diff --git a/public/js/api/factory/tempus/kalender.js b/public/js/api/factory/tempus/kalender.js index 5c0cda753..9d2746434 100644 --- a/public/js/api/factory/tempus/kalender.js +++ b/public/js/api/factory/tempus/kalender.js @@ -3,7 +3,7 @@ export default { getPlan(filter, start_date, end_date) { return { - method: 'get', + method: 'post', url: '/api/frontend/v1/tempus/Kalender/getPlan', params: { ...filter, start_date, end_date } }; @@ -112,7 +112,7 @@ export default { }, getRaumvorschlag(kalender_id) { return { - method: 'get', + method: 'post', url: '/api/frontend/v1/tempus/Kalender/getRaumvorschlag', params: { kalender_id } }; diff --git a/public/js/api/factory/tempus/studiengangtree.js b/public/js/api/factory/tempus/studiengangtree.js new file mode 100644 index 000000000..42412785d --- /dev/null +++ b/public/js/api/factory/tempus/studiengangtree.js @@ -0,0 +1,43 @@ +/** + * 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 . + */ + +export default { + get(path) { + let url = 'api/frontend/v1/lv/StgTree'; + if (path) + url += '/' + path; + return { + method: 'get', + url + }; + }, + favorites: { + get() { + return { + method: 'get', + url: 'api/frontend/v1/tempus/favorites' + }; + }, + set(favorites) { + return { + method: 'post', + url: 'api/frontend/v1/tempus/favorites/set', + params: { favorites } + }; + } + } +}; \ No newline at end of file diff --git a/public/js/components/Tempus/Coursepicker.js b/public/js/components/Tempus/Coursepicker.js index 1bd43b569..a358f3522 100644 --- a/public/js/components/Tempus/Coursepicker.js +++ b/public/js/components/Tempus/Coursepicker.js @@ -10,9 +10,9 @@ export default { draggable }, props: { - stg: { - type: [String, Number], - default: null, + studiengaenge: { + type: Array, + default: [], }, studiensemester: { type: String, @@ -77,23 +77,33 @@ export default { } }, watch: { - stg(val) { - this.searchparam = ''; - this.loadCoursesByStg(val); + studiengaenge: { + deep: true, + handler(val) { + this.searchparam = ''; + this.loadCoursesByStg(val); + } }, studiensemester() { - if (this.stg) - this.loadCoursesByStg(this.stg); + if (this.studiengaenge) + this.loadCoursesByStg(this.studiengaenge); }, }, methods: { async loadCoursesByStg(stg) { - if (!stg) { + if (stg.length <= 0) + { this.allCourses = []; return; } - this.$api.call(ApiCoursePicker.getByStg(this.stg, this.studiensemester)) + let payload = stg.map(({ studiengang_kz, semester, orgform_kurzbz }) => ({ + studiengang_kz, + semester, + orgform_kurzbz + })); + + this.$api.call(ApiCoursePicker.getByStg(payload, this.studiensemester)) .then(result => { this.allCourses = result.data.map(e => ({ lehreinheit_id: e.lehreinheit_id, @@ -161,7 +171,7 @@ export default { }, reload() { - this.loadCoursesByStg(this.stg); + this.loadCoursesByStg(this.studiengaenge); }, toggleMultiWeek(course) { @@ -191,7 +201,7 @@ export default { @@ -218,7 +228,7 @@ export default { -
+
Keine Lehreinheiten Wähle einen Studiengang, um Lehreinheiten anzuzeigen.
diff --git a/public/js/components/Tempus/Filters/LectureSelection.js b/public/js/components/Tempus/Filters/LectureSelection.js new file mode 100644 index 000000000..a25856b86 --- /dev/null +++ b/public/js/components/Tempus/Filters/LectureSelection.js @@ -0,0 +1,55 @@ +export default { + name: "LectureSelection", + props: { + lecturers: { + type: Array, + required: true + } + }, + emits: ['remove'], + template: ` +
+
+
+ Lektoren + +
+
+
+ {{ l.label }} + +
+ +
+
+ + Plan +
+
+ + Zeitsperren +
+
+ + Zeitwünsche +
+
+
+
+
+ ` +} \ No newline at end of file diff --git a/public/js/components/Tempus/Filters/RoomSelection.js b/public/js/components/Tempus/Filters/RoomSelection.js new file mode 100644 index 000000000..e0344b735 --- /dev/null +++ b/public/js/components/Tempus/Filters/RoomSelection.js @@ -0,0 +1,55 @@ +export default { + name: "RoomSelection", + props: { + rooms: { + type: Array, + required: true + } + }, + emits: ['update:rooms'], + methods: { + removeRoom(ort_kurzbz) + { + if (ort_kurzbz == null) + { + this.$emit('update:rooms', []); + } + else + { + this.$emit('update:rooms', this.rooms.filter(room => room.ort_kurzbz !== ort_kurzbz)); + } + } + }, + template: ` +
+
+ Räume + +
+
    +
  • + {{ room.ort_kurzbz }} + +
  • +
+
+ ` +} \ No newline at end of file diff --git a/public/js/components/Tempus/Filters/VerbandSelection.js b/public/js/components/Tempus/Filters/VerbandSelection.js new file mode 100644 index 000000000..ec51d563a --- /dev/null +++ b/public/js/components/Tempus/Filters/VerbandSelection.js @@ -0,0 +1,68 @@ +export default { + name: "VerbandSelection", + props: { + studiengaenge: { + type: Array, + required: true + }, + studiengaengeAll: { + type: Array, + default: () => [] + } + }, + emits: ['update:studiengaenge'], + methods: { + removeStg(stg_kz, semester, orgform_kurzbz) + { + if (stg_kz == null) + { + this.$emit('update:studiengaenge', []); + } + else + { + this.$emit('update:studiengaenge', this.studiengaenge.filter(studiengang => !(studiengang.studiengang_kz === stg_kz && studiengang.semester === semester && studiengang.orgform_kurzbz === orgform_kurzbz))); + } + }, + stgLabel(stg) + { + let found = this.studiengaengeAll.find(s => s.studiengang_kz == stg.studiengang_kz); + let name = found?.name ?? stg.studiengang_kz; + + if (stg.orgform_kurzbz) + return `${name} - ${stg.orgform_kurzbz}`; + + return stg.semester ? `${name} - ${stg.semester}. Semester` : name; + } + }, + template: ` +
+
+ Studiengänge + +
+
    +
  • + {{ stgLabel(studiengang) }} + +
  • +
+
+ ` +} \ No newline at end of file diff --git a/public/js/components/Tempus/Filters/searchbarOptions.js b/public/js/components/Tempus/Filters/searchbarOptions.js new file mode 100644 index 000000000..42150ed41 --- /dev/null +++ b/public/js/components/Tempus/Filters/searchbarOptions.js @@ -0,0 +1,50 @@ +export function getTempusSearchbarOptions(self) +{ + return { + origin: 'tempus', + cssclass: "position-relative", + calcheightonly: true, + types: [ + //"student", + "raum", + "mitarbeiter", + "mitarbeiter_ohne_zuordnung" + ], + actions: { + raum: { + defaultaction: { + type: "function", + action: self.setOrt + }, + childactions: [ + { + label: "zum Filter hinzufügen", + icon: "fas fa-plus", + type: "function", + action: (data) => { + self.addToFilter(data, 'ort'); + } + }, + ] + }, + employee: { + defaultaction: { + type: "function", + action: (data) => { + self.setEmp(data); + } + }, + childactions: [ + { + label: "zum Filter hinzufügen", + icon: "fas fa-plus", + type: "function", + action: (data) => { + self.addToFilter(data, 'mitarbeiter'); + } + }, + ] + }, + } + }; +} \ No newline at end of file diff --git a/public/js/components/Tempus/LectureSelection.js b/public/js/components/Tempus/LectureSelection.js deleted file mode 100644 index 5b223fff4..000000000 --- a/public/js/components/Tempus/LectureSelection.js +++ /dev/null @@ -1,44 +0,0 @@ -import FormInput from '../Form/Input.js'; - -export default { - name: "LectureSelection", - props: { - lecturers: { - type: Array, - required: true - } - }, - emits: ['remove'], - template: ` -
-
-
- {{ l.label }} - -
- -
-
- - Plan -
-
- - Zeitsperren -
-
- - Zeitwünsche -
-
-
-
- ` -} \ No newline at end of file diff --git a/public/js/components/Tempus/Reservierung.js b/public/js/components/Tempus/Reservierung.js index 80a309915..c0fe64aba 100644 --- a/public/js/components/Tempus/Reservierung.js +++ b/public/js/components/Tempus/Reservierung.js @@ -7,11 +7,12 @@ export default { name: 'ReservierungModal', components: { BsModal, - FormInput + FormInput, + Multiselect: primevue.multiselect, }, props: { - ortKurzbz: { - type: String, + rooms: { + type: Array, default: null } }, @@ -22,7 +23,7 @@ export default { beschreibung: '', start: null, end: null, - ort_kurzbz: null, + selected_rooms: [], raeume_array: [], studiensemester_array: [], teilnehmer: [], @@ -126,7 +127,10 @@ export default { this.beschreibung = ''; this.start = start; this.end = end; - this.ort_kurzbz = this.ortKurzbz ?? null; + + let prop_orte = (this.rooms ?? []).map(r => r.ort_kurzbz); + this.selected_rooms = this.raeume_array.filter(raum => prop_orte.includes(raum.ort_kurzbz)); + this.teilnehmer = [{ uid: null, rolle: null }]; this.specialFinalGroups = [{ gid: null, studiensemester_kurzbz: null, lehrverband: null, gruppe_kurzbz: null, rolle: null }]; this.$refs.modal.show(); @@ -141,7 +145,7 @@ export default { ApiReservierung.addReservierung( this.titel, this.beschreibung, - this.ort_kurzbz, + this.selected_rooms.map(r => r.ort_kurzbz), luxon.DateTime.fromFormat(this.start, 'yyyy-MM-dd HH:mm').toISO(), luxon.DateTime.fromFormat(this.end, 'yyyy-MM-dd HH:mm').toISO(), this.teilnehmer.filter(t => t.uid && t.rolle).map(nehmer => ({ uid: nehmer.uid, rolle: nehmer.rolle })), @@ -200,24 +204,22 @@ export default { />
- {{ $p.t('global', 'raum') }} + - - + +
- -
this.renderers), appConfig: Vue.computed(() => this.appconfig), contextMenuActions: useContextMenuActions({ - openRaumauswahl: (orig) => this.openRaumauswahl(orig), - openResourcesAssignmentModal: (orig) => this.openResourcesAssignmentModal(orig), - openHistory: (orig) => this.openHistory(orig), - deleteEntry: (orig) => this.deleteEntry(orig), - syncToLecturer: (orig) => this.syncToLecturer(orig), - syncToStudent: (orig) => this.syncToStudent(orig), - }), - tableActions: { - deleteEntries: (origList) => this.deleteEntries(origList), - openRaumauswahl: (orig) => this.openRaumauswahl(orig), - }, + openRaumauswahl: (orig) => this.openRaumauswahl(orig), + openResourcesAssignmentModal: (orig) => + this.openResourcesAssignmentModal(orig), + openHistory: (orig) => this.openHistory(orig), + deleteEntry: (orig) => this.deleteEntry(orig), + syncToLecturer: (orig) => this.syncToLecturer(orig), + syncToStudent: (orig) => this.syncToStudent(orig), + }), + tableActions: { + deleteEntries: (origList) => this.deleteEntries(origList), + openRaumauswahl: (orig) => this.openRaumauswahl(orig), + }, }; }, data() { return { appconfig: {}, - currentMode: 'week', + currentMode: "week", configEndpoints: ApiTempusConfig, endpoint: ApiStudiengangTree, raumVorschlaege: [], selected: [], - searchbaroptions: { - origin: "tempus", - cssclass: "position-relative", - calcheightonly: true, - types: [ - //"student", - "raum", - "mitarbeiter", - "mitarbeiter_ohne_zuordnung", - ], - actions: { - raum: { - defaultaction: { - type: "function", - action: this.setOrt, - }, - childactions: [], - }, - employee: { - defaultaction: { - type: "function", - action: (data) => { - this.setEmp(data); - }, - }, - childactions: [], - }, - }, - }, lv_id: null, events: null, minimized: false, @@ -152,11 +130,12 @@ export default { view: "room", parkedKeys: new Set(), lecturers: [], + studiengaenge: [], + rooms: [], overlayCache: [], extraBackgrounds: [], lastRange: null, stg: null, - show_stg: null, semester: null, studiensemester_kurzbz: null, raumModal: { @@ -184,12 +163,13 @@ export default { }, currentlyUpdatedEvent: null, multiWeekModal: { - show: false, - lehreinheitId: null, - ortKurzbz: null, - startTime: null, - endTime: null, - }, + show: false, + lehreinheitId: null, + ortKurzbz: null, + startTime: null, + endTime: null, + }, + studiengaenge_all: [], }; }, computed: { @@ -219,8 +199,8 @@ export default { })); }, keyboardShortcuts() { - return getTempusShortcuts(this); - }, + return getTempusShortcuts(this); + }, dropdownParsedAvailableResources() { return this.resourcesAssignmentModal.availableResources .map((unit) => { @@ -232,6 +212,9 @@ export default { }) .sort((a, b) => a.label?.localeCompare(b.label)); }, + searchbaroptions() { + return getTempusSearchbarOptions(this); + }, }, methods: { async openRaumauswahl(orig) { @@ -260,33 +243,30 @@ export default { this.$refs.resourcesAssignmentModal.show(); }, - async deleteEntry(orig) - { - if (!orig?.kalender_id) - return; + async deleteEntry(orig) { + if (!orig?.kalender_id) return; - await this.deleteEntryCall(orig); - this.$refs.calendar.resetEventLoader(); - this.$refs.coursepicker.reload(); - }, - async deleteEntries(origList) - { - let validList = (origList ?? []).filter(orig => orig?.kalender_id); - if (!validList.length) - return; + await this.deleteEntryCall(orig); + this.$refs.calendar.resetEventLoader(); + this.$refs.coursepicker.reload(); + }, + async deleteEntries(origList) { + let validList = (origList ?? []).filter((orig) => orig?.kalender_id); + if (!validList.length) return; - await Promise.allSettled(validList.map(orig => this.deleteEntryCall(orig))); - this.$refs.calendar.resetEventLoader(); - this.$refs.coursepicker.reload(); - }, - async deleteEntryCall(orig) - { - await this.$api.call(ApiKalender.deleteEntry( - orig.kalender_id - )).then(() => { - this.$refs.parking.unpark({ type: orig.type, id: orig.kalender_id }); - }); - }, + await Promise.allSettled( + validList.map((orig) => this.deleteEntryCall(orig)), + ); + this.$refs.calendar.resetEventLoader(); + this.$refs.coursepicker.reload(); + }, + async deleteEntryCall(orig) { + await this.$api + .call(ApiKalender.deleteEntry(orig.kalender_id)) + .then(() => { + this.$refs.parking.unpark({ type: orig.type, id: orig.kalender_id }); + }); + }, async openHistory(orig) { if (!orig?.kalender_id) return; await this.$api @@ -297,17 +277,17 @@ export default { }); }, syncToLecturer(orig) { - if (!orig?.kalender_id) - return; - return this.$api.call(ApiKalender.syncToLecturer(orig.kalender_id)) - .then(() => this.$refs.calendar.resetEventLoader()); - }, - syncToStudent(orig) { - if (!orig?.kalender_id) - return; - return this.$api.call(ApiKalender.syncToStudent(orig.kalender_id)) - .then(() => this.$refs.calendar.resetEventLoader()); - }, + if (!orig?.kalender_id) return; + return this.$api + .call(ApiKalender.syncToLecturer(orig.kalender_id)) + .then(() => this.$refs.calendar.resetEventLoader()); + }, + syncToStudent(orig) { + if (!orig?.kalender_id) return; + return this.$api + .call(ApiKalender.syncToStudent(orig.kalender_id)) + .then(() => this.$refs.calendar.resetEventLoader()); + }, async selectRaum(ort_kurzbz) { const orig = this.raumModal; await this.$api @@ -323,43 +303,69 @@ export default { }, setOrt: function (data) { this.ort_kurzbz = data.ort_kurzbz; - this.$refs.calendar.resetEventLoader(); + this.rooms = [{ ort_kurzbz: data.ort_kurzbz }]; }, onSelectVerbandAndClose(payload) { this.onSelectVerband(payload); bootstrap.Offcanvas.getOrCreateInstance(this.$refs.verbandMenu).hide(); }, - onSelectVerband({ link, name }) { - let stg = null; - let semester = null; - this.show_stg = name; - if (typeof link === "number") stg = link; - else if (typeof link === "string") { - [stg, semester] = link.split("/"); + onSelectVerband({ link, studiengang_kz, semester, orgform_kurzbz, name }) { + if (orgform_kurzbz) { + semester = null; + } else if (typeof link === "string") { + [studiengang_kz, semester] = link.split("/"); } - this.stg = stg; - if (semester !== null) this.semester = semester; - this.$refs.calendar.resetEventLoader(); + let exists = this.studiengaenge.some( + (stg) => + stg.studiengang_kz == studiengang_kz && + stg.semester == semester && + stg.orgform_kurzbz === orgform_kurzbz, + ); + + if (!exists) { + this.studiengaenge = [ + ...this.studiengaenge, + { studiengang_kz, semester, orgform_kurzbz, name }, + ]; + } }, setEmp: function (data) { const uid = data.uid; const label = data.name; - if (!this.lecturers.some((l) => l.uid === uid)) { - this.lecturers.push({ + + for (const lect of this.lecturers) delete this.overlayCache[lect.uid]; + + this.lecturers = [ + { uid, label, showEvents: true, overlays: { blocks: true, wishes: true }, - }); - } + }, + ]; this.$refs.calendar.resetEventLoader(); if (this.lastRange) this.handleRange(this.lastRange); }, - jumpToKw(kw) { - const num = parseInt(kw); - if (!num) return; + addToFilter: function (filter, type) { + if (type === "ort") { + const ort_kurzbz = filter.ort_kurzbz; + if (!this.rooms.some((room) => room.ort_kurzbz === ort_kurzbz)) { + this.rooms.push({ ort_kurzbz }); + } + } else if (type === "mitarbeiter") { + const uid = filter.uid; + const label = filter.name; + if (!this.lecturers.some((l) => l.uid === uid)) { + this.lecturers.push({ + uid, + label, + showEvents: true, + overlays: { blocks: true, wishes: true }, + }); + } + } const date = luxon.DateTime.fromObject( { @@ -376,12 +382,11 @@ export default { this.calendarDate = newDate.toISODate(); }, handleChangeMode(newMode, newDate) { - if (!newMode) - return; - this.currentMode = newMode; - if (newDate && luxon.DateTime.isDateTime(newDate) && newDate.isValid) - this.calendarDate = newDate.toISODate(); - }, + if (!newMode) return; + this.currentMode = newMode; + if (newDate && luxon.DateTime.isDateTime(newDate) && newDate.isValid) + this.calendarDate = newDate.toISODate(); + }, toggleStatus(selected) { if (!selected || selected.length === 0) { this.visibleStatus = ["all"]; @@ -401,15 +406,24 @@ export default { return this.$api.call(ApiSearchbar.search(params)); }, getPromiseFunc(start, end) { - const hasRoom = !!this.ort_kurzbz; + const hasRooms = this.rooms.length > 0; const hasLektoren = this.lecturers.length > 0; - const hasStg = !!this.stg; + const hasStg = this.studiengaenge.length > 0; const filter = {}; - if (hasRoom) filter.ort = this.ort_kurzbz; - if (hasStg) filter.stg = this.stg; - if (hasLektoren) filter.uid = this.lecturers.map((l) => l.uid); + if (hasRooms) filter.ort = this.rooms.map((room) => room.ort_kurzbz); + if (hasStg) { + filter.stg = this.studiengaenge.map( + ({ studiengang_kz, semester, orgform_kurzbz }) => ({ + studiengang_kz, + semester, + orgform_kurzbz, + }), + ); + } + if (hasLektoren) + filter.uid = this.lecturers.map((lecture) => lecture.uid); let response = null; if (this.previewRole === "lektor") { @@ -432,7 +446,6 @@ export default { ]; } - if (response) { response[0].then((result) => { this.scrollToAndEmphasizeUpdatedEvent(); @@ -598,18 +611,24 @@ export default { const obj = item[0]; if (!obj?.type) return alert("Unbekannter Drop-Typ"); - if (payload.targetKalenderId) - { - if (obj.type !== 'lehreinheit' || !obj.orig?.lehreinheit_id) - return alert("Nur Lehreinheiten können einem Termin hinzugefügt werden"); + if (payload.targetKalenderId) { + if (obj.type !== "lehreinheit" || !obj.orig?.lehreinheit_id) + return alert( + "Nur Lehreinheiten können einem Termin hinzugefügt werden", + ); - return this.$api.call( - ApiKalender.addToKalenderEvent(payload.targetKalenderId, obj.orig.lehreinheit_id) - ).then(() => { - this.$refs.calendar.resetEventLoader(); - this.bcc.postMessage('dropped'); - }); - } + return this.$api + .call( + ApiKalender.addToKalenderEvent( + payload.targetKalenderId, + obj.orig.lehreinheit_id, + ), + ) + .then(() => { + this.$refs.calendar.resetEventLoader(); + this.bcc.postMessage("dropped"); + }); + } const dates = this._parseDates(start, end); if (!dates) return; @@ -634,28 +653,30 @@ export default { this.reservierungPending = true; this.$refs.reservierung.show(start_time, end_time); } else if (obj.type === "lehreinheit") { - - if (obj.multiweek) - { - this.openMultiWeekPreview( - obj.orig.lehreinheit_id, - this.ort_kurzbz ? this.ort_kurzbz : obj.orig.ort_kurzbz, - start_time, - end_time - ); - return; - } + if (obj.multiweek) { + this.openMultiWeekPreview( + obj.orig.lehreinheit_id, + this.ort_kurzbz ? this.ort_kurzbz : obj.orig.ort_kurzbz, + start_time, + end_time, + ); + return; + } return this.$api .call( ApiKalender.addKalenderEvent( obj.orig.lehreinheit_id, - this.ort_kurzbz ? this.ort_kurzbz : obj.orig.ort_kurzbz, + this.rooms.length + ? this.rooms.map((r) => r.ort_kurzbz) + : obj.orig.ort_kurzbz + ? [obj.orig.ort_kurzbz] + : [], start_time, end_time, ), ) - .then(result => result.data) + .then((result) => result.data) .then(() => { this.$refs.calendar.resetEventLoader(); this.$refs.coursepicker.reload(); @@ -682,7 +703,7 @@ export default { this.updateKalenderEventElementDisplay( obj.orig.kalender_id, luxon.DateTime.fromISO(obj.orig.isostart), - luxon.DateTime.fromISO(obj.orig.isoend) + luxon.DateTime.fromISO(obj.orig.isoend), ); this.$refs.calendar.clearOutCalendarEventEmphasis(); this.$refs.calendar.resetEventLoader(); @@ -693,20 +714,20 @@ export default { } }, openMultiWeekPreview(lehreinheit_id, ort_kurzbz, start_time, end_time) { - this.multiWeekModal.lehreinheitId = lehreinheit_id; - this.multiWeekModal.ortKurzbz = ort_kurzbz; - this.multiWeekModal.startTime = start_time; - this.multiWeekModal.endTime = end_time; - this.multiWeekModal.show = true; - }, - closeMultiWeekModal() { - this.multiWeekModal.show = false; - }, - onMultiWeekConfirmed() { - this.$refs.calendar.resetEventLoader(); - this.$refs.coursepicker.reload(); - this.bcc.postMessage('dropped'); - }, + this.multiWeekModal.lehreinheitId = lehreinheit_id; + this.multiWeekModal.ortKurzbz = ort_kurzbz; + this.multiWeekModal.startTime = start_time; + this.multiWeekModal.endTime = end_time; + this.multiWeekModal.show = true; + }, + closeMultiWeekModal() { + this.multiWeekModal.show = false; + }, + onMultiWeekConfirmed() { + this.$refs.calendar.resetEventLoader(); + this.$refs.coursepicker.reload(); + this.bcc.postMessage("dropped"); + }, handleRange(range) { if (!range?.start || !range?.end) return; @@ -818,18 +839,18 @@ export default { }, removeLecturer(uid) { - this.lecturers = this.lecturers.filter((lecture) => lecture.uid !== uid); - delete this.overlayCache[uid]; - this.$refs.calendar.resetEventLoader(); - }, - clearOrt() { - this.ort_kurzbz = null; - this.$refs.calendar.resetEventLoader(); - }, - clearStg() { - this.stg = null; - this.show_stg = null; - this.$refs.calendar.resetEventLoader(); + if (uid == null) { + for (const lect of this.lecturers) delete this.overlayCache[lect.uid]; + + this.lecturers = []; + this.$refs.calendar.resetEventLoader(); + } else { + this.lecturers = this.lecturers.filter( + (lecture) => lecture.uid !== uid, + ); + delete this.overlayCache[uid]; + this.$refs.calendar.resetEventLoader(); + } }, triggerSync() { this.$api @@ -938,6 +959,25 @@ export default { this.resourcesAssignmentModal.selectedAvailableResource = null; this.resourcesAssignmentModal.areFormButtonsDisplayed = false; }, + removeLecturer(uid) { + if (uid == null) { + for (const lect of this.lecturers) delete this.overlayCache[lect.uid]; + + this.lecturers = []; + this.$refs.calendar.resetEventLoader(); + } else { + this.lecturers = this.lecturers.filter( + (lecture) => lecture.uid !== uid, + ); + delete this.overlayCache[uid]; + this.$refs.calendar.resetEventLoader(); + } + }, + triggerSync() { + this.$api + .call(ApiKalender.sync()) + .then(this.$refs.calendar.resetEventLoader()); + }, async saveAssignedResourcesToCalendarItem(calenderItem, assignedResources) { let getSchedulableResourcesByCalendar = await this.$api.call( ApiOperationalResourceToCalender.storeResourcesToCalendarRelationship( @@ -1080,46 +1120,39 @@ export default { } }, onEventHover(event) { - this.hoveredEvent = event; - }, - onEventUnhover(event) - { - if (this.hoveredEvent?.kalender_id === event?.kalender_id) { - this.hoveredEvent = null; - } - }, - parkHoveredEvent() - { - const event = this.hoveredEvent; - if (!event?.kalender_id) - return; + this.hoveredEvent = event; + }, + onEventUnhover(event) { + if (this.hoveredEvent?.kalender_id === event?.kalender_id) { + this.hoveredEvent = null; + } + }, + parkHoveredEvent() { + const event = this.hoveredEvent; + if (!event?.kalender_id) return; - if (this.$refs.parking.isParked(event.kalender_id)) - { - this.$refs.parking.unpark({ type: event.type, id: event.kalender_id }); - } - else - { - this.$refs.parking.park(null, { - type: 'kalender', - id: event.kalender_id, - orig: event - }); - } - }, - deleteHoveredEvent() { - const event = this.hoveredEvent; - if (!event?.kalender_id) - return; + if (this.$refs.parking.isParked(event.kalender_id)) { + this.$refs.parking.unpark({ type: event.type, id: event.kalender_id }); + } else { + this.$refs.parking.park(null, { + type: "kalender", + id: event.kalender_id, + orig: event, + }); + } + }, + deleteHoveredEvent() { + const event = this.hoveredEvent; + if (!event?.kalender_id) return; - this.deleteEntry(event); - }, - clearHoveredEvent() { - this.hoveredEvent = null; - }, - focusSearchbar() { - this.$refs.searchbar?.$refs?.input.focus() - }, + this.deleteEntry(event); + }, + clearHoveredEvent() { + this.hoveredEvent = null; + }, + focusSearchbar() { + this.$refs.searchbar?.$refs?.input.focus(); + }, }, watch: { lecturers: { @@ -1128,6 +1161,15 @@ export default { this.rebuildExtraBackgrounds(); }, }, + rooms() { + this.$refs.calendar.resetEventLoader(); + }, + studiengaenge: { + deep: true, + handler() { + this.$refs.calendar.resetEventLoader(); + }, + }, "resourcesAssignmentModal.selectedAvailableResource": function (newVal) { if (!newVal) return; @@ -1180,42 +1222,12 @@ export default { () => 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; } }); - - this.$api.call(ApiTempusConfig.getHeader()).then((res) => { - this.visibleStatusArray = res.data.visible_status; - this.visibleStatus = ["all"]; - }); }, - template: /*html*/ ` -
- + template: ` +
+
-
-
- {{ ort_kurzbz }} - -
-
- -
-
- {{ show_stg }} - -
-
+ +
- +
@@ -1561,7 +1555,7 @@ export default { -
` +
`, }; diff --git a/system/dbupdate_3.4/46975_tempus.php b/system/dbupdate_3.4/46975_tempus.php index 3e2af991f..68d5cdcf8 100644 --- a/system/dbupdate_3.4/46975_tempus.php +++ b/system/dbupdate_3.4/46975_tempus.php @@ -235,3 +235,17 @@ if(!$result = @$db->db_query("SELECT kalender_id FROM lehre.tbl_kalender_event L echo '
lehre.tbl_kalender_event: neue Tabellen hinzugefuegt'; } + +// Add new name type in public.tbl_variablenname +if ($result = @$db->db_query("SELECT 1 FROM public.tbl_variablenname WHERE name = 'tempus_favorites';")) +{ + if ($db->db_num_rows($result) == 0) + { + $qry = "INSERT INTO public.tbl_variablenname(name, defaultwert) VALUES('tempus_favorites', null);"; + + if (!$db->db_query($qry)) + echo 'public.tbl_variablenname '.$db->db_last_error().'
'; + else + echo 'public.tbl_variablenname: Added name "tempus_favorites"
'; + } +}