diff --git a/application/config/Events.php b/application/config/Events.php
index 3e0a5248f..bf9f317e3 100644
--- a/application/config/Events.php
+++ b/application/config/Events.php
@@ -23,6 +23,15 @@ Events::on('loadRenderers', function ($renderers) {
);
});
+Events::on('loadRenderers', function ($renderers) {
+ $fhc_core_renderers =& $renderers();
+ $fhc_core_renderers["slot_room"] = array(
+ 'modalTitle' => APP_ROOT.'public/js/components/Cis/Renderer/Slot/roomModalTitle.js',
+ 'modalContent' => APP_ROOT.'public/js/components/Cis/Renderer/Slot/roomModalContent.js',
+ 'calendarEventStyles' => APP_ROOT.'public/css/Cis4/CoreCalendarEvents.css'
+ );
+});
+
Events::on('loadRenderers', function ($renderers) {
$fhc_core_renderers =& $renderers();
$fhc_core_renderers["ferien"] = array(
diff --git a/application/controllers/api/frontend/v1/calendar/RoomPlan.php b/application/controllers/api/frontend/v1/calendar/RoomPlan.php
new file mode 100644
index 000000000..489d83b53
--- /dev/null
+++ b/application/controllers/api/frontend/v1/calendar/RoomPlan.php
@@ -0,0 +1,232 @@
+.
+ */
+
+if (! defined('BASEPATH')) exit('No direct script access allowed');
+
+class RoomPlan extends FHCAPI_Controller
+{
+
+ /**
+ * Object initialization
+ */
+ public function __construct()
+ {
+ parent::__construct([
+ 'addRoomReservation' => self::PERM_LOGGED,
+ 'deleteRoomReservation' => self::PERM_LOGGED,
+ 'getRoomCreationInfo' => self::PERM_LOGGED,
+ 'getGruppen' => self::PERM_LOGGED,
+ 'getLektor' => self::PERM_LOGGED,
+ 'getReservableMap' => self::PERM_LOGGED,
+ ]);
+
+ $this->load->library('LogLib');
+ $this->loglib->setConfigs(array(
+ 'classIndex' => 5,
+ 'functionIndex' => 5,
+ 'lineIndex' => 4,
+ 'dbLogType' => 'API',
+ 'dbExecuteUser' => 'RESTful API'
+ ));
+
+ $this->load->library('form_validation');
+ $this->load->library('PermissionLib');
+ $this->load->library('StundenplanLib');
+
+ $this->loadPhrases(['ui']);
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ // Public methods
+
+
+
+ public function addRoomReservation()
+ {
+ $this->form_validation->set_rules('selectedStart', "Start", "required");
+ $this->form_validation->set_rules('selectedEnd', "End", "required");
+ $this->form_validation->set_rules('title', "Title", "required|max_length[10]");
+ $this->form_validation->set_rules('beschreibung', "Beschreibung", "required|max_length[32]");
+ $this->form_validation->set_rules('ort_kurzbz', "Ort", "required|max_length[16]");
+ $this->form_validation->set_rules('studiengang', 'Studiengang', 'numeric');
+ $this->form_validation->set_rules('semester', 'Semester', 'integer|greater_than_equal_to[0]');
+ $this->form_validation->set_rules('verband', 'Verband', 'trim');
+ $this->form_validation->set_rules('gruppe', 'Gruppe', 'trim');
+ $this->form_validation->set_rules('spezialgruppe', 'Spezialgruppe', 'max_length[32]');
+ $this->form_validation->set_rules('lektoren', 'Lektoren');
+
+ if (!$this->form_validation->run())
+ $this->terminateWithValidationErrors($this->form_validation->error_array());
+
+ $start = $this->input->post('selectedStart');
+ $end = $this->input->post('selectedEnd');
+ $title = $this->input->post('title');
+ $beschreibung = $this->input->post('beschreibung');
+ $ort_kurzbz = $this->input->post('ort_kurzbz');
+
+ $studiengang_kz = $this->input->post('studiengang');
+ $semester = $this->input->post('semester');
+ $verband = $this->input->post('verband');
+ $gruppe = $this->input->post('gruppe');
+ $spezialgruppe = $this->input->post('spezialgruppe');
+ $lektoren = $this->input->post('lektoren');
+
+
+ $result = $this->stundenplanlib->addReservation($start, $end, $title, $beschreibung, $ort_kurzbz, $lektoren, $studiengang_kz, $semester, $verband, $gruppe, $spezialgruppe);
+
+ if (isError($result))
+ $this->terminateWithError($result);
+
+ $this->terminateWithSuccess($result);
+ }
+
+ public function deleteRoomReservation()
+ {
+ $reservierung_id = $this->input->post('reservierung_id');
+
+ $result = $this->stundenplanlib->deleteReservation($reservierung_id);
+
+ if (isError($result))
+ $this->terminateWithError($result);
+
+ $this->terminateWithSuccess($result);
+ }
+
+ public function getRoomCreationInfo()
+ {
+ $return_array = array('berechtigt' => false, 'studiengaenge' => []);
+ if (!$this->permissionlib->isBerechtigt('lehre/reservierung'))
+ $this->terminateWithSuccess($return_array);
+
+ $stg_berechtigungen = $this->permissionlib->getSTG_isEntitledFor('lehre/reservierung');
+ if (isEmptyArray($stg_berechtigungen))
+ $this->terminateWithSuccess($return_array);
+
+ $this->load->model('organisation/Studiengang_model', 'StudiengangModel');
+ $this->StudiengangModel->addSelect('studiengang_kz, UPPER(CONCAT(typ, kurzbz)) as kuerzel, kurzbzlang');
+ $this->StudiengangModel->addOrder('typ, kurzbz');
+ $this->StudiengangModel->db->where_in('studiengang_kz', $stg_berechtigungen);
+ $studiengaenge = $this->StudiengangModel->loadWhere(array('aktiv' => true));
+
+ if (isError($studiengaenge))
+ $this->terminateWithError($studiengaenge);
+
+ $return_array['studiengaenge'] = hasData($studiengaenge) ? getData($studiengaenge) : [];
+ $return_array['berechtigt'] = true;
+
+ $this->terminateWithSuccess($return_array);
+ }
+
+ public function getGruppen()
+ {
+ $query = $this->input->get('query');
+ if (is_null($query))
+ $this->terminateWithError($this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
+
+ $stg_berechtigungen = $this->permissionlib->getSTG_isEntitledFor('lehre/reservierung');
+
+ if (isEmptyArray($stg_berechtigungen))
+ $this->terminateWithSuccess([]);
+
+ $this->load->model('organisation/gruppe_model', 'GruppeModel');
+
+ $query_words = explode(' ', urldecode($query));
+
+ $this->GruppeModel->addOrder('gruppe_kurzbz');
+ $this->GruppeModel->db->group_start();
+ foreach ($query_words as $word)
+ {
+ $this->GruppeModel->db->group_start();
+ $this->GruppeModel->db->where('gruppe_kurzbz ILIKE', "%" . $word . "%");
+ $this->GruppeModel->db->or_where('bezeichnung ILIKE', "%" . $word . "%");
+ $this->GruppeModel->db->or_where('beschreibung ILIKE', "%" . $word . "%");
+ $this->GruppeModel->db->or_where('orgform_kurzbz ILIKE', "%" . $word . "%");
+
+ if (is_numeric($word))
+ {
+ $this->GruppeModel->db->or_where('studiengang_kz', $word);
+ }
+ $this->GruppeModel->db->group_end();
+ }
+ $this->GruppeModel->db->group_end();
+ $this->GruppeModel->db->where_in('studiengang_kz', $stg_berechtigungen);
+ $gruppen = $this->GruppeModel->loadWhere(array('sichtbar' => true, 'lehre' => true));
+ if (isError($gruppen))
+ $this->terminateWithError($gruppen);
+
+ $this->terminateWithSuccess(hasData($gruppen) ? getData($gruppen) : []);
+ }
+
+ public function getLektor()
+ {
+
+ $query = $this->input->get('query');
+ if (is_null($query))
+ $this->terminateWithError($this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
+
+ $stg_berechtigungen = $this->permissionlib->getSTG_isEntitledFor('lehre/reservierung');
+
+ if (isEmptyArray($stg_berechtigungen))
+ $this->terminateWithSuccess([]);
+
+ $this->load->model('ressource/Mitarbeiter_model', 'MitarbeiterModel');
+
+ $query_words = explode(' ', urldecode($query));
+
+ $this->MitarbeiterModel->addSelect('uid, person_id, vorname, nachname');
+ $this->MitarbeiterModel->addJoin('public.tbl_benutzer', 'uid = mitarbeiter_uid');
+ $this->MitarbeiterModel->addJoin('public.tbl_person', 'person_id');
+ $this->MitarbeiterModel->db->where('public.tbl_benutzer.aktiv', true);
+ $this->MitarbeiterModel->db->group_start();
+ foreach ($query_words as $word)
+ {
+ $this->MitarbeiterModel->db->group_start();
+ $this->MitarbeiterModel->db->where('tbl_person.vorname ILIKE', "%" . $word . "%");
+ $this->MitarbeiterModel->db->or_where('tbl_person.nachname ILIKE', "%" . $word . "%");
+ $this->MitarbeiterModel->db->or_where('uid ILIKE', "%" . $word . "%");
+ $this->MitarbeiterModel->db->group_end();
+ }
+ $this->MitarbeiterModel->db->group_end();
+
+ $this->MitarbeiterModel->addOrder('nachname');
+ $this->MitarbeiterModel->addOrder('vorname');
+ $mitarbeiter = $this->MitarbeiterModel->load();
+ if (isError($mitarbeiter))
+ $this->terminateWithError($mitarbeiter);
+
+ $this->terminateWithSuccess(hasData($mitarbeiter) ? getData($mitarbeiter) : []);
+ }
+
+ public function getReservableMap($ort_kurzbz = null)
+ {
+ $this->form_validation->set_rules('start_date', "StartDate", "required");
+ $this->form_validation->set_rules('end_date', "EndDate", "required");
+
+ if (!$this->form_validation->run())
+ $this->terminateWithValidationErrors($this->form_validation->error_array());
+
+ // storing the post parameter in local variables
+ $start_date = $this->input->post('start_date', true);
+ $end_date = $this->input->post('end_date', true);
+
+ $result = $this->stundenplanlib->getReservableMap($ort_kurzbz, $start_date, $end_date);
+
+ $this->terminateWithSuccess(array('reservierbarMap' => hasData($result) ? getData($result) : []));
+ }
+
+}
diff --git a/application/libraries/StundenplanLib.php b/application/libraries/StundenplanLib.php
index 7ed64da2c..7ece4fa65 100644
--- a/application/libraries/StundenplanLib.php
+++ b/application/libraries/StundenplanLib.php
@@ -368,6 +368,32 @@ class StundenplanLib
$item->gruppe = $gruppe_obj_array;
$item->lektor = $lektor_obj_array;
+ $this->_ci->load->library('PermissionLib');
+ $berechtigt_begrenzt = $this->_ci->permissionlib->isBerechtigt('lehre/reservierung:begrenzt', 'sui');
+
+ $now = time();
+ $res_lektor_start = $this->jump_day($now, RES_TAGE_LEKTOR_MIN - 1);
+ $res_lektor_ende = mktime(0, 0, 0, date('m', $now), date('d', $now) + RES_TAGE_LEKTOR_BIS, date('Y', $now));
+
+ $start_date = is_numeric($item->beginn) ? $item->beginn : strtotime($item->beginn);
+ if (!date('w', $start_date)) {
+ $start_date = $this->jump_day($start_date, 1);
+ }
+
+ $start_date_str = date('Y-m-d', $start_date);
+ $res_lektor_start_str = date('Y-m-d', $res_lektor_start);
+ $res_lektor_ende_str = date('Y-m-d', $res_lektor_ende);
+
+ $show_delete = (($berechtigt_begrenzt && ($item->insertvon == getAuthUID() || in_array(getAuthUID(), $item->uids))) &&
+ $start_date_str >= $res_lektor_start_str &&
+ $start_date_str <= $res_lektor_ende_str
+ );
+
+ if ($show_delete)
+ $item->deletable = true;
+ else
+ $item->deletable = false;
+
}
}
@@ -445,6 +471,219 @@ class StundenplanLib
return success($ferienEventsFlattened);
}
+ public function addReservation($start, $end, $title, $beschreibung, $ort_kurzbz, $lektoren = null, $studiengang = null, $semester = null, $verband = null, $gruppe = null, $spezialgruppe = null)
+ {
+ $this->_ci =& get_instance();
+ $this->_ci->load->model('ressource/Stunde_model', 'StundeModel');
+ $this->_ci->load->model('ressource/Reservierung_model', 'ReservierungModel');
+ $this->_ci->load->model('ressource/stundenplandev_model', 'StundenplandevModel');
+ $this->_ci->load->model('ressource/stundenplan_model', 'StundenplanModel');
+ $this->_ci->load->library('PermissionLib');
+
+ $startTime = new DateTime($start);
+ $endTime = new DateTime($end);
+
+ $stunden = $this->_ci->StundeModel->loadWhere(array(
+ 'beginn <' => $endTime->format('H:i:s'),
+ 'ende >' => $startTime->format('H:i:s')
+ ));
+
+ if (!hasData($stunden))
+ {
+ return error("Keine Stunden vorhanden");
+ }
+
+ $stunden = array_column(getData($stunden), 'stunde');
+
+ $this->_ci->StundenplandevModel->db->select('1');
+ $this->_ci->StundenplandevModel->db->where('datum', $startTime->format('Y-m-d'));
+ $this->_ci->StundenplandevModel->db->where('ort_kurzbz', $ort_kurzbz);
+ $this->_ci->StundenplandevModel->db->where_in('stunde', $stunden);
+ $stundenplandev_belegung = $this->_ci->StundenplandevModel->load();
+
+ $this->_ci->StundenplanModel->db->select('1');
+ $this->_ci->StundenplanModel->db->where('ort_kurzbz', $ort_kurzbz);
+ $this->_ci->StundenplanModel->db->where('datum', $startTime->format('Y-m-d'));
+ $this->_ci->StundenplanModel->db->where_in('stunde', $stunden);
+ $stundenplan_belegung = $this->_ci->StundenplanModel->load();
+
+ if ((hasData($stundenplandev_belegung) || hasData($stundenplan_belegung))
+ && !$this->_ci->permissionlib->isBerechtigt('lehre/reservierungAdvanced'))
+ return error ('lvplan/bereitsReserviert');
+
+ $this->_ci->ReservierungModel->addSelect('stunde');
+ $reservation_hours = $this->_ci->ReservierungModel->loadWhere(array('datum' => $startTime->format('Y-m-d'), 'ort_kurzbz' => $ort_kurzbz));
+
+
+ if (isError($reservation_hours))
+ return $reservation_hours;
+
+ $reservation_hours = hasData($reservation_hours) ? array_column(getData($reservation_hours), 'stunde') : array();
+
+ if (!empty(array_intersect($stunden, $reservation_hours))
+ && !$this->_ci->permissionlib->isBerechtigt('lehre/reservierungAdvanced'))
+ return error("lvplan/bereitsReserviert");
+
+
+ if (!empty($lektoren))
+ {
+ foreach ($lektoren as $lektor)
+ {
+ $insert = array('ort_kurzbz' => $ort_kurzbz,
+ 'datum' => $startTime->format('Y-m-d'),
+ 'titel' => $title,
+ 'studiengang_kz' => is_null($studiengang) ? 0 : $studiengang,
+ 'beschreibung' => $beschreibung,
+ 'insertvon' => getAuthUID(),
+ 'uid' => $lektor,
+ 'semester' => is_null($semester) ? null : $semester,
+ 'verband' => is_null($verband) ? null : $verband,
+ 'gruppe' => is_null($gruppe) ? null : $gruppe,
+ 'gruppe_kurzbz' => is_null($spezialgruppe) ? null : $spezialgruppe,
+ );
+
+ foreach ($stunden as $stunde)
+ {
+ $insert['stunde'] = $stunde;
+ $check_insert = $this->_ci->ReservierungModel->insert($insert);
+ if (isError($check_insert))
+ return $check_insert;
+ }
+ }
+ }
+ else
+ {
+ foreach ($stunden as $stunde)
+ {
+ $check_insert = $this->_ci->ReservierungModel->insert(array(
+ 'ort_kurzbz' => $ort_kurzbz,
+ 'uid' => getAuthUID(),
+ 'stunde' => $stunde,
+ 'datum' => $startTime->format('Y-m-d'),
+ 'titel' => $title,
+ 'studiengang_kz' => is_null($studiengang) ? 0 : $studiengang,
+ 'beschreibung' => $beschreibung,
+ 'insertvon' => getAuthUID()
+ ));
+ if (isError($check_insert))
+ return $check_insert;
+ }
+ }
+
+ return success("Erfolgreich");
+ }
+
+ public function deleteReservation($reservierung_id)
+ {
+ $this->_ci =& get_instance();
+ $this->_ci->load->model('ressource/Reservierung_model', 'ReservierungModel');
+ $this->_ci->load->model('ressource/Stunde_model', 'StundeModel');
+ $this->_ci->load->library('PermissionLib');
+
+
+ $this->_ci->ReservierungModel->db->where_in('reservierung_id', $reservierung_id);
+ $reservation = $this->_ci->ReservierungModel->load();
+ if (isError($reservation))
+ return $reservation;
+
+ if (!hasData($reservation))
+ return error("Reservierungen nicht gefunden");
+
+ $reservations = getData($reservation);
+
+ $today = new DateTime();
+ foreach ($reservations as $reservierung)
+ {
+ if ($today->format('Y-m-d') > $reservierung->datum)
+ return error("Vergangene Reservierungen können nicht gelöscht werden");
+
+ if (($this->_ci->permissionlib->isBerechtigt('lehre/reservierung:begrenzt')) && ($reservierung->insertvon == getAuthUID() || $reservierung->uid === getAuthUID()))
+ {
+ $delete_result = $this->_ci->ReservierungModel->delete($reservierung->reservierung_id);
+
+ if (isError($delete_result))
+ return $delete_result;
+ }
+ }
+ return success("Erfolgreich");
+ }
+
+
+ public function getReservableMap($ort_kurzbz, $start_date, $end_date)
+ {
+ $this->_ci =& get_instance();
+ $this->_ci->load->model('ressource/Ort_model', 'OrtModel');
+ $this->_ci->load->library('PermissionLib');
+
+ $berechtigt_begrenzt = $this->_ci->permissionlib->isBerechtigt('lehre/reservierung:begrenzt', 'suid');
+ $berechtigt_erweitert = $this->_ci->permissionlib->isBerechtigt('lehre/reservierung', 'suid');
+
+ $ort_data = $this->_ci->OrtModel->load($ort_kurzbz);
+ if (isError($ort_data) || !hasData($ort_data))
+ return [];
+
+ $ort_data = getData($ort_data)[0];
+
+ if (!$ort_data->reservieren)
+ return [];
+
+ if (!$berechtigt_begrenzt && !$berechtigt_erweitert)
+ return [];
+
+ $start_ts = is_numeric($start_date) ? (int)$start_date : strtotime($start_date);
+ $end_ts = is_numeric($end_date) ? (int)$end_date : strtotime($end_date);
+
+ if (!$start_ts || !$end_ts)
+ return [];
+
+ if ($end_ts < $start_ts)
+ {
+ $tmp = $start_ts;
+ $start_ts = $end_ts;
+ $end_ts = $tmp;
+ }
+
+ $now = time();
+ $tage_min = defined('RES_TAGE_LEKTOR_MIN') ? (int)RES_TAGE_LEKTOR_MIN : 0;
+ $tage_bis = defined('RES_TAGE_LEKTOR_BIS') ? (int)RES_TAGE_LEKTOR_BIS : 0;
+
+ $datum_res_lektor_start = $this->jump_day($now, $tage_min - 1);
+ $datum_res_lektor_ende = $this->jump_day($now, $tage_bis);
+
+ $start_ymd_allowed = date('Y-m-d', $datum_res_lektor_start);
+ $end_ymd_allowed = date('Y-m-d', $datum_res_lektor_ende);
+
+ $result = [];
+
+ $current = strtotime(date('Y-m-d', $start_ts) . ' 00:00:00');
+ $end_day = strtotime(date('Y-m-d', $end_ts) . ' 00:00:00');
+
+ while ($current <= $end_day)
+ {
+ $ymd = date('Y-m-d', $current);
+
+ if ((int)date('w', $current) === 0)
+ {
+ $result[$ymd] = false;
+ $current = $this->jump_day($current, 1);
+ continue;
+ }
+
+ $result[$ymd] = ($ymd >= $start_ymd_allowed && $ymd <= $end_ymd_allowed) ? true : false;
+
+ $current = $this->jump_day($current, 1);
+ }
+
+ return success($result);
+ }
+
+ private function jump_day($timestamp, $days)
+ {
+ $days = (int)$days;
+ $prefix = ($days >= 0 ? '+' : '');
+ return strtotime($prefix . $days . ' days', $timestamp);
+ }
+
// start of the private functions ########################################################################################################
// function used to sort an array of studiensemester strings
diff --git a/application/models/ressource/Reservierung_model.php b/application/models/ressource/Reservierung_model.php
index 0c391ea20..6d9bed9b4 100644
--- a/application/models/ressource/Reservierung_model.php
+++ b/application/models/ressource/Reservierung_model.php
@@ -50,11 +50,12 @@ class Reservierung_model extends DB_Model
$query_result= $this->execReadOnlyQuery("
SELECT
- 'reservierung' as type, beginn, ende, datum,
+ DISTINCT(insertvon),
+ 'reservierung' as type, beginn, ende, datum, array_agg(DISTINCT reservierung_id) AS reservierung_id,
COALESCE(titel, beschreibung) as topic,
array_agg(DISTINCT mitarbeiter_kurzbz) as lektor,
array_agg(DISTINCT (gruppe,verband,semester,studiengang_kz,gruppen_kuerzel)) as gruppe,
-
+ array_agg(DISTINCT(uid)) as uids,
ort_kurzbz, 'FFFFFF' as farbe
FROM
@@ -62,7 +63,7 @@ class Reservierung_model extends DB_Model
". $subquery ."
) AS subquery
- GROUP BY datum, beginn, ende, ort_kurzbz, titel, beschreibung
+ GROUP BY datum, beginn, ende, ort_kurzbz, titel, beschreibung, insertvon
ORDER BY datum, beginn
", is_null($ort_kurzbz) ?[getAuthUID(), getAuthUID(),$start_date,$end_date]: [$ort_kurzbz, $start_date, $end_date]);
diff --git a/public/css/Cis4/CoreCalendarEvents.css b/public/css/Cis4/CoreCalendarEvents.css
index 3941872ef..da2b87deb 100644
--- a/public/css/Cis4/CoreCalendarEvents.css
+++ b/public/css/Cis4/CoreCalendarEvents.css
@@ -97,3 +97,17 @@
display: none;
}
+.fhc-calendar-empty-slot-plus {
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%,-50%);
+ font-size: 18px;
+ opacity: 0;
+ pointer-events: none;
+ user-select: none;
+}
+
+.part-body:hover .fhc-calendar-empty-slot-plus {
+ opacity: 1;
+}
diff --git a/public/js/api/factory/calendar/roomPlan.js b/public/js/api/factory/calendar/roomPlan.js
new file mode 100644
index 000000000..d27843b37
--- /dev/null
+++ b/public/js/api/factory/calendar/roomPlan.js
@@ -0,0 +1,44 @@
+export default {
+ getReservableMap(ort_kurzbz, start_date, end_date) {
+ return {
+ method: 'post',
+ url: `/api/frontend/v1/calendar/RoomPlan/getReservableMap/${ort_kurzbz}`,
+ params: { start_date, end_date }
+ };
+ },
+
+ getRoomCreationInfo() {
+ return {
+ method: 'get',
+ url: '/api/frontend/v1/calendar/RoomPlan/getRoomCreationInfo'
+ };
+ },
+ getGruppen(query) {
+ return {
+ method: 'get',
+ url: `/api/frontend/v1/calendar/RoomPlan/getGruppen?query=${encodeURIComponent(query)}`
+ };
+ },
+ getLektor(query) {
+ return {
+ method: 'get',
+ url: `/api/frontend/v1/calendar/RoomPlan/getLektor?query=${encodeURIComponent(query)}`
+ };
+ },
+ addRoomReservation(formData) {
+ return {
+ method: 'post',
+ url: '/api/frontend/v1/calendar/RoomPlan/addRoomReservation',
+ params: formData
+ };
+ },
+ deleteRoomReservation(reservierung_id) {
+ return {
+ method: 'post',
+ url: '/api/frontend/v1/calendar/RoomPlan/deleteRoomReservation',
+ params: {
+ reservierung_id: reservierung_id
+ }
+ };
+ }
+}
\ No newline at end of file
diff --git a/public/js/components/Calendar/Base.js b/public/js/components/Calendar/Base.js
index 36d9877da..aeb374cde 100644
--- a/public/js/components/Calendar/Base.js
+++ b/public/js/components/Calendar/Base.js
@@ -44,7 +44,10 @@ export default {
return () => true;
}),
hasDragoverFunc: Vue.computed(() => this.onDragover),
- mode: Vue.computed(() => this.mode)
+ mode: Vue.computed(() => this.mode),
+ reservierbarMap: Vue.computed(() => this.reservierbarMap),
+ isReservierbar: Vue.computed(() => this.isReservierbar),
+ createContext: Vue.computed(() => this.createContext)
};
},
props: {
@@ -97,7 +100,13 @@ export default {
draggableEvents: [Boolean, Array, Function],
dropableEvents: [Boolean, Array, Function],
onDragover: Function,
- onDrop: Function
+ onDrop: Function,
+ isReservierbar: Boolean,
+ createContext: Object,
+ reservierbarMap: {
+ type: Object,
+ default: () => ({})
+ },
},
emits: [
"click:next",
@@ -105,11 +114,13 @@ export default {
"click:mode",
"click:event",
"click:day",
+ "click:slot",
"click:week",
"update:date",
"update:mode",
"update:range",
- "drop"
+ "drop",
+ "create-event"
],
data() {
return {
diff --git a/public/js/components/Calendar/Base/Grid.js b/public/js/components/Calendar/Base/Grid.js
index 3418a9151..1a10533b3 100644
--- a/public/js/components/Calendar/Base/Grid.js
+++ b/public/js/components/Calendar/Base/Grid.js
@@ -2,6 +2,7 @@ import GridLine from './Grid/Line.js';
import GridLineEvent from './Grid/Line/Event.js';
import CalDnd from '../../../directives/Calendar/DragAndDrop.js';
+import CalClick from '../../../directives/Calendar/Click.js';
export default {
name: "CalendarGrid",
@@ -10,12 +11,15 @@ export default {
GridLineEvent
},
directives: {
- CalDnd
+ CalDnd,
+ CalClick
},
inject: {
originalEvents: "events",
originalBackgrounds: "backgrounds",
- dropAllowed: "dropAllowed"
+ dropAllowed: "dropAllowed",
+ timezone: "timezone",
+ reservierbar: "isReservierbar"
},
provide() {
return {
@@ -308,6 +312,20 @@ export default {
} else {
this.$refs.scroller.scrollTo(0, 0);
}
+ },
+ isFreeSlot(date, part, dayEvents) {
+ const pastEnd = luxon.DateTime.now().setZone(this.timezone);
+
+ const start = date.plus(part.start || part);
+ const end = date.plus(part.end || part.plus({ hours: 1 }));
+
+ if (start < pastEnd)
+ return false;
+
+ if (!dayEvents || !dayEvents.length)
+ return true;
+
+ return !dayEvents.some(ev => ev.start < end && ev.end > start);
}
},
beforeUnmount() {
@@ -400,6 +418,18 @@ export default {
:style="'grid-' + axisCol + ':' + (1+index) + ';grid-' + axisRow + ':ps_' + i + '/pe_' + i"
>