diff --git a/application/controllers/api/frontend/v1/ClassScheduleApi.php b/application/controllers/api/frontend/v1/ClassScheduleApi.php
index 3f6c3a8ae..dcfd6f50d 100644
--- a/application/controllers/api/frontend/v1/ClassScheduleApi.php
+++ b/application/controllers/api/frontend/v1/ClassScheduleApi.php
@@ -34,8 +34,8 @@ class ClassScheduleApi extends FHCAPI_Controller
'deleteClassTimeSlotValidityPeriod' => array('lehre/unterrichtszeiten_gk:rw'),
'getClassTimeSlotsForValidityPeriod' => array('lehre/unterrichtszeiten_gk:r'),
'createClassTimeSlotsForValidityPeriod' => array('lehre/unterrichtszeiten_gk:r'),
- 'editClassTimeSlotsForValidityPeriod' => array('lehre/unterrichtszeiten_gk:r'),
- 'deleteClassTimeSlotsForValidityPeriodPerGroup' => array('lehre/unterrichtszeiten_gk:r'),
+ 'updateClassTimeSlotsForValidityPeriod' => array('lehre/unterrichtszeiten_gk:r'),
+ 'deleteClassTimeSlotsForValidityPeriod' => array('lehre/unterrichtszeiten_gk:r'),
'getAllClassScheduleTypes' => array('lehre/unterrichtszeiten_typ:r'),
'createClassTimeSlotType' => array('lehre/unterrichtszeiten_typ:rw'),
'updateClassTimeSlotType' => array('lehre/unterrichtszeiten_typ:rw'),
@@ -135,6 +135,9 @@ class ClassScheduleApi extends FHCAPI_Controller
$class_time_slot_validity_period_res = $this->ClassTimeSlotValidityPeriodModel->load($classTimeSlotValidityPeriodId);
$class_time_slot_validity_period_res = $this->getDataOrTerminateWithError($class_time_slot_validity_period_res);
+ if (!$class_time_slot_validity_period_res || count($class_time_slot_validity_period_res) === 0) {
+ $this->terminateWithError($this->p->t('ui', 'classTimeSlotValidityPeriodNotFound'));
+ }
if (!$this->isUserEntitledForOrganizationalUnit($class_time_slot_validity_period_res[0]->oe_kurzbz, 'lehre/unterrichtszeiten_gk')) {
$this->terminateWithError($this->p->t('ui', 'keineBerechtigung'));
@@ -154,8 +157,7 @@ class ClassScheduleApi extends FHCAPI_Controller
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => $this->p->t('ui', 'field_organizationalUnit')]),
'max_length' => $this->p->t('ui', 'error_fieldMaxLength', ['field' => $this->p->t('ui', 'field_organizationalUnit'), 'max' => 32])
]);
- $this->form_validation->set_rules('semester', 'Semester', 'required|is_natural_no_zero|less_than_equal_to[8]', [
- 'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => $this->p->t('ui', 'field_semester')]),
+ $this->form_validation->set_rules('semester', 'Semester', 'is_natural_no_zero|less_than_equal_to[8]', [
'is_natural_no_zero' => $this->p->t('ui', 'error_fieldInvalid', ['field' => $this->p->t('ui', 'field_semester')]),
'less_than_equal_to' => $this->p->t('ui', 'error_fieldMaxValue', ['field' => $this->p->t('ui', 'field_semester'), 'max' => 8])
]);
@@ -202,8 +204,7 @@ class ClassScheduleApi extends FHCAPI_Controller
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => $this->p->t('ui', 'field_organizationalUnit')]),
'max_length' => $this->p->t('ui', 'error_fieldMaxLength', ['field' => $this->p->t('ui', 'field_organizationalUnit'), 'max' => 32])
]);
- $this->form_validation->set_rules('semester', 'Semester', 'required|is_natural_no_zero|less_than_equal_to[8]', [
- 'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => $this->p->t('ui', 'field_semester')]),
+ $this->form_validation->set_rules('semester', 'Semester', 'is_natural_no_zero|less_than_equal_to[8]', [
'is_natural_no_zero' => $this->p->t('ui', 'error_fieldInvalid', ['field' => $this->p->t('ui', 'field_semester')]),
'less_than_equal_to' => $this->p->t('ui', 'error_fieldMaxValue', ['field' => $this->p->t('ui', 'field_semester'), 'max' => 8])
]);
@@ -265,7 +266,13 @@ class ClassScheduleApi extends FHCAPI_Controller
public function getClassTimeSlotsForValidityPeriod($classTimeSlotValidityPeriodId)
{
$validityPeriodResult = $this->ClassTimeSlotValidityPeriodModel->loadWhere(['unterrichtszeitengueltigkeit_id' => $classTimeSlotValidityPeriodId]);
- $validityPeriod = $this->getDataOrTerminateWithError($validityPeriodResult)[0];
+ $validityPeriodData = $this->getDataOrTerminateWithError($validityPeriodResult);
+ if (!$validityPeriodData || count($validityPeriodData) === 0) {
+ $this->terminateWithError($this->p->t('ui', 'classTimeSlotValidityPeriodNotFound'));
+ }
+
+ $validityPeriod = $validityPeriodData[0];
+
if (!$this->isUserEntitledForOrganizationalUnit($validityPeriod->oe_kurzbz, 'lehre/unterrichtszeiten_gk')) {
$this->terminateWithError($this->p->t('ui', 'keineBerechtigung'));
}
@@ -289,11 +296,8 @@ class ClassScheduleApi extends FHCAPI_Controller
$this->db->trans_start();
- $timeSlotGroupIdentifier = uniqid();
-
foreach ($this->input->post('unterrichtszeiten') as $timeSlot) {
$result = $this->ClassTimeSlotModel->insert([
- 'unterrichtszeit_gruppe_identifikator' => $timeSlotGroupIdentifier,
'wochentag' => $timeSlot['wochentag'],
'uhrzeit_von' => $timeSlot['startTime'],
'uhrzeit_bis' => $timeSlot['endTime'],
@@ -312,7 +316,7 @@ class ClassScheduleApi extends FHCAPI_Controller
$this->terminateWithSuccess(true);
}
- public function editClassTimeSlotsForValidityPeriod($classTimeSlotValidityPeriodId)
+ public function updateClassTimeSlotsForValidityPeriod($classTimeSlotValidityPeriodId)
{
$this->form_validation->set_rules('unterrichtszeiten', 'Class Time Slots', 'callback_validate_items_in_class_time_slots');
if($this->form_validation->run() == FALSE) $this->terminateWithValidationErrors($this->form_validation->error_array());
@@ -325,11 +329,19 @@ class ClassScheduleApi extends FHCAPI_Controller
$this->db->trans_start();
- $timeSlotGroupIdentifier = uniqid();
+ $currentTimeSlotsResult = $this->ClassTimeSlotModel->loadWhere(['unterrichtszeitengueltigkeit_id' => $classTimeSlotValidityPeriodId]);
+ $currentTimeSlots = $this->getDataOrTerminateWithError($currentTimeSlotsResult);
+ $currentTimeSlotIds = array_column($currentTimeSlots, 'unterrichtszeit_id');
+
+ $removedTimeSlotIds = array_values(array_diff($currentTimeSlotIds, array_column($this->input->post('unterrichtszeiten'), 'id')));
+
+ if (count($removedTimeSlotIds) > 0) {
+ $query = 'DELETE FROM lehre.tbl_unterrichtszeiten WHERE unterrichtszeit_id IN ?';
+ $result = $this->db->query($query, [ $removedTimeSlotIds ]);
+ }
foreach ($this->input->post('unterrichtszeiten') as $timeSlot) {
$data = [
- 'unterrichtszeit_gruppe_identifikator' => $timeSlotGroupIdentifier,
'wochentag' => $timeSlot['wochentag'],
'uhrzeit_von' => $timeSlot['startTime'],
'uhrzeit_bis' => $timeSlot['endTime'],
@@ -354,7 +366,7 @@ class ClassScheduleApi extends FHCAPI_Controller
$this->terminateWithSuccess(true);
}
- public function deleteClassTimeSlotsForValidityPeriodPerGroup($classTimeSlotValidityPeriodId, $groupIdentifikator)
+ public function deleteClassTimeSlotsForValidityPeriod($classTimeSlotValidityPeriodId)
{
$validityPeriodResult = $this->ClassTimeSlotValidityPeriodModel->loadWhere(['unterrichtszeitengueltigkeit_id' => $classTimeSlotValidityPeriodId]);
$validityPeriod = $this->getDataOrTerminateWithError($validityPeriodResult)[0];
@@ -364,7 +376,7 @@ class ClassScheduleApi extends FHCAPI_Controller
$this->db->trans_start();
- $result = $this->ClassTimeSlotModel->delete(['unterrichtszeitengueltigkeit_id'=> $classTimeSlotValidityPeriodId, 'unterrichtszeit_gruppe_identifikator' => $groupIdentifikator]);
+ $result = $this->ClassTimeSlotModel->delete(['unterrichtszeitengueltigkeit_id'=> $classTimeSlotValidityPeriodId]);
if (isError($result)) {
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
}
@@ -439,7 +451,8 @@ class ClassScheduleApi extends FHCAPI_Controller
if($this->form_validation->run() == FALSE) $this->terminateWithValidationErrors($this->form_validation->error_array());
- $this->db->trans_start();
+
+ $parsedClassTimeSlotTypeId = urldecode($classTimeSlotTypeId);
$descriptions = $this->input->post('descriptions');
$pgArray = $this->arrayToPgArray($descriptions);
@@ -451,7 +464,7 @@ class ClassScheduleApi extends FHCAPI_Controller
$this->input->post('isActive'),
date('c'),
getAuthUid(),
- $classTimeSlotTypeId,
+ $parsedClassTimeSlotTypeId,
]);
$this->db->trans_complete();
@@ -461,14 +474,15 @@ class ClassScheduleApi extends FHCAPI_Controller
public function deleteClassTimeSlotType($classTimeSlotTypeId)
{
$isClassTimeSlotDeletable = true;
-
- $validityPeriodResult = $this->ClassTimeSlotValidityPeriodModel->loadWhere(['unterrichtszeitentyp_kurzbz' => $classTimeSlotTypeId]);
+ $parsedClassTimeSlotTypeId = urldecode($classTimeSlotTypeId);
+
+ $validityPeriodResult = $this->ClassTimeSlotValidityPeriodModel->loadWhere(['unterrichtszeitentyp_kurzbz' => $parsedClassTimeSlotTypeId]);
$validityPeriod = $this->getDataOrTerminateWithError($validityPeriodResult);
if ($validityPeriod && count($validityPeriod) > 0) {
$isClassTimeSlotDeletable = false;
}
- $classTimeSlotResult = $this->ClassTimeSlotModel->loadWhere(['unterrichtszeitentyp_kurzbz' => $classTimeSlotTypeId]);
+ $classTimeSlotResult = $this->ClassTimeSlotModel->loadWhere(['unterrichtszeitentyp_kurzbz' => $parsedClassTimeSlotTypeId]);
$classTimeSlot = $this->getDataOrTerminateWithError($classTimeSlotResult);
if ($classTimeSlot && count($classTimeSlot) > 0) {
$isClassTimeSlotDeletable = false;
@@ -477,9 +491,9 @@ class ClassScheduleApi extends FHCAPI_Controller
$this->db->trans_start();
if (!$isClassTimeSlotDeletable) {
- $result = $this->ClassTimeSlotTypeModel->update($classTimeSlotTypeId, ['aktiv' => false, 'updateamum' => date('c'), 'updatevon' => getAuthUid()]);
+ $result = $this->ClassTimeSlotTypeModel->update($parsedClassTimeSlotTypeId, ['aktiv' => false, 'updateamum' => date('c'), 'updatevon' => getAuthUid()]);
} else {
- $result = $this->ClassTimeSlotTypeModel->delete(['unterrichtszeitentyp_kurzbz' => $classTimeSlotTypeId]);
+ $result = $this->ClassTimeSlotTypeModel->delete(['unterrichtszeitentyp_kurzbz' => $parsedClassTimeSlotTypeId]);
}
if (isError($result)) {
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
@@ -492,10 +506,16 @@ class ClassScheduleApi extends FHCAPI_Controller
//------------------------------------------------------------------------------------------------------------------
// Private methods
private function arrayToPgArray(array $assoc) {
- $flat = [];
+ $flat = [null, null];
foreach ($assoc as $assocItem) {
- $flat[] = $assocItem['lang'] . ':' . $assocItem['value'];
+ if ($assocItem['lang'] === 'de') {
+ $flat[0] = $assocItem['value'];
+ } else if ($assocItem['lang'] === 'en') {
+ $flat[1] = $assocItem['value'];
+ } else {
+ $flat[] = $assocItem['value'];
+ }
}
$escaped = array_map(function ($v) {
@@ -554,7 +574,7 @@ class ClassScheduleApi extends FHCAPI_Controller
return false;
}
- if (!in_array($timeSlot['wochentag'], [1, 2, 3, 4, 5, 6, 7])) {
+ if (!in_array($timeSlot['wochentag'], [1, 2, 3, 4, 5, 6, 0])) {
$this->form_validation->set_message(
'validate_items_in_class_time_slots',
$this->p->t('ui', 'error_fieldWeekdayInvalid', ['field' => $this->p->t('ui', 'field_classTimeSlot')])
diff --git a/application/controllers/api/frontend/v1/ClassroomHourApi.php b/application/controllers/api/frontend/v1/ClassroomHourApi.php
new file mode 100644
index 000000000..41956f849
--- /dev/null
+++ b/application/controllers/api/frontend/v1/ClassroomHourApi.php
@@ -0,0 +1,43 @@
+.
+ */
+
+if (! defined('BASEPATH')) exit('No direct script access allowed');
+class ClassroomHourApi extends FHCAPI_Controller
+{
+ public function __construct()
+ {
+ parent::__construct([
+ 'getAllClassroomHours' => self::PERM_LOGGED,
+ ]);
+
+ $this->load->model('ressource/Stunde_model', "ClassroomHourModel");
+
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ // Public methods
+
+ public function getAllClassroomHours()
+ {
+ $this->ClassroomHourModel->addOrder('stunde', 'ASC');
+ $result = $this->ClassroomHourModel->load();
+
+ $this->terminateWithSuccess($this->getDataOrTerminateWithError($result));
+ }
+}
+
diff --git a/application/controllers/api/frontend/v1/organisation/Studiensemester.php b/application/controllers/api/frontend/v1/organisation/Studiensemester.php
index 0ede3e00b..f7f39d436 100644
--- a/application/controllers/api/frontend/v1/organisation/Studiensemester.php
+++ b/application/controllers/api/frontend/v1/organisation/Studiensemester.php
@@ -31,8 +31,11 @@ class Studiensemester extends FHCAPI_Controller
'getStudySemestersByStudyPlanAndDates' => self::PERM_LOGGED,
)
);
- // Load model StudiensemesterModel
+
$this->load->model('organisation/studiensemester_model', 'StudiensemesterModel');
+ $this->load->model('organisation/Studiengang_model', 'StudiengangModel');
+ $this->load->model('organisation/Studienordnung_model', 'StudienordnungModel');
+ $this->load->model('organisation/Studienplan_model', 'StudienplanModel');
}
/**
@@ -171,10 +174,6 @@ class Studiensemester extends FHCAPI_Controller
public function getStudySemestersByOrganizationalUnitAndDates($organizationalUnitShortCode)
{
- $this->load->model('organisation/Studiengang_model', 'StudiengangModel');
- $this->load->model('organisation/Studienordnung_model', 'StudienordnungModel');
- $this->load->model('organisation/Studienplan_model', 'StudienplanModel');
-
$startDate = date('Y-m-d', strtotime($this->input->get('filter[startDate]')));
$endDate = date('Y-m-d', strtotime($this->input->get('filter[endDate]')));
if (!$startDate || !$endDate) {
diff --git a/application/controllers/lehre/ClassSchedule.php b/application/controllers/lehre/ClassSchedule.php
index d96551bf5..f1581acb3 100644
--- a/application/controllers/lehre/ClassSchedule.php
+++ b/application/controllers/lehre/ClassSchedule.php
@@ -34,8 +34,6 @@ class ClassSchedule extends Auth_Controller
);
$this->_setAuthUID();
-
- $this->setControllerId();
}
// -----------------------------------------------------------------------------------------------------------------
diff --git a/public/css/components/classSchedule.css b/public/css/components/classSchedule.css
index 80f854541..4decf6531 100644
--- a/public/css/components/classSchedule.css
+++ b/public/css/components/classSchedule.css
@@ -42,3 +42,13 @@
div[role="row"] {
background-color: white;
}
+
+.v-enter-active,
+.v-leave-active {
+ transition: opacity 0.5s ease;
+}
+
+.v-enter-from,
+.v-leave-to {
+ opacity: 0;
+}
\ No newline at end of file
diff --git a/public/js/api/factory/classSchedule.js b/public/js/api/factory/classSchedule.js
index a0a037f80..42af32034 100644
--- a/public/js/api/factory/classSchedule.js
+++ b/public/js/api/factory/classSchedule.js
@@ -65,14 +65,14 @@ export default {
params,
};
},
- editClassTimeSlotsForValidityPeriod(
+ updateClassTimeSlotsForValidityPeriod(
userId,
classTimeSlotValidityPeriodId,
params,
) {
return {
method: "post",
- url: `api/frontend/v1/ClassScheduleApi/editClassTimeSlotsForValidityPeriod/${classTimeSlotValidityPeriodId}`,
+ url: `api/frontend/v1/ClassScheduleApi/updateClassTimeSlotsForValidityPeriod/${classTimeSlotValidityPeriodId}`,
params,
};
},
@@ -87,14 +87,13 @@ export default {
params,
};
},
- deleteClassTimeSlotsForValidityPeriodPerGroup(
+ deleteClassTimeSlotsForValidityPeriod(
userId,
classTimeSlotValidityPeriodId,
- groupIdentifikator,
) {
return {
method: "post",
- url: `api/frontend/v1/ClassScheduleApi/deleteClassTimeSlotsForValidityPeriodPerGroup/${classTimeSlotValidityPeriodId}/${groupIdentifikator}`,
+ url: `api/frontend/v1/ClassScheduleApi/deleteClassTimeSlotsForValidityPeriod/${classTimeSlotValidityPeriodId}`,
};
},
getAllClassScheduleTypes(queryParams) {
@@ -115,14 +114,14 @@ export default {
updateClassTimeSlotType(classTimeSlotTypeId, params) {
return {
method: "post",
- url: `api/frontend/v1/ClassScheduleApi/updateClassTimeSlotType/${classTimeSlotTypeId}`,
+ url: `api/frontend/v1/ClassScheduleApi/updateClassTimeSlotType/${encodeURIComponent(classTimeSlotTypeId)}`,
params,
};
},
deleteClassTimeSlotType(userId, classTimeSlotTypeId) {
return {
method: "post",
- url: `api/frontend/v1/ClassScheduleApi/deleteClassTimeSlotType/${classTimeSlotTypeId}`,
+ url: `api/frontend/v1/ClassScheduleApi/deleteClassTimeSlotType/${encodeURIComponent(classTimeSlotTypeId)}`,
};
},
};
diff --git a/public/js/api/factory/classroomHour.js b/public/js/api/factory/classroomHour.js
new file mode 100644
index 000000000..4cd5ffda1
--- /dev/null
+++ b/public/js/api/factory/classroomHour.js
@@ -0,0 +1,25 @@
+/**
+ * Copyright (C) 2025 fhcomplete.org
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+export default {
+ getAllClassroomHours() {
+ return {
+ method: "get",
+ url: "/api/frontend/v1/ClassroomHourApi/getAllClassroomHours",
+ };
+ }
+};
diff --git a/public/js/components/ClassSchedule/ClassScheduleCalendarSelector.js b/public/js/components/ClassSchedule/ClassScheduleCalendarSelector.js
index 7406e01a0..83703efd2 100644
--- a/public/js/components/ClassSchedule/ClassScheduleCalendarSelector.js
+++ b/public/js/components/ClassSchedule/ClassScheduleCalendarSelector.js
@@ -13,6 +13,10 @@ export default {
required: false,
default: false,
},
+ classroomHours: {
+ type: [Array, null],
+ required: true,
+ },
classTimeSlotTypes: {
type: [Array, null],
required: true,
@@ -22,21 +26,28 @@ export default {
required: false,
default: () => [],
},
+ defaultClassTimeSlotType: {
+ type: String,
+ required: false,
+ default: null,
+ },
},
emits: ["overlaysChanged"],
watch: {
editedOverlays: {
async handler(newVal) {
- await this.$nextTick();
-
this.overlays = [];
- await this.$nextTick();
+
this.$refs.calendarContainer
- .querySelectorAll("div[id^='overlay-']")
+ ?.querySelectorAll("div[id^='overlay-']")
.forEach((element) => {
element.remove();
});
- newVal
+
+ await this.$nextTick();
+
+
+ await newVal
.map((slot) => {
return {
...slot,
@@ -48,7 +59,7 @@ export default {
),
};
})
- .forEach((overlay) => {
+ .forEach(async (overlay) => {
let firstElementDataNumber =
(overlay.weekday - 1) * this.timeSlotsInDay.length +
this.timeSlotsInDay.indexOf(overlay.startingTimeSlot);
@@ -64,6 +75,7 @@ export default {
this.$refs.calendarSelectorContainer.querySelector(
"div[data-number='" + lastElementDataNumber + "']",
);
+
if (!firstSelectedElement || !lastSelectedElement) {
this.$fhcAlert.alertError(
this.$p.t("ui", "classTimeSlotLoadingErrorMessage"),
@@ -84,7 +96,7 @@ export default {
? parseInt(lastSelectedElement.getAttribute("data-number"))
: null;
- this.createOverlay();
+ await this.createOverlay(1);
this.$refs.calendarSelectorContainer
.querySelectorAll("div[class*='part-body']")
@@ -98,15 +110,16 @@ export default {
this.overlays = this.overlays.map((existingOverlay, index) => {
let existingOverlayInNewVal = newVal[index];
+ let selectedClassTimeSlotType = this.$props.classTimeSlotTypes.find(
+ (type) =>
+ type.unterrichtszeitentyp_kurzbz === existingOverlayInNewVal.type,
+ );
existingOverlay.databaseId = existingOverlayInNewVal.databaseId;
existingOverlay.type = existingOverlayInNewVal.type;
- existingOverlay.hexColor =
- this.classTimeSlotTypes.find(
- (type) =>
- type.unterrichtszeitentyp_kurzbz ===
- existingOverlayInNewVal.type,
- )?.hintergrundfarbe || null;
+ existingOverlay.backgroundColor =
+ selectedClassTimeSlotType?.hintergrundfarbe || null;
+
return {
...existingOverlay,
};
@@ -115,17 +128,6 @@ export default {
deep: true,
immediate: true,
},
- classTimeSlotTypes() {
- this.overlays = this.overlays.map((overlay) => {
- let type = this.classTimeSlotTypes.find(
- (type) => type.unterrichtszeitentyp_kurzbz === overlay.type,
- );
- if (type) {
- overlay.hexColor = type.hintergrundfarbe;
- }
- return overlay;
- });
- },
overlays: {
handler(newVal) {
this.$emit("overlaysChanged", newVal);
@@ -144,24 +146,6 @@ export default {
this.$p.t("ui", "saturday"),
this.$p.t("ui", "sunday"),
],
- timeSlotsInDay: [
- "08:00-08:45",
- "08:45-09:30",
- "09:40-10:25",
- "10:25-11:10",
- "11:20-12:05",
- "12:05-12:50",
- "12:50-13:35",
- "13:35-14:20",
- "14:30-15:15",
- "15:15-16:00",
- "16:10-16:55",
- "16:55-17:40",
- "17:50-18:35",
- "18:35-19:20",
- "19:30-20:15",
- "20:15-21:00",
- ],
isTimeElementCreationInProgress: false,
overlays: [],
defaultTimeSlotLabelColor: "var(--fhc-calendar-bg-body)",
@@ -216,16 +200,30 @@ export default {
userLanguage() {
return Vue.ref(FHC_JS_DATA_STORAGE_OBJECT.user_language);
},
+ timeSlotsInDay() {
+ if (!this.$props.classroomHours) return ["08:00-08:45"];
+
+ return this.$props.classroomHours;
+ },
+ trackOverlayPool() {
+ let overlaysInPool = this.$refs.overlaysContainer.children;
+ if (!overlaysInPool < 5) {
+ alert("Could not get overlays in pool");
+ return [];
+ }
+ },
},
methods: {
- createOverlay() {
+ async createOverlay(test) {
this.hideOverlayClassTimeTypePopover();
let overlayElement;
- overlayElement = this.$refs.calendarSelectorContainer.querySelector(
- "#overlays-container",
- ).children[0];
+ overlayElement = this.$refs.overlaysContainer.children[0];
+ if (!overlayElement) {
+ console.error("Could not find overlay element");
+ return;
+ }
let firstSelectedChild =
this.$refs.calendarSelectorContainer.querySelector(
@@ -252,7 +250,6 @@ export default {
firstSelectedElementNumber === null ||
lastSelectedElementNumber === null
) {
- //console.error("Selected elements do not have data-number attribute");
return;
}
@@ -269,7 +266,7 @@ export default {
this.$fhcAlert.alertError(
this.$p.t("ui", "classTimeSlotMultipleWeeksSelectedErrorMessage"),
);
-
+ console.error(error);
return;
}
@@ -347,11 +344,19 @@ export default {
this.timeSlotsInDay[
this.currentLastSelectedElementNumber % this.timeSlotsInDay.length
],
- type: null,
- hexColor: null,
+ type:
+ this.$props.defaultClassTimeSlotType?.unterrichtszeitentyp_kurzbz ||
+ null,
+ backgroundColor:
+ this.$props.defaultClassTimeSlotType?.hintergrundfarbe || null,
weekday: gridLineNumber + 1,
});
}
+ this.$refs.calendarSelectorContainer
+ .querySelectorAll("div[class*='part-body']")
+ .forEach((child) => {
+ child.style.backgroundColor = this.defaultTimeSlotLabelColor;
+ });
},
deleteOverlay(overlayId) {
let confirm = window.confirm(
@@ -557,7 +562,7 @@ export default {
});
}
},
- handleMouseUp(event) {
+ async handleMouseUp(event) {
if (this.$props.isPreviewMode) return;
let isLeftMouseButton = event.buttons === 0;
@@ -637,7 +642,7 @@ export default {
});
}
- this.createOverlay();
+ await this.createOverlay(2);
this.$refs.calendarSelectorContainer
.querySelectorAll("div[class*='part-body']")
@@ -725,16 +730,12 @@ export default {
(overlay) => overlay.id === dropzoneItem.id,
);
if (!dropzoneOverlay) {
- // console.error(
- // "Could not find overlay for dropzone item with id " +
- // dropzoneItem.id,
- // );
return;
}
if (dropzoneOverlay.id !== this.selected[0].id) {
this.$fhcAlert.alertError(
- this.$p.t("ui", "classTimeSlotOverlapErrorMessage"),
+ this.$p.t("ui", "classTimeSlotOverlapErrorMessage2"),
);
return;
}
@@ -901,7 +902,7 @@ export default {
if (firstSkippedOverElement) {
this.$fhcAlert.alertError(
- this.$p.t("ui", "classTimeSlotOverlapErrorMessage"),
+ this.$p.t("ui", "classTimeSlotOverlapErrorMessage3"),
);
let elementBeforeFirstSkippedOverElement =
this.$refs.calendarSelectorContainer.querySelector(
@@ -1152,7 +1153,7 @@ export default {
if (firstSkippedOverElement) {
this.$fhcAlert.alertError(
- this.$p.t("ui", "classTimeSlotOverlapErrorMessage"),
+ this.$p.t("ui", "classTimeSlotOverlapErrorMessage4"),
);
let elementBeforeFirstSkippedOverElement =
this.$refs.calendarSelectorContainer.querySelector(
@@ -1224,7 +1225,7 @@ export default {
overlayId: null,
};
},
- handleMouseOverOnOverlay(overlayId) {
+ async handleMouseOverOnOverlay(overlayId) {
if (this.$props.isPreviewMode) return;
if (!this.isTimeElementCreationInProgress) return;
@@ -1247,7 +1248,9 @@ export default {
this.currentFirstSelectedElementNumber =
hitOverlayStartingTimeSlotElementNumber + 1;
}
- this.createOverlay();
+
+ await this.createOverlay(3);
+
this.isTimeElementCreationInProgress = false;
this.$refs.calendarSelectorContainer
.querySelectorAll("div[class*='part-body']")
@@ -1368,7 +1371,7 @@ export default {
if (!overlay) return "";
let typeDescriptions =
- this.classTimeSlotTypes.find(
+ this.$props.classTimeSlotTypes.find(
(type) => type.unterrichtszeitentyp_kurzbz === overlay.type,
)?.bezeichnung_mehrsprachig || "";
if (!typeDescriptions) return "";
@@ -1378,7 +1381,7 @@ export default {
: typeDescriptions[0].value;
},
handleChangeClassTimeSlotTypeForOverlay(newType) {
- let classTimeSlotType = this.classTimeSlotTypes.find(
+ let classTimeSlotType = this.$props.classTimeSlotTypes.find(
(type) => type.unterrichtszeitentyp_kurzbz === newType,
);
if (!classTimeSlotType) {
@@ -1390,7 +1393,7 @@ export default {
return {
...overlay,
type: classTimeSlotType.unterrichtszeitentyp_kurzbz,
- hexColor: classTimeSlotType.hintergrundfarbe,
+ backgroundColor: classTimeSlotType.hintergrundfarbe,
};
}
return overlay;
@@ -1423,7 +1426,7 @@ export default {
option.addEventListener("click", (event) => {
let selectedTypeDescription = event.currentTarget.innerText;
- let selectedType = this.classTimeSlotTypes.find((type) =>
+ let selectedType = this.$props.classTimeSlotTypes.find((type) =>
type.bezeichnung_mehrsprachig.some(
(desc) => desc.value === selectedTypeDescription,
),
@@ -1437,7 +1440,7 @@ export default {
return {
...overlay,
type: selectedType.unterrichtszeitentyp_kurzbz,
- hexColor: selectedType.hintergrundfarbe,
+ backgroundColor: selectedType.hintergrundfarbe,
};
}
return overlay;
@@ -1466,7 +1469,7 @@ export default {
this.hideOverlayClassTimeTypePopover();
},
template: /*html*/ `
-
+
-
+
-
{
- let descriptions = [];
- for (let item of type.bezeichnung_mehrsprachig) {
- let [lang, value] = item.split(":");
- descriptions.push({ lang, value });
- }
+ let descriptions = [{
+ lang: "de",
+ value: type.bezeichnung_mehrsprachig[0] || "",
+ }, {
+ lang: "en",
+ value: type.bezeichnung_mehrsprachig[1] || "",
+ }];
+
return {
...type,
bezeichnung_mehrsprachig: descriptions,
diff --git a/public/js/components/ClassSchedule/ClassScheduleOverview.js b/public/js/components/ClassSchedule/ClassScheduleOverview.js
index 05db598ad..6cea0e708 100644
--- a/public/js/components/ClassSchedule/ClassScheduleOverview.js
+++ b/public/js/components/ClassSchedule/ClassScheduleOverview.js
@@ -280,7 +280,9 @@ export default {
return events;
},
dropdownParsedOrganizationalUnits() {
- return this.organizationalUnits.map((unit) => {
+ return this.organizationalUnits
+ .filter((unit) => unit.aktiv)
+ .map((unit) => {
return {
label: `${unit.bezeichnung} (${unit.organisationseinheittyp_kurzbz})`,
value: unit.oe_kurzbz,
diff --git a/public/js/components/ClassSchedule/ClassScheduleTypeModal.js b/public/js/components/ClassSchedule/ClassScheduleTypeModal.js
index 7a59dbf47..cc1c6cae8 100644
--- a/public/js/components/ClassSchedule/ClassScheduleTypeModal.js
+++ b/public/js/components/ClassSchedule/ClassScheduleTypeModal.js
@@ -60,11 +60,14 @@ export default {
if (getAllClassScheduleTypeResponse.meta.status === "success") {
this.classScheduleTypes = getAllClassScheduleTypeResponse.data.map(
(type) => {
- let descriptions = [];
- for (let item of type.bezeichnung_mehrsprachig) {
- let [lang, value] = item.split(":");
- descriptions.push({ lang, value });
- }
+ let descriptions = [{
+ lang: "de",
+ value: type.bezeichnung_mehrsprachig[0] || "",
+ }, {
+ lang: "en",
+ value: type.bezeichnung_mehrsprachig[1] || "",
+ }];
+
return {
...type,
bezeichnung_mehrsprachig: descriptions,
@@ -190,10 +193,10 @@ export default {
@@ -214,20 +217,20 @@ export default {
diff --git a/public/js/components/ClassSchedule/ClassScheduleValidityPeriodForm.js b/public/js/components/ClassSchedule/ClassScheduleValidityPeriodForm.js
index 4c09a995b..0dfc2dfd1 100644
--- a/public/js/components/ClassSchedule/ClassScheduleValidityPeriodForm.js
+++ b/public/js/components/ClassSchedule/ClassScheduleValidityPeriodForm.js
@@ -1,4 +1,5 @@
import ApiClassSchedule from "../../../js/api/factory/classSchedule.js";
+import ApiClassroomHour from "../../../js/api/factory/classroomHour.js";
import ClassScheduleCalendarSelector from "./ClassScheduleCalendarSelector.js";
@@ -8,6 +9,10 @@ export default {
ClassScheduleCalendarSelector,
},
props: {
+ classTimeSlotTypes: {
+ type: [Array, null],
+ required: true,
+ },
classTimeSlotValidityPeriod: {
type: Object,
required: true,
@@ -17,6 +22,11 @@ export default {
required: false,
default: () => [],
},
+ classroomHours: {
+ type: Array,
+ required: false,
+ default: () => [],
+ },
},
emits: ["hideForm", "classTimeSlotsCreated", "classTimeSlotsEdited"],
watch: {
@@ -26,7 +36,7 @@ export default {
return {
databaseId: slot.id,
id: slot.identifier,
- weekday: slot.wochentag,
+ weekday: slot.wochentag === 0 ? 7 : slot.wochentag,
type: slot.unterrichtszeitentyp_kurzbz,
startTime: slot.startTime,
endTime: slot.endTime,
@@ -40,7 +50,6 @@ export default {
return {
editedOverlays: [],
classTimeSlots: [],
- classTimeSlotTypes: [],
};
},
computed: {
@@ -78,7 +87,10 @@ export default {
this.$props.classTimeSlotValidityPeriod
.unterrichtszeitengueltigkeit_id,
{
- unterrichtszeiten: this.classTimeSlots,
+ unterrichtszeiten: this.classTimeSlots.map((slot) => {
+ slot.wochentag = parseInt(slot.wochentag) === 7 ? 0 : slot.wochentag;
+ return slot;
+ }),
},
),
);
@@ -87,17 +99,20 @@ export default {
this.classTimeSlots = [];
this.$emit("classTimeSlotsCreated");
} else {
- this.$fhcAlert.handleSystemError(error);
+ this.$fhcAlert.handleSystemError(response.meta.message);
}
},
- async editClassTimeSlots() {
+ async updateClassTimeSlots() {
let response = await this.$api.call(
- ApiClassSchedule.editClassTimeSlotsForValidityPeriod(
+ ApiClassSchedule.updateClassTimeSlotsForValidityPeriod(
this.id,
this.$props.classTimeSlotValidityPeriod
.unterrichtszeitengueltigkeit_id,
{
- unterrichtszeiten: this.classTimeSlots,
+ unterrichtszeiten: this.classTimeSlots.map((slot) => {
+ slot.wochentag = parseInt(slot.wochentag) === 7 ? 0 : slot.wochentag;
+ return slot;
+ }),
},
),
);
@@ -134,35 +149,13 @@ export default {
});
},
},
- async created() {
- let getAllClassTimeSlotTypesResponse = await this.$api.call(
- ApiClassSchedule.getAllClassScheduleTypes("filter[aktiv]=true"),
- );
- if (getAllClassTimeSlotTypesResponse.meta.status === "success") {
- this.classTimeSlotTypes = getAllClassTimeSlotTypesResponse.data.map(
- (type) => {
- let descriptions = [];
- for (let item of type.bezeichnung_mehrsprachig) {
- let [lang, value] = item.split(":");
- descriptions.push({ lang, value });
- }
- return {
- ...type,
- bezeichnung_mehrsprachig: descriptions,
- };
- },
- );
- } else {
- this.$fhcAlert.alertError(
- this.$p.t("ui", "errorFetchingClassScheduleTimeSlotTypes"),
- );
- }
- },
template: `
-
@@ -170,7 +163,7 @@ export default {
-
+
`,
diff --git a/public/js/components/ClassSchedule/ClassScheduleValidityPeriodModal.js b/public/js/components/ClassSchedule/ClassScheduleValidityPeriodModal.js
index ecfb9db38..319ea74bd 100644
--- a/public/js/components/ClassSchedule/ClassScheduleValidityPeriodModal.js
+++ b/public/js/components/ClassSchedule/ClassScheduleValidityPeriodModal.js
@@ -47,19 +47,21 @@ export default {
.call(ApiClassSchedule.getClassTimeValidityPeriod(newValue))
.then((response) => {
let validityPeriodData = response.data[0];
- let organizationalUnit = this.organizationalUnits.find(
- (unit) => unit.oe_kurzbz === validityPeriodData.oe_kurzbz,
+ let parsedOrganizationalUnit = this.dropdownParsedOrganizationalUnits.find(
+ (unit) => unit.value === validityPeriodData.oe_kurzbz,
);
- if (!organizationalUnit) {
- this.$fhcAlert.alertError(this.$p.t("ui", "errorLoadingData"));
- return;
+ if (!parsedOrganizationalUnit) {
+ parsedOrganizationalUnit = {
+ value: validityPeriodData.oe_kurzbz,
+ label: validityPeriodData.oe_bezeichnung ,
+ };
}
this.editedClassTimeSlotValidityPeriod = validityPeriodData;
this.classTimeSlotValidityPeriodFormData = {
id: validityPeriodData.unterrichtszeitengueltigkeit_id,
- organizationalUnit,
+ organizationalUnit: parsedOrganizationalUnit,
studyPlanId: validityPeriodData.studienplan_id,
classTimeSlotTypeShortcode:
validityPeriodData.unterrichtszeitentyp_kurzbz,
@@ -136,12 +138,22 @@ export default {
userLanguage() {
return Vue.ref(FHC_JS_DATA_STORAGE_OBJECT.user_language);
},
+ dropdownParsedOrganizationalUnits() {
+ return this.organizationalUnits
+ .filter((unit) => unit.aktiv)
+ .map((unit) => {
+ return {
+ label: `${unit.bezeichnung} (${unit.organisationseinheittyp_kurzbz})`,
+ value: unit.oe_kurzbz,
+ };
+ });
+ },
},
methods: {
updateClassTimeSlotValidityPeriodFormDataWatcher() {
if (
!this.classTimeSlotValidityPeriodFormData.organizationalUnit
- ?.oe_kurzbz ||
+ ?.value ||
!this.classTimeSlotValidityPeriodFormData.validityPeriodFrom ||
!this.classTimeSlotValidityPeriodFormData.validityPeriodTo
) {
@@ -153,7 +165,7 @@ export default {
},
async refetchFilterableOptions() {
this.studyPlans = await this.getTargetedStudyPlans(
- this.classTimeSlotValidityPeriodFormData.organizationalUnit?.oe_kurzbz,
+ this.classTimeSlotValidityPeriodFormData.organizationalUnit?.value,
this.formattedValidityPeriodFrom,
this.formattedValidityPeriodTo,
);
@@ -171,11 +183,6 @@ export default {
);
if (editedStudyPlan) {
this.studyPlans.push(editedStudyPlan);
- } else {
- // console.error(
- // "Edited study plan not found:",
- // this.editedClassTimeSlotValidityPeriod.studienplan_id,
- // );
}
}
}
@@ -183,7 +190,7 @@ export default {
let studySemestersByDates =
await this.getStudySemestersByOrganizationalUnitAndDates(
this.classTimeSlotValidityPeriodFormData.organizationalUnit
- ?.oe_kurzbz,
+ ?.value,
this.formattedValidityPeriodFrom,
this.formattedValidityPeriodTo,
);
@@ -325,7 +332,7 @@ export default {
...this.classTimeSlotValidityPeriodFormData,
organizationalUnitShortCode:
this.classTimeSlotValidityPeriodFormData.organizationalUnit
- ?.oe_kurzbz,
+ ?.value,
}),
)
.then((response) => {
@@ -349,7 +356,7 @@ export default {
...this.classTimeSlotValidityPeriodFormData,
organizationalUnitShortCode:
this.classTimeSlotValidityPeriodFormData.organizationalUnit
- ?.oe_kurzbz,
+ ?.value,
},
),
)
@@ -384,12 +391,12 @@ export default {
const query = event.query.toLowerCase();
if (!query) {
return (this.filteredOrganizationalUnits = [
- ...this.organizationalUnits,
+ ...this.dropdownParsedOrganizationalUnits,
]);
}
return (this.filteredOrganizationalUnits =
- this.organizationalUnits.filter((unit) => {
+ this.dropdownParsedOrganizationalUnits.filter((unit) => {
let label = `${unit.bezeichnung} (${unit.organisationseinheittyp_kurzbz})`;
return label.toLowerCase().includes(query);
}));
@@ -430,11 +437,14 @@ export default {
if (getAllClassTimeSlotTypesResponse.meta.status === "success") {
this.classTimeSlotTypes = getAllClassTimeSlotTypesResponse.data.map(
(type) => {
- let descriptions = [];
- for (let item of type.bezeichnung_mehrsprachig) {
- let [lang, value] = item.split(":");
- descriptions.push({ lang, value });
- }
+ let descriptions = [{
+ lang: "de",
+ value: type.bezeichnung_mehrsprachig[0] || "",
+ }, {
+ lang: "en",
+ value: type.bezeichnung_mehrsprachig[1] || "",
+ }];
+
return {
...type,
bezeichnung_mehrsprachig: descriptions,
@@ -460,8 +470,8 @@ export default {
v-model="classTimeSlotValidityPeriodFormData.organizationalUnit"
:label="$capitalize($p.t('lehre/organisationseinheit')) + ' *'"
:suggestions="filteredOrganizationalUnits"
- :optionValue="(option) => option.kurzbz"
- :optionLabel="(option) => option.bezeichnung + ' (' + option.organisationseinheittyp_kurzbz + ')'"
+ :optionValue="(option) => option.value"
+ :optionLabel="(option) => option.label"
@complete="filterOrganizationalUnits"
dropdown
forceSelection
@@ -523,7 +533,7 @@ export default {
id="ausbildungssemester"
name="semester"
:disabled="isStudyPlanSelectDisabled"
- :label="$p.t('lehre', 'ausbildungssemester')+ '*'"
+ :label="$p.t('lehre', 'ausbildungssemester')"
v-model="classTimeSlotValidityPeriodFormData.semester"
>
-
+
{ isClassTimeSlotFormVisible = false; fetchClassTimeSlots(); this.editedClassTimeSlots = []; }"
- @classTimeSlotsEdited="() => { isClassTimeSlotFormVisible = false; fetchClassTimeSlots(); this.editedClassTimeSlots = []; }"
- @hideForm="() => { isClassTimeSlotFormVisible = false; this.editedClassTimeSlots = []; }"
+ @classTimeSlotsCreated="() => { isClassTimeSlotFormVisible = false; this.areClassTimeSlotsLoaded = false; this.classTimeSlots = []; fetchClassTimeSlots(); this.editedClassTimeSlots = []; }"
+ @classTimeSlotsEdited="() => { isClassTimeSlotFormVisible = false; this.areClassTimeSlotsLoaded = false; this.classTimeSlots = []; fetchClassTimeSlots(); this.editedClassTimeSlots = []; }"
+ @hideForm="() => { isClassTimeSlotFormVisible = false; this.areClassTimeSlotsLoaded = false; this.classTimeSlots = []; fetchClassTimeSlots(); this.editedClassTimeSlots = []; }"
class="mb-4"
/>
{{ $p.t("ui", "classScheduleValidityPeriodTimeSlots") }}
-
-
-
+
+
{{ $p.t("ui", "noClassScheduleValidityPeriodTimeSlotsFound") }}
diff --git a/public/js/components/ClassSchedule/ClassScheduleValidityPeriodPreview.js b/public/js/components/ClassSchedule/ClassScheduleValidityPeriodPreview.js
index 24b3d1f4f..1215a7e55 100644
--- a/public/js/components/ClassSchedule/ClassScheduleValidityPeriodPreview.js
+++ b/public/js/components/ClassSchedule/ClassScheduleValidityPeriodPreview.js
@@ -1,4 +1,5 @@
import ClassScheduleCalendarSelector from "./ClassScheduleCalendarSelector.js";
+import ApiClassroomHour from "../../../js/api/factory/classroomHour.js";
export default {
name: "ClassScheduleValidityPeriodPreview",
@@ -20,7 +21,9 @@ export default {
},
},
data: () => {
- return {};
+ return {
+ classRoomHours: [],
+ };
},
computed: {
classScheduleValidityPeriodStartDate() {
@@ -29,38 +32,18 @@ export default {
let dateParts = this.$props.classScheduleValidityPeriod.gueltig_von
.split("-")
.reverse();
- return dateParts.join("/");
+ return dateParts.join(".");
},
classScheduleValidityPeriodEndDate() {
if (!this.$props.classScheduleValidityPeriod) return null;
let dateParts = this.$props.classScheduleValidityPeriod.gueltig_bis
.split("-")
.reverse();
- return dateParts.join("/");
+ return dateParts.join(".");
},
classScheduleValidityPeriodStudyPlan() {
return this.$props.classScheduleValidityPeriod.studienplan_bezeichnung;
},
- parsedClassTimeSlots() {
- let classTimeSlotsGroupedByWeek = [];
-
- this.$props.classTimeSlots.forEach((slot) => {
- let groupIdentifikator = slot["unterrichtszeit_gruppe_identifikator"];
- let existingGroup = classTimeSlotsGroupedByWeek.find(
- (group) => group.groupIdentifikator === groupIdentifikator,
- );
- if (existingGroup) {
- existingGroup.slots.push(slot);
- } else {
- classTimeSlotsGroupedByWeek.push({
- groupIdentifikator,
- slots: [slot],
- });
- }
- });
-
- return classTimeSlotsGroupedByWeek;
- },
},
methods: {
showClassScheduleValidityPeriod(classScheduleValidityPeriodId) {
@@ -72,7 +55,22 @@ export default {
});
},
},
- async created() {},
+ async created() {
+ let getAllClassroomHoursResponse = await this.$api.call(
+ ApiClassroomHour.getAllClassroomHours(),
+ );
+ if (getAllClassroomHoursResponse.meta.status === "success") {
+ this.classroomHours = getAllClassroomHoursResponse.data.map((hour) => {
+ return {
+ ...hour,
+ beginn: hour.beginn.substring(0, 5),
+ ende: hour.ende.substring(0, 5),
+ };
+ });
+ } else {
+ this.$fhcAlert.alertError(this.$p.t("ui", "errorFetchingClassroomHours"));
+ }
+ },
template: /* html */ `
@@ -86,15 +84,16 @@ export default {
>
-
-
+
+
{
return {
databaseId: slot.id,
id: slot.identifier,
- weekday: slot.wochentag,
+ weekday: parseInt(slot.wochentag) === 0 ? 7 : slot.wochentag,
type: slot.unterrichtszeitentyp_kurzbz,
startTime: slot.uhrzeit_von,
endTime: slot.uhrzeit_bis,
diff --git a/system/dbupdate_3.4/76031_unterrichtszeiten_der_studiengänge.php b/system/dbupdate_3.4/76031_unterrichtszeiten_der_studiengänge.php
index 210e277d1..4382fd858 100644
--- a/system/dbupdate_3.4/76031_unterrichtszeiten_der_studiengänge.php
+++ b/system/dbupdate_3.4/76031_unterrichtszeiten_der_studiengänge.php
@@ -37,7 +37,6 @@ if(!$result = @$db->db_query("SELECT 1 FROM lehre.tbl_unterrichtszeiten LIMIT 1"
$qry = '
CREATE TABLE lehre.tbl_unterrichtszeiten (
"unterrichtszeit_id" INTEGER NOT NULL,
- "unterrichtszeit_gruppe_identifikator" VARCHAR(32) NOT NULL,
"wochentag" INTEGER NOT NULL,
"uhrzeit_von" TIME NOT NULL,
"uhrzeit_bis" TIME NOT NULL,
@@ -104,6 +103,7 @@ if(!$result = @$db->db_query("SELECT 1 FROM lehre.tbl_unterrichtszeiten_typ LIMI
"bezeichnung_mehrsprachig" TEXT[] NOT NULL,
"aktiv" BOOLEAN DEFAULT true,
"hintergrundfarbe" VARCHAR(7),
+ "ist_standard" BOOLEAN DEFAULT false,
"insertamum" TIMESTAMP WITH TIME ZONE DEFAULT now(),
"insertvon" VARCHAR(32),
"updateamum" TIMESTAMP WITH TIME ZONE DEFAULT now(),
@@ -156,12 +156,12 @@ if(!$result = @$db->db_query("SELECT 1 FROM lehre.tbl_unterrichtszeiten_typ LIMI
$qry = "
- INSERT INTO lehre.tbl_unterrichtszeiten_typ (unterrichtszeitentyp_kurzbz, bezeichnung_mehrsprachig, aktiv, hintergrundfarbe) VALUES
- ('unterrichtszeiten', ARRAY['de:unterrichtszeiten', 'en:teaching times'], 't', '#FFFFFF'),
- ('vorlesungen', ARRAY['de:Vorlesung', 'en:Lecture'], 't', '#FF8A8A'),
- ('backuptage', ARRAY['de:Übung', 'en:Exercise'], 't', '#8AFF8A'),
- ('ausgleichswochen', ARRAY['de:Ausgleichswochen', 'en:Compensation Weeks'], 't', '#8A8AFF'),
- ('prüfungswochen', ARRAY['de:Prüfungswochen', 'en:Exam Weeks'], 't', '#FFFF8A');
+ INSERT INTO lehre.tbl_unterrichtszeiten_typ (unterrichtszeitentyp_kurzbz, bezeichnung_mehrsprachig, aktiv, hintergrundfarbe, ist_standard) VALUES
+ ('unterrichtszeiten', ARRAY['Unterrichtszeiten', 'Teaching Times'], 't', '#FFFFFF', 'f'),
+ ('vorlesungen', ARRAY['Vorlesung', 'Lecture'], 't', '#FF8A8A', 't'),
+ ('backuptage', ARRAY['Übung', 'Exercise'], 't', '#8AFF8A', 'f'),
+ ('ausgleichswochen', ARRAY['Ausgleichswochen', 'Compensation Weeks'], 't', '#8A8AFF', 'f'),
+ ('prüfungswochen', ARRAY['Prüfungswochen', 'Exam Weeks'], 't', '#FFFF8A', 'f');
";
if(!$db->db_query($qry))
diff --git a/system/phrasesupdate.php b/system/phrasesupdate.php
index e35f6aa36..cfd6a28b2 100644
--- a/system/phrasesupdate.php
+++ b/system/phrasesupdate.php
@@ -57844,13 +57844,13 @@ I have been informed that I am under no obligation to consent to the transmissio
'phrases' => array(
array(
'sprache' => 'German',
- 'text' => 'Kein Gültigkeitszeitraum für diese Unterrichtszeit gefunden',
+ 'text' => 'Kein Gültigkeitszeitraum gefunden',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
- 'text' => 'No validity period found for this class time slot',
+ 'text' => 'No validity period found',
'description' => '',
'insertvon' => 'system'
),
@@ -58636,6 +58636,26 @@ I have been informed that I am under no obligation to consent to the transmissio
)
)
),
+ array(
+ 'app' => 'core',
+ 'category' => 'ui',
+ 'phrase' => 'errorFetchingClassroomHours',
+ 'insertvon' => 'system',
+ 'phrases' => array(
+ array(
+ 'sprache' => 'German',
+ 'text' => 'Fehler beim Abrufen der Unterrichtsstunden',
+ 'description' => '',
+ 'insertvon' => 'system'
+ ),
+ array(
+ 'sprache' => 'English',
+ 'text' => 'Error fetching classroom hours',
+ 'description' => '',
+ 'insertvon' => 'system'
+ )
+ )
+ ),
);