mirror of
https://github.com/FH-Complete/FHC-Core.git
synced 2026-07-18 23:42:17 +00:00
Add removal of multiple weeks per validation period, and other minor changes
This commit is contained in:
@@ -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')])
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2024 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -34,8 +34,6 @@ class ClassSchedule extends Auth_Controller
|
||||
);
|
||||
|
||||
$this->_setAuthUID();
|
||||
|
||||
$this->setControllerId();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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)}`,
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
@@ -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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
export default {
|
||||
getAllClassroomHours() {
|
||||
return {
|
||||
method: "get",
|
||||
url: "/api/frontend/v1/ClassroomHourApi/getAllClassroomHours",
|
||||
};
|
||||
}
|
||||
};
|
||||
@@ -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*/ `
|
||||
<div ref="calendarSelectorContainer" >
|
||||
<div ref="calendarSelectorContainer">
|
||||
<div
|
||||
ref="calendarContainer"
|
||||
@mousedown="handleMouseDown"
|
||||
@@ -1714,9 +1717,9 @@ export default {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="overlays-container" class='d-none'>
|
||||
<div ref="overlaysContainer" id="overlaysContainer" class='d-none'>
|
||||
<div
|
||||
v-for="(index) in 50"
|
||||
v-for="(index) in 100"
|
||||
v-draggable:copyLink.noimage="selectedDragObject"
|
||||
@mousedown='overlaySelectionChanged($event, "overlay-item-" + index)'
|
||||
@mouseover="handleMouseOverOnOverlay('overlay-item-' + index)"
|
||||
@@ -1724,7 +1727,9 @@ export default {
|
||||
:class="{
|
||||
'fhc-drag-handle': !$props.isPreviewMode,
|
||||
}"
|
||||
:style="{ backgroundColor: this.overlays.find(overlay => overlay.id === 'overlay-item-' + index)?.hexColor || this.defaultOverlayColor }"
|
||||
:style="{
|
||||
backgroundColor: this.overlays.find(overlay => overlay.id === 'overlay-item-' + index)?.backgroundColor || this.defaultOverlayColor,
|
||||
}"
|
||||
:title="getOverlayClassScheduleTypeTitle('overlay-item-' + index)"
|
||||
class="d-none fhc-pointer-events-all flex-column justify-content-between align-items-center shadow rounded-1"
|
||||
:draggable='!$props.isPreviewMode ? "true" : "false"'
|
||||
@@ -1776,7 +1781,7 @@ export default {
|
||||
</div>
|
||||
<div ref="classScheduleTypeSelectorContainer" class="d-none">
|
||||
<div class='d-flex flex-column gap-2'>
|
||||
<span v-for="(type, index) in classTimeSlotTypes"
|
||||
<span v-for="(type, index) in $props.classTimeSlotTypes"
|
||||
:key="index"
|
||||
:data-type="type.unterrichtszeitentyp_kurzbz"
|
||||
class="btn btn-sm btn-outline-dark class-schedule-type-selector-option"
|
||||
|
||||
+8
-5
@@ -82,11 +82,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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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 {
|
||||
<core-form v-else-if="isFormVisible && hasLehreUnterrichtszeitenTypWPermission" ref="classTimeSlotTypeForm" class="row g-3 pb-3">
|
||||
<div v-if="!isEditInProgress" class="row mb-3">
|
||||
<form-input
|
||||
v-model="classTimeSlotTypeFormData.shortCode"
|
||||
:label="$p.t('ui/shortName')"
|
||||
type="text"
|
||||
name="shortCode"
|
||||
:label="$p.t('ui/shortName')"
|
||||
v-model="classTimeSlotTypeFormData.shortCode"
|
||||
>
|
||||
</form-input>
|
||||
</div>
|
||||
@@ -214,20 +217,20 @@ export default {
|
||||
</div>
|
||||
<div class="row mb-3">
|
||||
<form-input
|
||||
type="text"
|
||||
name="backgroundColor"
|
||||
v-model="classTimeSlotTypeFormData.backgroundColor"
|
||||
:label="$p.t('ui/backgroundColor')"
|
||||
v-model="classTimeSlotTypeFormData.backgroundColor"
|
||||
type="color"
|
||||
name="backgroundColor"
|
||||
>
|
||||
</form-input>
|
||||
</div>
|
||||
<div class="row mb-3">
|
||||
<div class="col d-flex align-items-center justify-content-end">
|
||||
<form-input
|
||||
v-model="classTimeSlotTypeFormData.isActive"
|
||||
:label="$p.t('ui/isActive')"
|
||||
type="checkbox"
|
||||
name="isActive"
|
||||
:label="$p.t('ui/isActive')"
|
||||
v-model="classTimeSlotTypeFormData.isActive"
|
||||
>
|
||||
</form-input>
|
||||
</div>
|
||||
|
||||
@@ -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: `
|
||||
<div class='row'>
|
||||
<div class='col-12'>
|
||||
<class-schedule-calendar-selector
|
||||
:class-time-slot-types="this.classTimeSlotTypes"
|
||||
<class-schedule-calendar-selector
|
||||
:classroom-hours="this.$props.classroomHours"
|
||||
:default-class-time-slot-type="this.$props.classTimeSlotTypes.find(type => type.ist_standard)"
|
||||
:class-time-slot-types="this.$props.classTimeSlotTypes"
|
||||
:edited-overlays="this.editedOverlays"
|
||||
@overlaysChanged="handleOverlaysChanged"
|
||||
/>
|
||||
@@ -170,7 +163,7 @@ export default {
|
||||
<div class="col-12 d-flex justify-content-end gap-2">
|
||||
<button type="button" class="btn btn-secondary" @click="hideForm">{{$p.t('ui', 'abbrechen')}}</button>
|
||||
<button v-if="!areClassTimeSlotsEdited" type="button" class="btn btn-primary" @click="createClassTimeSlots">{{$p.t('ui', 'speichern')}}</button>
|
||||
<button v-else type="button" class="btn btn-primary" @click="editClassTimeSlots">{{$p.t('ui', 'btnAktualisieren')}}</button>
|
||||
<button v-else type="button" class="btn btn-primary" @click="updateClassTimeSlots">{{$p.t('ui', 'btnAktualisieren')}}</button>
|
||||
</div>
|
||||
</div>
|
||||
`,
|
||||
|
||||
@@ -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"
|
||||
>
|
||||
<option
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import ApiClassSchedule from "../../../js/api/factory/classSchedule.js";
|
||||
import ApiClassroomHour from "../../../js/api/factory/classroomHour.js";
|
||||
|
||||
import BsModal from "../Bootstrap/Modal.js";
|
||||
import ClassScheduleValidityPeriodForm from "./ClassScheduleValidityPeriodForm.js";
|
||||
@@ -15,9 +16,11 @@ export default {
|
||||
},
|
||||
data: () => {
|
||||
return {
|
||||
classroomHours: [],
|
||||
isClassTimeSlotFormVisible: false,
|
||||
classTimeSlotValidityPeriodId: null,
|
||||
classTimeSlotValidityPeriod: null,
|
||||
areClassTimeSlotsLoaded: false,
|
||||
classTimeSlots: [],
|
||||
classTimeSlotTypes: [],
|
||||
editedClassTimeSlots: [],
|
||||
@@ -32,14 +35,14 @@ export default {
|
||||
let dateParts = this.classTimeSlotValidityPeriod.gueltig_von
|
||||
.split("-")
|
||||
.reverse();
|
||||
return dateParts.join("/");
|
||||
return dateParts.join(".");
|
||||
},
|
||||
classScheduleValidityPeriodEndDate() {
|
||||
if (!this.classTimeSlotValidityPeriod) return null;
|
||||
let dateParts = this.classTimeSlotValidityPeriod.gueltig_bis
|
||||
.split("-")
|
||||
.reverse();
|
||||
return dateParts.join("/");
|
||||
return dateParts.join(".");
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
@@ -49,6 +52,7 @@ export default {
|
||||
this.classTimeSlotValidityPeriodId,
|
||||
),
|
||||
);
|
||||
|
||||
if (getClassTimeValidityPeriodResponse.meta.status === "success") {
|
||||
this.classTimeSlotValidityPeriod =
|
||||
getClassTimeValidityPeriodResponse.data[0];
|
||||
@@ -74,52 +78,38 @@ export default {
|
||||
if (
|
||||
getClassTimeSlotsForValidityPeriodResponse.meta.status === "success"
|
||||
) {
|
||||
let classTimeSlotsGroupedByWeek = [];
|
||||
getClassTimeSlotsForValidityPeriodResponse.data.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],
|
||||
});
|
||||
}
|
||||
});
|
||||
this.classTimeSlots = classTimeSlotsGroupedByWeek;
|
||||
this.classTimeSlots = getClassTimeSlotsForValidityPeriodResponse.data;
|
||||
} else {
|
||||
this.$fhcAlert.alertError(
|
||||
this.$p.t("ui", "errorFetchingClassScheduleTimeSlotForValidityPeriod"),
|
||||
this.$p.t(
|
||||
"ui",
|
||||
"errorFetchingClassScheduleTimeSlotForValidityPeriod",
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
this.areClassTimeSlotsLoaded = true;
|
||||
},
|
||||
showClassTimeSlotForm() {
|
||||
this.isClassTimeSlotFormVisible = true;
|
||||
},
|
||||
async editClassTimeSlotsForValidityPeriodPerGroup(groupIdentifikator) {
|
||||
async editClassTimeSlotsForValidityPeriod() {
|
||||
await this.fetchClassTimeSlots();
|
||||
|
||||
this.editedClassTimeSlots =
|
||||
this.classTimeSlots
|
||||
.filter(
|
||||
(group) => group.groupIdentifikator === groupIdentifikator,
|
||||
)?.[0]
|
||||
.slots.map((slot) => {
|
||||
return {
|
||||
...slot,
|
||||
id: slot.unterrichtszeit_id,
|
||||
startTime: slot.uhrzeit_von,
|
||||
endTime: slot.uhrzeit_bis,
|
||||
classTimeSlotTypeShortcode: slot.unterrichtszeitentyp_kurzbz,
|
||||
};
|
||||
}) || [];
|
||||
this.classTimeSlots.map((slot) => {
|
||||
return {
|
||||
...slot,
|
||||
id: slot.unterrichtszeit_id,
|
||||
startTime: slot.uhrzeit_von,
|
||||
endTime: slot.uhrzeit_bis,
|
||||
classTimeSlotTypeShortcode: slot.unterrichtszeitentyp_kurzbz,
|
||||
};
|
||||
}) || [];
|
||||
|
||||
this.showClassTimeSlotForm();
|
||||
},
|
||||
deleteClassTimeSlotsForValidityPeriodPerGroup(groupIdentifikator) {
|
||||
deleteClassTimeSlotsForValidityPeriod() {
|
||||
let isDeletionConfirmed = confirm(
|
||||
this.$p.t("ui", "confirmDeleteClassTimeSlotsForGroup"),
|
||||
);
|
||||
@@ -129,10 +119,9 @@ export default {
|
||||
|
||||
return this.$api
|
||||
.call(
|
||||
ApiClassSchedule.deleteClassTimeSlotsForValidityPeriodPerGroup(
|
||||
ApiClassSchedule.deleteClassTimeSlotsForValidityPeriod(
|
||||
this.id,
|
||||
this.classTimeSlotValidityPeriodId,
|
||||
groupIdentifikator,
|
||||
),
|
||||
)
|
||||
.then((response) => {
|
||||
@@ -194,7 +183,7 @@ export default {
|
||||
this.classTimeSlotValidityPeriodId =
|
||||
this.$route.params.classTimeSlotValidityPeriodId;
|
||||
|
||||
this.fetchClassTimeValidityPeriod();
|
||||
await this.fetchClassTimeValidityPeriod();
|
||||
|
||||
let getAllClassTimeSlotTypesResponse = await this.$api.call(
|
||||
ApiClassSchedule.getAllClassScheduleTypes("filter[aktiv]=true"),
|
||||
@@ -202,11 +191,13 @@ 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,
|
||||
@@ -219,6 +210,21 @@ export default {
|
||||
);
|
||||
}
|
||||
|
||||
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"));
|
||||
}
|
||||
|
||||
this.fetchClassTimeSlots();
|
||||
},
|
||||
template: /* html */ `
|
||||
@@ -250,44 +256,49 @@ export default {
|
||||
</h5>
|
||||
</div>
|
||||
<div>
|
||||
<div v-if='!isClassTimeSlotFormVisible' class="col-12 d-flex justify-content-end">
|
||||
<div v-if='!isClassTimeSlotFormVisible && !classTimeSlots.length && areClassTimeSlotsLoaded' class="col-12 d-flex justify-content-end">
|
||||
<button type="button" class="btn btn-primary" @click="showClassTimeSlotForm">{{$p.t('ui', 'addClassTimeSlotButton')}}</button>
|
||||
</div>
|
||||
<class-schedule-validity-period-form
|
||||
v-else
|
||||
v-if="isClassTimeSlotFormVisible"
|
||||
:class-time-slot-types="this.classTimeSlotTypes"
|
||||
:classroom-hours="this.classroomHours.map(hour => hour.beginn + '-' + hour.ende)"
|
||||
:class-time-slot-validity-period="classTimeSlotValidityPeriod"
|
||||
:edited-class-time-slots="editedClassTimeSlots"
|
||||
@classTimeSlotsCreated="() => { 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"
|
||||
/>
|
||||
<div>
|
||||
<h4>{{ $p.t("ui", "classScheduleValidityPeriodTimeSlots") }}</h4>
|
||||
</div>
|
||||
<div v-if="classTimeSlots && Object.keys(classTimeSlots).length > 0">
|
||||
<div v-for="(classTimeSlotsPerWeek, index) in classTimeSlots" :key="index" class="row border-top rounded p-2 mt-4 mb-2 pt-1 pb-5">
|
||||
<transition>
|
||||
<div v-if="classTimeSlots && Object.keys(classTimeSlots).length > 0 && !isClassTimeSlotFormVisible">
|
||||
<div class="col-12 d-flex align-items-center justify-content-end gap-2">
|
||||
<a class="ml-auto" @click="editClassTimeSlotsForValidityPeriodPerGroup(classTimeSlotsPerWeek.groupIdentifikator)"><i class="fa fa-edit fs-5"></i></a>
|
||||
<a class="ml-auto" @click="deleteClassTimeSlotsForValidityPeriodPerGroup(classTimeSlotsPerWeek.groupIdentifikator)"><i class="fa fa-trash text-danger fs-5"></i></a>
|
||||
<a class="ml-auto" @click="editClassTimeSlotsForValidityPeriod"><i class="fa fa-edit fs-5"></i></a>
|
||||
<a class="ml-auto" @click="deleteClassTimeSlotsForValidityPeriod"><i class="fa fa-trash text-danger fs-5"></i></a>
|
||||
</div>
|
||||
<div class="row border-top rounded p-2 mt-4 mb-2 pt-1 pb-5">
|
||||
<class-schedule-calendar-selector
|
||||
:classroom-hours="this.classroomHours.map(hour => hour.beginn + '-' + hour.ende)"
|
||||
:class-time-slot-types="this.classTimeSlotTypes"
|
||||
:edited-overlays="classTimeSlots.map((slot) => {
|
||||
return {
|
||||
databaseId: slot.id,
|
||||
id: slot.identifier,
|
||||
weekday: parseInt(slot.wochentag) === 0 ? 7 : slot.wochentag,
|
||||
type: slot.unterrichtszeitentyp_kurzbz,
|
||||
startTime: slot.uhrzeit_von,
|
||||
endTime: slot.uhrzeit_bis,
|
||||
};
|
||||
})"
|
||||
:isPreviewMode="true"
|
||||
/>
|
||||
</div>
|
||||
<class-schedule-calendar-selector
|
||||
:class-time-slot-types="this.classTimeSlotTypes"
|
||||
:edited-overlays="classTimeSlotsPerWeek.slots.map((slot) => {
|
||||
return {
|
||||
databaseId: slot.id,
|
||||
id: slot.identifier,
|
||||
weekday: slot.wochentag,
|
||||
type: slot.unterrichtszeitentyp_kurzbz,
|
||||
startTime: slot.uhrzeit_von,
|
||||
endTime: slot.uhrzeit_bis,
|
||||
};
|
||||
})"
|
||||
:isPreviewMode="true"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="d-flex align-items-center justify-content-center border rounded p-4 mt-4">
|
||||
</transition>
|
||||
<div v-if="!classTimeSlots || Object.keys(classTimeSlots).length === 0" class="d-flex align-items-center justify-content-center border rounded p-4 mt-4">
|
||||
<p class="m-0">{{ $p.t("ui", "noClassScheduleValidityPeriodTimeSlotsFound") }}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -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 */ `
|
||||
<div class="container mt-4">
|
||||
<div class='py-3 d-flex align-items-center justify-content-between'>
|
||||
@@ -86,15 +84,16 @@ export default {
|
||||
><i class="fa fa-eye fs-5"></i></a>
|
||||
</div>
|
||||
<div class='py-3 mb-4'>
|
||||
<div v-if="parsedClassTimeSlots && parsedClassTimeSlots.length > 0">
|
||||
<div v-for="(classTimeSlotsPerWeek, index) in parsedClassTimeSlots" :key="index" class="row border-top rounded pt-1 pb-5">
|
||||
<div v-if="$props.classTimeSlots && $props.classTimeSlots.length > 0">
|
||||
<div class="row border-top rounded pt-1 pb-5">
|
||||
<class-schedule-calendar-selector
|
||||
:classroom-hours="this.classroomHours.map(hour => hour.beginn + '-' + hour.ende)"
|
||||
:class-time-slot-types="this.classTimeSlotTypes"
|
||||
:edited-overlays="classTimeSlotsPerWeek.slots.map((slot) => {
|
||||
:edited-overlays="$props.classTimeSlots.map((slot) => {
|
||||
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,
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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'
|
||||
)
|
||||
)
|
||||
),
|
||||
);
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user