mirror of
https://github.com/FH-Complete/FHC-Core.git
synced 2026-10-12 15:04:04 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9dadd470de |
@@ -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);
|
||||
|
||||
@@ -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']);
|
||||
|
||||
@@ -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]);
|
||||
|
||||
@@ -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,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 {
|
||||
|
||||
@@ -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)"
|
||||
|
||||
@@ -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-->
|
||||
|
||||
@@ -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>`,
|
||||
};
|
||||
};
|
||||
Reference in New Issue
Block a user