mirror of
https://github.com/FH-Complete/FHC-Core.git
synced 2026-06-01 20:29:29 +00:00
Implementation CIS => LvPlanWidget
This commit is contained in:
@@ -17,6 +17,9 @@ class Cis4 extends Auth_Controller
|
||||
'index' => 'basis/cis:r'
|
||||
)
|
||||
);
|
||||
|
||||
// Load Config
|
||||
$this->load->config('calendar');
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------------------
|
||||
@@ -27,15 +30,16 @@ class Cis4 extends Auth_Controller
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$this->load->model('person/Person_model','PersonModel');
|
||||
$this->load->model('person/Person_model', 'PersonModel');
|
||||
$personData = getData($this->PersonModel->getByUid(getAuthUID()))[0];
|
||||
|
||||
$viewData = array(
|
||||
'uid' => getAuthUID(),
|
||||
'name' => $personData->vorname,
|
||||
'person_id' => $personData->person_id
|
||||
'person_id' => $personData->person_id,
|
||||
'timezone' => $this->config->item('timezone')
|
||||
);
|
||||
|
||||
$this->load->view('CisRouterView/CisRouterView.php',['viewData' => $viewData, 'route' => 'FhcDashboard']);
|
||||
$this->load->view('CisRouterView/CisRouterView.php', ['viewData' => $viewData, 'route' => 'FhcDashboard']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -124,27 +124,27 @@
|
||||
|
||||
.dayPageContainer .feiertagEventContent #ferienEventTitle {}
|
||||
|
||||
/* Minimized Container Styles */
|
||||
/* List Page Container Styles */
|
||||
|
||||
/* Ferientage Events for Minimized */
|
||||
/* Ferientage Events for List Page */
|
||||
|
||||
.minimizedContainer .feiertagEventContent{
|
||||
.listPageContainer .feiertagEventContent{
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
color: var(--fhc-light);
|
||||
}
|
||||
|
||||
.minimizedContainer .feiertagEventContent #ferienEventIcon{
|
||||
.listPageContainer .feiertagEventContent #ferienEventIcon{
|
||||
margin: 0.5rem;
|
||||
}
|
||||
|
||||
.minimizedContainer .feiertagEventContent #ferienEventTitle{
|
||||
.listPageContainer .feiertagEventContent #ferienEventTitle{
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
/* Lehreinheits Events in Minimized */
|
||||
.dayPageContainer .lehreinheitEventContent {
|
||||
/* Lehreinheits Events in List Page */
|
||||
.listPageContainer .lehreinheitEventContent {
|
||||
display: flex;
|
||||
padding-left: 4rem;
|
||||
justify-content: space-evenly;
|
||||
@@ -152,15 +152,43 @@
|
||||
|
||||
}
|
||||
|
||||
.dayPageContainer .lehreinheitEventContent #lehreinheitEventHeader {
|
||||
.listPageContainer .lehreinheitEventContent #lehreinheitEventHeader {
|
||||
display: grid;
|
||||
align-content: center;
|
||||
}
|
||||
|
||||
.dayPageContainer .lehreinheitEventContent #lehreinheitEventText {
|
||||
.listPageContainer .lehreinheitEventContent #lehreinheitEventText {
|
||||
display: contents;
|
||||
}
|
||||
|
||||
.dayPageContainer .lehreinheitEventContent #lehreinheitEventText * {
|
||||
.listPageContainer .lehreinheitEventContent #lehreinheitEventText * {
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Widget Styles */
|
||||
.dashboard-widget-lvplan .fhc-calendar-base .card {
|
||||
--bs-card-cap-padding-x: 0;
|
||||
--bs-card-cap-padding-y: 0;
|
||||
--bs-card-border-radius: 0;
|
||||
--bs-card-border-width: 0;
|
||||
--dp-input-padding: .375rem .75rem;
|
||||
--dp-input-icon-padding: calc(1rem + 24px);
|
||||
}
|
||||
.dashboard-widget-lvplan .fhc-calendar-base .card-header {
|
||||
border-bottom-width: var(--bs-border-width);
|
||||
}
|
||||
.dashboard-widget-lvplan .fhc-calendar-base .card-header > .row > .col-auto,
|
||||
.dashboard-widget-lvplan .fhc-calendar-base .card-header .btn-group {
|
||||
width: 100%;
|
||||
}
|
||||
.dashboard-widget-lvplan .fhc-calendar-base .card-header input {
|
||||
--dp-font-size: .7em;
|
||||
}
|
||||
.dashboard-widget-lvplan .fhc-calendar-base .card-header .btn {
|
||||
--bs-btn-font-size: .7em;
|
||||
}
|
||||
.dashboard-widget-lvplan .fhc-calendar-base-label-day {
|
||||
cursor: initial;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.fhc-calendar-base-grid-line-event {
|
||||
.event {
|
||||
cursor: pointer;
|
||||
}
|
||||
.fhc-calendar-mode-week .all-day-events .fhc-calendar-base-grid-line-event .weekPageContainer {
|
||||
@@ -59,9 +59,9 @@
|
||||
.fhc-calendar-base-grid-line-event .event-type-reservierung {
|
||||
--event-default-bg: var(--fhc-calendar-bg-reservierung, #fff);
|
||||
}
|
||||
.fhc-calendar-base-grid-line-event > * {
|
||||
.fhc-calendar-base .event > * {
|
||||
background-color: var(--event-bg, var(--event-default-bg));
|
||||
}
|
||||
.fhc-calendar-base-grid-line-event > *:hover {
|
||||
.fhc-calendar-base .event > *:hover {
|
||||
filter: brightness(120%);
|
||||
}
|
||||
|
||||
@@ -264,6 +264,7 @@ export default {
|
||||
:btn-week="!!modes['week'] && (btnWeek || (showBtns && btnWeek !== false))"
|
||||
:btn-month="!!modes['month'] && (btnMonth || (showBtns && btnMonth !== false))"
|
||||
:btn-list="!!modes['list'] && (btnList || (showBtns && btnList !== false))"
|
||||
:mode-options="modeOptions ? modeOptions[cMode] : undefined"
|
||||
>
|
||||
<slot name="actions" />
|
||||
</base-header>
|
||||
|
||||
@@ -42,7 +42,7 @@ export default {
|
||||
},
|
||||
template: /* html */`
|
||||
<div
|
||||
class="fhc-calendar-base-grid-line-event"
|
||||
class="fhc-calendar-base-grid-line-event event"
|
||||
:class="classes"
|
||||
style="z-index: 1"
|
||||
:draggable="draggable"
|
||||
|
||||
@@ -17,6 +17,10 @@ export default {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
modeOptions: {
|
||||
type: Object,
|
||||
default: {}
|
||||
},
|
||||
btnMonth: Boolean,
|
||||
btnWeek: Boolean,
|
||||
btnDay: Boolean,
|
||||
@@ -62,6 +66,7 @@ export default {
|
||||
@update:date="$emit('update:date', $event)"
|
||||
@open="open = true"
|
||||
@closed="open = false"
|
||||
:list-length="modeOptions.length"
|
||||
/>
|
||||
<button
|
||||
class="btn btn-outline-secondary border-0"
|
||||
|
||||
@@ -51,20 +51,17 @@ export default {
|
||||
case "month":
|
||||
return this.date.toLocaleString({ month: 'long', year: 'numeric' });
|
||||
case "week":
|
||||
const year = this.date.localWeekYear;
|
||||
const week = this.date.toFormat('nn');
|
||||
var year = this.date.localWeekYear;
|
||||
var week = this.date.toFormat('nn');
|
||||
return this.$p.t('calendar/year_kw', { year, week });
|
||||
case "list":
|
||||
return this.date.toLocaleString(luxon.DateTime.DATE_FULL) + '-' + this.date.plus({ days: this.listLength - 1 }).toLocaleString(luxon.DateTime.DATE_FULL);
|
||||
case "day":
|
||||
return this.date.toLocaleString(luxon.DateTime.DATE_FULL);
|
||||
default:
|
||||
return 'View not Supported';
|
||||
}
|
||||
},
|
||||
format() {
|
||||
const title = this.title;
|
||||
return `'${title}'`;
|
||||
},
|
||||
weekStart() {
|
||||
return luxon.Info.getStartOfWeek(this.date)%7;
|
||||
}
|
||||
@@ -97,10 +94,10 @@ export default {
|
||||
<vue-date-picker
|
||||
:model-value="current"
|
||||
@update:model-value="update"
|
||||
:format="format"
|
||||
:format="() => title"
|
||||
:month-picker="mode == 'month'"
|
||||
:week-picker="mode == 'week'"
|
||||
:range="mode == 'list' ? { autoRange: listLength } : false"
|
||||
:range="mode == 'list' ? { autoRange: listLength - 1 } : false"
|
||||
:text-input="mode == 'day'"
|
||||
:week-start="weekStart"
|
||||
:week-numbers="{ type: weekNumbers }"
|
||||
|
||||
@@ -20,7 +20,8 @@ export default {
|
||||
emits: [
|
||||
"update:currentDate",
|
||||
"update:range",
|
||||
"click"
|
||||
"click",
|
||||
"requestModalOpen"
|
||||
],
|
||||
data() {
|
||||
return {
|
||||
@@ -35,9 +36,9 @@ export default {
|
||||
|
||||
if (this.rangeOffset != 0) {
|
||||
if (this.rangeOffset < 0) {
|
||||
first = first.plus({ days: this.rangeOffset * this.length });
|
||||
first = first.plus({ days: this.rangeOffset });
|
||||
} else {
|
||||
last = last.plus({ days: this.rangeOffset * this.length });
|
||||
last = first.plus({ days: this.rangeOffset + this.length });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,7 +47,7 @@ export default {
|
||||
},
|
||||
watch: {
|
||||
currentDate() {
|
||||
this.rangeOffset = Math.floor(this.currentDate.startOf('day').diff(this.focusDate.startOf('day'), 'days').days / this.length);
|
||||
this.rangeOffset = this.currentDate.startOf('day').diff(this.focusDate.startOf('day'), 'days').days;
|
||||
if (this.rangeOffset) {
|
||||
this.$emit('update:range', this.range);
|
||||
this.$refs.slider.slidePages(this.rangeOffset).then(this.updatePage);
|
||||
@@ -65,15 +66,23 @@ export default {
|
||||
this.$refs.slider.nextPage().then(this.updatePage);
|
||||
},
|
||||
updatePage(offset) {
|
||||
const newFocusDate = this.focusDate.plus({ days: offset * this.length });
|
||||
const newFocusDate = this.focusDate.plus({ days: offset });
|
||||
this.focusDate = newFocusDate;
|
||||
this.rangeOffset = 0;
|
||||
this.$emit('update:currentDate', this.focusDate);
|
||||
this.$emit('update:range', this.range);
|
||||
},
|
||||
viewAttrs(offset) {
|
||||
const day = this.focusDate.plus({ days: offset * this.length });
|
||||
const day = this.focusDate.plus({ days: offset });
|
||||
return { day, length: this.length };
|
||||
},
|
||||
handleClickDefaults(evt) {
|
||||
switch (evt.detail.source) {
|
||||
case 'event':
|
||||
// default: Request Modal
|
||||
this.$emit('requestModalOpen', { event: evt.detail.value });
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
@@ -82,6 +91,7 @@ export default {
|
||||
template: `
|
||||
<div
|
||||
class="fhc-calendar-mode-list flex-grow-1 position-relative"
|
||||
@cal-click-default.capture="handleClickDefaults"
|
||||
>
|
||||
<base-slider ref="slider" v-slot="slot">
|
||||
<list-view v-bind="viewAttrs(slot.offset)">
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
import LabelDay from '../../Base/Label/Day.js';
|
||||
import LabelDow from '../../Base/Label/Dow.js';
|
||||
|
||||
import CalDnd from '../../../../directives/Calendar/DragAndDrop.js';
|
||||
import CalClick from '../../../../directives/Calendar/Click.js';
|
||||
|
||||
// TODO(chris): drag and drop
|
||||
|
||||
export default {
|
||||
@@ -9,7 +12,12 @@ export default {
|
||||
LabelDay,
|
||||
LabelDow
|
||||
},
|
||||
directives: {
|
||||
CalDnd,
|
||||
CalClick
|
||||
},
|
||||
inject: {
|
||||
draggableEvents: "draggableEvents",
|
||||
events: "events"
|
||||
},
|
||||
props: {
|
||||
@@ -43,20 +51,31 @@ export default {
|
||||
return eventsPerDay.filter(day => day.events.length);
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
draggable(event) {
|
||||
return this.draggableEvents(event.orig, 'list');
|
||||
},
|
||||
},
|
||||
template: /* html */`
|
||||
<div
|
||||
class="fhc-calendar-mode-list-view h-100"
|
||||
>
|
||||
<div v-if="!eventsPerDay.length">
|
||||
<div class="fhc-calendar-mode-list-view h-100 overflow-auto">
|
||||
<div v-if="!eventsPerDay.length" class="h-100">
|
||||
<slot :event="undefined" mode="list" />
|
||||
</div>
|
||||
<div v-for="{ day, events } in eventsPerDay" class="text-center">
|
||||
<label-dow :date="day" class="d-inline" />, <label-day :date="day" class="d-inline" />
|
||||
<div v-for="event in events">
|
||||
<div v-if="slot.event.type == 'loading'" class="placeholder-glow opacity-50">
|
||||
<div v-if="event.type == 'loading'" class="placeholder-glow opacity-50">
|
||||
<span class="placeholder w-100" />
|
||||
</div>
|
||||
<slot v-else :event="event.orig" mode="list" />
|
||||
<div
|
||||
v-else
|
||||
class="event"
|
||||
:draggable="draggable(event)"
|
||||
v-cal-dnd:draggable="event"
|
||||
v-cal-click:event="event.orig"
|
||||
>
|
||||
<slot :event="event.orig" mode="list" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -19,9 +19,8 @@ export default {
|
||||
viewData: {
|
||||
type: Object,
|
||||
required: true,
|
||||
default: () => ({name: '', uid: ''}),
|
||||
validator(value) {
|
||||
return value && value.name && value.uid
|
||||
return value && value.name && value.uid && value.timezone
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -37,6 +36,7 @@ export default {
|
||||
return {
|
||||
editMode: Vue.computed(()=>this.editMode),
|
||||
widgetsSetup: Vue.computed(() => this.widgets),
|
||||
timezone: Vue.computed(() => this.viewData.timezone)
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
|
||||
@@ -1,266 +1,115 @@
|
||||
import Phrasen from '../../mixins/Phrasen.js';
|
||||
import AbstractWidget from './Abstract.js';
|
||||
import FhcCalendar from '../Calendar/Calendar.js';
|
||||
import LvModal from '../Cis/Mylv/LvModal.js';
|
||||
import ContentModal from '../Cis/Cms/ContentModal.js'
|
||||
import CalendarDate from '../../composables/CalendarDate.js';
|
||||
import FhcCalendar from '../Calendar/Base.js';
|
||||
|
||||
import ApiLvPlan from '../../api/factory/lvPlan.js';
|
||||
import ApiOrt from '../../api/factory/ort.js';
|
||||
|
||||
import { useEventLoader } from '../../composables/EventLoader.js';
|
||||
|
||||
import ModeList from '../Calendar/Mode/List.js';
|
||||
|
||||
export default {
|
||||
name: "LvPlanWidget",
|
||||
components: {
|
||||
FhcCalendar
|
||||
},
|
||||
mixins: [
|
||||
Phrasen,
|
||||
AbstractWidget
|
||||
],
|
||||
components: {
|
||||
FhcCalendar,
|
||||
LvModal,
|
||||
ContentModal
|
||||
},
|
||||
|
||||
inject: [
|
||||
"renderers",
|
||||
"timezone"
|
||||
],
|
||||
data() {
|
||||
return {
|
||||
stunden: [],
|
||||
minimized: true,
|
||||
events: null,
|
||||
currentDay: this.getCurrentDate(),
|
||||
calendarDate: new CalendarDate(new Date()),
|
||||
roomInfoContentID: null,
|
||||
ort_kurzbz: null,
|
||||
selectedEvent: null,
|
||||
isModalContentResolved: false,
|
||||
isModalTitleResolved: false,
|
||||
isShowModal: false,
|
||||
}
|
||||
},
|
||||
inject: ["renderers"],
|
||||
watch:{
|
||||
modalLoaded: {
|
||||
handler: function (newValue) {
|
||||
if (this.isShowModal && newValue.isModalContentResolved && newValue.isModalTitleResolved) {
|
||||
this.$nextTick(() => {
|
||||
if (this.$refs.lvmodal) this.$refs.lvmodal.show();
|
||||
this.isShowModal = false;
|
||||
});
|
||||
now: luxon.DateTime.now().setZone(this.timezone),
|
||||
modes: {
|
||||
list: Vue.markRaw(ModeList)
|
||||
},
|
||||
modeOptions: {
|
||||
list: {
|
||||
length: 7
|
||||
}
|
||||
},
|
||||
immediate: true
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
modalLoaded: function () {
|
||||
return { isModalContentResolved: this.isModalContentResolved, isModalTitleResolved: this.isModalTitleResolved };
|
||||
},
|
||||
allEventsGrouped() {
|
||||
// groups all events of the next 7 days together
|
||||
const currentCalendarDate = new CalendarDate(this.currentDay)
|
||||
const mapArr = currentCalendarDate.nextSevenDays.map((d) => [new CalendarDate(d), []])
|
||||
|
||||
// return map of key => calendar date of next 7 days & values the respective events on that date
|
||||
return new Map((this.events || []).filter(evt => evt.start >= this.currentDay).reduce((acc, cur) => {
|
||||
const date = new CalendarDate(new Date(cur.datum))
|
||||
const arr = acc.find(el => el[0].compare(date))
|
||||
if(!arr) return acc
|
||||
arr[1].push(cur)
|
||||
|
||||
return acc
|
||||
}, mapArr));
|
||||
},
|
||||
currentEvents() {
|
||||
return (this.events || []).filter(evt => evt.end < this.dayAfterCurrentDay && evt.start >= this.currentDay);
|
||||
},
|
||||
dayAfterCurrentDay() {
|
||||
let currentDay = new Date(this.currentDay);
|
||||
currentDay.setDate(currentDay.getDate() + 1);
|
||||
return currentDay;
|
||||
},
|
||||
monthFirstDay: function () {
|
||||
return this.calendarDateToString(this.calendarDate.cdFirstDayOfCalendarMonth);
|
||||
},
|
||||
monthLastDay: function () {
|
||||
return this.calendarDateToString(this.calendarDate.cdLastDayOfNextCalendarMonth);
|
||||
},
|
||||
currentDay: luxon.DateTime.now().setZone(this.timezone).startOf('day')
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
showModal: function (event) {
|
||||
this.currentlySelectedEvent = event;
|
||||
Vue.nextTick(() => {
|
||||
if (this.isModalContentResolved && this.isModalTitleResolved) {
|
||||
if (this.$refs.lvmodal) this.$refs.lvmodal.show();
|
||||
}
|
||||
else {
|
||||
this.isShowModal = true;
|
||||
}
|
||||
})
|
||||
},
|
||||
modalTitleResolved: function () {
|
||||
this.isModalTitleResolved = true;
|
||||
|
||||
},
|
||||
modalContentResolved: function () {
|
||||
this.isModalContentResolved = true;
|
||||
|
||||
},
|
||||
modalTitleComponent(type) {
|
||||
return this.renderers[type]?.modalTitle;
|
||||
},
|
||||
modalContentComponent(type) {
|
||||
return this.renderers[type]?.modalContent;
|
||||
},
|
||||
calendarEventComponent(type) {
|
||||
return this.renderers[type]?.calendarEvent;
|
||||
},
|
||||
getEventStyle: function(evt) {
|
||||
const styles = {'background-color': evt.color};
|
||||
if(evt.start.getTime() < Date.now()) styles.opacity = 0.5;
|
||||
eventStyle(event) {
|
||||
const styles = {};
|
||||
if (event.farbe)
|
||||
styles['--event-bg'] = '#' + event.farbe;
|
||||
else if (event.type == 'reservierung')
|
||||
styles['--event-bg'] = '#ffffff';
|
||||
else
|
||||
styles['--event-bg'] = '#cccccc';
|
||||
|
||||
const eventEnd = luxon.DateTime.fromISO(event.isoend, { zone: this.timezone });
|
||||
if (eventEnd < this.now)
|
||||
styles['opacity'] = .5;
|
||||
|
||||
return styles;
|
||||
},
|
||||
getCurrentDate: function() {
|
||||
const today = new Date()
|
||||
today.setHours(0,0,0)
|
||||
return today
|
||||
},
|
||||
calendarDateToString: function (calendarDate) {
|
||||
|
||||
return calendarDate instanceof CalendarDate ?
|
||||
[calendarDate.y, calendarDate.m + 1, calendarDate.d].join('-') :
|
||||
null;
|
||||
|
||||
},
|
||||
showRoomInfoModal: function(ort_kurzbz){
|
||||
// getting the content_id of the ort_kurzbz
|
||||
this.$api
|
||||
.call(ApiOrt.getContentID(ort_kurzbz))
|
||||
.then(res => {
|
||||
this.roomInfoContentID = res.data;
|
||||
this.ort_kurzbz = ort_kurzbz;
|
||||
|
||||
// only showing the modal after vue was able to set the reactive data
|
||||
Vue.nextTick(() => { this.$refs.contentModal.show(); });
|
||||
})
|
||||
.catch(err => {
|
||||
console.err(err);
|
||||
this.ort_kurzbz = null;
|
||||
this.roomInfoContentID = null;
|
||||
});
|
||||
},
|
||||
showLvUebersicht: function (event){
|
||||
this.selectedEvent= event;
|
||||
Vue.nextTick(()=>{
|
||||
this.$refs.lvmodal.show();
|
||||
});
|
||||
},
|
||||
|
||||
selectDay(day) {
|
||||
this.currentDay = day;
|
||||
this.minimized = true;
|
||||
},
|
||||
|
||||
updateRange: function (data) {
|
||||
|
||||
let tmp_date = new CalendarDate(data.start);
|
||||
// only load month data if the month or year has changed
|
||||
if (tmp_date.m != this.calendarDate.m || tmp_date.y != this.calendarDate.y) {
|
||||
this.calendarDate = tmp_date;
|
||||
Vue.nextTick(() => {
|
||||
this.loadEvents();
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
loadEvents: function () {
|
||||
Promise.allSettled([
|
||||
this.$api.call(ApiLvPlan.LvPlanEvents(this.monthFirstDay, this.monthLastDay)),
|
||||
this.$api.call(ApiLvPlan.getLvPlanReservierungen(this.monthFirstDay, this.monthLastDay))
|
||||
]).then((result) => {
|
||||
let promise_events = [];
|
||||
result.forEach((promise_result) => {
|
||||
if (promise_result.status === 'fulfilled' && promise_result.value.meta.status === "success") {
|
||||
|
||||
let data = promise_result.value.data;
|
||||
// adding additional information to the events
|
||||
if (data && data.forEach) {
|
||||
|
||||
data.forEach((el, i) => {
|
||||
el.id = i;
|
||||
if (el.type === 'reservierung') {
|
||||
el.color = '#' + (el.farbe || 'FFFFFF');
|
||||
} else {
|
||||
el.color = '#' + (el.farbe || 'CCCCCC');
|
||||
}
|
||||
|
||||
el.start = new Date(el.datum + ' ' + el.beginn);
|
||||
el.end = new Date(el.datum + ' ' + el.ende);
|
||||
|
||||
});
|
||||
}
|
||||
promise_events = promise_events.concat(data);
|
||||
}
|
||||
})
|
||||
this.events = promise_events;
|
||||
});
|
||||
},
|
||||
|
||||
setCalendarMaximized() {
|
||||
this.minimized = false
|
||||
updateRange(rangeInterval) {
|
||||
this.rangeInterval = rangeInterval;
|
||||
}
|
||||
|
||||
},
|
||||
setup() {
|
||||
const $api = Vue.inject('$api');
|
||||
|
||||
const rangeInterval = Vue.ref(null);
|
||||
|
||||
const { events } = useEventLoader(rangeInterval, (start, end) => {
|
||||
return [
|
||||
$api.call(ApiLvPlan.LvPlanEvents(start.toISODate(), end.toISODate())),
|
||||
$api.call(ApiLvPlan.getLvPlanReservierungen(start.toISODate(), end.toISODate()))
|
||||
];
|
||||
});
|
||||
|
||||
return {
|
||||
rangeInterval,
|
||||
events
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.$emit('setConfig', false);
|
||||
this.loadEvents();
|
||||
},
|
||||
template: /*html*/`
|
||||
<div class="dashboard-widget-lvplan d-flex flex-column h-100">
|
||||
<lv-modal v-if="selectedEvent" ref="lvmodal" :event="selectedEvent" >
|
||||
<template #modalTitle>
|
||||
<Suspense @pending="isModalTitleResolved=false" @resolve="modalTitleResolved">
|
||||
<component :is="modalTitleComponent(selectedEvent.type)" v-if="selectedEvent" :event="selectedEvent" ></component>
|
||||
</Suspense>
|
||||
</template>
|
||||
<template #modalContent>
|
||||
<Suspense @pending="isModalContentResolved=false" @resolve="modalContentResolved">
|
||||
<component :is="modalContentComponent(selectedEvent.type)" v-if="selectedEvent" :event="selectedEvent" ></component>
|
||||
</Suspense>
|
||||
</template>
|
||||
</lv-modal>
|
||||
<content-modal :content_id="roomInfoContentID" dialogClass="modal-lg" ref="contentModal"/>
|
||||
<fhc-calendar @change:range="updateRange" :initial-date="currentDay" class="border-0" class-header="p-0" @select:day="selectDay" :widget="true" v-model:minimized="minimized" :events="events" no-week-view :show-weeks="false" >
|
||||
<template #monthPage="{event,day}">
|
||||
<div v-if="event.type=='moodle'">
|
||||
<div class="d-flex small w-100" >
|
||||
<moodle-svg></moodle-svg>
|
||||
<span v-contrast class="flex-grow-1 text-center "><strong v-html="event.titel"></strong> - {{event.topic}}</span>
|
||||
</div>
|
||||
<fhc-calendar
|
||||
v-model:date="currentDay"
|
||||
:modes="modes"
|
||||
:mode-options="modeOptions"
|
||||
@update:range="updateRange"
|
||||
:timezone="timezone"
|
||||
:locale="$p.user_locale.value"
|
||||
:events="events"
|
||||
>
|
||||
<template v-slot="{ event, mode }">
|
||||
<div
|
||||
v-if="!event"
|
||||
class="h-100 d-flex justify-content-center align-items-center"
|
||||
>
|
||||
{{ $p.t('lehre/noLvFound') }}
|
||||
</div>
|
||||
<span v-else class="small" >
|
||||
{{event.topic}}
|
||||
</span>
|
||||
</template>
|
||||
<template #minimizedPage >
|
||||
<div class="minimizedContainer flex-grow-1" style="overflow-y: auto; overflow-x: hidden">
|
||||
<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>
|
||||
<template v-else-if="allEventsGrouped.size" v-for="([key, value], index) in allEventsGrouped" :key="index" style="margin-top: 8px;">
|
||||
<div class=" card-header d-grid p-0">
|
||||
<button class="btn fhc-tertiary text-decoration-none" @click="setCalendarMaximized">{{ key.format({dateStyle: "full"}, $p.user_locale.value)}}</button>
|
||||
</div>
|
||||
<div role="button" @click="showLvUebersicht(evt)" v-for="evt in value" :key="evt.id" class="list-group-item small" :style="getEventStyle(evt)">
|
||||
<component :is="calendarEventComponent(evt.type)" :event="evt" ></component>
|
||||
</div>
|
||||
<div v-if="!value.length" class="list-group-item small text-center">
|
||||
{{ $p.t('lehre/noLvFound') }}
|
||||
</div>
|
||||
</template>
|
||||
<div v-else class="d-flex h-100 justify-content-center align-items-center fst-italic text-center">
|
||||
{{ $p.t('lehre/noLvFound') }}
|
||||
</div>
|
||||
<component
|
||||
v-else-if="mode == 'eventheader'"
|
||||
:is="renderers[event.type]?.modalTitle"
|
||||
:event="event"
|
||||
></component>
|
||||
<component
|
||||
v-else-if="mode == 'event'"
|
||||
:is="renderers[event.type]?.modalContent"
|
||||
:event="event"
|
||||
></component>
|
||||
<div
|
||||
v-else
|
||||
:class="'event-type-' + event.type + ' ' + mode + 'PageContainer'"
|
||||
:style="eventStyle(event)"
|
||||
>
|
||||
<component
|
||||
:is="renderers[event.type]?.calendarEvent"
|
||||
:event="event"
|
||||
></component>
|
||||
</div>
|
||||
</template>
|
||||
</fhc-calendar>
|
||||
|
||||
Reference in New Issue
Block a user