Merge branch 'merge_C4_25999_61235_61730' into rc1_FHC4_C4

This commit is contained in:
Harald Bamberger
2025-08-05 16:32:50 +02:00
14 changed files with 942 additions and 402 deletions
+1
View File
@@ -62,6 +62,7 @@ $route['api/v1/ressource/[B|b]etriebsmittelperson/(:any)'] = 'api/v1/ressource/b
$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';
// Studierendenverwaltung List Routes
$route['api/frontend/v1/stv/[sS]tudents/inout'] = 'api/frontend/v1/stv/Students/index';
+39
View File
@@ -0,0 +1,39 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
/**
*
*/
class MyLvPlan 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()
{
$viewData = array(
'uid'=>getAuthUID(),
'timezone' => $this->config->item('timezone')
);
$this->load->view('CisRouterView/CisRouterView.php', ['viewData' => $viewData, 'route' => 'MyLvPlan']);
}
}
@@ -36,9 +36,12 @@ class LvPlan extends FHCAPI_Controller
'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
]);
$this->load->library('LogLib');
@@ -51,100 +54,95 @@ class LvPlan extends FHCAPI_Controller
));
$this->load->library('form_validation');
//load models
$this->load->model('ressource/Stundenplan_model', 'StundenplanModel');
$this->load->model('ressource/Reservierung_model', 'ReservierungModel');
}
//------------------------------------------------------------------------------------------------------------------
// Public methods
/**
/**
* fetches LvPlan and Moodle events together
* @access public
*
*/
public function LvPlanEvents(){
public function LvPlanEvents()
{
$hasLv = $this->input->post('lv_id');
return $hasLv ? $this->eventsLv() : $this->eventsPersonal();
}
/**
* fetches LvPlan, Moodle and Ferien events together for the logged in user
*
* @access public
*/
public function eventsPersonal()
{
$this->load->library('StundenplanLib');
// form validation
$this->load->library('form_validation');
$this->form_validation->set_data($_GET);
$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() === FALSE)
if (!$this->form_validation->run())
$this->terminateWithValidationErrors($this->form_validation->error_array());
// storing the get parameter in local variables
$start_date = $this->input->get('start_date', TRUE);
$end_date = $this->input->get('end_date', TRUE);
$lv_id = $this->input->get('lv_id', TRUE);
// storing the post parameter in local variables
$start_date = $this->input->post('start_date', true);
$end_date = $this->input->post('end_date', true);
$res_lvplan_events = $this->stundenplanlib->getStundenplan($start_date,$end_date,$lv_id);
$lvplan_events = $this->getDataOrTerminateWithError($res_lvplan_events);
if( is_null($lvplan_events) || isEmptyArray($lvplan_events) )
{
$lvplan_events = array();
}
// fetching lvplan events
$result = $this->stundenplanlib->getEventsUser($start_date, $end_date);
$lvplanEvents = $this->getDataOrTerminateWithError($result);
// fetching moodle events
$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) {
return $moodle_events;
},
[
'start_date' => $start->format('c'),
'end_date' => $end->format('c'),
'username' => getAuthUID()
]
);
$moodleEvents = $this->fetchMoodleEvents($start_date, $end_date);
$lvAndMoodleEvents = array_merge($lvplan_events,$moodle_events);
// fetching ferien events
$ferienEvents = $this->fetchFerienEvents($start_date, $end_date);
$this->load->model('education/Studentlehrverband_model','StudentLehrverbandModel');
$this->load->model('organisation/Studiensemester_model','StudiensemesterModel');
$current_Studiensemester = $this->StudiensemesterModel->getByDate($start_date);
$current_Studiensemester = $this->getDataOrTerminateWithError($current_Studiensemester);
$current_Studiensemester = current($current_Studiensemester)->studiensemester_kurzbz;
$studiengang = $this->StudentLehrverbandModel->loadWhere(["student_uid"=>getAuthUID(),"studiensemester_kurzbz"=>$current_Studiensemester]);
$studiengang = $this->getDataOrTerminateWithError($studiengang);
if(!empty($studiengang)){
$studiengang = current($studiengang)->studiengang_kz;
}else{
$studiengang = 0;
}
$this->terminateWithSuccess(array_merge(
$lvplanEvents,
$moodleEvents,
$ferienEvents
));
}
$ferienEvents = $this->stundenplanlib->fetchFerienTageEvents($start_date, $end_date, $studiengang);
$ferienEvents = $this->getDataOrTerminateWithError($ferienEvents);
$allEvents = array_merge($lvAndMoodleEvents,$ferienEvents);
// sort array with moodle events first
usort($lvAndMoodleEvents, function($a, $b){
if ($a->type === 'moodle' && $b->type !== 'moodle') {
return -1;
} elseif ($a->type !== 'moodle' && $b->type === 'moodle') {
return 1;
} elseif ($a->type === 'ferien' && ($b->type !== 'moodle' && $b->type !== 'ferien')) {
return -1;
} elseif (($a->type !== 'ferien' && $a->type !== 'moodle') && $b->type === 'ferien') {
return 1;
} else {
return 0;
}
});
/**
* fetches LvPlan and Ferien events together for the lv
*
* @access public
*/
public function eventsLv()
{
$this->load->library('StundenplanLib');
$this->terminateWithSuccess($allEvents);
// 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('lv_id', "lv_id", "required|integer");
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);
$lv_id = $this->input->post('lv_id', true);
// fetching lvplan events
$result = $this->stundenplanlib->getEventsLv($lv_id, $start_date, $end_date);
$lvplanEvents = $this->getDataOrTerminateWithError($result);
// fetching ferien events
$ferienEvents = $this->fetchFerienEvents($start_date, $end_date);
$this->terminateWithSuccess(array_merge(
$lvplanEvents,
$ferienEvents
));
}
//TODO: delete this function if we don't use the old calendar export endpoints anymore
@@ -193,9 +191,6 @@ class LvPlan extends FHCAPI_Controller
*/
public function getRoomplan()
{
// form validation
$this->load->library('form_validation');
$this->form_validation->set_rules('ort_kurzbz', "Ort", "required");
$this->form_validation->set_rules('start_date', "start_date", "required");
$this->form_validation->set_rules('end_date', "end_date", "required");
@@ -228,9 +223,6 @@ class LvPlan extends FHCAPI_Controller
*/
public function getReservierungen($ort_kurzbz = null)
{
//form validation
$this->load->library('form_validation');
$this->form_validation->set_rules('start_date', "StartDate", "required");
$this->form_validation->set_rules('end_date', "EndDate", "required");
@@ -259,6 +251,112 @@ class LvPlan extends FHCAPI_Controller
$this->terminateWithSuccess($result);
}
/**
* get details for a lv
* @access public
*
* @param integer $lehrveranstaltung_id
* @return void
*/
public function getLv($lehrveranstaltung_id)
{
if (!$lehrveranstaltung_id && $lehrveranstaltung_id !== 0 && $lehrveranstaltung_id !== '0')
return show_404();
// Load Phrases
$this->loadPhrases(['lehre']);
// Validation
$this->form_validation->set_data([
'lehrveranstaltung_id' => $lehrveranstaltung_id
]);
$this->form_validation->set_rules('lehrveranstaltung_id', $this->p->t('lehre', 'lehrveranstaltung_id'), 'integer');
if (!$this->form_validation->run())
$this->terminateWithValidationErrors($this->form_validation->error_array());
// Get Data
$this->load->model('education/Lehrveranstaltung_model', 'LehrveranstaltungModel');
$result = $this->LehrveranstaltungModel->load($lehrveranstaltung_id);
$result = $this->getDataOrTerminateWithError($result);
return $this->terminateWithSuccess(current($result));
}
/**
* fetch moodle events
*
* @param string $start_date
* @param string $end_date
* @return array
*/
private function fetchMoodleEvents($start_date, $end_date)
{
$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) {
return $moodle_events;
},
[
'start_date' => $start->format('c'),
'end_date' => $end->format('c'),
'username' => getAuthUID()
]
);
return $moodle_events;
}
/**
* fetch ferien events
*
* @param string $start_date
* @param string $end_date
* @return array
*/
private function fetchFerienEvents($start_date, $end_date)
{
$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(),
"studiensemester_kurzbz" => $studentsemester_kurzbz
]);
$studiengang = $this->getDataOrTerminateWithError($studiengang);
if ($studiengang)
$studiengang_kz = current($studiengang)->studiengang_kz;
else
$studiengang_kz = 0;
} else {
$studiengang_kz = 0;
}
$ferienEvents = $this->stundenplanlib->fetchFerienTageEvents($start_date, $end_date, $studiengang_kz);
return $this->getDataOrTerminateWithError($ferienEvents);
}
}
+242 -181
View File
@@ -8,125 +8,177 @@ use \DateTimeZone as DateTimeZone;
use \DateInterval as DateInterval;
use \DatePeriod as DatePeriod;
class StundenplanLib{
class StundenplanLib
{
private $_ci; // Code igniter instance
/**
* fetches Stundenplan events from a UID and start/end date
* @access public
* fetches Stundenplan events for the loggedin user between start and end
* or for a lv
*
* @param string $start
* @param string $end
* @param string|null $lehrveranstaltung_id
* @return stdClass
* @access public
*/
public function getStundenplan($start_date, $end_date, $lv_id = null){
public function getStundenplan($start, $end, $lehrveranstaltung_id = null)
{
if (!$lehrveranstaltung_id && $lehrveranstaltung_id !== 0)
return $this->getEventsUser($start, $end);
return $this->getEventsLv($lehrveranstaltung_id, $start, $end);
}
/**
* fetches Stundenplan events for the loggedin user between start and end
*
* @param string $start
* @param string $end
* @return stdClass
* @access public
*/
public function getEventsUser($start, $end)
{
$this->_ci =& get_instance();
// Load Config
$this->_ci->load->config('calendar');
$this->_ci->load->model('ressource/Mitarbeiter_model', 'MitarbeiterModel');
$this->_ci->load->model('ressource/Mitarbeiter_model','MitarbeiterModel');
$this->_ci->load->model('organisation/Studiensemester_model','StudiensemesterModel');
$this->_ci->load->model('education/Studentlehrverband_model', 'StudentlehrverbandModel');
$this->_ci->load->model('person/Benutzergruppe_model','BenutzergruppeModel');
$this->_ci->load->model('ressource/Stundenplan_model', 'StundenplanModel');
$student_uid = getAuthUID();
if(is_null($student_uid))
{
$uid = getAuthUID();
if (is_null($uid))
return error("No UID");
}
$semester_range = $this->studienSemesterErmitteln($start_date,$end_date);
if(isError($semester_range))
{
return error(getData($semester_range));
}
$is_mitarbeiter = getData($this->_ci->MitarbeiterModel->isMitarbeiter($uid));
if ($is_mitarbeiter)
return $this->getEventsEmployee($uid, $start, $end);
return $this->getEventsStudent($uid, $start, $end);
}
/**
* fetches Stundenplan events for a student between start and end
*
* @param string $student_uid
* @param string $start
* @param string $end
* @return stdClass
* @access public
*/
public function getEventsStudent($student_uid, $start, $end)
{
$this->_ci =& get_instance();
$this->_ci->load->model('ressource/Stundenplan_model', 'StundenplanModel');
$semester_range = $this->studienSemesterErmitteln($start, $end);
if (isError($semester_range))
return $semester_range;
$semester_range = getData($semester_range);
$this->sortStudienSemester($semester_range);
$function_error = $this->applyLoadUeberSemesterHaelfte($semester_range);
if(!is_null($function_error)){
if ($function_error)
return $function_error;
}
if($lv_id) { // fetch Stundenplan for lva, irrelevant of who is requesting it (for now)
// getting the gruppen_kurzbz of the student in the different studiensemester
$benutzer_gruppen = $this->fetchBenutzerGruppenFromStudiensemester($student_uid, $semester_range);
if (isError($benutzer_gruppen))
return $benutzer_gruppen;
$benutzer_gruppen = getData($benutzer_gruppen);
$stundenplan_data = $this->_ci->StundenplanModel->getStundenplanLVA($start_date, $end_date, $lv_id);
if(isError($stundenplan_data))
{
return error(getData($stundenplan_data));
}
$stundenplan_data = getData($stundenplan_data) ?? [];
$function_error = $this->expand_object_information($stundenplan_data);
if(!is_null($function_error)){
return $function_error;
}
// query lv itself in case its Stundenplan is being queried and it has no entries
$this->_ci->load->model('education/Lehrveranstaltung_model','LehrveranstaltungModel');
$lv_result = $this->_ci->LehrveranstaltungModel->load($lv_id);
if(isError($lv_result))
{
return error(getData($lv_result));
}
$lv = getData($lv_result)[0];
return success($stundenplan_data);
}
// getting the student_lehrverbaende of the student in the different studiensemester
$student_lehrverband = $this->fetchStudentlehrverbandFromStudiensemester($student_uid, $semester_range);
if (isError($student_lehrverband))
return $student_lehrverband;
$student_lehrverband = getData($student_lehrverband);
$is_mitarbeiter = getData($this->_ci->MitarbeiterModel->isMitarbeiter($student_uid));
if($is_mitarbeiter)
{
$stundenplan_data = $this->_ci->StundenplanModel->getStundenplanMitarbeiter($start_date, $end_date, $student_uid);
if(isError($stundenplan_data))
{
return error(getData($stundenplan_data));
}
$stundenplan_data = getData($stundenplan_data) ?? [];
$function_error = $this->expand_object_information($stundenplan_data);
if(!is_null($function_error)){
return error($function_error);
}
return success($stundenplan_data);
} else {
// getting the gruppen_kurzbz of the student in the different studiensemester
$benutzer_gruppen = $this->fetchBenutzerGruppenFromStudiensemester($semester_range);
if(isError($benutzer_gruppen))
{
return error(getData($benutzer_gruppen));
}
$benutzer_gruppen = getData($benutzer_gruppen);
// getting the student_lehrverbaende of the student in the different studiensemester
$student_lehrverband = $this->fetchStudentlehrverbandFromStudiensemester($semester_range);
if(isError($student_lehrverband))
{
return error(getData($student_lehrverband));
}
$student_lehrverband = getData($student_lehrverband);
$stundenplan_query = $this->_ci->StundenplanModel->getStundenplanQuery($start_date, $end_date, $semester_range, $benutzer_gruppen, $student_lehrverband);
if(!$stundenplan_query)
{
return success([]);
}
$stundenplan_data = $this->_ci->StundenplanModel->stundenplanGruppierung($stundenplan_query);
if(isError($stundenplan_data))
{
return error(getData($stundenplan_data));
}
$stundenplan_data = getData($stundenplan_data) ?? [];
$function_error = $this->expand_object_information($stundenplan_data);
if(!is_null($function_error)){
return $function_error;
}
return success($stundenplan_data);
}
$stundenplan_query = $this->_ci->StundenplanModel->getStundenplanQuery(
$start,
$end,
$semester_range,
$benutzer_gruppen,
$student_lehrverband
);
if (!$stundenplan_query)
return success([]);
$stundenplan_data = $this->_ci->StundenplanModel->stundenplanGruppierung($stundenplan_query);
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);
}
/**
* fetches Stundenplan events for an employee between start and end
*
* @param string $uid
* @param string $start
* @param string $end
* @return stdClass
* @access public
*/
public function getEventsEmployee($uid, $start, $end)
{
$this->_ci =& get_instance();
$this->_ci->load->model('ressource/Stundenplan_model', 'StundenplanModel');
$stundenplan_data = $this->_ci->StundenplanModel->getStundenplanMitarbeiter($start, $end, $uid);
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);
}
/**
* fetches Stundenplan events for a LV between start and end
*
* @param integer $lehrveranstaltung_id
* @param string $start
* @param string $end
* @return stdClass
* @access public
*/
public function getEventsLv($lehrveranstaltung_id, $start, $end)
{
$this->_ci =& get_instance();
$this->_ci->load->model('ressource/Stundenplan_model', 'StundenplanModel');
$stundenplan_data = $this->_ci->StundenplanModel->getStundenplanLVA($start, $end, $lehrveranstaltung_id);
if (isError($stundenplan_data))
return $stundenplan_data;
$stundenplan_data = getData($stundenplan_data) ?? [];
$function_error = $this->expandObjectInformation($stundenplan_data);
if ($function_error)
return $function_error;
// query lv itself in case its Stundenplan is being queried and it has no entries
$this->_ci->load->model('education/Lehrveranstaltung_model', 'LehrveranstaltungModel');
$lv_result = $this->_ci->LehrveranstaltungModel->load($lehrveranstaltung_id);
if (isError($lv_result))
return $lv_result;
if (!hasData($lv_result))
return error('LV not found');
return success($stundenplan_data);
}
/**
@@ -152,7 +204,7 @@ class StundenplanLib{
if (isError($roomplan_data))
return $roomplan_data;
$this->expand_object_information($roomplan_data->retval);
$this->expandObjectInformation($roomplan_data->retval);
return $roomplan_data;
}
@@ -173,6 +225,8 @@ class StundenplanLib{
$this->_ci->load->config('calendar');
// Load Models
$this->_ci->load->model('ressource/Mitarbeiter_model', 'MitarbeiterModel');
$this->_ci->load->model('ressource/Reservierung_model', 'ReservierungModel');
$this->_ci->load->model('ressource/Stundenplan_model', 'StundenplanModel');
$is_mitarbeiter = getData($this->_ci->MitarbeiterModel->isMitarbeiter(getAuthUID()));
@@ -186,7 +240,7 @@ class StundenplanLib{
if (isError($reservierungen))
return $reservierungen;
$function_error = $this->expand_object_information($reservierungen->retval);
$function_error = $this->expandObjectInformation($reservierungen->retval);
if (!is_null($function_error))
return $function_error;
@@ -228,9 +282,15 @@ class StundenplanLib{
return success($lektoren);
}
public function expand_object_information($data){
public function expandObjectInformation($data)
{
$this->_ci =& get_instance();
// Load Config
$this->_ci->load->config('calendar');
// Load Model
$this->_ci->load->model('ressource/Stundenplan_model', 'StundenplanModel');
foreach ($data as $item)
{
$tz = new DateTimeZone($this->_ci->config->item('timezone'));
@@ -324,69 +384,64 @@ class StundenplanLib{
$ferienEvents = $this->_ci->FerienModel->execReadOnlyQuery("
SELECT *
FROM lehre.tbl_ferien
WHERE (bisdatum >= ? AND vondatum <= ?) AND (studiengang_kz = 0 OR studiengang_kz = ?)
",[$start_date, $end_date, $studiengang_kz]);
WHERE (bisdatum >= ? AND vondatum < ?) AND (studiengang_kz = 0 OR studiengang_kz = ?)
", [$start_date, $end_date, $studiengang_kz]);
if (isError($ferienEvents)) {
return error(getData($ferienEvents));
}
if (isError($ferienEvents))
return $ferienEvents;
$ferienEvents = getData($ferienEvents);
if(is_array($ferienEvents) && count($ferienEvents) > 0){
$ferienEvents = array_map(function($event){
$event_start = new DateTime($event->vondatum);
$event_end = new DateTime($event->bisdatum);
$event_end->modify('+1 day');
$interval = new DateInterval('P1D');
$period = new DatePeriod($event_start, $interval, $event_end);
$event->dates = iterator_to_array($period);
return $event;
}, $ferienEvents);
$start_date = new DateTime($start_date);
$start_date->setTime(0, 0, 0);
$end_date = new DateTime($end_date);
$end_date->setTime(23, 59, 59);
$ferienEventsFlattened=[];
foreach($ferienEvents as $ferien_event){
foreach($ferien_event->dates as $date){
if ($date < $start_date || $date > $end_date)
continue;
$event = new stdClass();
$event->bezeichnung = $ferien_event->bezeichnung;
$event->datum = $date->format('Y-m-d');
$event->type = 'ferien';
$ferienEventsFlattened[] = $event;
}
};
$today=new DateTime();
$ferienEventsFlattened = array_map(function($event) use($today, $tz){
$ferien_event = (object) array(
'type' => 'ferien',
'beginn' => $today->format('H:i:s'),
'ende' => $today->format('H:i:s'),
'isostart' => (new DateTime($event->datum . ' 00:00:00', $tz))->format('c'),
'isoend' => (new DateTime($event->datum . ' 23:59:59', $tz))->format('c'),
'allDayEvent' => true,
'datum' => $event->datum,
'topic' => $event->bezeichnung,
'titel' => $event->bezeichnung,
'farbe' => '00689E'
);
return $ferien_event;
}, $ferienEventsFlattened);
return success($ferienEventsFlattened);
}
else{
if (!$ferienEvents)
return success([]);
}
$ferienEvents = array_map(function ($event) {
$event_start = new DateTime($event->vondatum);
$event_end = new DateTime($event->bisdatum);
$event_end->modify('+1 day');
$interval = new DateInterval('P1D');
$period = new DatePeriod($event_start, $interval, $event_end);
$event->dates = iterator_to_array($period);
return $event;
}, $ferienEvents);
$start_date = new DateTime($start_date);
$start_date->setTime(0, 0, 0);
$end_date = new DateTime($end_date);
$end_date->setTime(23, 59, 59);
$ferienEventsFlattened = [];
foreach ($ferienEvents as $ferien_event) {
foreach ($ferien_event->dates as $date) {
if ($date < $start_date || $date > $end_date)
continue;
$event = new stdClass();
$event->bezeichnung = $ferien_event->bezeichnung;
$event->datum = $date->format('Y-m-d');
$event->type = 'ferien';
$ferienEventsFlattened[] = $event;
}
};
$today = new DateTime();
$ferienEventsFlattened = array_map(function ($event) use ($today, $tz) {
$ferien_event = (object)array(
'type' => 'ferien',
'beginn' => $today->format('H:i:s'),
'ende' => $today->format('H:i:s'),
'isostart' => (new DateTime($event->datum . ' 00:00:00', $tz))->format('c'),
'isoend' => (new DateTime($event->datum . ' 23:59:59', $tz))->format('c'),
'allDayEvent' => true,
'datum' => $event->datum,
'topic' => $event->bezeichnung,
'titel' => $event->bezeichnung,
'farbe' => '00689E'
);
return $ferien_event;
}, $ferienEventsFlattened);
return success($ferienEventsFlattened);
}
// start of the private functions ########################################################################################################
@@ -437,8 +492,10 @@ class StundenplanLib{
private function fetchBenutzerGruppenFromStudiensemester($semester_range){
$student_uid = getAuthUID();
private function fetchBenutzerGruppenFromStudiensemester($student_uid, $semester_range)
{
$this->_ci->load->model('person/Benutzergruppe_model', 'BenutzergruppeModel');
$benutzer_gruppen = [];
// for each studiensemester fetch the benutzer gruppen and add them to an associate $bentuzer_gruppen array
/*
@@ -499,8 +556,10 @@ class StundenplanLib{
return success($benutzer_gruppen);
}
private function fetchStudentlehrverbandFromStudiensemester($semester_range){
$student_uid = getAuthUID();
private function fetchStudentlehrverbandFromStudiensemester($student_uid, $semester_range)
{
$this->_ci->load->model('person/Benutzergruppe_model', 'BenutzergruppeModel');
$student_lehrverband = [];
// for each studiensemester fetch the studentlehrverbaende and add them to an associate $student_lehrverband array
/*
@@ -566,7 +625,10 @@ class StundenplanLib{
return success($student_lehrverband);
}
private function applyLoadUeberSemesterHaelfte(&$semester_range){
private function applyLoadUeberSemesterHaelfte(&$semester_range)
{
$this->_ci->load->model('organisation/Studiensemester_model', 'StudiensemesterModel');
/*
@var($semester_collection)
convert the array of studiensemester into an associative array with the studiensemester as the key
@@ -692,30 +754,29 @@ class StundenplanLib{
}
}
private function studienSemesterErmitteln($start_date,$end_date){
private function studienSemesterErmitteln($start_date, $end_date)
{
$this->_ci->load->model('organisation/Studiensemester_model', 'StudiensemesterModel');
// gets all studiensemester from the student from start_date to end_date
$semester_range = $this->_ci->StudiensemesterModel->getByDateRange($start_date,$end_date);
if(isError($semester_range))
{
return error(getData($semester_range));
}
$semester_range = array_map(
function($sem)
{
$semester_range = $this->_ci->StudiensemesterModel->getByDateRange($start_date, $end_date);
if (isError($semester_range))
return $semester_range;
$semester_range = array_map(
function ($sem) {
return $sem->studiensemester_kurzbz;
},
getData($semester_range) ?: []
);
// if no studiensemester is found for the given timespan, get the nearest studiensemester
if(count($semester_range) == 0)
if (count($semester_range) == 0)
{
$aktuelle_studiensemester = $this->_ci->StudiensemesterModel->getNearest();
if(isError($aktuelle_studiensemester))
{
return error(getData($aktuelle_studiensemester));
}
if (isError($aktuelle_studiensemester))
return $aktuelle_studiensemester;
$aktuelle_studiensemester = getData($aktuelle_studiensemester);
if (count($aktuelle_studiensemester) == 0) {
return error("No aktuelles semester");
@@ -723,8 +784,8 @@ class StundenplanLib{
$aktuelle_studiensemester = current($aktuelle_studiensemester)->studiensemester_kurzbz;
// push aktuelles semester in active semester array
array_push($semester_range, $aktuelle_studiensemester);
}
return success($semester_range);
}
}
+30 -30
View File
@@ -4,96 +4,96 @@
height: 100%;
}
/* Feiertag */
.feiertagEventContent {
/* Feiertage */
.cis-renderer-feiertage-calendar-event {
align-items: center;
color: var(--fhc-light);
}
.monthPageContainer .feiertagEventContent,
.weekPageContainer .feiertagEventContent,
.dayPageContainer .feiertagEventContent {
.monthPageContainer .cis-renderer-feiertage-calendar-event,
.weekPageContainer .cis-renderer-feiertage-calendar-event,
.dayPageContainer .cis-renderer-feiertage-calendar-event {
display: grid;
grid-template-columns: auto 1fr;
justify-items: center;
}
.listPageContainer .feiertagEventContent {
.listPageContainer .cis-renderer-feiertage-calendar-event {
display: flex;
justify-content: center;
}
.monthPageContainer .feiertagEventContent #ferienEventIcon {
.monthPageContainer .cis-renderer-feiertage-calendar-event .event-icon {
margin: 0 .5rem;
}
.weekPageContainer .feiertagEventContent #ferienEventIcon,
.dayPageContainer .feiertagEventContent #ferienEventIcon,
.listPageContainer .feiertagEventContent #ferienEventIcon {
.weekPageContainer .cis-renderer-feiertage-calendar-event .event-icon,
.dayPageContainer .cis-renderer-feiertage-calendar-event .event-icon,
.listPageContainer .cis-renderer-feiertage-calendar-event .event-icon {
margin: .5rem;
}
.listPageContainer .feiertagEventContent #ferienEventTitle {
.listPageContainer .cis-renderer-feiertage-calendar-event .event-title {
flex-grow: 1;
}
/* Lehreinheit */
.monthPageContainer .lehreinheitEventContent {
/* Reservierungen */
.monthPageContainer .calendar-event-default {
padding: 0!important;
}
.monthPageContainer .lehreinheitEventContent #lehreinheitEventHeader,
.monthPageContainer .lehreinheitEventContent #lehreinheitLektoren,
.monthPageContainer .lehreinheitEventContent #lektorEllipsis {
.monthPageContainer .calendar-event-default .event-time,
.monthPageContainer .calendar-event-default .event-lectors {
display: none!important;
}
.monthPageContainer .lehreinheitEventContent #lehreinheitEventText {
.monthPageContainer .calendar-event-default .event-text {
display: flex;
justify-content: space-evenly;
align-items: center;
}
.weekPageContainer .lehreinheitEventContent {
.weekPageContainer .calendar-event-default {
display: grid;
grid-template-columns: auto 1fr;
}
.weekPageContainer .lehreinheitEventContent #lehreinheitEventHeader {
.weekPageContainer .calendar-event-default .event-time {
border-inline-end: solid 1px var(--bs-secondary);
align-self: stretch;
align-content: center;
padding: .25em .5em .25em .25em;
margin-inline-end: .25rem;
}
.weekPageContainer .lehreinheitEventContent #lehreinheitEventText {
.weekPageContainer .calendar-event-default .event-text {
display: flex;
flex-direction: column;
justify-content: space-evenly;
align-items: center;
}
.dayPageContainer .lehreinheitEventContent,
.listPageContainer .lehreinheitEventContent {
.dayPageContainer .calendar-event-default,
.listPageContainer .calendar-event-default {
display: flex;
align-items: center;
}
.dayPageContainer .lehreinheitEventContent #lehreinheitEventHeader,
.listPageContainer .lehreinheitEventContent #lehreinheitEventHeader {
.dayPageContainer .calendar-event-default .event-time,
.listPageContainer .calendar-event-default .event-time {
align-content: center;
padding-inline-end: .5em;
border-inline-end: solid 1px;
margin-inline-end: .5em;
}
.dayPageContainer .lehreinheitEventContent #lehreinheitEventText,
.listPageContainer .lehreinheitEventContent #lehreinheitEventText {
.dayPageContainer .calendar-event-default .event-text,
.listPageContainer .calendar-event-default .event-text {
flex: 1 1 auto;
display: flex;
flex-wrap: wrap;
gap: .25em;
justify-content: center;
}
.dayPageContainer .lehreinheitEventContent #lehreinheitTopic,
.dayPageContainer .lehreinheitEventContent #lehreinheitOrt,
.listPageContainer .lehreinheitEventContent #lehreinheitTopic,
.listPageContainer .lehreinheitEventContent #lehreinheitOrt {
.dayPageContainer .calendar-event-default .event-topic,
.dayPageContainer .calendar-event-default .event-place,
.listPageContainer .calendar-event-default .event-topic,
.listPageContainer .calendar-event-default .event-place {
flex: 0 0 100%;
text-align: center;
}
.fhc-roominformation .lehreinheitEventContent #lehreinheitOrt {
.fhc-roominformation .calendar-event-default .event-place {
display: none;
}
+21 -2
View File
@@ -30,8 +30,21 @@ export default {
params: { start_date, end_date, lv_id }
};
},
eventsPersonal(start_date, end_date) {
return {
method: 'post',
url: '/api/frontend/v1/lvPlan/eventsPersonal',
params: { start_date, end_date }
};
},
eventsLv(lv_id, start_date, end_date) {
return {
method: 'post',
url: '/api/frontend/v1/lvPlan/eventsLv',
params: { lv_id, start_date, end_date }
};
},
getStunden() {
// TODO(chris): seems to be called from nowhere?
return {
method: 'get',
url: '/api/frontend/v1/LvPlan/Stunden'
@@ -65,7 +78,7 @@ export default {
},
LvPlanEvents(start_date, end_date, lv_id) {
return {
method: 'get',
method: 'post',
url: '/api/frontend/v1/LvPlan/LvPlanEvents',
params: {
start_date: start_date,
@@ -74,4 +87,10 @@ export default {
}
};
},
getLv(lehrveranstaltung_id) {
return {
method: 'get',
url: '/api/frontend/v1/LvPlan/getLv/' + lehrveranstaltung_id
};
}
};
+19 -36
View File
@@ -3,7 +3,8 @@ import PluginsPhrasen from '../../plugins/Phrasen.js';
import Theme from '../../plugin/Theme.js';
import contrast from '../../directives/contrast.js';
import {setScrollbarWidth} from "../../helpers/CssVarCalcHelpers.js";
import LvPlan, {DEFAULT_MODE_LVPLAN} from "../../components/Cis/LvPlan/LvPlan.js";
import LvPlan from "../../components/Cis/LvPlan/Lehrveranstaltung.js";
import MyLvPlan from "../../components/Cis/LvPlan/Personal.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";
@@ -154,10 +155,14 @@ const router = VueRouter.createRouter({
path: "/Cis/LvPlan/:lv_id(\\d+)",
name: "LvPlanOld",
component: LvPlan,
redirect: (to) => {
redirect(to) {
const route = Vue.unref(router.currentRoute);
const { mode, focus_date } = route.params; // keep mode and focus_date if available
return { // redirect to longer LvPlan url and map params
name: "LvPlan",
params: {
mode,
focus_date,
lv_id: to.params.lv_id
},
};
@@ -167,42 +172,20 @@ const router = VueRouter.createRouter({
path: `/Cis/LvPlan/:mode?/:focus_date?/:lv_id?`,
name: 'LvPlan',
component: LvPlan,
props: (route) => { // validate and set mode/focus date if for some reason missing
const validModes = ["Month", "Week", "Day"];
// check mode string
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_LVPLAN;
// default to today date if not provided or string forms invalid date
const d = new Date(route.params.focus_date)
const focus_date = !isNaN(d) ? route.params.focus_date : new Date().toISOString().split("T")[0];
// for consistency reasons format the props into one object but actually use a new name to we dont collide with
// existing viewData declaration written from codeigniter 3 into routerview tag
props(route) {
return {
propsViewData: {
mode,
focus_date,
lv_id: route.params.lv_id
}
propsViewData: route.params
};
}
},
{
path: `/Cis/MyLvPlan/:mode?/:focus_date?`,
name: 'MyLvPlan',
component: MyLvPlan,
props(route) {
return {
propsViewData: route.params
};
},
beforeEnter: (to, from, next) => {
// missing mode or focus_date -> set defaults
if (!to.params.mode || !to.params.focus_date) {
next({
name: "LvPlan",
params: {
mode: to.params.mode || DEFAULT_MODE_LVPLAN,
focus_date: to.params.focus_date || new Date().toISOString().split("T")[0],
lv_id: to.params.lv_id
}
});
} else {
next();
}
}
},
{
+3
View File
@@ -258,6 +258,9 @@ export default {
this.modalEvent.closeFn();
}
},
beforeUnmount() {
this.hideEventModal();
},
template: /* html */`
<div class="fhc-calendar-base h-100">
<base-draganddrop
@@ -0,0 +1,107 @@
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: 'LvPlanLehrveranstaltung',
components: {
FhcCalendar
},
props: {
viewData: Object, // NOTE(chris): this is inherited from router-view
propsViewData: Object
},
data() {
return {
lv: 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;
},
currentLv() {
if (isNaN(parseInt(this.propsViewData?.lv_id)))
return null;
return this.propsViewData.lv_id;
},
lvTitle() {
if (this.currentLv === null)
return '';
if (!this.lv)
return '';
if (this.$p.user_language.value === 'English')
return this.lv.bezeichnung_english;
return this.lv.bezeichnung;
}
},
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: "LvPlan",
params: {
mode,
focus_date,
lv_id: this.currentLv
}
});
},
getPromiseFunc(start, end) {
return [
this.$api.call(ApiLvPlan.eventsLv(this.propsViewData.lv_id, start.toISODate(), end.toISODate())),
this.$api.call(ApiLvPlan.getLvPlanReservierungen(start.toISODate(), end.toISODate()))
];
}
},
created() {
if (this.currentLv === null)
return;
this.$api
.call(ApiLvPlan.getLv(this.propsViewData?.lv_id))
.then(res => {
this.lv = res.data;
});
},
template: /*html*/`
<div class="cis-lvplan-personal d-flex flex-column h-100">
<h2>
{{ $p.t('lehre/stundenplan') }}
<span v-if="lvTitle" class="ps-3">
{{ lvTitle }}
</span>
</h2>
<hr>
<div v-if="currentLv === null || lv === false">
{{ $p.t('lehre/noLvFound') }}
</div>
<fhc-calendar
v-else-if="lv"
ref="calendar"
:timezone="viewData.timezone"
:get-promise-func="getPromiseFunc"
:date="currentDay"
:mode="currentMode"
@update:date="handleChangeDate"
@update:mode="handleChangeMode"
class="responsive-calendar"
/>
</div>`
};
+143
View File
@@ -0,0 +1,143 @@
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: 'LvPlanPersonal',
components: {
FhcCalendar
},
props: {
viewData: Object, // NOTE(chris): this is inherited from router-view
propsViewData: Object
},
data() {
return {
studiensemester_kurzbz: null,
studiensemester_start: null,
studiensemester_ende: null,
uid: 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;
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=student'
+ '&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: "MyLvPlan",
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.$api.call(ApiLvPlan.getLvPlanReservierungen(start.toISODate(), end.toISODate()))
];
}
},
created() {
this.$api
.call(ApiAuthinfo.getAuthUID())
.then(res => {
this.uid = res.data.uid;
});
},
template: /*html*/`
<div class="cis-lvplan-personal d-flex flex-column h-100">
<h2>
{{ $p.t('lehre/stundenplan') }}
<span v-if="studiensemester_kurzbz" class="ps-3">
{{ studiensemester_kurzbz }}
</span>
</h2>
<hr>
<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>`
};
@@ -7,8 +7,8 @@ export default {
},
},
template: `
<div class="feiertagEventContent " >
<i id="ferienEventIcon" class="fa-regular fa-calendar"></i>
<span id="ferienEventTitle" class="fw-bold text-center">{{event.titel}}</span>
</div>`,
<div class="cis-renderer-feiertage-calendar-event">
<i class="event-icon" class="fa-regular fa-calendar"></i>
<span class="event-title fw-bold text-center">{{ event.titel }}</span>
</div>`,
};
@@ -1,59 +1,92 @@
export default {
methods:{
convertTime: function ([hour, minute]) {
let date = new Date();
date.setHours(hour);
date.setMinutes(minute);
// returns date string as hh:mm
return date.toLocaleTimeString(this.$p.user_locale, { hour: '2-digit', minute: '2-digit', hour12: false });
},
},
computed:{
calendarEventTooltip: function(){
let lektorenEmpty = true;
let tooltipString = `${this.$p.t('global','uhrzeit')}: ${this.convertTime(this.event.beginn.split(":"))} / ${this.convertTime(this.event.ende.split(":")) }`;
tooltipString += `\n${this.$p.t('profilUpdate', 'topic')}: ${this.event.topic}`;
tooltipString += `${this.$p.t('person', 'ort')}: ${this.event.ort_kurzbz}`;
if(Array.isArray(this.event.lektor) && this.event.lektor.length > 0){
lektorenEmpty = false;
tooltipString += `\n${this.$p.t('lehre','lektor')}: `;
this.event.lektor.slice(0,3).forEach(lektor => {
tooltipString += `${lektor.kurzbz}\n`;
})
if(this.event.lektor.length > 3){
tooltipString += `${this.$p.t('lehre', 'weitereLektoren', [(this.event.lektor.length - 3)])}\n`;
}
}
if(lektorenEmpty){
tooltipString += "\n";
}
return tooltipString;
},
},
props:{
event: {
type:Object,
required:true,
type: Object,
required: true
}
},
computed:{
tooltipString() {
const tooltipArray = [];
tooltipArray.push([
this.$p.t('global/uhrzeit'),
[this.start, this.end].join(' - ')
].join(": "));
tooltipArray.push([
this.$p.t('profilUpdate/topic'),
this.event.topic
].join(": "));
tooltipArray.push([
this.$p.t('person/ort'),
this.event.ort_kurzbz
].join(": "));
this.event.lektor = [
this.event.lektor[0],
this.event.lektor[0],
this.event.lektor[0],
this.event.lektor[0],
this.event.lektor[0],
];
if (Array.isArray(this.event.lektor) && this.event.lektor.length > 0) {
if (this.event.lektor.length > 3) {
tooltipArray.push([
this.$p.t('lehre/lektor'),
this.event.lektor.slice(0, 3).map(lektor => lektor.kurzbz).join("\n")
+ "\n" + this.$p.t('lehre/weitereLektoren', [this.event.lektor.length - 3])
].join(": "));
} else {console.log(this.event.lektor);
tooltipArray.push([
this.$p.t('lehre/lektor'),
this.event.lektor.map(lektor => lektor.kurzbz).join("\n")
].join(": "));
}
}
return tooltipArray.join("\n");
},
start() {
return luxon.Duration
.fromISOTime(this.event.beginn)
.toISOTime({ suppressSeconds: true });
},
end() {
return luxon.Duration
.fromISOTime(this.event.ende)
.toISOTime({ suppressSeconds: true });
}
},
template: /*html*/`
<div class="lehreinheitEventContent h-100 w-100 p-1" @wheel.stop >
<div id="lehreinheitEventHeader" class="d-none d-xl-grid h-100 " v-if="!event.allDayEvent && event?.beginn && event?.ende" >
<span >{{convertTime(event.beginn.split(":"))}}</span>
<span >{{convertTime(event.ende.split(":"))}}</span>
<div
class="cis-renderer-lehreinheit-calendar-event calendar-event-default h-100 w-100 p-1"
@wheel.stop
>
<div
v-if="!event.allDayEvent && event?.beginn && event?.ende"
class="event-time d-none d-xl-grid h-100"
>
<span>{{ start }}</span>
<span>{{ end }}</span>
</div>
<div id="lehreinheitEventText" v-tooltip="calendarEventTooltip">
<span id="lehreinheitTopic">{{event.topic}}</span>
<span id="lehreinheitOrt">{{event.ort_kurzbz}}</span>
<span id="lehreinheitLektoren" v-for="(lektor,index) in event.lektor.slice(0,3)">
{{lektor.kurzbz}}
<div class="event-text" v-tooltip="tooltipString">
<span class="event-topic">{{ event.topic }}</span>
<span class="event-place">{{ event.ort_kurzbz }}</span>
<span
v-for="(lektor,index) in event.lektor.slice(0, 3)"
class="event-lectors"
>
{{ lektor.kurzbz }}
</span>
<span
v-if="event.lektor.length > 3"
class="event-lectors-plus"
>
... +{{ event.lektor.length - 3 }}
</span>
<span id="lektorEllipsis" class="fw-bold" v-if="event.lektor.length > 3">...+
{{event.lektor.length-3}}</span>
</div>
</div>
`,
@@ -1,30 +1,83 @@
export default {
methods: {
convertTime: function ([hour, minute]) {
let date = new Date();
date.setHours(hour);
date.setMinutes(minute);
// returns date string as hh:mm
return date.toLocaleTimeString(this.$p.user_locale, { hour: '2-digit', minute: '2-digit', hour12: false });
},
},
props: {
event: {
type: Object,
required: true,
},
required: true
}
},
template: `
<div class="lehreinheitEventContent h-100 w-100 p-1" >
<div id="lehreinheitEventHeader" class="h-100 " v-if="!event.allDayEvent && event?.beginn && event?.ende" >
<span class="small">{{convertTime(event.beginn.split(":"))}}</span>
<span class="small">{{convertTime(event.ende.split(":"))}}</span>
computed: {
tooltipString() {
const tooltipArray = [];
tooltipArray.push([
this.$p.t('global/uhrzeit'),
[this.start, this.end].join(' - ')
].join(": "));
tooltipArray.push([
this.$p.t('profilUpdate/topic'),
this.event.topic
].join(": "));
tooltipArray.push([
this.$p.t('person/ort'),
this.event.ort_kurzbz
].join(": "));
if (Array.isArray(this.event.lektor) && this.event.lektor.length > 0) {
if (this.event.lektor.length > 3) {
tooltipArray.push([
this.$p.t('lehre/lektor'),
this.event.lektor.slice(0, 3).map(lektor => lektor.kurzbz).join("\n")
+ "\n" + this.$p.t('lehre/weitereLektoren', [this.event.lektor.length - 3])
].join(": "));
} else {
tooltipArray.push([
this.$p.t('lehre/lektor'),
this.event.lektor.map(lektor => lektor.kurzbz).join("\n")
].join(": "));
}
}
return tooltipArray.join("\n");
},
start() {
return luxon.Duration
.fromISOTime(this.event.beginn)
.toISOTime({ suppressSeconds: true });
},
end() {
return luxon.Duration
.fromISOTime(this.event.ende)
.toISOTime({ suppressSeconds: true });
}
},
template: /* html */`
<div
class="cis-renderer-reservierungen-calendar-event calendar-event-default h-100 w-100 p-1"
>
<div
v-if="!event.allDayEvent && event?.beginn && event?.ende"
class="event-time d-grid h-100"
>
<span>{{ start }}</span>
<span>{{ end }}</span>
</div>
<div id="lehreinheitEventText">
<span>{{event.topic}}</span>
<span v-for="lektor in event.lektor">{{lektor.kurzbz}}</span>
<span>{{event.ort_kurzbz}}</span>
<div class="event-text" v-tooltip="tooltipString">
<span class="event-topic">{{ event.topic }}</span>
<span
v-for="lektor in event.lektor.slice(0, 3)"
class="event-lectors"
>
{{ lektor.kurzbz }}
</span>
<span
v-if="event.lektor.length > 3"
class="event-lectors-plus"
>
... +{{ event.lektor.length - 3 }}
</span>
<span class="event-place">{{ event.ort_kurzbz }}</span>
</div>
</div>
`,
@@ -34,7 +34,7 @@ export default {
start_time: function () {
if (!this.event.beginn)
return 'N/A';
if (!this.event.beginn instanceof Date) {
if (!(this.event.beginn instanceof Date)) {
return this.event.beginn;
}
return numberPadding(this.event.beginn.getHours()) + ":" + numberPadding(this.event.beginn.getMinutes());
@@ -42,7 +42,7 @@ export default {
end_time: function () {
if (!this.event.ende)
return 'N/A';
if (!this.event.ende instanceof Date) {
if (!(this.event.ende instanceof Date)) {
return this.event.ende;
}
return numberPadding(this.event.ende.getHours()) + ":" + numberPadding(this.event.ende.getMinutes());