diff --git a/application/controllers/api/frontend/v1/RendererLoader.php b/application/controllers/api/frontend/v1/RendererLoader.php
new file mode 100644
index 000000000..dc16bb3fc
--- /dev/null
+++ b/application/controllers/api/frontend/v1/RendererLoader.php
@@ -0,0 +1,72 @@
+.
+ */
+
+if (! defined('BASEPATH')) exit('No direct script access allowed');
+
+use CI3_Events as Events;
+
+class RendererLoader extends FHCAPI_Controller
+{
+
+ /**
+ * Object initialization
+ */
+ public function __construct()
+ {
+
+ parent::__construct([
+ 'GetRenderers' => self::PERM_LOGGED,
+
+ ]);
+
+ $this->load->library('LogLib');
+ $this->loglib->setConfigs(array(
+ 'classIndex' => 5,
+ 'functionIndex' => 5,
+ 'lineIndex' => 4,
+ 'dbLogType' => 'API', // required
+ 'dbExecuteUser' => 'RESTful API'
+ ));
+
+
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ // Public methods
+
+ /**
+ * fetches Stundenplan and Moodle events together
+ * @access public
+ *
+ */
+ public function GetRenderers(){
+ $renderer_paths = [];
+ Events::trigger(
+ 'loadRenderers',
+ function & () use (&$renderer_paths)
+ {
+ return $renderer_paths;
+ }
+ );
+ $this->terminateWithSuccess($renderer_paths);
+ }
+
+
+
+
+}
diff --git a/application/controllers/api/frontend/v1/Stundenplan.php b/application/controllers/api/frontend/v1/Stundenplan.php
index 11a8a7034..fd765cf74 100644
--- a/application/controllers/api/frontend/v1/Stundenplan.php
+++ b/application/controllers/api/frontend/v1/Stundenplan.php
@@ -82,10 +82,12 @@ class Stundenplan extends FHCAPI_Controller
$lv_id = $this->input->get('lv_id', TRUE);
$stundenplan_events = $this->stundenplanlib->getStundenplan($start_date,$end_date,$lv_id);
+ $stundenplan_events = $this->getDataOrTerminateWithError($stundenplan_events);
if( is_null($stundenplan_events) || isEmptyArray($stundenplan_events) )
{
$stundenplan_events = array();
}
+
// fetching moodle events
$moodle_events = [];
Events::trigger(
diff --git a/application/core/CI3_Events.php b/application/core/CI3_Events.php
index 37f6c3f21..e283230c9 100644
--- a/application/core/CI3_Events.php
+++ b/application/core/CI3_Events.php
@@ -49,6 +49,9 @@ require_once(APPPATH.'config/Events.php');
$active_addons_array = explode(";", ACTIVE_ADDONS);
+// Load Events from FHC core
+require_once APPPATH.'core/Events.php';
+
foreach (scandir(APPPATH.'config/extensions') as $dir)
if ($dir[0] != '.' && file_exists(APPPATH.'config/extensions/'.$dir.'/Events.php'))
require_once APPPATH.'config/extensions/'.$dir.'/Events.php';
diff --git a/application/core/Events.php b/application/core/Events.php
new file mode 100644
index 000000000..cc61cd509
--- /dev/null
+++ b/application/core/Events.php
@@ -0,0 +1,15 @@
+ APP_ROOT.'public/js/components/Cis/Stundenplan/EventTypes/calendarEvent.js',
+ 'modalTitle' => APP_ROOT.'public/js/components/Cis/Mylv/modalTitle.js',
+ 'modalContent' => APP_ROOT.'public/js/components/Cis/Mylv/modalContent.js'
+ );
+});
+
+
diff --git a/public/css/components/calendar.css b/public/css/components/calendar.css
index 580e0becf..7eb6487dc 100644
--- a/public/css/components/calendar.css
+++ b/public/css/components/calendar.css
@@ -411,4 +411,79 @@
pointer-events: none;
z-index: 2;
opacity: 0.5;
-}
\ No newline at end of file
+}
+
+
+.dayPageContainer, .weekPageContainer{
+ container-type: inline-size;
+}
+
+.dayPageContainer .lehreinheitEventContent,
+.weekPageContainer .lehreinheitEventContent {
+ display: flex;
+ flex-direction: column;
+}
+
+.dayPageContainer .moodleEventContent,
+.weekPageContainer .moodleEventContent{
+ display: flex;
+ flex-direction: row;
+}
+
+.dayPageContainer .lehreinheitEventContent{
+ flex-grow:1;
+ align-items: center;
+ font-size: 0.875rem;
+ font-weight: 400;
+ line-height:1.25;
+}
+
+.dayPageContainer .lehreinheitEventHeader {
+ display: flex;
+ flex-direction: column;
+ padding: 1rem;
+ border-right: 1px solid gray;
+}
+
+.dayPageContainer .moodleEventContent {
+ align-items: center;
+ font-size: 0.875rem;
+ font-weight: 400;
+ line-height: 1.25;
+ width:100%;
+}
+
+.weekPageContainer .moodleEventContent {
+ align-items: center;
+ font-size: 0.875rem;
+ font-weight: 400;
+ line-height: 1.25;
+ width: 100%;
+}
+
+.weekPageContainer .lehreinheitEventHeader {
+ display: flex;
+ flex-direction: column;
+ padding: 1rem;
+ border-right: 1px solid gray;
+}
+
+.weekPageContainer .lehreinheitEventContent {
+ flex-grow: 1;
+ align-items: center;
+ font-size: 0.875rem;
+ font-weight: 400;
+ line-height: 1.25;
+}
+
+
+@container( min-width: 500px){
+ .dayPageContainer .lehreinheitEventContent,
+ .weekPageContainer .lehreinheitEventContent {
+ flex-direction: row;
+ }
+
+ .dayPageContainer .lehreinheitEventContent{
+ justify-content: space-evenly;
+ }
+}
diff --git a/public/js/api/factory/renderers.js b/public/js/api/factory/renderers.js
new file mode 100644
index 000000000..fee81e4df
--- /dev/null
+++ b/public/js/api/factory/renderers.js
@@ -0,0 +1,12 @@
+
+export default {
+
+ loadRenderers() {
+ return {
+ method: 'get',
+ url: '/api/frontend/v1/RendererLoader/GetRenderers',
+ params: {
+ }
+ };
+ },
+}
\ No newline at end of file
diff --git a/public/js/apps/Dashboard/Fhc.js b/public/js/apps/Dashboard/Fhc.js
index a7c88874e..4f3452b60 100644
--- a/public/js/apps/Dashboard/Fhc.js
+++ b/public/js/apps/Dashboard/Fhc.js
@@ -16,6 +16,8 @@ import AbgabetoolMitarbeiter from "../../components/Cis/Abgabetool/AbgabetoolMit
import DeadlineOverview from "../../components/Cis/Abgabetool/DeadlineOverview.js";
import Studium from "../../components/Cis/Studium/Studium.js";
+import ApiRenderers from '../../api/factory/renderers.js';
+
const ciPath = FHC_JS_DATA_STORAGE_OBJECT.app_root.replace(/(https:|)(^|\/\/)(.*?\/)/g, '') + FHC_JS_DATA_STORAGE_OBJECT.ci_router;
const router = VueRouter.createRouter({
@@ -235,7 +237,8 @@ const router = VueRouter.createRouter({
const app = Vue.createApp({
name: 'FhcApp',
data: () => ({
- appSideMenuEntries: {}
+ appSideMenuEntries: {},
+ renderers: null,
}),
components: {},
computed: {
@@ -245,7 +248,8 @@ const app = Vue.createApp({
},
provide() {
return { // provide injectable & watchable language property
- language: Vue.computed(() => this.$p.user_language)
+ language: Vue.computed(() => this.$p.user_language),
+ renderers: Vue.computed(() => this.renderers),
}
},
methods: {
@@ -283,6 +287,28 @@ const app = Vue.createApp({
}
}
},
+ async created(){
+ await this.$api
+ .call(ApiRenderers.loadRenderers())
+ .then(res => res.data)
+ .then(data => {
+ for (let rendertype of Object.keys(data)) {
+
+ let modalTitle = Vue.markRaw(Vue.defineAsyncComponent(() => import(data[rendertype].modalTitle)));
+ let modalContent = Vue.markRaw(Vue.defineAsyncComponent(() => import(data[rendertype].modalContent)));
+ let calendarEvent = Vue.markRaw(Vue.defineAsyncComponent(() => import(data[rendertype].calendarEvent)));
+ if(this.renderers === null) {
+ this.renderers = {};
+ }
+ if (!this.renderers[rendertype]) {
+ this.renderers[rendertype] = {}
+ }
+ this.renderers[rendertype].modalTitle = modalTitle;
+ this.renderers[rendertype].modalContent = modalContent;
+ this.renderers[rendertype].calendarEvent = calendarEvent;
+ }
+ });
+ },
mounted() {
document.addEventListener('click', this.handleClick);
},
diff --git a/public/js/components/Cis/Mylv/LvInfo.js b/public/js/components/Cis/Mylv/LvInfo.js
index 7120c5821..4fdbb695d 100644
--- a/public/js/components/Cis/Mylv/LvInfo.js
+++ b/public/js/components/Cis/Mylv/LvInfo.js
@@ -10,13 +10,6 @@ export default {
}
},
computed: {
- LV_TYPES: function () {
- return {
- lehreinheit: "lehreinheit",
- reservierung: "reservierung",
- moodle: "moodle",
- };
- },
lektorenLinks: function () {
if (!this.event || !Array.isArray(this.event.lektor) || !this.event.lektor.length) return "a";
@@ -56,49 +49,6 @@ export default {
},
template:/*html*/`
-
-
-
- | {{
- $p.t('global','datum')?
- $p.t('global','datum')+':'
- :''
- }} |
- {{methodFormatDate(event?.datum)}} |
-
-
- | {{$p.t('global','aktivitaet')}}: |
- |
-
-
- | {{$p.t('global','typ')}}: |
- {{event?.purpose}} |
-
-
- | {{$p.t('fristenmanagement','frist')}}: |
- {{start_time}} |
-
-
- | {{$p.t('lvinfo','actionname')}}: |
-
- {{event?.actionname}}
- |
-
-
- | {{$p.t('lvinfo','overdue')}}: |
-
- {{$p.t('lvinfo','overdueEvent')}}
- |
-
-
- | {{$p.t('lvinfo','moodleLink')}} |
-
-
- |
-
-
-
-
| {{
@@ -157,7 +107,6 @@ export default {
| {{event.organisationseinheit}} |
-
`
}
diff --git a/public/js/components/Cis/Mylv/LvModal.js b/public/js/components/Cis/Mylv/LvModal.js
index 435caa97c..f62243475 100644
--- a/public/js/components/Cis/Mylv/LvModal.js
+++ b/public/js/components/Cis/Mylv/LvModal.js
@@ -1,7 +1,6 @@
import BsModal from "../../Bootstrap/Modal.js";
import Alert from "../../Bootstrap/Alert.js";
import LvMenu from "./LvMenu.js"
-import LvInfo from "./LvInfo.js"
import ApiStundenplan from '../../../api/factory/stundenplan.js';
import ApiAddons from '../../../api/factory/addons.js';
@@ -11,7 +10,6 @@ export default {
BsModal,
Alert,
LvMenu,
- LvInfo,
},
mixins: [BsModal],
props: {
@@ -44,6 +42,9 @@ export default {
};
},
methods:{
+ onHideModal: function(){
+ this.menu = null;
+ },
onModalShow: function()
{
// do not load the menu if the menu is not getting rendered
@@ -74,22 +75,13 @@ export default {
return BsModal.popup.bind(this)(null, options);
},
template: /*html*/ `
-
+
-
- {{ event.titel + ' - ' + event.lehrfach_bez + ' [' + event.ort_kurzbz+']'}}
- {{ event.lehrfach_bez + ' [' + event.ort_kurzbz+']'}}
+
-
-
- {{$p.t('lvinfo','Moodleinformationen')}}
-
-
- {{$p.t('lvinfo','lehrveranstaltungsinformationen')}}
-
-
-
+
+
{{$p.t('lehre','lehrveranstaltungsmenue')}}
diff --git a/public/js/components/Cis/Mylv/modalContent.js b/public/js/components/Cis/Mylv/modalContent.js
new file mode 100644
index 000000000..c0050e9cc
--- /dev/null
+++ b/public/js/components/Cis/Mylv/modalContent.js
@@ -0,0 +1,113 @@
+import { numberPadding, formatDate } from "../../../helpers/DateHelpers.js"
+
+
+export default {
+ props:{
+ event: {
+ type: Object,
+ required: true,
+ }
+ },
+ computed: {
+ lektorenLinks: function () {
+ if (!this.event || !Array.isArray(this.event.lektor) || !this.event.lektor.length) return "a";
+
+ let lektorenLinks = {};
+ this.event.lektor.forEach((lektor) => {
+ lektorenLinks[lektor.kurzbz] = FHC_JS_DATA_STORAGE_OBJECT.app_root + FHC_JS_DATA_STORAGE_OBJECT.ci_router + `/Cis/Profil/View/${lektor.mitarbeiter_uid}`;
+ })
+ return lektorenLinks;
+ },
+ getOrtContentLink: function () {
+ if (!this.event || !this.event.ort_content_id) return "a";
+
+ return FHC_JS_DATA_STORAGE_OBJECT.app_root + FHC_JS_DATA_STORAGE_OBJECT.ci_router + `/CisVue/Cms/content/${this.event.ort_content_id}`
+ },
+ start_time: function () {
+ if (!this.event.start) return 'N/A';
+ if (!this.event.start instanceof Date) {
+ return this.event.start;
+ }
+ return numberPadding(this.event.start.getHours()) + ":" + numberPadding(this.event.start.getMinutes());
+ },
+ end_time: function () {
+ if (!this.event.end) return 'N/A';
+ if (!this.event.end instanceof Date) {
+ return this.event.end;
+ }
+ return numberPadding(this.event.end.getHours()) + ":" + numberPadding(this.event.end.getMinutes());
+ }
+ },
+ methods: {
+ mehtodNumberPadding: function (number) {
+ return numberPadding(number);
+ },
+ methodFormatDate: function (d) {
+ return formatDate(d);
+ },
+ },
+ template: `
+
+ {{$p.t('lvinfo','lehrveranstaltungsinformationen')}}
+
+
+
+
+ | {{
+ $p.t('global','datum')?
+ $p.t('global','datum')+':'
+ :''
+ }} |
+ {{methodFormatDate(event.datum)}} |
+
+
+ | {{
+ $p.t('global','raum')?
+ $p.t('global','raum')+':'
+ :''
+ }} |
+
+
+ {{event.ort_kurzbz}}
+ |
+
+
+ | {{
+ $p.t('lehre','lehrveranstaltung')?
+ $p.t('lehre','lehrveranstaltung')+':'
+ :''
+ }} |
+ {{'('+event.lehrform+') ' + event.lehrfach_bez}} |
+
+
+ | {{
+ $p.t('lehre','lektor')?
+ $p.t('lehre','lektor')+':'
+ :''
+ }} |
+
+
+ |
+
+
+ | {{
+ $p.t('ui','zeitraum')?
+ $p.t('ui','zeitraum')+':'
+ :''
+ }} |
+ {{start_time + ' - ' + end_time}} |
+
+
+ | {{
+ $p.t('lehre','organisationseinheit')?
+ $p.t('lehre','organisationseinheit')+':'
+ :''
+ }} |
+ {{event.organisationseinheit}} |
+
+
+
`,
+}
\ No newline at end of file
diff --git a/public/js/components/Cis/Mylv/modalTitle.js b/public/js/components/Cis/Mylv/modalTitle.js
new file mode 100644
index 000000000..4acb90248
--- /dev/null
+++ b/public/js/components/Cis/Mylv/modalTitle.js
@@ -0,0 +1,12 @@
+export default {
+ props:{
+ event: {
+ type: Object,
+ required: true,
+ }
+ },
+ template:`
+ {{ event.titel + ' - ' + event.lehrfach_bez + ' [' + event.ort_kurzbz+']'}}
+ {{ event.lehrfach_bez + ' [' + event.ort_kurzbz+']'}}
+`
+}
\ No newline at end of file
diff --git a/public/js/components/Cis/Stundenplan/EventTypes/calendarEvent.js b/public/js/components/Cis/Stundenplan/EventTypes/calendarEvent.js
new file mode 100644
index 000000000..088fb42f9
--- /dev/null
+++ b/public/js/components/Cis/Stundenplan/EventTypes/calendarEvent.js
@@ -0,0 +1,30 @@
+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,
+ },
+ },
+ template: `
+
+
+ {{event.topic}}
+ {{lektor.kurzbz}}
+ {{event.ort_kurzbz}}
+
+
+ `,
+}
diff --git a/public/js/components/Cis/Stundenplan/Stundenplan.js b/public/js/components/Cis/Stundenplan/Stundenplan.js
index efb8c06ea..700d8b463 100644
--- a/public/js/components/Cis/Stundenplan/Stundenplan.js
+++ b/public/js/components/Cis/Stundenplan/Stundenplan.js
@@ -1,13 +1,13 @@
import FhcCalendar from "../../Calendar/Calendar.js";
import CalendarDate from "../../../composables/CalendarDate.js";
import LvModal from "../Mylv/LvModal.js";
-import LvInfo from "../Mylv/LvInfo.js"
import LvMenu from "../Mylv/LvMenu.js"
-import moodleSvg from "../../../helpers/moodleSVG.js"
+import lehreinheitEvent from "./EventTypes/calendarEvent.js"
import ApiStundenplan from '../../../api/factory/stundenplan.js';
import ApiAuthinfo from '../../../api/factory/authinfo.js';
+
export const DEFAULT_MODE_STUNDENPLAN = 'Week'
const Stundenplan = {
@@ -25,7 +25,10 @@ const Stundenplan = {
studiensemester_kurzbz: null,
studiensemester_start: null,
studiensemester_ende: null,
- uid: null
+ uid: null,
+ renderComponents: {},
+ isModalContentResolved: false,
+ isModalTitleResolved: false,
}
},
props: {
@@ -46,7 +49,9 @@ const Stundenplan = {
eventMaxHeight: this.eventMaxHeight
}
},
+ inject:["renderers"],
watch: {
+
weekFirstDay: {
handler: async function (newValue) {
let data = await this.fetchStudiensemesterDetails(newValue);
@@ -69,9 +74,10 @@ const Stundenplan = {
}
},
components: {
- FhcCalendar, LvModal, LvMenu, LvInfo, moodleSvg
+ FhcCalendar, LvModal, LvMenu, lehreinheitEvent,
},
computed:{
+
downloadLinks: function(){
if(!this.studiensemester_start || !this.studiensemester_ende || !this.uid )return;
let start = new Date(this.studiensemester_start);
@@ -105,17 +111,38 @@ const Stundenplan = {
},
},
methods:{
+ modalTitleResolved: function () {
+ this.isModalTitleResolved = true;
+ if(this.isModalContentResolved && this.isModalTitleResolved)
+ Vue.nextTick(() => {
+ if(this.$refs.lvmodal)
+ this.$refs.lvmodal.show();
+ });
+ },
+ modalContentResolved: function () {
+ this.isModalContentResolved = true;
+ if (this.isModalContentResolved && this.isModalTitleResolved)
+ Vue.nextTick(() => {
+ if (this.$refs.lvmodal)
+ this.$refs.lvmodal.show();
+ });
+ },
+ // component renderers fetches from different addons
+ modalTitleComponent(type){
+ return this.renderers[type].modalTitle;
+ },
+ modalContentComponent(type) {
+ return this.renderers[type].modalContent;
+ },
+ calendarEventComponent(type){
+ return this.renderers[type].calendarEvent;
+ },
+
+
fetchStudiensemesterDetails: async function (date) {
return this.$api.call(ApiStundenplan.studiensemesterDateInterval(date));
},
- 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});
-
- },
+
setSelectedEvent: function (event) {
this.currentlySelectedEvent = event;
},
@@ -177,9 +204,8 @@ const Stundenplan = {
},
showModal: function(event){
this.currentlySelectedEvent = event;
- Vue.nextTick(() => {
- this.$refs.lvmodal.show();
- });
+ this.isModalTitleResolved = false;
+ this.isModalContentResolved = false;
},
updateRange: function ({start,end, mounted}) {
let checkDate = (date) => {
@@ -242,25 +268,41 @@ const Stundenplan = {
},
},
created() {
+
+
this.$api
.call(ApiAuthinfo.getAuthUID())
.then(res => res.data)
.then(data => {
this.uid = data.uid;
});
+
// this.loadEvents();
},
beforeUnmount() {
if(this.$refs.lvmodal) this.$refs.lvmodal.hide()
},
template:/*html*/`
+
{{$p.t('lehre/stundenplan')}}
{{studiensemester_kurzbz}}
{{ $p.user_language.value === 'German' ? lv?.bezeichnung : lv?.bezeichnung_english}}
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
- - {{event.topic}}
-
-
-
-
{{event.topic}}
+
+
-
-
-
- {{convertTime(event.beginn.split(":"))}}
- {{convertTime(event.ende.split(":"))}}
-
-
-
-
- - {{event.topic}}
-
-
- {{event.topic}}
- {{lektor.kurzbz}}
- {{event.ort_kurzbz}}
-
+
+
-
-
-
-
- - {{event.topic}}
-
-
-
-
-
-
- {{convertTime(event.beginn.split(":"))}}
- {{convertTime(event.ende.split(":"))}}
-
-
-
-
{{ $p.t('lehre/lehrveranstaltung') }}:
-
{{event?.topic}}
-
-
-
{{ $p.t('lehre/lektor') }}:
-
{{lektor.kurzbz}}
-
-
-
{{ $p.t('profil/Ort') }}:
-
{{event?.ort_kurzbz}}
-
-
-
+
@@ -362,7 +359,8 @@ const Stundenplan = {
{{ $p.t('lehre/noLvFound') }}
- `
+
+ `
}
export default Stundenplan
\ No newline at end of file
diff --git a/public/js/helpers/moodleSVG.js b/public/js/helpers/moodleSVG.js
deleted file mode 100644
index 679c9b1a6..000000000
--- a/public/js/helpers/moodleSVG.js
+++ /dev/null
@@ -1,5 +0,0 @@
-export default {
- template:`
-
- `
-}