Compare commits

...
Author SHA1 Message Date
ma0048 9dadd470de raumvorschlag slots erstentwurf 2026-08-05 14:17:24 +02:00
8 changed files with 455 additions and 62 deletions
@@ -20,6 +20,7 @@ class Kalender extends FHCAPI_Controller
'getPlan' => self::PERM_LOGGED,
'getPlanByOrt' => self::PERM_LOGGED,
'getRaumvorschlag' => self::PERM_LOGGED,
'getRaumvorschlagSlots' => self::PERM_LOGGED,
'getHistory' => 'lehre/lvplan:rw',
'deleteEntry' => 'lehre/lvplan:rw',
'syncToLecturer' => 'lehre/lvplan:rw',
@@ -235,6 +236,22 @@ class Kalender extends FHCAPI_Controller
$this->terminateWithSuccess($this->_ci->raumvorschlaglib->getVorschlaege($filter->kalender_id));
}
public function getRaumvorschlagSlots()
{
$this->_ci->form_validation->set_data($_GET);
$this->_ci->form_validation->set_rules('lehreinheit_id',"lehreinheit_id","required");
$this->_ci->form_validation->set_rules('start_date',"start_date","required");
$this->_ci->form_validation->set_rules('end_date',"end_date","required");
if($this->_ci->form_validation->run() === FALSE)
$this->terminateWithValidationErrors($this->_ci->form_validation->error_array());
$lehreinheit_id = $this->_ci->input->get('lehreinheit_id', TRUE);
$start_date = $this->_ci->input->get('start_date', TRUE);
$end_date = $this->_ci->input->get('end_date', TRUE);
$this->terminateWithSuccess(getData($this->_ci->raumvorschlaglib->getVorschlaegeSlots($lehreinheit_id, $start_date, $end_date)));
}
public function getHistory()
{
$this->_ci->form_validation->set_data($_GET);
+1
View File
@@ -313,6 +313,7 @@ class KalenderLib
foreach ($lehrverband_gruppen as $lvg)
{
$lvg = (array) $lvg;
$this->_ci->KalenderModel->db->or_group_start();
$this->_ci->KalenderModel->db->where('tbl_lehreinheitgruppe.studiengang_kz', $lvg['studiengang_kz']);
$this->_ci->KalenderModel->db->where('tbl_lehreinheitgruppe.semester', $lvg['semester']);
+176 -15
View File
@@ -23,7 +23,6 @@ class RaumvorschlagLib
$this->_ci->load->model('organisation/gruppe_model', 'GruppeModel');
$this->_ci->load->model('organisation/Lehrverband_model', 'LehrverbandModel');
$this->_ci->load->model('education/Lehreinheitgruppe_model', 'LehreinheitgruppeModel');
$this->_ci->load->model('education/Lehreinheitgruppe_model', 'LehreinheitgruppeModel');
$this->_ci->load->library('CollisionChecker');
@@ -37,14 +36,18 @@ class RaumvorschlagLib
$event = $this->_ci->kalenderlib->getByKalenderId($kalender_id);
$event = $event[0];
$raumkandidaten = $this->_getRaumkandidaten($event);
if (empty($kandidaten)) return [];
$lektor_uids = array_column($event->lektor, 'mitarbeiter_uid');
$gruppen_kurzbz = array_values(array_filter(array_column($event->gruppe, 'gruppe_kurzbz')));
$lehrverband_gruppen = array_values(array_filter($event->gruppe, function($gruppe)
{
$lehrverband_gruppen = array_values(array_filter($event->gruppe, function($gruppe) {
return empty($gruppe['gruppe_kurzbz']);
}));
$lehrverband_gruppen_bezeichnung = array_column($lehrverband_gruppen, 'bezeichnung');
$tages_events = $this->_ci->kalenderlib->getForRaumvorschlag(
$event->datum,
$event->datum,
@@ -53,22 +56,170 @@ class RaumvorschlagLib
$lehrverband_gruppen
);
$lektor_davor = $this->_getEventDavor($tages_events, $event->isostart, $lektor_uids, 'lektor');
$gruppen_davor = $this->_getEventDavor($tages_events, $event->isostart, $gruppen_kurzbz, 'gruppe');
return $this->_getRatings($tages_events, $event, $raumkandidaten, $lektor_uids, $gruppen_kurzbz, $lehrverband_gruppen_bezeichnung);
}
public function getVorschlaegeSlots($lehreinheit_id, $start_date, $end_date)
{
$lehreinheit_result = $this->_ci->LehreinheitModel->load($lehreinheit_id);
if (!hasData($lehreinheit_result))
return error('Lehreinheit nicht gefunden');
$lehreinheit = getData($lehreinheit_result)[0];
$block = $lehreinheit->stundenblockung;
if ($block <= 0)
return error('Stundenblockung ist ungültig');
$this->_ci->StundeModel->addOrder('stunde', 'ASC');
$stunden_result = $this->_ci->StundeModel->load();
$stunden = hasData($stunden_result) ? array_values(getData($stunden_result)) : [];
if (empty($stunden))
return error('Kein Stunden-Raster gefunden');
$lektoren_result = $this->_ci->LehreinheitMitarbeiterModel->loadWhere(['lehreinheit_id' => $lehreinheit_id]);
$lektor_uids = hasData($lektoren_result) ? array_column(getData($lektoren_result), 'mitarbeiter_uid') : [];
$gruppen_result = $this->_ci->LehreinheitgruppeModel->getDirectGroup($lehreinheit_id);
$gruppen = getData($gruppen_result);
$gruppen_kurzbz = hasData($gruppen_result) ? array_column($gruppen, 'gruppe_kurzbz') : [];
$lehrverband_result = $this->_ci->LehreinheitgruppeModel->getByLehreinheit($lehreinheit_id);
$lehrverband_gruppen = hasData($lehrverband_result) ? getData($lehrverband_result) : [];
$lehrverband_gruppen_bezeichnung = array_column($lehrverband_gruppen, 'bezeichnung');
$verplante_events = $this->_ci->kalenderlib->getForRaumvorschlag(
$start_date,
$end_date,
$lektor_uids,
$gruppen_kurzbz,
$lehrverband_gruppen);
$start_day = strtotime($start_date);
$end_day = strtotime($end_date);
$moegliche_slots = array();
while ($start_day < $end_day)
{
$tag = date('Y-m-d', $start_day);
$verplante_tages_events = array_values(array_filter($verplante_events, function($event) use ($tag)
{
return $event->datum === $tag;
}));
foreach ($stunden as $index => $start_stunde)
{
if (!isset($stunden[$index + $block - 1]))
continue;
$end_stunde = $stunden[$index + $block - 1];
$slot_start = $tag . ' ' . $start_stunde->beginn;
$slot_end = $tag . ' ' . $end_stunde->ende;
if (!$this->_isFrei($slot_start, $slot_end, $verplante_tages_events, $lektor_uids, 'lektor'))
continue;
if (!$this->_isFrei($slot_start, $slot_end, $verplante_tages_events, $gruppen_kurzbz, 'gruppe'))
continue;
if (!$this->_isFrei($slot_start, $slot_end, $verplante_tages_events, $lehrverband_gruppen_bezeichnung, 'lehrverband'))
continue;
$moegliche_slots[] = [
'isostart' => (new DateTime($slot_start))->format('c'),
'isoend' => (new DateTime($slot_end))->format('c'),
'marker_isoend' => (new DateTime($tag . ' ' . $start_stunde->ende))->format('c'),
];
}
$start_day = strtotime('+1 day', $start_day);
}
$slots = [];
foreach ($moegliche_slots as $slot)
{
$event_obj = (object) [
'lehreinheit_id' => [$lehreinheit_id],
'isostart' => $slot['isostart'],
'isoend' => $slot['isoend'],
];
$raumkandidaten = $this->_getRaumkandidaten($event_obj);
if (empty($raumkandidaten))
continue;
$ratings = $this->_getRatings($verplante_events, $slot, $raumkandidaten, $lektor_uids, $gruppen_kurzbz, $lehrverband_gruppen_bezeichnung);
$best = $ratings[0];
$anzahl_weitere = count($ratings) - 1;
$slots[] = [
'isostart' => $slot['isostart'],
'isoend' => $slot['isoend'],
'marker_isoend' => $slot['marker_isoend'],
'rating' => $this->_scoreToRating($best['score']),
'label' => $anzahl_weitere > 0 ? $best['ort_kurzbz'] . ' (' . $best['score'] . ') + ' . $anzahl_weitere . ' weitere' : $best['ort_kurzbz'] . ' (' . $best['score'] . ')',
'raeume' => $ratings,
];
}
return success($slots);
}
//TODO (david) umbauen auf CollisionChecks
private function _isFrei($slot_start, $slot_end, $events, $check_array, $type)
{
if (empty($check_array)) return true;
$slot_start_ts = strtotime($slot_start);
$slot_end_ts = strtotime($slot_end);
foreach ($events as $event)
{
$event_start_ts = strtotime($event->isostart);
$event_end_ts = strtotime($event->isoend);
if ($event_end_ts <= $slot_start_ts || $event_start_ts >= $slot_end_ts)
continue;
$event_uids = $this->_getIds($event, $type);
if (!empty(array_intersect($event_uids, $check_array)))
return false;
}
return true;
}
private function _scoreToRating($score)
{
if ($score >= 90)
return 'good';
if ($score >= 60)
return 'mid';
return 'bad';
}
private function _getRatings($events, $event, $raumkandidaten, $lektor_uids, $gruppen_kurzbz, $lehrverband_gruppen_bezeichnung)
{
$event = (object)$event;
$lektor_davor = $this->_getEventDavor($events, $event->isostart, $lektor_uids, 'lektor');
$gruppen_davor = $this->_getEventDavor($events, $event->isostart, $gruppen_kurzbz, 'gruppe');
$lehrverband_davor = $this->_getEventDavor($events, $event->isostart, $lehrverband_gruppen_bezeichnung, 'lehrverband');
$lektor_davor_ort = $lektor_davor ? $this->_getOrtDetails($lektor_davor->ort_kurzbz) : null;
$gruppen_davor_ort = $gruppen_davor ? $this->_getOrtDetails($gruppen_davor->ort_kurzbz) : null;
$kandidaten = $this->_getRaumkandidaten($event);
if (empty($kandidaten)) return [];
$lehrverband_davor_ort = $lehrverband_davor ? $this->_getOrtDetails($lehrverband_davor->ort_kurzbz) : null;
$ratings = [];
foreach ($kandidaten as $raum)
foreach ($raumkandidaten as $raum)
{
$rating = ['ort_kurzbz' => $raum->ort_kurzbz, 'score' => 100, 'details' => []];
$this->_rateLektor($rating, $raum, $lektor_davor_ort);
$this->_rateGruppen($rating, $raum, $gruppen_davor_ort);
$this->_rateGruppen($rating, $raum, $lehrverband_davor_ort);
Events::trigger('room_rating',
function & () use (&$rating) {
@@ -86,7 +237,6 @@ class RaumvorschlagLib
});
return $ratings;
}
private function _getOrtDetails($ort_kurzbz_array)
@@ -196,10 +346,7 @@ class RaumvorschlagLib
if (empty($event->ort_kurzbz))
continue;
if ($type === 'lektor')
$event_uids = array_column($event->lektor, 'mitarbeiter_uid');
else
$event_uids = array_column($event->gruppe, 'gruppe_kurzbz');
$event_uids = $this->_getIds($event, $type);
if (empty(array_intersect($event_uids, $uids)))
continue;
@@ -211,6 +358,20 @@ class RaumvorschlagLib
return $kandidat;
}
private function _getIds($event, $type)
{
$event_uids = array();
if ($type === 'lektor')
$event_uids = array_column($event->lektor, 'mitarbeiter_uid');
else if ($type === 'gruppen')
$event_uids = array_column($event->gruppe, 'gruppe_kurzbz');
else if ($type === 'lehrverband')
$event_uids = array_column($event->gruppe, 'bezeichnung');
return $event_uids;
}
private function _getRaumkandidaten($event)
{
$lehreinheit = $this->_ci->LehreinheitModel->load($event->lehreinheit_id[0]);
+15
View File
@@ -171,6 +171,21 @@ body {
}
.bg-raumvorschlag-slot {
opacity: .70;
}
.bg-raumvorschlag-slot.rating-good {
background-color: var(--bs-success);
}
.bg-raumvorschlag-slot.rating-mid {
background-color: var(--bs-warning);
}
.bg-raumvorschlag-slot.rating-bad {
background-color: var(--bs-danger);
}
.wish-w--2 {
background-color: #FF2200;
}
+8
View File
@@ -8,6 +8,14 @@ export default {
params: { ...filter, start_date, end_date }
};
},
getRaumvorschlagSlots(lehreinheit_id, start_date, end_date)
{
return {
method: 'get',
url: '/api/frontend/v1/tempus/Kalender/getRaumvorschlagSlots',
params: { lehreinheit_id, start_date, end_date }
};
},
getPlanLecturer(start_date, end_date)
{
return {
+5 -1
View File
@@ -59,6 +59,10 @@ export default {
type: Array,
default: () => ['all']
},
showEvents: {
type: Boolean,
default: true
}
},
emits: [
"update:date",
@@ -227,7 +231,7 @@ export default {
>
<template v-slot="{ event, mode }">
<div
:class="['event-type-' + event.type + ' ' + mode + 'PageContainer', { 'event--parked': parkedEvents.has(String(event.kalender_id)) }]"
:class="['event-type-' + event.type + ' ' + mode + 'PageContainer', { 'event--parked': parkedEvents.has(String(event.kalender_id)) }, {'event--opacity': !showEvents}]"
:type="mode == 'day' ? 'button' : undefined"
:style="eventStyle(event)"
@mouseenter="$emit('event-hover', event)"
+34 -2
View File
@@ -18,8 +18,16 @@ export default {
type: String,
default: null
},
previewLehreinheitId: {
type: [String, Number],
default: null
},
previewLoading: {
type: Boolean,
default: false
},
},
emits: ['select-lecturer', 'select-kw'],
emits: ['select-lecturer', 'select-kw', 'preview-raumvorschlag'],
data() {
return {
searchparam: '',
@@ -209,6 +217,17 @@ export default {
{
return this.favorites.has(course.lehreinheit_id);
},
selectRaumvorschlag(course)
{
if (this.isRaumvorschlagActive(course))
this.$emit('preview-raumvorschlag', null);
else
this.$emit('preview-raumvorschlag', course.orig);
},
isRaumvorschlagActive(course)
{
return this.previewLehreinheitId != null && this.previewLehreinheitId === course.lehreinheit_id;
},
},
mounted() {
this.favorites = new Set(JSON.parse(localStorage.getItem('tempus_coursepicker_favs') || '[]'));
@@ -263,7 +282,7 @@ export default {
style="cursor:grab"
:style="courseStyle(course)"
class="course-picker-row rounded-3 mb-2 p-2"
:class="{ 'course-picker-row-pinned': isPinned(course) }"
:class="{ 'course-picker-row-pinned': isPinned(course), 'course-picker-row-preview': isRaumvorschlagActive(course) }"
v-draggable:move.noimage="dragLehreinheitCollection(course)"
tabindex="0"
>
@@ -283,6 +302,19 @@ export default {
v-tooltip="isMultiWeek(course) ? 'MultiWeek aktiv' : 'MultiWeek Verplanung aktivieren'"
@click.stop="toggleMultiWeek(course)"
></i>
<i
v-if="!(previewLoading && isRaumvorschlagActive(course))"
class="fa fa-door-open"
:class="isRaumvorschlagActive(course) ? 'text-primary' : 'text-muted'"
style="cursor:pointer"
v-tooltip="isRaumvorschlagActive(course) ? 'Raumvorschlag ausblenden' : 'Raumvorschlag einblenden'"
@click.stop="selectRaumvorschlag(course)"
></i>
<i
v-else
class="fa fa-spinner fa-spin text-primary"
v-tooltip="'Räume werden geprüft...'"
></i>
</div>
<!--TODO(david) entfernen, dient nur für das mappen mit der lvverwaltung-->
+199 -44
View File
@@ -121,11 +121,6 @@ export default {
hoveredEvent: null,
//currentDay: new Date(),
studiensemesterKurzbz: this.defaultSemester,
lists: {
nations: [],
sprachen: [],
geschlechter: [],
},
renderers: null,
ort_kurzbz: null,
view: "room",
@@ -170,6 +165,9 @@ export default {
assignedResources: [],
areFormButtonsDisplayed: false,
},
raumvorschlagPreview: null,
raumvorschlagLoading: false,
showEvents: true
};
},
computed: {
@@ -228,7 +226,8 @@ export default {
this.$refs.raumModal.show();
});
},
async openResourcesAssignmentModal(orig) {
async openResourcesAssignmentModal(orig)
{
if (!orig?.kalender_id) return;
this.resourcesAssignmentModal.calendar = orig;
@@ -249,6 +248,7 @@ export default {
await this.deleteEntryCall(orig);
this.$refs.calendar.resetEventLoader();
this.$refs.coursepicker.reload();
this.rebuildRaumvorschlag();
},
async deleteEntries(origList) {
let validList = (origList ?? []).filter((orig) => orig?.kalender_id);
@@ -290,16 +290,102 @@ export default {
},
async selectRaum(ort_kurzbz) {
const orig = this.raumModal;
if (orig.kalender_id)
{
await this.$api
.call(
ApiKalender.updateKalenderEvent(orig.kalender_id, {
ort_kurzbz,
start_time: orig.von,
end_time: orig.bis,
}),
)
.then(() => {
this.$refs.raumModal.hide();
this.rebuildRaumvorschlag();
});
this.$refs.calendar.resetEventLoader();
return;
}
await this.$api
.call(
ApiKalender.updateKalenderEvent(orig.kalender_id, {
ort_kurzbz,
start_time: orig.von,
end_time: orig.bis,
}),
ApiKalender.addKalenderEvent(
orig.lehreinheit_id,
[ort_kurzbz],
orig.von,
orig.bis,
),
)
.then(() => this.$refs.raumModal.hide());
this.$refs.calendar.resetEventLoader();
.then(() => {
this.$refs.raumModal.hide();
this.$refs.calendar.resetEventLoader();
this.$refs.coursepicker.reload();
this.bcc.postMessage("dropped");
this.rebuildRaumvorschlag();
});
},
rebuildRaumvorschlag()
{
this.previewRaumvorschlag({ lehreinheit_id: this.raumvorschlagPreview.lehreinheit_id });
},
async previewRaumvorschlag(orig)
{
if (!orig)
{
this.clearRaumvorschlagPreview();
return;
}
if (!this.lastRange) return;
this.raumvorschlagLoading = true;
this.raumvorschlagPreview = { lehreinheit_id: orig.lehreinheit_id, slots: [] };
await this.$api
.call(
ApiKalender.getRaumvorschlagSlots(
orig.lehreinheit_id,
this.lastRange.start.toISODate(),
this.lastRange.end.toISODate(),
),
)
.then((result) => {
this.raumvorschlagPreview.slots = (result.data ?? []).map((slot) => ({
class: `rounded-3 bg-raumvorschlag-slot rating-${slot.rating}`,
start: slot.isostart,
matchEnd: slot.isoend,
end: slot.marker_isoend,
label: slot.label,
raeume: slot.raeume,
}));
if (this.raumvorschlagPreview.slots.length > 0)
this.showEvents = false;
})
.catch(this.$fhcAlert.handleSystemError)
.finally(() => {
this.raumvorschlagLoading = false;
this.rebuildExtraBackgrounds();
});
},
clearRaumvorschlagPreview() {
this.raumvorschlagPreview = null;
this.rebuildExtraBackgrounds();
this.showEvents = true;
},
findRaumvorschlagSlot(lehreinheit_id, startDT, endDT) {
if (this.raumvorschlagPreview?.lehreinheit_id !== lehreinheit_id) return null;
return this.raumvorschlagPreview.slots.find((slot) => {
const slotStart = luxon.DateTime.fromISO(slot.start);
const slotEnd = luxon.DateTime.fromISO(slot.matchEnd);
return (
slotStart.toMillis() === startDT.toMillis() &&
slotEnd.toMillis() === endDT.toMillis()
);
}) ?? null;
},
setOrt: function (data) {
this.ort_kurzbz = data.ort_kurzbz;
@@ -572,6 +658,7 @@ export default {
() => {
this.$refs.calendar.resetEventLoader();
this.$refs.coursepicker.reload();
this.rebuildRaumvorschlag();
},
);
},
@@ -586,7 +673,9 @@ export default {
const obj = item[0];
if (!obj?.type) return alert("Unbekannter Drop-Typ");
if (payload.targetKalenderId) {
if (payload.targetKalenderId)
{
if (obj.type !== "lehreinheit" || !obj.orig?.lehreinheit_id)
return alert(
"Nur Lehreinheiten können einem Termin hinzugefügt werden",
@@ -601,6 +690,7 @@ export default {
)
.then(() => {
this.$refs.calendar.resetEventLoader();
this.rebuildRaumvorschlag();
this.bcc.postMessage("dropped");
});
}
@@ -610,11 +700,15 @@ export default {
const { startDT, endDT, start_time, end_time } = dates;
if (obj.type === "reservierung") {
if (obj.type === "reservierung")
{
this.reservierungPending = true;
this.$refs.reservierung.show(start_time, end_time);
} else if (obj.type === "lehreinheit") {
if (obj.multiweek) {
}
else if (obj.type === "lehreinheit")
{
if (obj.multiweek)
{
this.openMultiWeekPreview(
obj.orig.lehreinheit_id,
this.ort_kurzbz ? this.ort_kurzbz : obj.orig.ort_kurzbz,
@@ -624,26 +718,66 @@ export default {
return;
}
return this.$api
.call(
ApiKalender.addKalenderEvent(
obj.orig.lehreinheit_id,
this.rooms.length
? this.rooms.map((r) => r.ort_kurzbz)
: obj.orig.ort_kurzbz
? [obj.orig.ort_kurzbz]
: [],
start_time,
end_time,
),
)
.then((result) => result.data)
.then((result) => {
this.$refs.calendar.resetEventLoader();
this.$refs.coursepicker.reload();
this.bcc.postMessage("dropped");
});
} else if (obj.type === "kalender") {
const matchedSlot = this.findRaumvorschlagSlot(
obj.orig.lehreinheit_id,
startDT,
endDT,
);
const raeume = matchedSlot?.raeume ?? null;
if (!raeume)
{
return this.$api
.call(
ApiKalender.addKalenderEvent(
obj.orig.lehreinheit_id,
this.rooms.length
? this.rooms.map((r) => r.ort_kurzbz)
: obj.orig.ort_kurzbz
? [obj.orig.ort_kurzbz]
: [],
start_time,
end_time,
),
)
.then((result) => result.data)
.then((result) => {
this.$refs.calendar.resetEventLoader();
this.$refs.coursepicker.reload();
this.bcc.postMessage("dropped");
this.rebuildRaumvorschlag();
});
}
if (raeume.length === 1)
{
return this.$api
.call(
ApiKalender.addKalenderEvent(
obj.orig.lehreinheit_id,
[raeume[0].ort_kurzbz],
start_time,
end_time,
),
)
.then(() => {
this.$refs.calendar.resetEventLoader();
this.$refs.coursepicker.reload();
this.bcc.postMessage("dropped");
this.rebuildRaumvorschlag();
});
}
this.raumModal = {
lehreinheit_id: obj.orig.lehreinheit_id,
von: start_time,
bis: end_time,
};
this.raumVorschlaege = raeume;
this.$refs.raumModal.show();
}
else if (obj.type === "kalender")
{
return this._updateKalenderEvent(
obj,
startDT,
@@ -656,10 +790,13 @@ export default {
id: obj.orig.kalender_id,
});
this.$refs.calendar.resetEventLoader();
this.rebuildRaumvorschlag();
this.bcc.postMessage("dropped");
},
);
} else {
}
else
{
alert("Unbekannter Drop-Typ: " + obj.type);
}
},
@@ -676,6 +813,7 @@ export default {
onMultiWeekConfirmed() {
this.$refs.calendar.resetEventLoader();
this.$refs.coursepicker.reload();
this.rebuildRaumvorschlag();
this.bcc.postMessage("dropped");
},
handleRange(range) {
@@ -699,6 +837,9 @@ export default {
}
this.rebuildExtraBackgrounds();
if (this.raumvorschlagPreview)
this.previewRaumvorschlag({ lehreinheit_id: this.raumvorschlagPreview.lehreinheit_id });
},
getOverlays(uid, range, rangeKey) {
@@ -785,6 +926,9 @@ export default {
if (lect.overlays.wishes) res.push(...(entry.wishes || []));
}
if (this.raumvorschlagPreview)
res.push(...this.raumvorschlagPreview.slots);
this.extraBackgrounds = res;
},
@@ -987,6 +1131,7 @@ export default {
studiengaenge: {
deep: true,
handler() {
this.clearRaumvorschlagPreview();
this.$refs.calendar.resetEventLoader();
},
},
@@ -1082,7 +1227,7 @@ export default {
<div
class="tempus"
data-cy="tempus"
>
>
<keyboard-shortcuts :shortcuts="keyboardShortcuts" />
<header class="navbar navbar-expand-lg navbar-dark bg-dark flex-md-nowrap p-0 shadow">
<div class="col-md-4 col-lg-3 col-xl-2 d-flex align-items-center">
@@ -1212,9 +1357,9 @@ export default {
/>-->
<div
class="d-flex gap-1 py-1"
data-cy="previewRoleOptionsHolder"
>
class="d-flex gap-1 py-1"
data-cy="previewRoleOptionsHolder"
>
<button
class="btn btn-sm"
:class="previewRole === 'planer' ? 'btn-dark' : 'btn-outline-dark'"
@@ -1264,7 +1409,16 @@ export default {
v-model:parked-keys="parkedKeys"
></parking-slot>
<fhc-coursepicker ref="coursepicker" :studiengaenge="studiengaenge" @select-lecturer="setEmp" @select-kw="jumpToKw" :studiensemester="selectedStudiensemester"></fhc-coursepicker>
<fhc-coursepicker
ref="coursepicker"
:studiengaenge="studiengaenge"
:studiensemester="selectedStudiensemester"
:preview-lehreinheit-id="raumvorschlagPreview?.lehreinheit_id ?? null"
:preview-loading="raumvorschlagLoading"
@select-lecturer="setEmp"
@select-kw="jumpToKw"
@preview-raumvorschlag="previewRaumvorschlag"
></fhc-coursepicker>
</div>
<stv-studiensemester v-model:studiensemester-kurzbz="selectedStudiensemester"></stv-studiensemester>
@@ -1280,6 +1434,7 @@ export default {
:mode="currentMode"
:parkedEvents="parkedKeys"
:visible-lecturers="visibleLecturerUids"
:show-events="showEvents"
@drop="dropHandler"
@resize="resizeHandler"
@update:date="handleChangeDate"
@@ -1425,4 +1580,4 @@ export default {
@confirmed="onMultiWeekConfirmed"
/>
</div>`,
};
};