mirror of
https://github.com/FH-Complete/FHC-Core.git
synced 2026-07-19 16:02:15 +00:00
Merge branch 'feature-25999/C4_cleanup' into feature-53416/stundenplan_eine_lva
# Conflicts: # public/js/apps/Cis/Stundenplan.js # public/js/components/DashboardWidget/Stundenplan.js
This commit is contained in:
@@ -52,7 +52,7 @@ class LvMenu extends FHCAPI_Controller
|
||||
$this->load->library("PermissionLib", null, 'PermissionLib');
|
||||
|
||||
$this->load->library("PhrasesLib");
|
||||
$this->loadPhrases(array('global'));
|
||||
$this->loadPhrases(array('global', 'lehre'));
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------------
|
||||
@@ -68,18 +68,12 @@ class LvMenu extends FHCAPI_Controller
|
||||
if(!isset($lvid) || !isset($studiensemester_kurzbz))
|
||||
$this->terminateWithError('Missing parameters', self::ERROR_TYPE_GENERAL);
|
||||
|
||||
// FH-Core Variables
|
||||
// ##########################################################################################
|
||||
require_once(FHCPATH.'include/phrasen.class.php');
|
||||
|
||||
// get the sprache
|
||||
$sprache = getUserLanguage();
|
||||
$p = new phrasen($sprache);
|
||||
//$p = $this->$p;
|
||||
|
||||
// get the user
|
||||
if (!$user=getAuthUID())
|
||||
$this->terminateWithError($p->t('global/nichtAngemeldet'));
|
||||
$this->terminateWithError($this->p->t('global', 'nichtAngemeldet'));
|
||||
|
||||
// check if is_lector
|
||||
$is_lector = false;
|
||||
@@ -209,39 +203,29 @@ class LvMenu extends FHCAPI_Controller
|
||||
|
||||
$menu = array();
|
||||
|
||||
//todo: digitale anwesenheiten sollte ein Events.php im config/ folder beinhalten
|
||||
//$this->fhc_menu_digitale_anwesenheiten($menu, $angemeldet, $studiengang_kz, $semester, $lvid, $angezeigtes_stsem, $p);
|
||||
|
||||
$this->fhc_menu_lvinfo($menu, $lvid, $studiengang_kz, $lektor_der_lv, $is_lector, $lehrfach_oe_kurzbz_arr, $p);
|
||||
$this->fhc_menu_lvinfo($menu, $lvid, $studiengang_kz, $lektor_der_lv, $is_lector, $lehrfach_oe_kurzbz_arr);
|
||||
|
||||
$this->fhc_menu_feedback($menu, $angemeldet, $lvid, $p);
|
||||
$this->fhc_menu_feedback($menu, $angemeldet, $lvid);
|
||||
|
||||
$this->fhc_menu_gesamtnote($menu, $angemeldet, $lvid, $lv, $is_lector, $angezeigtes_stsem, $p);
|
||||
$this->fhc_menu_gesamtnote($menu, $angemeldet, $lvid, $lv, $is_lector, $angezeigtes_stsem);
|
||||
|
||||
$this->fhc_menu_emailStudierende($menu, $user, $angemeldet, $lvid, $angezeigtes_stsem, $p);
|
||||
$this->fhc_menu_emailStudierende($menu, $user, $angemeldet, $lvid, $angezeigtes_stsem);
|
||||
|
||||
$this->fhc_menu_abmeldung($menu, $user, $is_lector, $lvid, $angezeigtes_stsem, $p);
|
||||
$this->fhc_menu_abmeldung($menu, $user, $is_lector, $lvid, $angezeigtes_stsem);
|
||||
|
||||
$this->fhc_menu_lehretools($menu, $lvid, $angezeigtes_stsem, $sprache);
|
||||
|
||||
$this->fhc_menu_anrechnungStudent($menu, $lvid, $angezeigtes_stsem, $p);
|
||||
$this->fhc_menu_anrechnungStudent($menu, $lvid, $angezeigtes_stsem);
|
||||
|
||||
$this->fhc_menu_anrechnungLector($menu, $angezeigtes_stsem, $p);
|
||||
$this->fhc_menu_anrechnungLector($menu, $angezeigtes_stsem);
|
||||
|
||||
// LEGACY FH-CORE MENU POINTS
|
||||
//$this->fhc_menu_notenliste($menu, $angemeldet, $is_lector, $lvid, $studiengang_kz, $angezeigtes_stsem, $kurzbz, $semester, $short_short_name, $p);
|
||||
//$this->fhc_menu_download($menu, $angemeldet, $user_is_allowed_to_upload, $rechte, $semester, $kurzbz, $studiengang_kz, $short_short_name, $short, $p);
|
||||
//$this->fhc_menu_semesterplan($menu, $angemeldet, $user_is_allowed_to_upload, $rechte, $lvid, $studiengang_kz, $kurzbz, $semester, $short_short_name, $p);
|
||||
//$this->fhc_menu_stundenupload($menu, $angemeldet, $lvid, $is_lector, $studiengang_kz, $kurzbz, $semester, $short, $short_short_name, $p);
|
||||
//$this->fhc_menu_pinboard($menu, $angemeldet, $is_lector, $studiengang_kz, $semester, $p);
|
||||
|
||||
|
||||
// Addons Menu Logic
|
||||
// ##########################################################################################
|
||||
|
||||
$params = [
|
||||
'sprache'=>$sprache,
|
||||
'p'=>$p,
|
||||
//'p'=>$p,
|
||||
'ci_p'=> $this->p,
|
||||
//'db'=>$db,
|
||||
'user'=>$user,
|
||||
@@ -301,7 +285,7 @@ class LvMenu extends FHCAPI_Controller
|
||||
}
|
||||
|
||||
|
||||
private function fhc_menu_digitale_anwesenheiten(&$menu, $angemeldet, $studiengang_kz, $semester, $lvid, $angezeigtes_stsem, $p){
|
||||
private function fhc_menu_digitale_anwesenheiten(&$menu, $angemeldet, $studiengang_kz, $semester, $lvid, $angezeigtes_stsem){
|
||||
|
||||
// DIGITALE ANWESENHEITEN
|
||||
if (CIS_LEHRVERANSTALTUNG_ANWESENHEIT_ANZEIGEN && $angemeldet) {
|
||||
@@ -310,7 +294,7 @@ class LvMenu extends FHCAPI_Controller
|
||||
(
|
||||
'id' => 'core_menu_digitale_anwesenheitslisten',
|
||||
'position' => '50',
|
||||
'name' => $p->t('lehre/digiAnw'),
|
||||
'name' => $this->p->t('lehre', 'digiAnw'),
|
||||
'c4_icon' => base_url('skin/images/button_kreuzerltool.png'),
|
||||
'c4_link' => base_url("index.ci.php/extensions/FHC-Core-Anwesenheiten/?stg_kz=$studiengang_kz&sem=$semester&lvid=$lvid&sem_kurzbz=$angezeigtes_stsem&nav=false"),
|
||||
'c4_linkList' => []
|
||||
@@ -318,7 +302,7 @@ class LvMenu extends FHCAPI_Controller
|
||||
}
|
||||
}
|
||||
|
||||
private function fhc_menu_lvinfo(&$menu, $lvid, $studiengang_kz, $lektor_der_lv, $is_lector, $lehrfach_oe_kurzbz_arr, $p){
|
||||
private function fhc_menu_lvinfo(&$menu, $lvid, $studiengang_kz, $lektor_der_lv, $is_lector, $lehrfach_oe_kurzbz_arr){
|
||||
|
||||
// LVINFO
|
||||
if(!defined('CIS_LEHRVERANSTALTUNG_LVINFO_ANZEIGEN') || CIS_LEHRVERANSTALTUNG_LVINFO_ANZEIGEN)
|
||||
@@ -333,7 +317,7 @@ class LvMenu extends FHCAPI_Controller
|
||||
|| $this->PermissionLib->isBerechtigtMultipleOe('lehre/lvinfo', $lehrfach_oe_kurzbz_arr)
|
||||
)
|
||||
{
|
||||
$c4_linkList[]= [$p->t('lehre/lvInfoBearbeiten'), 'ects/index.php?lvid='.$lvid];
|
||||
$c4_linkList[]= [$this->p->t('lehre', 'lvInfoBearbeiten'), 'ects/index.php?lvid='.$lvid];
|
||||
}
|
||||
elseif ($is_lector)
|
||||
{
|
||||
@@ -344,7 +328,7 @@ class LvMenu extends FHCAPI_Controller
|
||||
(
|
||||
'id'=>'core_menu_lvinfo',
|
||||
'position'=>'10',
|
||||
'name'=>$p->t('lehre/lehrveranstaltungsinformation'),
|
||||
'name'=>$this->p->t('lehre', 'lehrveranstaltungsinformation'),
|
||||
'icon'=>'../../../skin/images/button_lvinfo.png',
|
||||
'link'=>'',
|
||||
'c4_icon'=> base_url('skin/images/button_lvinfo.png'),
|
||||
@@ -354,7 +338,7 @@ class LvMenu extends FHCAPI_Controller
|
||||
}
|
||||
}
|
||||
|
||||
private function fhc_menu_feedback(&$menu, $angemeldet, $lvid, $p){
|
||||
private function fhc_menu_feedback(&$menu, $angemeldet, $lvid){
|
||||
//FEEDBACK
|
||||
if((!defined('CIS_LEHRVERANSTALTUNG_FEEDBACK_ANZEIGEN') || CIS_LEHRVERANSTALTUNG_FEEDBACK_ANZEIGEN) && $angemeldet)
|
||||
{
|
||||
@@ -362,14 +346,14 @@ class LvMenu extends FHCAPI_Controller
|
||||
(
|
||||
'id'=>'core_menu_feedback',
|
||||
'position'=>'60',
|
||||
'name'=>$p->t('lehre/feedback'),
|
||||
'name'=>$this->p->t('lehre', 'feedback'),
|
||||
'c4_icon'=> base_url('skin/images/button_feedback.png'),
|
||||
'c4_link'=> base_url('feedback.php?lvid='.$lvid),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private function fhc_menu_gesamtnote(&$menu, $angemeldet, $lvid, $lv_obj, $is_lector, $angezeigtes_stsem, $p){
|
||||
private function fhc_menu_gesamtnote(&$menu, $angemeldet, $lvid, $lv_obj, $is_lector, $angezeigtes_stsem){
|
||||
//Gesamtnote
|
||||
if($is_lector && ((!defined('CIS_LEHRVERANSTALTUNG_GESAMTNOTE_ANZEIGEN') || CIS_LEHRVERANSTALTUNG_GESAMTNOTE_ANZEIGEN) && $angemeldet))
|
||||
{
|
||||
@@ -379,7 +363,7 @@ class LvMenu extends FHCAPI_Controller
|
||||
(
|
||||
'id'=>'core_menu_gesamtnote',
|
||||
'position'=>'80',
|
||||
'name'=>$p->t('lehre/gesamtnote'),
|
||||
'name'=>$this->p->t('lehre', 'gesamtnote'),
|
||||
'c4_icon'=> base_url('skin/images/button_endnote.png'),
|
||||
'c4_link'=> base_url('cis/private/lehre/benotungstool/lvgesamtnoteverwalten.php?lvid='.urlencode($lvid).'&stsem='.urlencode($angezeigtes_stsem))
|
||||
//'c4_link'=> base_url('benotungstool/lvgesamtnoteverwalten.php?lvid='.urlencode($lvid).'&stsem='.urlencode($angezeigtes_stsem))
|
||||
@@ -391,10 +375,10 @@ class LvMenu extends FHCAPI_Controller
|
||||
(
|
||||
'id'=>'core_menu_gesamtnote',
|
||||
'position'=>'80',
|
||||
'name'=>$p->t('lehre/gesamtnote'),
|
||||
'name'=>$this->p->t('lehre', 'gesamtnote'),
|
||||
'c4_icon'=>base_url('skin/images/button_endnote.png'),
|
||||
'c4_link'=>'#',
|
||||
'c4_linkList'=>[[$p->t('lehre/noteneingabedeaktiviert'),'#']],
|
||||
'c4_linkList'=>[[$this->p->t('lehre', 'noteneingabedeaktiviert'),'#']],
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -402,7 +386,7 @@ class LvMenu extends FHCAPI_Controller
|
||||
|
||||
|
||||
|
||||
private function fhc_menu_emailStudierende(&$menu, $user, $angemeldet, $lvid, $angezeigtes_stsem, $p){
|
||||
private function fhc_menu_emailStudierende(&$menu, $user, $angemeldet, $lvid, $angezeigtes_stsem){
|
||||
// Email an Studierende
|
||||
if((!defined('CIS_LEHRVERANSTALTUNG_MAILSTUDIERENDE_ANZEIGEN') || CIS_LEHRVERANSTALTUNG_MAILSTUDIERENDE_ANZEIGEN) && $angemeldet)
|
||||
{
|
||||
@@ -448,10 +432,10 @@ class LvMenu extends FHCAPI_Controller
|
||||
if($nomail != '')
|
||||
{
|
||||
$c4_linkList[] = array(
|
||||
$p->t('lehre/keinMailverteiler', array($nomail)),
|
||||
$this->p->t('lehre', 'keinMailverteiler', array('nomail' => $nomail)),
|
||||
'#'
|
||||
);
|
||||
$link_onclick = 'alert(\''.$p->t('lehre/keinMailverteiler', array($nomail)) . '\');';
|
||||
$link_onclick = 'alert(\''.$this->p->t('lehre', 'keinMailverteiler', array('nomail' => $nomail)) . '\');';
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -463,7 +447,7 @@ class LvMenu extends FHCAPI_Controller
|
||||
(
|
||||
'id'=>'core_menu_mailanstudierende',
|
||||
'position'=>'100',
|
||||
'name'=>$p->t('lehre/mail'),
|
||||
'name'=>$this->p->t('lehre', 'mail'),
|
||||
'c4_icon'=>base_url('skin/images/button_feedback.png'),
|
||||
'c4_icon2' => 'fa-regular fa-envelope',
|
||||
'c4_link'=>$mailto,
|
||||
@@ -475,7 +459,7 @@ class LvMenu extends FHCAPI_Controller
|
||||
|
||||
|
||||
|
||||
private function fhc_menu_abmeldung(&$menu, $user, $is_lector, $lvid, $angezeigtes_stsem, $p){
|
||||
private function fhc_menu_abmeldung(&$menu, $user, $is_lector, $lvid, $angezeigtes_stsem){
|
||||
if(!defined('CIS_LEHRVERANSTALTUNG_ABMELDUNG_ANZEIGEN') || CIS_LEHRVERANSTALTUNG_ABMELDUNG_ANZEIGEN)
|
||||
{
|
||||
if(!$is_lector)
|
||||
@@ -487,7 +471,7 @@ class LvMenu extends FHCAPI_Controller
|
||||
(
|
||||
'id'=>'core_menu_abmeldung',
|
||||
'position'=>'120',
|
||||
'name'=>$p->t('lehre/abmelden'),
|
||||
'name'=>$this->p->t('lehre', 'abmelden'),
|
||||
'c4_icon'=>base_url('skin/images/button_studiupload.png'),
|
||||
'c4_link'=>base_url('abmeldung.php?lvid='.urlencode($lvid).'&stsem='.urlencode($angezeigtes_stsem)),
|
||||
);
|
||||
@@ -512,7 +496,7 @@ class LvMenu extends FHCAPI_Controller
|
||||
}
|
||||
}
|
||||
|
||||
private function fhc_menu_anrechnungStudent(&$menu, $lvid, $angezeigtes_stsem, $p){
|
||||
private function fhc_menu_anrechnungStudent(&$menu, $lvid, $angezeigtes_stsem){
|
||||
// Anerkennung nachgewiesener Kenntnisse (Anrechnung) - Anzeige fuer Studenten
|
||||
if((!defined('CIS_LEHRVERANSTALTUNG_ANRECHNUNG_ANZEIGEN') || CIS_LEHRVERANSTALTUNG_ANRECHNUNG_ANZEIGEN)
|
||||
&& $this->PermissionLib->isBerechtigt('student/anrechnung_beantragen'))
|
||||
@@ -521,7 +505,7 @@ class LvMenu extends FHCAPI_Controller
|
||||
(
|
||||
'id' => 'core_menu_anerkennungNachgewiesenerKenntnisse',
|
||||
'position' => '128',
|
||||
'name' => $p->t('lehre/anrechnung'),
|
||||
'name' => $this->p->t('lehre', 'anrechnung'),
|
||||
'c4_icon' => base_url('skin/images/button_listen.png'),
|
||||
'c4_icon2' => 'fa-regular fa-folder-open',
|
||||
'c4_link' => base_url('cis.php/lehre/anrechnung/RequestAnrechnung?studiensemester='.urlencode($angezeigtes_stsem).'&lv_id='.urlencode($lvid))
|
||||
@@ -529,7 +513,7 @@ class LvMenu extends FHCAPI_Controller
|
||||
}
|
||||
}
|
||||
|
||||
private function fhc_menu_anrechnungLector(&$menu, $angezeigtes_stsem, $p){
|
||||
private function fhc_menu_anrechnungLector(&$menu, $angezeigtes_stsem){
|
||||
// Anerkennung nachgewiesener Kenntnisse (Anrechnung) - Anzeige fuer LektorInnen
|
||||
if((!defined('CIS_LEHRVERANSTALTUNG_ANRECHNUNG_ANZEIGEN') || CIS_LEHRVERANSTALTUNG_ANRECHNUNG_ANZEIGEN)
|
||||
&& $this->PermissionLib->isBerechtigt('lehre/anrechnung_empfehlen'))
|
||||
@@ -538,7 +522,7 @@ class LvMenu extends FHCAPI_Controller
|
||||
(
|
||||
'id' => 'core_menu_anerkennungNachgewiesenerKenntnisse_empfehlen',
|
||||
'position' => '128',
|
||||
'name' => $p->t('lehre/anrechnungen'),
|
||||
'name' => $this->p->t('lehre', 'anrechnungen'),
|
||||
'c4_icon'=> base_url('skin/images/button_listen.png'),
|
||||
'c4_icon2' => 'fa-regular fa-folder-open',
|
||||
'c4_link' => base_url('cis.php/lehre/anrechnung/ReviewAnrechnungUebersicht?studiensemester='.urlencode($angezeigtes_stsem))
|
||||
|
||||
@@ -565,6 +565,7 @@ class FilterCmptLib
|
||||
getAuthPersonId()
|
||||
);
|
||||
|
||||
|
||||
// If filters were loaded
|
||||
if (hasData($filters))
|
||||
{
|
||||
@@ -1172,5 +1173,4 @@ class FilterCmptLib
|
||||
|
||||
return $filterName;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -177,5 +177,4 @@
|
||||
</body>
|
||||
</html>
|
||||
|
||||
<!-- Footer end -->
|
||||
|
||||
<!-- Footer end -->
|
||||
@@ -27,6 +27,7 @@ define('CIS_LEHRVERANSTALTUNG_SEMESTERINFO_ANZEIGEN',true);
|
||||
define('CIS_LEHRVERANSTALTUNG_LEHRFACH_ANZEIGEN',false);
|
||||
define('CIS_LEHRVERANSTALTUNG_GESAMTNOTE_ANZEIGEN', true);
|
||||
define('CIS_LEHRVERANSTALTUNG_ANRECHNUNG_ANZEIGEN', true);
|
||||
define('CIS_LEHRVERANSTALTUNG_ANWESENHEIT_ANZEIGEN', true);
|
||||
|
||||
// Im CIS Menue Links bei Modulen anzeigen wenn Lehrauftrag
|
||||
define('CIS_LEHRVERANSTALTUNG_MODULE_LINK',true);
|
||||
|
||||
@@ -240,13 +240,37 @@ function checkZeilenUmbruch()
|
||||
);
|
||||
}
|
||||
|
||||
// Digitale Anwesenheiten
|
||||
if(CIS_LEHRVERANSTALTUNG_ANWESENHEIT_ANZEIGEN && $angemeldet
|
||||
&& ($rechte->isBerechtigt('extension/anw_ent_admin')
|
||||
|| $rechte->isBerechtigt('extension/anwesenheit_lektor')
|
||||
|| $rechte->isBerechtigt('extension/anwesenheit_student')
|
||||
|| $rechte->isBerechtigt('extension/anwesenheit_admin')))
|
||||
{
|
||||
|
||||
$link='';
|
||||
$text='';
|
||||
|
||||
$link= APP_ROOT."index.ci.php/extensions/FHC-Core-Anwesenheiten/?stg_kz=$studiengang_kz&sem=$semester&lvid=$lvid&sem_kurzbz=$angezeigtes_stsem";
|
||||
|
||||
$menu[]=array
|
||||
(
|
||||
'id'=>'core_menu_digitale_anwesenheitslisten',
|
||||
'position'=>'50',
|
||||
'name'=> $p->t('lehre/digiAnw'),
|
||||
'icon'=>'../../../skin/images/button_kreuzerltool.png',
|
||||
'link'=>$link,
|
||||
'text'=>$text
|
||||
);
|
||||
}
|
||||
|
||||
//FEEDBACK
|
||||
if((!defined('CIS_LEHRVERANSTALTUNG_FEEDBACK_ANZEIGEN') || CIS_LEHRVERANSTALTUNG_FEEDBACK_ANZEIGEN) && $angemeldet)
|
||||
{
|
||||
$menu[]=array
|
||||
(
|
||||
'id'=>'core_menu_feedback',
|
||||
'position'=>'50',
|
||||
'position'=>'60',
|
||||
'name'=>$p->t('lehre/feedback'),
|
||||
'icon'=>'../../../skin/images/button_feedback.png',
|
||||
'link'=>'feedback.php?lvid='.$lvid,
|
||||
@@ -584,4 +608,4 @@ function isDirectoryEmpty($DOC_ROOT, $kurzbz, $semester, $short_short_name, $typ
|
||||
}
|
||||
?>
|
||||
</tr>
|
||||
</table>
|
||||
</table>
|
||||
@@ -16,6 +16,7 @@ $this->phrasen['lehre/upload']='Upload';
|
||||
$this->phrasen['lehre/ziparchiv']='Zip-Archiv';
|
||||
$this->phrasen['lehre/ziparchivTitle']='Alle Dateien im Download Verzeichnis als Zip-Archiv herunterladen';
|
||||
$this->phrasen['lehre/anwesenheitsUndNotenlisten']='Anwesenheits- und Notenlisten';
|
||||
$this->phrasen['lehre/digiAnw']='Digitale Anwesenheiten';
|
||||
$this->phrasen['lehre/leistungsuebersicht']='Leistungsübersicht';
|
||||
$this->phrasen['lehre/newsgroups']='Newsgroups';
|
||||
$this->phrasen['lehre/feedback']='Feedback';
|
||||
|
||||
@@ -16,6 +16,7 @@ $this->phrasen['lehre/upload']='Upload';
|
||||
$this->phrasen['lehre/ziparchiv']='Zip-File';
|
||||
$this->phrasen['lehre/ziparchivTitle']='Download all Files as Zip-File';
|
||||
$this->phrasen['lehre/anwesenheitsUndNotenlisten']='Attendance and grade list';
|
||||
$this->phrasen['lehre/digiAnw']='Digital Attendances';
|
||||
$this->phrasen['lehre/leistungsuebersicht']='Performance List';
|
||||
$this->phrasen['lehre/newsgroups']='Newsgroups';
|
||||
$this->phrasen['lehre/feedback']='Feedback';
|
||||
|
||||
@@ -68,6 +68,21 @@
|
||||
box-shadow: 0 0 0 1px #dee2e6 !important;
|
||||
}
|
||||
|
||||
.fhc-calendar-no-events-overlay{
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.fhc-calendar-no-events-overlay::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
margin:auto;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-image: linear-gradient(120deg, white, gray );
|
||||
opacity: .7;
|
||||
}
|
||||
.fhc-calendar-day-page {
|
||||
/*aspect-ratio: 7/6;*/
|
||||
min-height: 0;
|
||||
@@ -77,7 +92,7 @@
|
||||
/*width: calc(100% + 1.5em);*/
|
||||
height: calc(100% + 1.5em);
|
||||
}
|
||||
.fhc-calendar-day-page .flex-column > div {
|
||||
.fhc-calendar-day-page .flex-column > .flex-grow-1 {
|
||||
padding-left: 3em;
|
||||
}
|
||||
.fhc-calendar-day-page .flex-column {
|
||||
|
||||
@@ -33,6 +33,7 @@ const app = Vue.createApp({
|
||||
monthLastDay: function () {
|
||||
return this.calendarDateToString(this.calendarDate.cdLastDayOfCalendarMonth);
|
||||
},
|
||||
|
||||
},
|
||||
methods:{
|
||||
getLvID: function () {
|
||||
@@ -57,7 +58,7 @@ const app = Vue.createApp({
|
||||
if (checkDate(new CalendarDate(start)) && checkDate(new CalendarDate(end))){
|
||||
// reset the events before querying the new events to activate the loading spinner
|
||||
this.events = null;
|
||||
this.calendarDate = tmp_date;
|
||||
this.calendarDate = new CalendarDate(end);
|
||||
Vue.nextTick(() => {
|
||||
this.loadEvents();
|
||||
});
|
||||
@@ -102,9 +103,9 @@ const app = Vue.createApp({
|
||||
});
|
||||
},
|
||||
},
|
||||
created(){
|
||||
created()
|
||||
{
|
||||
this.getLvID()
|
||||
this.loadEvents();
|
||||
},
|
||||
//TODO: Stundenplan phrase
|
||||
template:/*html*/`
|
||||
|
||||
@@ -26,6 +26,7 @@ export default {
|
||||
focusDate: this.focusDate,
|
||||
size: Vue.computed({ get: () => this.size, set: v => this.size = v }),
|
||||
events: Vue.computed(() => this.eventsPerDay),
|
||||
filteredEvents: Vue.computed(() => this.filteredEvents),
|
||||
minimized: Vue.computed({ get: () => this.minimized, set: v => this.$emit('update:minimized', v) }),
|
||||
showWeeks: this.showWeeks,
|
||||
noMonthView: this.noMonthView,
|
||||
@@ -55,7 +56,28 @@ export default {
|
||||
},
|
||||
minimized: Boolean,
|
||||
noWeekView: Boolean,
|
||||
noMonthView: Boolean
|
||||
noMonthView: Boolean,
|
||||
},
|
||||
watch:{
|
||||
// scroll to the first event if the html element was found
|
||||
async scrollTime(newScrollTime){
|
||||
// scroll the Stundenplan to the closest event
|
||||
await Vue.nextTick();
|
||||
let previousScrollAnchor = document.getElementById('scroll' + (newScrollTime-1) + this.focusDate.d + this.focusDate.w)
|
||||
let scrollAnchor = document.getElementById('scroll' + newScrollTime+this.focusDate.d+this.focusDate.w);
|
||||
|
||||
if (previousScrollAnchor)
|
||||
{
|
||||
previousScrollAnchor.scrollIntoView({ behavior: 'smooth', block: 'start' });
|
||||
}
|
||||
else
|
||||
{
|
||||
if (scrollAnchor)
|
||||
{
|
||||
scrollAnchor.scrollIntoView({ behavior: 'smooth', block: 'start' });
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
emits: [
|
||||
'select:day',
|
||||
@@ -102,7 +124,52 @@ export default {
|
||||
}
|
||||
return result;
|
||||
}, {});
|
||||
}
|
||||
},
|
||||
// returns the hour of the earliest event, used to scroll to the events in the calendar (week / day view)
|
||||
scrollTime: function () {
|
||||
// return the first beginning time of the filtered events
|
||||
if(this.filteredEvents && Array.isArray(this.filteredEvents) && this.filteredEvents.length > 0)
|
||||
{
|
||||
return parseInt(this.filteredEvents.sort((a, b) => parseInt(a.beginn) - parseInt(b.beginn))[0].beginn);
|
||||
}
|
||||
// there is no event that matches the current view mode constraints
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
},
|
||||
// filters the events based on the current calendar view mode
|
||||
// week view - filter events based on their week
|
||||
// day view - filter events based on their day and week
|
||||
// month view - does not filter the events
|
||||
filteredEvents: function(){
|
||||
if (this.events && Array.isArray(this.events) && this.events.length > 0) {
|
||||
let filteredEvents = this.events.filter(event => {
|
||||
let eventDate = new CalendarDate(new Date(event.datum));
|
||||
if (this.mode == 'week')
|
||||
{
|
||||
// week view filters the elements only for the same week
|
||||
return this.focusDate.w == eventDate.w;
|
||||
}
|
||||
else if (this.mode == 'day')
|
||||
{
|
||||
// day view filters the elements for the same day and the same week
|
||||
return this.focusDate.d == eventDate.d && this.focusDate.w == eventDate.w;
|
||||
}
|
||||
else
|
||||
{
|
||||
// returns all the events, does not filter the events
|
||||
return true;
|
||||
}
|
||||
})
|
||||
|
||||
return filteredEvents;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
handleInput(day) {
|
||||
@@ -136,9 +203,10 @@ export default {
|
||||
}
|
||||
}).observe(this.$refs.container);
|
||||
}
|
||||
|
||||
},
|
||||
template: /*html*/`
|
||||
<div ref="container" class="fhc-calendar card" :class="sizeClass">
|
||||
<div ref="container" class="fhc-calendar card h-100" :class="sizeClass">
|
||||
<component :is="'calendar-' + mode" @updateMode="mode = $event" @change:range="$emit('change:range',$event)" @input="handleInput" >
|
||||
<template #weekPage="{event,day}">
|
||||
<slot name="weekPage" :event="event" :day="day"></slot>
|
||||
@@ -146,6 +214,9 @@ export default {
|
||||
<template #dayPage="{event,day}">
|
||||
<slot name="dayPage" :event="event" :day="day"></slot>
|
||||
</template>
|
||||
<template #minimizedPage="{event,day}">
|
||||
<slot name="minimizedPage" :event="event" :day="day"></slot>
|
||||
</template>
|
||||
</component>
|
||||
</div>`
|
||||
}
|
||||
|
||||
@@ -15,7 +15,11 @@ export default {
|
||||
'focusDate',
|
||||
'size',
|
||||
'events',
|
||||
'noMonthView'
|
||||
'noMonthView',
|
||||
'filteredEvents',
|
||||
'isSliding',
|
||||
'calendarScrollTop',
|
||||
'calendarClientHeight',
|
||||
],
|
||||
props: {
|
||||
year: Number,
|
||||
@@ -28,6 +32,9 @@ export default {
|
||||
'input'
|
||||
],
|
||||
computed: {
|
||||
noEventsTextPosition(){
|
||||
return this.calendarScrollTop + 100;
|
||||
},
|
||||
hours() {
|
||||
// returns an array with elements starting at 7 and ending at 24
|
||||
return [...Array(24).keys()].filter(hour => hour >= 7 && hour <= 24);
|
||||
@@ -39,6 +46,9 @@ export default {
|
||||
return result;
|
||||
},
|
||||
eventsPerDayAndHour() {
|
||||
// return early if the calendar pane is sliding
|
||||
if (this.isSliding) return {};
|
||||
|
||||
const res = {};
|
||||
this.days.forEach(day => {
|
||||
let key = day.toDateString();
|
||||
@@ -75,7 +85,7 @@ export default {
|
||||
},
|
||||
smallestTimeFrame() {
|
||||
return [30, 15, 10, 5][this.size];
|
||||
}
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
calcHourPosition(event) {
|
||||
@@ -149,23 +159,28 @@ export default {
|
||||
</div>
|
||||
</div>
|
||||
<div ref="eventcontainer" class="position-relative flex-grow-1" @mousemove="calcHourPosition" @mouseleave="" >
|
||||
<div v-for="hour in hours" :key="hour" class="position-absolute box-shadow-border-top" style="pointer-events: none;" :style="{top:getAbsolutePositionForHour(hour),left:0,right:0,'z-index':0}"></div>
|
||||
<div :id="'scroll'+hour+focusDate.d+week" v-for="hour in hours" :key="hour" class="position-absolute box-shadow-border-top" style="pointer-events: none;" :style="{top:getAbsolutePositionForHour(hour),left:0,right:0,'z-index':0}"></div>
|
||||
<div v-if="hourPosition" class="position-absolute border-top small" style="pointer-events: none; padding-left:3.5rem; margin-top:-1px;z-index:2;border-color:#00649C !important" :style="{top:hourPosition+'px',left:0,right:0}">
|
||||
<span class="border border-top-0 px-2 bg-white">{{hourPositionTime}}</span>
|
||||
</div>
|
||||
<div class="events">
|
||||
<div class="hours">
|
||||
<div v-for="hour in hours" style="min-height:100px" :key="hour" class="text-muted text-end small" :ref="'hour' + hour">{{hour}}:00</div>
|
||||
</div>
|
||||
<div v-for="day in eventsPerDayAndHour" :key="day" class=" day border-start" :style="{'grid-template-columns': '1 1fr', 'grid-template-rows': 'repeat(' + (hours.length * 60 / smallestTimeFrame) + ', 1fr)'}">
|
||||
<div :style="{'background-color':event.orig.color}" class="mx-2 border border-dark border-2 small rounded overflow-hidden " @click.prevent="$emit('input', event.orig)" :style="{'z-index':1,'grid-column-start': 1+(event.lane-1)*day.lanes/event.maxLane, 'grid-column-end': 1+event.lane*day.lanes/event.maxLane, 'grid-row-start': dateToMinutesOfDay(event.start), 'grid-row-end': dateToMinutesOfDay(event.end) ,'--test': dateToMinutesOfDay(event.end)}" v-for="event in day.events" :key="event">
|
||||
<slot name="dayPage" :event="event" :day="day">
|
||||
<p>this is a placeholder which means that no template was passed to the Calendar Page slot</p>
|
||||
</slot>
|
||||
<div>
|
||||
<h1 v-if="filteredEvents.length==0" class="m-0 text-secondary" ref="noEventsText" :style="{'top':noEventsTextPosition+'px'}" style="position:absolute; left:0; text-align:center; width: 100%; z-index:1">Keine Lehrveranstaltungen</h1>
|
||||
<div class="events" :class="{'fhc-calendar-no-events-overlay':filteredEvents.length==0}">
|
||||
|
||||
<div class="hours">
|
||||
<div v-for="hour in hours" style="min-height:100px" :key="hour" class="text-muted text-end small" :ref="'hour' + hour">{{hour}}:00</div>
|
||||
</div>
|
||||
<div v-for="day in eventsPerDayAndHour" :key="day" class=" day border-start" :style="{'grid-template-columns': '1 1fr', 'grid-template-rows': 'repeat(' + (hours.length * 60 / smallestTimeFrame) + ', 1fr)'}">
|
||||
<div :style="{'background-color':event.orig.color}" class="mx-2 border border-dark border-2 small rounded overflow-hidden " @click.prevent="$emit('input', event.orig)" :style="{'z-index':1,'grid-column-start': 1+(event.lane-1)*day.lanes/event.maxLane, 'grid-column-end': 1+event.lane*day.lanes/event.maxLane, 'grid-row-start': dateToMinutesOfDay(event.start), 'grid-row-end': dateToMinutesOfDay(event.end) ,'--test': dateToMinutesOfDay(event.end)}" v-for="event in day.events" :key="event">
|
||||
<slot name="dayPage" :event="event" :day="day">
|
||||
<p>this is a placeholder which means that no template was passed to the Calendar Page slot</p>
|
||||
</slot>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -3,10 +3,11 @@ export default {
|
||||
return{
|
||||
selected: this.mode,
|
||||
modes:{
|
||||
week:"Woche",
|
||||
month:"Monat",
|
||||
day: "Tag",
|
||||
week: { mode_bezeichnung: "Woche", icon: "fa-calendar-week", condition: !this.noWeekView },
|
||||
month: { mode_bezeichnung: "Monat", icon: "fa-calendar-days", condition: !this.noMonthView },
|
||||
day: { mode_bezeichnung: "Tag", icon: "fa-sun" , condition:true},
|
||||
},
|
||||
headerPadding:null,
|
||||
}
|
||||
},
|
||||
inject: [
|
||||
@@ -44,36 +45,36 @@ export default {
|
||||
return c;
|
||||
}
|
||||
},
|
||||
template: `
|
||||
template: /*html*/`
|
||||
<div class="calendar-header card-header w-100" :class="classHeader">
|
||||
|
||||
<div v-if="!noWeekView && !noMonthView" class="row justify-content-end" style="position: absolute; width: 98%; pointer-events: none;">
|
||||
<div class="col-auto" style="pointer-events: all;">
|
||||
<div role="group" aria-label="Kalender Modus">
|
||||
<button type="button" :class="{'active':mode_kurzbz == mode}" style="margin-right: 4px;" @click.prevent="$emit('updateMode',mode_kurzbz)" class="btn btn-outline-secondary" v-for="(mode_bezeichnung,mode_kurzbz) in modes">
|
||||
<i v-if="!noWeekView && mode_kurzbz == 'week'" class="fa fa-calendar-week"></i>
|
||||
<i v-else-if="!noMonthView && mode_kurzbz == 'month'" class="fa fa-calendar-days"></i>
|
||||
<i v-else-if="mode_kurzbz == 'day'" class="fa-solid fa-sun"></i>
|
||||
</button>
|
||||
<div class="row align-items-center ">
|
||||
<div class="col offset-0 offset-md-3" :style="{'padding-left':headerPadding}">
|
||||
<div class="row align-items-center justify-content-center">
|
||||
<div class="col-auto ">
|
||||
<button class="btn btn-outline-secondary border-0" :class="{'btn-sm':!this.size}" @click="$emit('prev')"><i class="fa fa-chevron-left"></i></button>
|
||||
</div>
|
||||
<div class="justify-content-center text-center col-auto">
|
||||
<div class="d-flex justify-content-center align-items-center">
|
||||
<button class="btn btn-link link-secondary text-decoration-none" :class="{'btn-sm': !this.size}" @click="$emit('click')">
|
||||
{{ title }}
|
||||
<i v-if="eventsAreNull" class="fa fa-spinner fa-pulse"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-auto ">
|
||||
<button class="btn btn-outline-secondary border-0" :class="{'btn-sm': !this.size}" @click="$emit('next')"><i class="fa fa-chevron-right"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-5 d-flex justify-content-end">
|
||||
<button class="btn btn-outline-secondary border-0" :class="{'btn-sm':!this.size}" @click="$emit('prev')"><i class="fa fa-chevron-left"></i></button>
|
||||
</div>
|
||||
<div class="justify-content-center text-center col-2">
|
||||
<div class="d-flex justify-content-center align-items-center">
|
||||
<button class="btn btn-link link-secondary text-decoration-none" :class="{'btn-sm': !this.size}" @click="$emit('click')">
|
||||
{{ title }}
|
||||
<i v-if="eventsAreNull" class="fa fa-spinner fa-pulse"></i>
|
||||
</button>
|
||||
<div ref="viewButtons" v-if="!noWeekView && !noMonthView" class=" col-12 col-md-3 d-flex justify-content-center justify-content-md-end align-items-center" style="pointer-events: none;">
|
||||
<div style="pointer-events: all;">
|
||||
<div role="group" aria-label="Kalender Modus">
|
||||
<button type="button" :class="{'active':mode_kurzbz === mode}" style="margin-right: 4px;" @click.prevent="$emit('updateMode',mode_kurzbz)" class="btn btn-outline-secondary" v-for="({mode_bezeichnung,icon,condition},mode_kurzbz) in modes">
|
||||
<i v-if="condition" class="fa" :class="icon" ></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-5 d-flex justify-content-start">
|
||||
<button class="btn btn-outline-secondary border-0" :class="{'btn-sm': !this.size}" @click="$emit('next')"><i class="fa fa-chevron-right"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>`
|
||||
}
|
||||
@@ -22,9 +22,10 @@ export default {
|
||||
}
|
||||
},
|
||||
template: `
|
||||
<div class="fhc-calendar-minimized">
|
||||
<div class="fhc-calendar-minimized h-100 d-flex flex-column">
|
||||
<div class="card-header d-grid" :class="classHeader">
|
||||
<button class="btn btn-link link-secondary text-decoration-none" @click="maximize">{{ date.format({dateStyle: ['long','full','full','full'][this.size]}) }}</button>
|
||||
</div>
|
||||
<slot name="minimizedPage"></slot>
|
||||
</div>`
|
||||
}
|
||||
|
||||
@@ -6,7 +6,17 @@ export default {
|
||||
return {
|
||||
carousel: null,
|
||||
queue: 0,
|
||||
offset: 0
|
||||
offset: 0,
|
||||
slideAnimation:false,
|
||||
scrollTop:null,
|
||||
clientHeight:null,
|
||||
}
|
||||
},
|
||||
provide() {
|
||||
return {
|
||||
isSliding: Vue.computed(() => this.slideAnimation),
|
||||
calendarScrollTop: Vue.computed(() =>this.scrollTop),
|
||||
calendarClientHeight: Vue.computed(() => this.clientHeight),
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@@ -15,6 +25,10 @@ export default {
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
scrollCalendar(event){
|
||||
this.scrollTop = this.$refs.calendarContainer.scrollTop;
|
||||
this.clientHeight = this.$refs.calendarContainer.clientHeight;
|
||||
},
|
||||
prev() {
|
||||
if (!this.queue--)
|
||||
this.carousel.prev();
|
||||
@@ -34,6 +48,10 @@ export default {
|
||||
else
|
||||
this.carousel.prev();
|
||||
}
|
||||
this.slideAnimation = false;
|
||||
},
|
||||
slide(evt) {
|
||||
this.slideAnimation = true;
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
@@ -43,11 +61,13 @@ export default {
|
||||
interval: false
|
||||
});
|
||||
}
|
||||
this.scrollTop = this.$refs.calendarContainer.scrollTop;
|
||||
this.clientHeight = this.$refs.calendarContainer.clientHeight;
|
||||
},
|
||||
template: `
|
||||
<div ref="carousel" class="calendar-pane carousel slide" @[\`slid.bs.carousel\`]="slid" :data-queue="queue">
|
||||
<div ref="carousel" class="calendar-pane carousel slide" @[\`slide.bs.carousel\`]="slide" @[\`slid.bs.carousel\`]="slid" :data-queue="queue">
|
||||
<!--height calc function just for user testing purpose (has to be fixed)-->
|
||||
<div class="carousel-inner " style="height:calc(100vh - 220px); overflow:scroll">
|
||||
<div @scroll="scrollCalendar" ref="calendarContainer" class="carousel-inner " style="height:calc(100vh - 220px); overflow:scroll">
|
||||
<div v-for="i in [...Array(3).keys()]" :key="i" class="carousel-item">
|
||||
<slot :index="i" :offset="offsets[i]" />
|
||||
</div>
|
||||
|
||||
@@ -15,7 +15,8 @@ export default {
|
||||
'focusDate',
|
||||
'size',
|
||||
'events',
|
||||
'noMonthView'
|
||||
'noMonthView',
|
||||
'isSliding'
|
||||
],
|
||||
props: {
|
||||
year: Number,
|
||||
@@ -45,6 +46,9 @@ export default {
|
||||
|
||||
},
|
||||
eventsPerDayAndHour() {
|
||||
// return early if the calendar pane is sliding
|
||||
if (this.isSliding) return {};
|
||||
|
||||
const res = {};
|
||||
this.days.forEach(day => {
|
||||
let key = day.toDateString();
|
||||
@@ -137,11 +141,12 @@ export default {
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
|
||||
setTimeout(() => this.$refs.eventcontainer.scrollTop = this.$refs.eventcontainer.scrollHeight / 3 + 1, 0);
|
||||
},
|
||||
template: `
|
||||
template: /*html*/`
|
||||
<div class="fhc-calendar-week-page">
|
||||
|
||||
|
||||
<div class="d-flex flex-column">
|
||||
<div class="fhc-calendar-week-page-header d-grid border-2 border-bottom text-center" :style="{'z-index':4,'grid-template-columns': 'repeat(' + days.length + ', 1fr)', 'grid-template-rows':1}" style="position:sticky; top:0; " >
|
||||
<div type="button" v-for="day in days" :key="day" class="flex-grow-1" :title="day.toLocaleString(undefined, {dateStyle:'short'})" @click.prevent="changeToMonth(day)">
|
||||
@@ -150,7 +155,7 @@ export default {
|
||||
</div>
|
||||
</div>
|
||||
<div ref="eventcontainer" class="position-relative flex-grow-1" @mousemove="calcHourPosition" @mouseleave="" >
|
||||
<div v-for="hour in hours" :key="hour" class="position-absolute box-shadow-border-top" style="pointer-events: none;" :style="{top:getAbsolutePositionForHour(hour),left:0,right:0,'z-index':0}"></div>
|
||||
<div :id="'scroll'+hour+focusDate.d+week" v-for="hour in hours" :key="hour" class="position-absolute box-shadow-border-top" style="pointer-events: none;" :style="{top:getAbsolutePositionForHour(hour),left:0,right:0,'z-index':0}"></div>
|
||||
<div v-if="hourPosition" class="position-absolute border-top small" style="pointer-events: none; padding-left:3.5rem; margin-top:-1px;z-index:2;border-color:#00649C !important" :style="{top:hourPosition+'px',left:0,right:0}">
|
||||
<span class="border border-top-0 px-2 bg-white">{{hourPositionTime}}</span>
|
||||
</div>
|
||||
|
||||
@@ -43,7 +43,7 @@ export default {
|
||||
}, []))
|
||||
},
|
||||
currentEvents() {
|
||||
return (this.events || []).filter(evt => evt.end < this.dayAfterCurrentDay && evt.start >= this.currentDay)//.sort((e1, e2) => e1.beginn > e2.beginn);
|
||||
return (this.events || []).filter(evt => evt.end < this.dayAfterCurrentDay && evt.start >= this.currentDay);
|
||||
},
|
||||
dayAfterCurrentDay() {
|
||||
let currentDay = new Date(this.currentDay);
|
||||
@@ -61,7 +61,7 @@ export default {
|
||||
},
|
||||
monthLastDay: function () {
|
||||
return this.calendarDateToString(this.calendarDate.cdLastDayOfCalendarMonth);
|
||||
}
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
getEventStyle: function(evt) {
|
||||
@@ -192,6 +192,30 @@ export default {
|
||||
<div class="dashboard-widget-stundenplan d-flex flex-column h-100">
|
||||
<lv-modal v-if="selectedEvent" ref="lvmodal" :event="selectedEvent" />
|
||||
<content-modal :contentID="roomInfoContentID" :ort_kurzbz="" dialogClass="modal-lg" ref="contentModal"/>
|
||||
<fhc-calendar @change:range="updateRange" :initial-date="currentDay" class="border-0" class-header="p-0" @select:day="selectDay" v-model:minimized="minimized" :events="events" no-week-view :show-weeks="false" >
|
||||
<template #minimizedPage >
|
||||
<div class="flex-grow-1 overflow-scroll">
|
||||
<div v-if="events === null" class="d-flex h-100 justify-content-center align-items-center">
|
||||
<i class="fa-solid fa-spinner fa-pulse fa-3x"></i>
|
||||
</div>
|
||||
<div v-else-if="currentEvents.length" class="list-group list-group-flush">
|
||||
<div role="button" @click="showLvUebersicht(evt)" class="" v-for="evt in currentEvents" :key="evt.id" class="list-group-item small" :style="{'background-color':evt.color}">
|
||||
<b>{{evt.topic}}</b>
|
||||
<br>
|
||||
<small class="d-flex w-100 justify-content-between">
|
||||
<!-- event modifier stop to prevent opening the modal for the lv Uebersicht when clicking on the ort_kurzbz -->
|
||||
<span @click.stop="showRoomInfoModal(evt.ort_kurzbz)" style="text-decoration:underline" type="button">{{evt.ort_kurzbz}}</span>
|
||||
<span>{{evt.start.toLocaleTimeString(undefined, {hour:'numeric',minute:'numeric'})}}-{{evt.end.toLocaleTimeString(undefined, {hour:'numeric',minute:'numeric'})}}</span>
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="d-flex h-100 justify-content-center align-items-center fst-italic text-center">
|
||||
{{ p.t('lehre/noLvFound') }}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</fhc-calendar>
|
||||
|
||||
<fhc-calendar ref="calendar" @change:range="updateRange" :initial-date="currentDay" class="border-0" class-header="p-0" @select:day="selectDay" v-model:minimized="minimized" :events="events" no-week-view :show-weeks="false" />
|
||||
<div v-show="minimized" class="flex-grow-1 overflow-scroll">
|
||||
<div v-if="events === null" class="d-flex h-100 justify-content-center align-items-center">
|
||||
|
||||
@@ -16,7 +16,11 @@ export default {
|
||||
id: String,
|
||||
name: String,
|
||||
inputClass: [String, Array, Object],
|
||||
noList: Boolean
|
||||
noList: Boolean,
|
||||
accept: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
stringifyFile(file) {
|
||||
@@ -84,8 +88,8 @@ export default {
|
||||
},
|
||||
template: `
|
||||
<div class="form-upload-dms">
|
||||
<input ref="upload" class="form-control" :class="inputClass" :id="id" :name="name" :multiple="multiple" type="file" @change="addFiles">
|
||||
<ul v-if="modelValue.length && multiple && !noList" class="list-unstyled m-0">
|
||||
<input ref="upload" class="form-control" :accept="accept" :class="inputClass" :id="id" :name="name" :multiple="multiple" type="file" @change="addFiles">
|
||||
<ul v-if="modelValue.length && multiple && !noList" :accept="accept" class="list-unstyled m-0">
|
||||
<dms-item
|
||||
v-for="(file, index) in modelValue"
|
||||
:key="index"
|
||||
@@ -96,4 +100,4 @@ export default {
|
||||
</dms-item>
|
||||
</ul>
|
||||
</div>`
|
||||
}
|
||||
}
|
||||
@@ -43,7 +43,8 @@ export const CoreFilterCmpt = {
|
||||
emits: [
|
||||
'nwNewEntry',
|
||||
'click:new',
|
||||
'tableBuilt'
|
||||
'tableBuilt',
|
||||
'uuidDefined'
|
||||
],
|
||||
props: {
|
||||
onNwNewEntry: Function, // NOTE(chris): Hack to get the nwNewEntry listener into $props
|
||||
@@ -200,16 +201,16 @@ export const CoreFilterCmpt = {
|
||||
}
|
||||
// Define a default tabulator options in case it was not provided
|
||||
let tabulatorOptions = {...{
|
||||
height: 500,
|
||||
layout: "fitDataStretch",
|
||||
movableColumns: true,
|
||||
columnDefaults:{
|
||||
tooltip: true,
|
||||
},
|
||||
placeholder,
|
||||
reactiveData: true,
|
||||
persistence: true
|
||||
}, ...(this.tabulatorOptions || {})};
|
||||
height: 500,
|
||||
layout: "fitDataStretch",
|
||||
movableColumns: true,
|
||||
columnDefaults:{
|
||||
tooltip: true,
|
||||
},
|
||||
placeholder,
|
||||
reactiveData: true,
|
||||
persistence: true
|
||||
}, ...(this.tabulatorOptions || {})};
|
||||
|
||||
if (!this.tableOnly) {
|
||||
tabulatorOptions.data = this.filteredData;
|
||||
@@ -573,6 +574,7 @@ export const CoreFilterCmpt = {
|
||||
if (this.sideMenu && (!this.$props.onNwNewEntry || !(this.$props.onNwNewEntry instanceof Function)))
|
||||
alert('"nwNewEntry" listener is mandatory when sideMenu is true');
|
||||
this.uuid = _uuid++;
|
||||
this.$emit('uuidDefined', this.uuid)
|
||||
if (!this.tableOnly)
|
||||
this.getFilter(); // get the filter data
|
||||
},
|
||||
@@ -664,4 +666,3 @@ export const CoreFilterCmpt = {
|
||||
<div ref="table" :id="'filterTableDataset' + idExtra" class="filter-table-dataset"></div>
|
||||
`
|
||||
};
|
||||
|
||||
|
||||
@@ -227,6 +227,25 @@ export default {
|
||||
});
|
||||
});
|
||||
},
|
||||
confirm(options) {
|
||||
return new Promise((resolve, reject) => {
|
||||
helperAppInstance.$confirm.require({
|
||||
group: options?.group ?? 'fhcAlertConfirm',
|
||||
header: options?.header ?? 'Achtung',
|
||||
message: options?.message ?? '',
|
||||
acceptLabel: options?.acceptLabel ?? 'Ok',
|
||||
acceptClass: options?.acceptClass ?? 'btn btn-primary',
|
||||
rejectLabel: options?.rejectLabel ?? 'Abbrechen',
|
||||
rejectClass: options?.rejectClass ?? 'btn btn-outline-secondary',
|
||||
accept() {
|
||||
resolve(true);
|
||||
},
|
||||
reject() {
|
||||
resolve(false);
|
||||
},
|
||||
});
|
||||
});
|
||||
},
|
||||
alertDefault(severity, title, message, sticky = false) {
|
||||
let options = { severity: severity, summary: title, detail: message};
|
||||
|
||||
|
||||
@@ -46,9 +46,9 @@ export default {
|
||||
result.meta.response = response;
|
||||
return result;
|
||||
}
|
||||
|
||||
const baseURL = FHC_JS_DATA_STORAGE_OBJECT.app_root + FHC_JS_DATA_STORAGE_OBJECT.ci_router + "/";
|
||||
const fhcApiAxios = axios.create({
|
||||
timeout: 5000,
|
||||
timeout: 500000,
|
||||
baseURL: FHC_JS_DATA_STORAGE_OBJECT.app_root + FHC_JS_DATA_STORAGE_OBJECT.ci_router + "/"
|
||||
});
|
||||
|
||||
@@ -58,7 +58,7 @@ export default {
|
||||
|
||||
if (config.data instanceof FormData)
|
||||
return config;
|
||||
|
||||
|
||||
if (!Object.values(config.data).every(item => {
|
||||
if (item instanceof FileList)
|
||||
return false;
|
||||
@@ -96,7 +96,7 @@ export default {
|
||||
|| response.config?.errorHandling === false
|
||||
|| response.config?.errorHandling == 'fail')
|
||||
return _clean_return_value(response);
|
||||
|
||||
|
||||
// NOTE(chris): loop through errors
|
||||
if (response.data.errors)
|
||||
response.data.errors = response.data.errors.filter(
|
||||
@@ -107,7 +107,7 @@ export default {
|
||||
}, error => {
|
||||
if (error.code == 'ERR_CANCELED')
|
||||
return Promise.reject({...{handled: true}, ...error});
|
||||
|
||||
|
||||
if (error.config?.errorHandling == 'off'
|
||||
|| error.config?.errorHandling === false
|
||||
|| error.config?.errorHandling == 'success')
|
||||
@@ -118,7 +118,7 @@ export default {
|
||||
app.config.globalProperties.$fhcAlert.alertDefault('error', error.message, error.request.responseURL, true);
|
||||
return Promise.reject({...{handled: true}, ...error});
|
||||
}
|
||||
|
||||
|
||||
// NOTE(chris): loop through errors
|
||||
error.response.data.errors = error.response.data.errors.filter(
|
||||
err => (error.config[err.type + 'ErrorHandler'] || app.config.globalProperties.$fhcApi._defaultErrorHandlers[err.type])(err, error.config)
|
||||
@@ -132,7 +132,7 @@ export default {
|
||||
app.config.globalProperties.$fhcAlert.alertError(error.message);
|
||||
return Promise.reject({...{handled: true}, ...error});
|
||||
}
|
||||
|
||||
|
||||
return Promise.reject(error);
|
||||
});
|
||||
|
||||
|
||||
@@ -374,4 +374,4 @@ if($neue==false)
|
||||
echo '<br>Keine neuen Webservicerechte';
|
||||
|
||||
echo '</body></html>';
|
||||
?>
|
||||
?>
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
if (! defined('DB_NAME')) exit('No direct script access allowed');
|
||||
|
||||
// add app fhctemplate
|
||||
if($result = $db->db_query("SELECT 1 FROM system.tbl_app WHERE app='anwesenheiten'"))
|
||||
{
|
||||
if($db->db_num_rows($result) === 0)
|
||||
{
|
||||
$qry = "INSERT INTO system.tbl_app (app) VALUES('anwesenheiten');";
|
||||
|
||||
if(!$db->db_query($qry))
|
||||
echo '<strong>System Tabelle app: '.$db->db_last_error().'</strong><br>';
|
||||
else
|
||||
echo '<br>app anwesenheiten hinzugefuegt';
|
||||
}
|
||||
}
|
||||
+262
-2
@@ -31224,6 +31224,66 @@ array(
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'anwesenheiten',
|
||||
'category' => 'global',
|
||||
'phrase' => 'notAuthorizedForLva',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'Keine Berechtigung für die Lehrveranstaltung.',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => 'No Authorization for that Course.',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'anwesenheiten',
|
||||
'category' => 'global',
|
||||
'phrase' => 'notAuthorizedForLe',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'Keine Berechtigung für die Lehreinheit.',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => 'No Authorization for that Teaching Unit.',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'anwesenheiten',
|
||||
'category' => 'global',
|
||||
'phrase' => 'noAuthorization',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'Keine Berechtigung.',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => 'No Authorization.',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'anwesenheiten',
|
||||
'category' => 'global',
|
||||
@@ -31279,7 +31339,7 @@ array(
|
||||
array(
|
||||
'app' => 'anwesenheiten',
|
||||
'category' => 'global',
|
||||
'phrase' => 'tooltipStudentAssistenz',
|
||||
'phrase' => 'tooltipAssistenz',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
@@ -36856,6 +36916,206 @@ array(
|
||||
'insertvon' => 'system'
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'global',
|
||||
'phrase' => 'nichtAngemeldet',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'Sie sind nicht angemeldet. Es wurde keine Benutzer UID gefunden',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => 'You are not logged in. No UID found',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'lehre',
|
||||
'phrase' => 'lvInfoBearbeiten',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'Bearbeiten',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => 'Edit',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'lehre',
|
||||
'phrase' => 'lehrveranstaltungsinformation',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'Lehrveranstaltungsinformation',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => 'Course Information',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'lehre',
|
||||
'phrase' => 'gesamtnote',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'Gesamtnote',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => 'Final Grade',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'lehre',
|
||||
'phrase' => 'noteneingabedeaktiviert',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'Noteneingabe deaktiviert',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => 'Grading disabled',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'lehre',
|
||||
'phrase' => 'keinMailverteiler',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'Für die Gruppe(n) {nomail} existiert kein Verteiler! Die Studierenden in diesen Gruppen bekommen kein Mail.',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => 'There is no e-mail distribution list for the group(s) {nomail}! The students in these groups will not receive an e-mail.',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'lehre',
|
||||
'phrase' => 'mail',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'E-Mail an Studierende',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => 'E-Mail to students',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'lehre',
|
||||
'phrase' => 'abmelden',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'Abmelden',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => 'Unsubscribe',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'lehre',
|
||||
'phrase' => 'anrechnung',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'Anrechnung',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => 'Exemption',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'lehre',
|
||||
'phrase' => 'anrechnungen',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'Anrechnungen',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => 'Exemptions',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
)
|
||||
)
|
||||
)
|
||||
// CIS4 phrases from legacy code end
|
||||
);
|
||||
@@ -36981,4 +37241,4 @@ foreach ($phrases as $phrase)
|
||||
}
|
||||
|
||||
if(!$new)
|
||||
echo '<b>Keine neuen Phrasen</b><br>';
|
||||
echo '<b>Keine neuen Phrasen</b><br>';
|
||||
|
||||
Reference in New Issue
Block a user