diff --git a/application/libraries/KalenderLib.php b/application/libraries/KalenderLib.php index 3274aae99..2a7b4df6f 100644 --- a/application/libraries/KalenderLib.php +++ b/application/libraries/KalenderLib.php @@ -237,7 +237,7 @@ class KalenderLib WHERE tbl_betriebsmittel_kalender.eindeutige_kalender_gruppen_id = tbl_kalender.eindeutige_kalender_gruppen_id ) AS has_assigned_resources" ]); - + $data = $this->_loadFilteredBasePlan($start_date, $end_date); return $this->_mapEvents($data, $collisionCheck, $maxDailyEventLimit); @@ -415,7 +415,7 @@ class KalenderLib if (in_array($kalender_entry->status_kurzbz, array('to_delete', 'to_delete_live', 'to_delete_preview', 'deleted'))) { return error([ - 'message' => $this->_ci->phraseslib->t('ui', 'entry_not_editable'), + 'message' => $this->_ci->phraseslib->t('ui', 'entry_marked_for_deletion_not_editable'), 'errorCode' => 'entry_not_editable' ]); } @@ -466,7 +466,7 @@ class KalenderLib if (in_array($kalender_entry->status_kurzbz, array('to_delete', 'to_delete_live', 'to_delete_preview', 'deleted'))) { return error([ - 'message' => $this->_ci->phraseslib->t('ui', 'entry_not_editable'), + 'message' => $this->_ci->phraseslib->t('ui', 'entry_marked_for_deletion_not_editable'), 'errorCode' => 'entry_not_editable' ]); } @@ -1077,7 +1077,7 @@ class KalenderLib if (in_array($kalender_entry->status_kurzbz, array('to_delete', 'to_delete_live', 'to_delete_preview', 'deleted'))) { return error([ - 'message' => $this->_ci->phraseslib->t('ui', 'entry_not_editable'), + 'message' => $this->_ci->phraseslib->t('ui', 'entry_marked_for_deletion_not_editable'), 'errorCode' => 'entry_not_editable' ]); } @@ -1153,7 +1153,7 @@ class KalenderLib if (in_array($kalender_entry->status_kurzbz, array('to_delete', 'to_delete_live', 'to_delete_preview', 'deleted'))) { return error([ - 'message' => $this->_ci->phraseslib->t('ui', 'entry_not_editable'), + 'message' => $this->_ci->phraseslib->t('ui', 'entry_marked_for_deletion_not_editable'), 'errorCode' => 'entry_not_editable' ]); } @@ -1497,6 +1497,7 @@ class KalenderLib tbl_organisationseinheit.bezeichnung as organisationseinheit, lehrfach.kurzbz AS lehrfach_kurzbz, lehrfach.bezeichnung AS lehrfach_bezeichnung, + lehrfach.kurzbz AS lehrfach_kurz_bezeichnung, lehrfach.farbe, COALESCE(orginasator.uid, tbl_lehreinheitmitarbeiter.mitarbeiter_uid) as mitarbeiter_uid, COALESCE(reservierung_person.vorname, tbl_person.vorname) as vorname, @@ -1704,7 +1705,6 @@ class KalenderLib 'datum' => $von->format('Y-m-d'), 'isostart' => $von->format('c'), 'isoend' => $bis->format('c'), - 'tooltip' => 'tip', 'status_kurzbz' => $row->status_kurzbz, 'ort_kurzbz' => [], 'ort_infos' => [], @@ -1740,6 +1740,7 @@ class KalenderLib $events[$id]->lehreinheit_infos[] = ['lehreinheit_id' => $row->lehreinheit_id, 'anmerkung' => (isset($row->le_anmerkung) ? $row->le_anmerkung : ''), 'lehrfach_bezeichnung' => (isset($row->lehrfach_bezeichnung) ? $row->lehrfach_bezeichnung : ''), + 'lehrfach_kurz_bezeichnung' => (isset($row->lehrfach_kurz_bezeichnung) ? $row->lehrfach_kurz_bezeichnung : ''), 'studiensemester_kurzbz' => (isset($row->le_studiensemester_kurzbz) ? $row->le_studiensemester_kurzbz : ''), ]; } @@ -1750,6 +1751,7 @@ class KalenderLib $events[$id]->lehrveranstaltung_infos[] = ['lehrveranstaltung_id' => $row->lehrveranstaltung_id, 'lehrform_kurzbz' => (isset($row->lehrform_kurzbz) ? $row->lehrform_kurzbz : ''), 'lehrfach_bezeichnung' => (isset($row->lehrfach_bezeichnung) ? $row->lehrfach_bezeichnung : ''), + 'lehrfach_kurz_bezeichnung' => (isset($row->lehrfach_kurz_bezeichnung) ? $row->lehrfach_kurz_bezeichnung : ''), 'oe_bezeichnung' => (isset($row->organisationseinheit) ? $row->organisationseinheit : ''), 'studiensemester_kurzbz' => (isset($row->le_studiensemester_kurzbz) ? $row->le_studiensemester_kurzbz : ''), ]; diff --git a/application/libraries/collision/checks/LectureCollisionCheck.php b/application/libraries/collision/checks/LectureCollisionCheck.php index bfe89b1b1..d7c65e924 100644 --- a/application/libraries/collision/checks/LectureCollisionCheck.php +++ b/application/libraries/collision/checks/LectureCollisionCheck.php @@ -53,12 +53,14 @@ class LectureCollisionCheck implements ICollisionCheck $kollisionsfreie_user = unserialize(KOLLISIONSFREIE_USER); $grouped = []; - $this->_ci->KalenderModel->addSelect('tbl_kalender.kalender_id, current_lehreinheit_ma.mitarbeiter_uid, other_kalender.von, other_kalender.kalender_id as other_kalender_id'); + $this->_ci->KalenderModel->addSelect('tbl_kalender.kalender_id, current_lehreinheit_ma.mitarbeiter_uid, current_mitarbeiter.kurzbz, other_kalender.von, other_kalender.kalender_id as other_kalender_id'); $this->_ci->KalenderModel->addJoin('lehre.tbl_kalender_lehreinheit current_kalender_le', 'current_kalender_le.kalender_id = tbl_kalender.kalender_id'); $this->_ci->KalenderModel->addJoin('lehre.tbl_lehreinheitmitarbeiter current_lehreinheit_ma', 'current_lehreinheit_ma.lehreinheit_id = current_kalender_le.lehreinheit_id'); $this->_ci->KalenderModel->addJoin('lehre.tbl_lehreinheitmitarbeiter other_lehreinheithreinheit_ma', 'other_lehreinheithreinheit_ma.mitarbeiter_uid = current_lehreinheit_ma.mitarbeiter_uid'); $this->_ci->KalenderModel->addJoin('lehre.tbl_kalender_lehreinheit other_kalender_le', 'other_kalender_le.lehreinheit_id = other_lehreinheithreinheit_ma.lehreinheit_id'); $this->_ci->KalenderModel->addJoin('lehre.tbl_kalender other_kalender', 'other_kalender.kalender_id = other_kalender_le.kalender_id'); + $this->_ci->KalenderModel->addJoin('public.tbl_mitarbeiter current_mitarbeiter', 'current_mitarbeiter.mitarbeiter_uid = current_lehreinheit_ma.mitarbeiter_uid'); + $this->_ci->KalenderModel->db->where('other_kalender.kalender_id != tbl_kalender.kalender_id', null, false); $this->_ci->KalenderModel->db->where('other_kalender.von < tbl_kalender.bis', null, false); @@ -84,7 +86,7 @@ class LectureCollisionCheck implements ICollisionCheck foreach (getData($result) as $row) { $grouped[$row->kalender_id][] = [ - 'message' => $this->_ci->phraseslib->t('ui', 'ma_le_kollision') . ': ' . $row->mitarbeiter_uid, + 'message' => $this->_ci->phraseslib->t('ui', 'ma_le_kollision') . ': ' . ($row->kurzbz ? $row->kurzbz . ' [' . $row->mitarbeiter_uid . ']' : $row->mitarbeiter_uid), 'kalender_id' => $row->other_kalender_id, 'datum' => $row->von, ]; diff --git a/application/libraries/collision/checks/VerbandCollisionCheck.php b/application/libraries/collision/checks/VerbandCollisionCheck.php index d7c2f9780..6f90d4053 100644 --- a/application/libraries/collision/checks/VerbandCollisionCheck.php +++ b/application/libraries/collision/checks/VerbandCollisionCheck.php @@ -43,6 +43,7 @@ class VerbandCollisionCheck implements ICollisionCheck AND other_lehreinheitguppe.gruppe_kurzbz IS NULL AND ( current_lehreinheitguppe.verband IS NULL + OR other_lehreinheitguppe.verband IS NULL OR ( current_lehreinheitguppe.verband = other_lehreinheitguppe.verband AND (current_lehreinheitguppe.gruppe IS NULL OR other_lehreinheitguppe.gruppe IS NULL OR current_lehreinheitguppe.gruppe = other_lehreinheitguppe.gruppe) @@ -99,6 +100,7 @@ class VerbandCollisionCheck implements ICollisionCheck { $sql_gruppen = " SELECT + DISTINCT (current_kalender.kalender_id), other_kalender.von, other_kalender.bis, COALESCE( @@ -246,6 +248,7 @@ class VerbandCollisionCheck implements ICollisionCheck AND other_event_teilnehmer.gruppe_kurzbz IS NULL AND ( current_event_teilnehmer.verband IS NULL + OR other_event_teilnehmer.verband IS NULL OR ( current_event_teilnehmer.verband = other_event_teilnehmer.verband AND (current_event_teilnehmer.gruppe IS NULL OR other_event_teilnehmer.gruppe IS NULL OR current_event_teilnehmer.gruppe = other_event_teilnehmer.gruppe) @@ -312,7 +315,7 @@ class VerbandCollisionCheck implements ICollisionCheck $placeholders = implode(',', array_fill(0, count($kalender_ids), '?')); $sql = " - SELECT DISTINCT ON (current_kalender.kalender_id) current_kalender.kalender_id, + SELECT DISTINCT current_kalender.kalender_id, COALESCE( other_lehreinheitguppe.gruppe_kurzbz, UPPER(stg.typ::text || stg.kurzbz::text) || '-' || other_lehreinheitguppe.semester || @@ -367,6 +370,7 @@ class VerbandCollisionCheck implements ICollisionCheck AND other_lehreinheitguppe.gruppe_kurzbz IS NULL AND ( current_lehreinheitguppe.verband IS NULL + OR other_lehreinheitguppe.verband IS NULL OR ( current_lehreinheitguppe.verband = other_lehreinheitguppe.verband AND (current_lehreinheitguppe.gruppe IS NULL OR other_lehreinheitguppe.gruppe IS NULL OR current_lehreinheitguppe.gruppe = other_lehreinheitguppe.gruppe) diff --git a/public/css/Tempus.css b/public/css/Tempus.css index 08ad0f746..0123a0e00 100644 --- a/public/css/Tempus.css +++ b/public/css/Tempus.css @@ -286,4 +286,9 @@ body { .timepicker-row { display: flex; align-items: center; -} \ No newline at end of file +} + +.event-dialog-location { + overflow-wrap: anywhere; +} + diff --git a/public/js/components/Calendar/Mode/Table/View.js b/public/js/components/Calendar/Mode/Table/View.js index f5cc6e465..ca3d77d66 100644 --- a/public/js/components/Calendar/Mode/Table/View.js +++ b/public/js/components/Calendar/Mode/Table/View.js @@ -1,7 +1,7 @@ -import {CoreFilterCmpt} from "../../../../components/filter/Filter.js"; +import {CoreFilterCmpt} from "../../../filter/Filter.js"; import BsModal from '../../../Bootstrap/Modal.js'; import FormInput from "../../../Form/Input.js"; -import CoreTag from '../../../../components/Tag/Tag.js'; +import CoreTag from '../../../Tag/Tag.js'; import { buildTagHeaderFilterExpression, @@ -59,7 +59,8 @@ export default { }, }, tagEndpoint: ApiTempusTag, - selectedColumnValues: [] + selectedColumnValues: [], + pendingSelection: null } }, computed: { @@ -170,13 +171,41 @@ export default { tableBuilt() { this.$refs.tableViewTable.tabulator.updateColumnDefinition('tags', { headerFilterParams: this.tagHeaderFilterParams(), - });; - + }); }, + + rememberSelection() { + const tab = this.$refs.tableViewTable?.tabulator; + this.pendingSelection = (tab?.getSelectedData() ?? []) + .map(r => r.eindeutige_kalender_gruppen_id); + }, + clearPendingSelection() { + this.pendingSelection = null; + }, + restoreSelection() { + const ids = this.pendingSelection; + if (!ids?.length) return; + + const tab = this.$refs.tableViewTable?.tabulator; + + if (!tab) return; + + const rows = tab.getRows().filter(row => + ids.includes(row.getData().eindeutige_kalender_gruppen_id) + ); + + if (!rows.length) return; + + this.clearPendingSelection(); + tab.selectRow(rows); + tab.scrollToRow(rows[0], "center", false).catch(() => {}); + }, + openModal() { let selected = this.$refs.tableViewTable?.tabulator?.getSelectedData() ?? []; if (!selected.length) return; + this.rememberSelection(); this.tableActions?.openRaumauswahl(selected) }, async deleteSelected() { @@ -203,14 +232,20 @@ export default { let isConfirmed = await this.$fhcAlert.confirmDelete(); if (!isConfirmed) return; await this.tableActions?.deleteEntries(selected) + return; } - else if (this.actionSelect === 'toLecturer') - { - await this.tableActions?.syncToLecturer(selected) - } - else if (this.actionSelect === 'toStudent') - { - await this.tableActions?.syncToStudent(selected) + try { + if (this.actionSelect === 'toLecturer') + { + await this.tableActions?.syncToLecturer(selected) + } + else if (this.actionSelect === 'toStudent') + { + await this.tableActions?.syncToStudent(selected) + } + } catch (e) { + this.clearPendingSelection(); + throw e; } }, async fetchAssignedTagsByCalender(calendarGroupId) { @@ -362,6 +397,7 @@ export default { :tabulator-events="[{ event: 'tableBuilt', handler: tableBuilt }, { event: 'rowSelectionChanged', handler: updateSelectedRows }, { event: 'dataLoaded', handler: dataLoadedHandler }, + { event: 'dataProcessed', handler: restoreSelection }, { event: 'dataFiltered', handler: dataFilteredHandler }, { event: 'columnWidth', handler: columnWidthHandler }, { event: 'rowClick', handler: onRowClick } diff --git a/public/js/components/Calendar/Tempus.js b/public/js/components/Calendar/Tempus.js index dca514e74..aaa1566ec 100644 --- a/public/js/components/Calendar/Tempus.js +++ b/public/js/components/Calendar/Tempus.js @@ -127,6 +127,10 @@ export default { type: Boolean, default: true, }, + canAccessSettingsView: { + type: Boolean, + default: true, + }, canToggleCollisionCheck: { type: Boolean, default: true, @@ -492,17 +496,30 @@ export default {