mirror of
https://github.com/FH-Complete/FHC-Core.git
synced 2026-07-25 08:34:29 +00:00
add class schedule controllers, components, and updated phrases
This commit is contained in:
@@ -119,6 +119,9 @@ $route['api/frontend/v1/stv/[sS]tudents/([WS]S[0-9]{4})/prestudent/(:num)'] = 'a
|
||||
// // (studiensemester_kurzbz)/person/(person_id)
|
||||
$route['api/frontend/v1/stv/[sS]tudents/([WS]S[0-9]{4})/person/(:num)'] = 'api/frontend/v1/stv/Students/getPerson/$1/$2';
|
||||
|
||||
|
||||
$route['lehre/ClassSchedule/(:any)/(:any)'] = 'lehre/ClassSchedule/index';
|
||||
|
||||
// load routes from extensions, also look for environment-specific configs
|
||||
$subdirs = ['application/config/extensions', 'application/config/' . ENVIRONMENT . '/extensions'];
|
||||
|
||||
|
||||
@@ -0,0 +1,477 @@
|
||||
<?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 ClassScheduleApi extends FHCAPI_Controller
|
||||
{
|
||||
|
||||
/**
|
||||
* Object initialization
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct([
|
||||
'getAllClassTimeValidityPeriods'=> array('lehre/unterrichtszeiten_gk:r'),
|
||||
'getClassTimeValidityPeriod' => array('lehre/unterrichtszeiten_gk:r'),
|
||||
'createClassTimeSlotValidityPeriod' => array('lehre/unterrichtszeiten_gk:rw'),
|
||||
'updateClassTimeSlotValidityPeriod' => array('lehre/unterrichtszeiten_gk:rw'),
|
||||
'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'),
|
||||
'getAllClassScheduleTypes' => array('lehre/unterrichtszeiten_typ:r'),
|
||||
'createClassTimeSlotType' => array('lehre/unterrichtszeiten_typ:rw'),
|
||||
'updateClassTimeSlotType' => array('lehre/unterrichtszeiten_typ:rw'),
|
||||
'deleteClassTimeSlotType' => array('lehre/unterrichtszeiten_typ:rw'),
|
||||
]);
|
||||
|
||||
$this->load->library('form_validation');
|
||||
|
||||
$this->load->model('education/ClassTimeSlotValidityPeriod_model', "ClassTimeSlotValidityPeriodModel");
|
||||
$this->load->model('education/ClassTimeSlot_model', "ClassTimeSlotModel");
|
||||
$this->load->model('education/ClassTimeSlotType_model', "ClassTimeSlotTypeModel");
|
||||
|
||||
// Loads phrases system
|
||||
$this->loadPhrases([
|
||||
'global'
|
||||
]);
|
||||
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------------
|
||||
// Public methods
|
||||
|
||||
public function getAllClassTimeValidityPeriods()
|
||||
{
|
||||
$this->ClassTimeSlotValidityPeriodModel->addJoin('lehre.tbl_studienplan', 'lehre.tbl_studienplan.studienplan_id=lehre.tbl_unterrichtszeiten_gueltigkeit.studienplan_id', 'LEFT');
|
||||
$this->ClassTimeSlotValidityPeriodModel->addOrder('gueltig_von', 'DESC');
|
||||
$class_time_slot_validity_period_res = $this->ClassTimeSlotValidityPeriodModel->load();
|
||||
$class_time_slot_validity_period_res = $this->getDataOrTerminateWithError($class_time_slot_validity_period_res);
|
||||
$this->terminateWithSuccess($class_time_slot_validity_period_res);
|
||||
}
|
||||
|
||||
public function getClassTimeValidityPeriod($classTimeSlotValidityPeriodId)
|
||||
{
|
||||
$this->ClassTimeSlotValidityPeriodModel->addJoin('lehre.tbl_studienplan', 'lehre.tbl_studienplan.studienplan_id=lehre.tbl_unterrichtszeiten_gueltigkeit.studienplan_id', 'LEFT');
|
||||
$class_time_slot_validity_period_res = $this->ClassTimeSlotValidityPeriodModel->load($classTimeSlotValidityPeriodId);
|
||||
$class_time_slot_validity_period_res = $this->getDataOrTerminateWithError($class_time_slot_validity_period_res);
|
||||
$this->terminateWithSuccess($class_time_slot_validity_period_res);
|
||||
}
|
||||
|
||||
public function createClassTimeSlotValidityPeriod()
|
||||
{
|
||||
$this->form_validation->set_rules('validityPeriodFrom', 'Validity Period From', 'required|is_valid_date[Y-m-d]');
|
||||
$this->form_validation->set_rules('validityPeriodTo', 'Validity Period To', 'required|is_valid_date[Y-m-d]|callback_date_greater_equal[validityPeriodFrom]');
|
||||
$this->form_validation->set_rules('degreeProgramShortcode', 'Degree Program Shortcode', 'required|max_length[32]');
|
||||
$this->form_validation->set_rules('semester', 'Semester', 'required|is_natural_no_zero|less_than_equal_to[8]');
|
||||
$this->form_validation->set_rules('classTimeSlotTypeShortcode', 'Class Time Slot Type Shortcode', 'max_length[32]');
|
||||
$this->form_validation->set_rules('studyPlanId', 'Study Plan ID', 'is_natural_no_zero');
|
||||
|
||||
if($this->form_validation->run() == FALSE) $this->terminateWithValidationErrors($this->form_validation->error_array());
|
||||
|
||||
$this->db->trans_start();
|
||||
|
||||
$result = $this->ClassTimeSlotValidityPeriodModel->insert([
|
||||
'gueltig_von' => $this->input->post('validityPeriodFrom'),
|
||||
'gueltig_bis' => $this->input->post('validityPeriodTo'),
|
||||
'oe_kurzbz' => $this->input->post('degreeProgramShortcode'),
|
||||
'ausbildungssemester' => $this->input->post('semester'),
|
||||
'anmerkung' => $this->input->post('description'),
|
||||
'unterrichtszeitentyp_kurzbz' => $this->input->post('classTimeSlotTypeShortcode') ?? '',
|
||||
'studienplan_id' => $this->input->post('studyPlanId'),
|
||||
'insertamum' => date('c'),
|
||||
'insertvon' => getAuthUid(),
|
||||
'updateamum' => date('c'),
|
||||
'updatevon' => getAuthUid(),
|
||||
]);
|
||||
|
||||
$data = $this->getDataOrTerminateWithError($result);
|
||||
|
||||
$this->db->trans_complete();
|
||||
|
||||
$this->terminateWithSuccess(true);
|
||||
|
||||
$this->terminateWithSuccess($this->input->post());
|
||||
}
|
||||
|
||||
public function updateClassTimeSlotValidityPeriod($classTimeSlotValidityPeriodId)
|
||||
{
|
||||
$this->form_validation->set_rules('validityPeriodFrom', 'Validity Period From', 'required|is_valid_date[Y-m-d]');
|
||||
$this->form_validation->set_rules('validityPeriodTo', 'Validity Period To', 'required|is_valid_date[Y-m-d]|callback_date_greater_equal[validityPeriodFrom]');
|
||||
$this->form_validation->set_rules('degreeProgramShortcode', 'Degree Program Shortcode', 'required|max_length[32]');
|
||||
$this->form_validation->set_rules('semester', 'Semester', 'required|is_natural_no_zero|less_than_equal_to[8]');
|
||||
$this->form_validation->set_rules('classTimeSlotTypeShortcode', 'Class Time Slot Type Shortcode', 'max_length[32]');
|
||||
$this->form_validation->set_rules('studyPlanId', 'Study Plan ID', 'is_natural_no_zero');
|
||||
|
||||
if($this->form_validation->run() == FALSE) $this->terminateWithValidationErrors($this->form_validation->error_array());
|
||||
|
||||
$result = $this->ClassTimeSlotValidityPeriodModel->update($classTimeSlotValidityPeriodId, [
|
||||
'gueltig_von' => $this->input->post('validityPeriodFrom'),
|
||||
'gueltig_bis' => $this->input->post('validityPeriodTo'),
|
||||
'oe_kurzbz' => $this->input->post('degreeProgramShortcode'),
|
||||
'ausbildungssemester' => $this->input->post('semester'),
|
||||
'anmerkung' => $this->input->post('description'),
|
||||
'unterrichtszeitentyp_kurzbz' => $this->input->post('classTimeSlotTypeShortcode'),
|
||||
'studienplan_id' => $this->input->post('studyPlanId'),
|
||||
'updateamum' => date('c'),
|
||||
'updatevon' => getAuthUid(),
|
||||
]);
|
||||
|
||||
$data = $this->getDataOrTerminateWithError($result);
|
||||
|
||||
$this->terminateWithSuccess(true);
|
||||
}
|
||||
|
||||
public function deleteClassTimeSlotValidityPeriod($classTimeSlotValidityPeriodId)
|
||||
{
|
||||
$result = $this->ClassTimeSlotValidityPeriodModel->delete($classTimeSlotValidityPeriodId);
|
||||
if (isError($result)) {
|
||||
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
|
||||
}
|
||||
|
||||
$result = $this->ClassTimeSlotModel->delete(['unterrichtszeitengueltigkeit_id'=> $classTimeSlotValidityPeriodId]);
|
||||
if (isError($result)) {
|
||||
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
|
||||
}
|
||||
|
||||
$this->terminateWithSuccess(true);
|
||||
}
|
||||
|
||||
public function getClassTimeSlotsForValidityPeriod($classTimeSlotValidityPeriodId)
|
||||
{
|
||||
$this->ClassTimeSlotModel->addOrder('insertamum', 'DESC');
|
||||
$class_time_slots_res = $this->ClassTimeSlotModel->loadWhere(['unterrichtszeitengueltigkeit_id' => $classTimeSlotValidityPeriodId]);
|
||||
$class_time_slots_res = $this->getDataOrTerminateWithError($class_time_slots_res);
|
||||
$this->terminateWithSuccess($class_time_slots_res);
|
||||
}
|
||||
|
||||
public function createClassTimeSlotsForValidityPeriod($classTimeSlotValidityPeriodId)
|
||||
{
|
||||
$this->form_validation->set_rules('classTimeSlots', 'Validity Period From', 'callback_validate_items_in_class_time_slots');
|
||||
if($this->form_validation->run() == FALSE) $this->terminateWithValidationErrors($this->form_validation->error_array());
|
||||
|
||||
$this->db->trans_start();
|
||||
|
||||
$timeSlotGroupIdentifier = uniqid();
|
||||
|
||||
foreach ($this->input->post('classTimeSlots') as $timeSlot) {
|
||||
$result = $this->ClassTimeSlotModel->insert([
|
||||
'unterrichtszeit_gruppe_identifikator' => $timeSlotGroupIdentifier,
|
||||
'wochentag' => $timeSlot['wochentag'],
|
||||
'uhrzeit_von' => $timeSlot['startTime'],
|
||||
'uhrzeit_bis' => $timeSlot['endTime'],
|
||||
'unterrichtszeitentyp_kurzbz' => $timeSlot['classTimeSlotTypeShortcode'],
|
||||
'unterrichtszeitengueltigkeit_id' => $classTimeSlotValidityPeriodId,
|
||||
'insertamum' => date('c'),
|
||||
'insertvon' => getAuthUid(),
|
||||
'updateamum' => date('c'),
|
||||
'updatevon' => getAuthUid(),
|
||||
]);
|
||||
|
||||
$this->getDataOrTerminateWithError($result);
|
||||
}
|
||||
$this->db->trans_complete();
|
||||
|
||||
$this->terminateWithSuccess(true);
|
||||
}
|
||||
|
||||
public function editClassTimeSlotsForValidityPeriod($classTimeSlotValidityPeriodId)
|
||||
{
|
||||
$this->form_validation->set_rules('classTimeSlots', 'Validity Period From', 'callback_validate_items_in_class_time_slots');
|
||||
if($this->form_validation->run() == FALSE) $this->terminateWithValidationErrors($this->form_validation->error_array());
|
||||
|
||||
$this->db->trans_start();
|
||||
|
||||
$timeSlotGroupIdentifier = uniqid();
|
||||
|
||||
foreach ($this->input->post('classTimeSlots') as $timeSlot) {
|
||||
$data = [
|
||||
'unterrichtszeit_gruppe_identifikator' => $timeSlotGroupIdentifier,
|
||||
'wochentag' => $timeSlot['wochentag'],
|
||||
'uhrzeit_von' => $timeSlot['startTime'],
|
||||
'uhrzeit_bis' => $timeSlot['endTime'],
|
||||
'unterrichtszeitentyp_kurzbz' => $timeSlot['classTimeSlotTypeShortcode'],
|
||||
'unterrichtszeitengueltigkeit_id' => $classTimeSlotValidityPeriodId,
|
||||
'updateamum' => date('c'),
|
||||
'updatevon' => getAuthUid(),
|
||||
];
|
||||
if (isset($timeSlot['id'])) {
|
||||
$result = $this->ClassTimeSlotModel->update($timeSlot['id'], $data);
|
||||
} else {
|
||||
$result = $this->ClassTimeSlotModel->insert(array_merge($data, [
|
||||
'insertvon' => getAuthUid(),
|
||||
'updateamum' => date('c'),
|
||||
]));
|
||||
}
|
||||
|
||||
$this->getDataOrTerminateWithError($result);
|
||||
}
|
||||
$this->db->trans_complete();
|
||||
|
||||
$this->terminateWithSuccess(true);
|
||||
|
||||
}
|
||||
public function deleteClassTimeSlotsForValidityPeriodPerGroup($classTimeSlotValidityPeriodId, $groupIdentifikator)
|
||||
{
|
||||
$result = $this->ClassTimeSlotModel->delete(['unterrichtszeitengueltigkeit_id'=> $classTimeSlotValidityPeriodId, 'unterrichtszeit_gruppe_identifikator' => $groupIdentifikator]);
|
||||
if (isError($result)) {
|
||||
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
|
||||
}
|
||||
|
||||
$this->terminateWithSuccess(true);
|
||||
}
|
||||
|
||||
public function getAllClassScheduleTypes()
|
||||
{
|
||||
$filter = $this->input->get('filter');
|
||||
|
||||
if ($filter) {
|
||||
if (isset($filter['aktiv'])) {
|
||||
$this->ClassTimeSlotTypeModel->db->where('aktiv', $filter['aktiv']);
|
||||
}
|
||||
}
|
||||
|
||||
$class_schedule_types_res = $this->ClassTimeSlotTypeModel->load();
|
||||
$class_schedule_types_res = $this->getDataOrTerminateWithError($class_schedule_types_res);
|
||||
|
||||
$this->terminateWithSuccess($class_schedule_types_res);
|
||||
}
|
||||
|
||||
public function createClassTimeSlotType()
|
||||
{
|
||||
$this->form_validation->set_rules('shortCode', 'Short Code', 'required|max_length[32]');
|
||||
$this->form_validation->set_rules('descriptions', 'Descriptions', 'callback_validate_descriptions_array');
|
||||
|
||||
if($this->form_validation->run() == FALSE) $this->terminateWithValidationErrors($this->form_validation->error_array());
|
||||
|
||||
$this->db->trans_start();
|
||||
|
||||
$descriptions = $this->input->post('descriptions');
|
||||
$pgArray = $this->arrayToPgArray($descriptions);
|
||||
|
||||
$query = 'INSERT INTO lehre.tbl_unterrichtszeiten_typ (
|
||||
unterrichtszeitentyp_kurzbz,
|
||||
bezeichnung_mehrsprachig,
|
||||
aktiv,
|
||||
insertamum,
|
||||
insertvon,
|
||||
updateamum,
|
||||
updatevon) VALUES (?, ?, ?, ?, ?, ?, ?)';
|
||||
$result = $this->db->query($query, [
|
||||
$this->input->post('shortCode'),
|
||||
$pgArray,
|
||||
$this->input->post('isActive'),
|
||||
date('c'),
|
||||
getAuthUid(),
|
||||
date('c'),
|
||||
getAuthUid(),
|
||||
]);
|
||||
$this->db->trans_complete();
|
||||
|
||||
$this->terminateWithSuccess(true);
|
||||
}
|
||||
|
||||
public function updateClassTimeSlotType($classTimeSlotTypeId)
|
||||
{
|
||||
$this->form_validation->set_rules('descriptions', 'Descriptions', 'callback_validate_descriptions_array');
|
||||
|
||||
if($this->form_validation->run() == FALSE) $this->terminateWithValidationErrors($this->form_validation->error_array());
|
||||
|
||||
$this->db->trans_start();
|
||||
|
||||
$descriptions = $this->input->post('descriptions');
|
||||
$pgArray = $this->arrayToPgArray($descriptions);
|
||||
|
||||
$query = 'UPDATE lehre.tbl_unterrichtszeiten_typ SET bezeichnung_mehrsprachig = ?, aktiv = ?, updateamum = ?, updatevon = ? WHERE unterrichtszeitentyp_kurzbz = ?';
|
||||
$result = $this->db->query($query, [
|
||||
$pgArray,
|
||||
$this->input->post('isActive'),
|
||||
date('c'),
|
||||
getAuthUid(),
|
||||
$classTimeSlotTypeId,
|
||||
]);
|
||||
$this->db->trans_complete();
|
||||
|
||||
$this->terminateWithSuccess(true);
|
||||
}
|
||||
|
||||
public function deleteClassTimeSlotType($classTimeSlotTypeId)
|
||||
{
|
||||
$result = $this->ClassTimeSlotTypeModel->delete(['unterrichtszeitentyp_kurzbz' => $classTimeSlotTypeId]);
|
||||
if (isError($result)) {
|
||||
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
|
||||
}
|
||||
|
||||
$this->terminateWithSuccess(true);
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------------------------
|
||||
// Private methods
|
||||
private function arrayToPgArray(array $assoc) {
|
||||
$flat = [];
|
||||
|
||||
foreach ($assoc as $assocItem) {
|
||||
$flat[] = $assocItem['lang'] . ':' . $assocItem['value'];
|
||||
}
|
||||
|
||||
$escaped = array_map(function ($v) {
|
||||
return '"' . addslashes($v) . '"';
|
||||
}, $flat);
|
||||
return '{' . implode(',', $escaped) . '}';
|
||||
}
|
||||
|
||||
public function date_greater_equal($toDate, $fromField)
|
||||
{
|
||||
$fromDate = $this->input->post($fromField);
|
||||
|
||||
// Check if "from" exists
|
||||
if (!$fromDate) {
|
||||
$this->form_validation->set_message(
|
||||
'date_greater_equal',
|
||||
'Validity Period From is required.'
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Validate both dates
|
||||
if (!strtotime($toDate) || !strtotime($fromDate)) {
|
||||
$this->form_validation->set_message(
|
||||
'date_greater_equal',
|
||||
'Both dates must be valid.'
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Compare dates
|
||||
if (strtotime($toDate) < strtotime($fromDate)) {
|
||||
$this->form_validation->set_message(
|
||||
'date_greater_equal',
|
||||
'The {field} must be greater than or equal to Validity Period From.'
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function validate_items_in_class_time_slots($classTimeSlots)
|
||||
{
|
||||
// see if $classTimeSlots is an array and has at least one item
|
||||
|
||||
if (!is_array($this->input->post('classTimeSlots')) || count($this->input->post('classTimeSlots')) === 0) {
|
||||
$this->form_validation->set_message(
|
||||
'validate_items_in_class_time_slots',
|
||||
'At least one class time slot is required.'
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach ($this->input->post('classTimeSlots') as $index => $timeSlot) {
|
||||
if (!isset($timeSlot['wochentag'], $timeSlot['startTime'], $timeSlot['endTime'], $timeSlot['classTimeSlotTypeShortcode'])) {
|
||||
$this->form_validation->set_message(
|
||||
'validate_items_in_class_time_slots',
|
||||
'Each class time slot must have a weekday, start time, end time and class time slot type shortcode.'
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!in_array($timeSlot['wochentag'], [1, 2, 3, 4, 5])) {
|
||||
$this->form_validation->set_message(
|
||||
'validate_items_in_class_time_slots',
|
||||
'Weekday must be an integer between 1 (Monday) and 5 (Friday).'
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
log_message('error', 'Validating class time slots: ' . print_r($timeSlot['startTime'], true));
|
||||
if (!strtotime($timeSlot['startTime']) || !strtotime($timeSlot['endTime'])) {
|
||||
$this->form_validation->set_message(
|
||||
'validate_items_in_class_time_slots',
|
||||
'Start time and end time must be valid time strings.'
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (strtotime($timeSlot['endTime']) <= strtotime($timeSlot['startTime'])) {
|
||||
$this->form_validation->set_message(
|
||||
'validate_items_in_class_time_slots',
|
||||
'End time must be greater than start time.'
|
||||
);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
$slotsByDay = [];
|
||||
foreach ($this->input->post('classTimeSlots') as $timeSlot) {
|
||||
$slotsByDay[$timeSlot['wochentag']][] = $timeSlot;
|
||||
}
|
||||
|
||||
foreach ($slotsByDay as $day => $slots) {
|
||||
usort($slots, function ($a, $b) {
|
||||
return strtotime($a['startTime']) - strtotime($b['startTime']);
|
||||
});
|
||||
|
||||
for ($i = 1; $i < count($slots); $i++) {
|
||||
if (strtotime($slots[$i]['startTime']) < strtotime($slots[$i - 1]['endTime'])) {
|
||||
$this->form_validation->set_message(
|
||||
'validate_items_in_class_time_slots',
|
||||
'Class time slots for each day must not overlap.'
|
||||
);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function validate_descriptions_array($descriptions)
|
||||
{
|
||||
$descriptions = $this->input->post('descriptions');
|
||||
if (!is_array($descriptions) || count($descriptions) === 0) {
|
||||
$this->form_validation->set_message(
|
||||
'validate_descriptions_array',
|
||||
'Descriptions must be a non-empty array.'
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach ($descriptions as $index => $description) {
|
||||
if (!isset($description['lang'], $description['value'])) {
|
||||
$this->form_validation->set_message(
|
||||
'validate_descriptions_array',
|
||||
'Each description must have a language and a value.'
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (empty($description['lang']) || empty($description['value'])) {
|
||||
$this->form_validation->set_message(
|
||||
'validate_descriptions_array',
|
||||
'Language and value in each description must not be empty.'
|
||||
);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
if (! defined('BASEPATH')) exit('No direct script access allowed');
|
||||
|
||||
/**
|
||||
*/
|
||||
class ClassSchedule extends Auth_Controller
|
||||
{
|
||||
private $_uid; // uid of the logged user
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct(
|
||||
array(
|
||||
'index' => array('lehre/unterrichtszeiten_gk:r'),
|
||||
)
|
||||
);
|
||||
|
||||
$this->load->library('PermissionLib');
|
||||
$this->load->library('AuthLib');
|
||||
|
||||
$this->loadPhrases(
|
||||
array(
|
||||
'ui',
|
||||
'global',
|
||||
'person',
|
||||
'abschlusspruefung',
|
||||
'password',
|
||||
'lehre'
|
||||
)
|
||||
);
|
||||
|
||||
$this->_setAuthUID();
|
||||
|
||||
$this->setControllerId();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------------------
|
||||
// Public methods
|
||||
public function index()
|
||||
{
|
||||
return $this->load->view('lehre/class_schedule/index.php', [
|
||||
'permissions' => [
|
||||
'lehre/unterrichtszeiten_typ_w' => $this->permissionlib->isBerechtigt('lehre/unterrichtszeiten_typ', 'suid'),
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------------------
|
||||
// Private methods
|
||||
|
||||
/**
|
||||
* Retrieve the UID of the logged user and checks if it is valid
|
||||
*/
|
||||
private function _setAuthUID()
|
||||
{
|
||||
$this->_uid = getAuthUID();
|
||||
|
||||
if (!$this->_uid) show_error('User authentification failed');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
$includesArray = array(
|
||||
'title' => 'Unterrichtszeiten der Studiengänge',
|
||||
'vue3' => true,
|
||||
'axios027' => true,
|
||||
'bootstrap5' => true,
|
||||
'tabulator5' => true,
|
||||
'fontawesome6' => true,
|
||||
'primevue3' => true,
|
||||
'navigationcomponent' => true,
|
||||
'filtercomponent' => true,
|
||||
'customJSs' => array(
|
||||
'vendor/vuejs/vuedatepicker_js/vue-datepicker.iife.js',
|
||||
'vendor/moment/luxonjs/luxon.min.js'
|
||||
),
|
||||
'customJSModules' => array(
|
||||
'public/js/apps/lehre/ClassScheduleApp.js'
|
||||
),
|
||||
'customCSSs' => array(
|
||||
'public/css/components/vue-datepicker.css',
|
||||
'public/css/components/primevue.css',
|
||||
'public/css/components/verticalsplit.css',
|
||||
'public/extensions/FHC-Core-Developer/css/FhcMain.css'
|
||||
)
|
||||
);
|
||||
|
||||
$this->load->view('templates/FHC-Header', $includesArray);
|
||||
?>
|
||||
|
||||
<div id="main">
|
||||
|
||||
<router-view
|
||||
cis-root="<?= CIS_ROOT; ?>"
|
||||
:permissions="<?= htmlspecialchars(json_encode($permissions)); ?>"
|
||||
>
|
||||
</router-view>
|
||||
</div>
|
||||
|
||||
<?php $this->load->view('templates/FHC-Footer', $includesArray); ?>
|
||||
|
||||
@@ -0,0 +1,121 @@
|
||||
/**
|
||||
* 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 {
|
||||
getAllClassTimeValidityPeriods() {
|
||||
return {
|
||||
method: "get",
|
||||
url: "/api/frontend/v1/ClassScheduleApi/getAllClassTimeValidityPeriods",
|
||||
};
|
||||
},
|
||||
getClassTimeValidityPeriod(classTimeSlotValidityPeriodId) {
|
||||
return {
|
||||
method: "get",
|
||||
url: `/api/frontend/v1/ClassScheduleApi/getClassTimeValidityPeriod/${classTimeSlotValidityPeriodId}`,
|
||||
};
|
||||
},
|
||||
createClassTimeSlotValidityPeriod(userId, params) {
|
||||
return {
|
||||
method: "post",
|
||||
url: "api/frontend/v1/ClassScheduleApi/createClassTimeSlotValidityPeriod/",
|
||||
params,
|
||||
};
|
||||
},
|
||||
deleteClassTimeSlotValidityPeriod(userId, classTimeSlotValidityPeriodId) {
|
||||
return {
|
||||
method: "post",
|
||||
url: `api/frontend/v1/ClassScheduleApi/deleteClassTimeSlotValidityPeriod/${classTimeSlotValidityPeriodId}`,
|
||||
};
|
||||
},
|
||||
getClassTimeSlotsForValidityPeriod(classTimeSlotValidityPeriodId) {
|
||||
return {
|
||||
method: "get",
|
||||
url: `api/frontend/v1/ClassScheduleApi/getClassTimeSlotsForValidityPeriod/${classTimeSlotValidityPeriodId}`,
|
||||
};
|
||||
},
|
||||
createClassTimeSlotsForValidityPeriod(
|
||||
userId,
|
||||
classTimeSlotValidityPeriodId,
|
||||
params,
|
||||
) {
|
||||
return {
|
||||
method: "post",
|
||||
url: `api/frontend/v1/ClassScheduleApi/createClassTimeSlotsForValidityPeriod/${classTimeSlotValidityPeriodId}`,
|
||||
params,
|
||||
};
|
||||
},
|
||||
editClassTimeSlotsForValidityPeriod(
|
||||
userId,
|
||||
classTimeSlotValidityPeriodId,
|
||||
params,
|
||||
) {
|
||||
return {
|
||||
method: "post",
|
||||
url: `api/frontend/v1/ClassScheduleApi/editClassTimeSlotsForValidityPeriod/${classTimeSlotValidityPeriodId}`,
|
||||
params,
|
||||
};
|
||||
},
|
||||
updateClassTimeSlotValidityPeriod(
|
||||
userId,
|
||||
classTimeSlotValidityPeriodId,
|
||||
params,
|
||||
) {
|
||||
return {
|
||||
method: "post",
|
||||
url: `api/frontend/v1/ClassScheduleApi/updateClassTimeSlotValidityPeriod/${classTimeSlotValidityPeriodId}`,
|
||||
params,
|
||||
};
|
||||
},
|
||||
deleteClassTimeSlotsForValidityPeriodPerGroup(
|
||||
userId,
|
||||
classTimeSlotValidityPeriodId,
|
||||
groupIdentifikator,
|
||||
) {
|
||||
return {
|
||||
method: "post",
|
||||
url: `api/frontend/v1/ClassScheduleApi/deleteClassTimeSlotsForValidityPeriodPerGroup/${classTimeSlotValidityPeriodId}/${groupIdentifikator}`,
|
||||
};
|
||||
},
|
||||
getAllClassScheduleTypes(queryParams) {
|
||||
return {
|
||||
method: "get",
|
||||
url:
|
||||
"/api/frontend/v1/ClassScheduleApi/getAllClassScheduleTypes?" +
|
||||
new URLSearchParams(queryParams).toString(),
|
||||
};
|
||||
},
|
||||
createClassTimeSlotType(params) {
|
||||
return {
|
||||
method: "post",
|
||||
url: "api/frontend/v1/ClassScheduleApi/createClassTimeSlotType/",
|
||||
params,
|
||||
};
|
||||
},
|
||||
updateClassTimeSlotType(classTimeSlotTypeId, params) {
|
||||
return {
|
||||
method: "post",
|
||||
url: `api/frontend/v1/ClassScheduleApi/updateClassTimeSlotType/${classTimeSlotTypeId}`,
|
||||
params,
|
||||
};
|
||||
},
|
||||
deleteClassTimeSlotType(userId, classTimeSlotTypeId) {
|
||||
return {
|
||||
method: "post",
|
||||
url: `api/frontend/v1/ClassScheduleApi/deleteClassTimeSlotType/${classTimeSlotTypeId}`,
|
||||
};
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,59 @@
|
||||
/**
|
||||
* Copyright (C) 2023 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/>.
|
||||
*/
|
||||
|
||||
import ClassScheduleOverview from "../../components/ClassSchedule/ClassScheduleOverview.js";
|
||||
import ClassScheduleValidityPeriodOverview from "../../components/ClassSchedule/ClassScheduleValidityPeriodOverview.js";
|
||||
|
||||
import FhcAlert from "../../plugins/FhcAlert.js";
|
||||
import Phrasen from "../../plugins/Phrasen.js";
|
||||
import FhcApi from "../../plugins/Api.js";
|
||||
|
||||
const ciPath =
|
||||
FHC_JS_DATA_STORAGE_OBJECT.app_root.replace(/(https:|)(^|\/\/)(.*?\/)/g, "") +
|
||||
FHC_JS_DATA_STORAGE_OBJECT.ci_router;
|
||||
|
||||
const router = VueRouter.createRouter({
|
||||
history: VueRouter.createWebHistory(),
|
||||
routes: [
|
||||
{
|
||||
name: "overview",
|
||||
path: `/${ciPath}/lehre/ClassSchedule`,
|
||||
component: ClassScheduleOverview,
|
||||
},
|
||||
{
|
||||
name: "validityPeriodOverview",
|
||||
path: `/${ciPath}/lehre/ClassSchedule/validityPeriods/:classTimeSlotValidityPeriodId`,
|
||||
component: ClassScheduleValidityPeriodOverview,
|
||||
params: true,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const app = Vue.createApp({
|
||||
components: {
|
||||
ClassScheduleOverview,
|
||||
ClassScheduleValidityPeriodOverview,
|
||||
},
|
||||
});
|
||||
|
||||
app
|
||||
.use(router)
|
||||
.use(primevue.config.default, { zIndex: { overlay: 9999 } })
|
||||
.use(FhcAlert)
|
||||
.use(Phrasen)
|
||||
.use(FhcApi)
|
||||
.mount("#main");
|
||||
@@ -0,0 +1,276 @@
|
||||
// Import the Core Filter- and Core RESTClient Component to build your table and handle data
|
||||
import { CoreFilterCmpt } from "../filter/Filter.js";
|
||||
import ApiClassSchedule from "../../../js/api/factory/classSchedule.js";
|
||||
|
||||
import ClassScheduleTypeModal from "./ClassScheduleTypeModal.js";
|
||||
import ClassScheduleValidityPeriodModal from "./ClassScheduleValidityPeriodModal.js";
|
||||
|
||||
export default {
|
||||
name: "ClassScheduleOverview",
|
||||
components: {
|
||||
CoreFilterCmpt,
|
||||
ClassScheduleTypeModal,
|
||||
ClassScheduleValidityPeriodModal,
|
||||
},
|
||||
props: {
|
||||
permissions: Object,
|
||||
},
|
||||
provide() {
|
||||
return {
|
||||
cisRoot: this.cisRoot,
|
||||
hasLehreUnterrichtszeitenTypWPermission:
|
||||
this.permissions["lehre/unterrichtszeiten_typ_w"] || false,
|
||||
};
|
||||
},
|
||||
data: () => {
|
||||
return {
|
||||
phrasesLoaded: false,
|
||||
editorParams: null,
|
||||
classTimeSlotValidityPeriods: [],
|
||||
classTimeSlotValidityPeriodId: null,
|
||||
editedClassTimeSlotValidityPeriodId: null,
|
||||
mondayClassTimeSlots: [],
|
||||
isClassTimeSlotTypeModalVisible: false,
|
||||
isClassTimeSlotValidityPeriodModalVisible: false,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
tabulatorOptions() {
|
||||
const options = {
|
||||
ajaxURL: "dummy",
|
||||
ajaxRequestFunc: () =>
|
||||
this.$api.call(ApiClassSchedule.getAllClassTimeValidityPeriods()),
|
||||
ajaxResponse: (url, params, response) => response.data,
|
||||
persistenceID: "core_class_schedule_validity_periods",
|
||||
selectableRows: true,
|
||||
columns: [
|
||||
{
|
||||
title: "gueltig von",
|
||||
field: "gueltig_von",
|
||||
width: 150,
|
||||
},
|
||||
{ title: "gueltig bis", field: "gueltig_bis", width: 150 },
|
||||
{ title: "orgform kurzbz", field: "orgform_kurzbz", width: 150 },
|
||||
{
|
||||
title: "ausbildungssemester",
|
||||
field: "ausbildungssemester",
|
||||
width: 150,
|
||||
},
|
||||
{
|
||||
title: "typ",
|
||||
field: "unterrichtszeitentyp_kurzbz",
|
||||
},
|
||||
{
|
||||
field: "unterrichtszeitengueltigkeit_id",
|
||||
visible: false,
|
||||
},
|
||||
{
|
||||
title: "Aktionen",
|
||||
field: "actions",
|
||||
minWidth: 150,
|
||||
maxWidth: 150,
|
||||
formatter: (cell, formatterParams, onRendered) => {
|
||||
let container = document.createElement("div");
|
||||
container.className = "d-flex gap-2";
|
||||
|
||||
let button = document.createElement("button");
|
||||
|
||||
button = document.createElement("button");
|
||||
button.className = "btn btn-outline-secondary btn-action";
|
||||
button.innerHTML = '<i class="fa fa-eye"></i>';
|
||||
button.title = this.$p.t(
|
||||
"classSchedule",
|
||||
"btn_showClassTimeSlotValidityPeriod",
|
||||
);
|
||||
button.addEventListener("click", (event) =>
|
||||
this.$router.push({
|
||||
name: "validityPeriodOverview",
|
||||
params: {
|
||||
classTimeSlotValidityPeriodId:
|
||||
cell.getData().unterrichtszeitengueltigkeit_id,
|
||||
},
|
||||
}),
|
||||
);
|
||||
container.append(button);
|
||||
|
||||
button = document.createElement("button");
|
||||
button.className = "btn btn-outline-secondary btn-action";
|
||||
button.innerHTML = '<i class="fa fa-edit"></i>';
|
||||
button.title = this.$p.t(
|
||||
"classSchedule",
|
||||
"btn_editClassTimeSlotValidityPeriod",
|
||||
);
|
||||
button.addEventListener("click", (event) =>
|
||||
this.editClassTimeSlotValidityPeriod(
|
||||
cell.getData().unterrichtszeitengueltigkeit_id,
|
||||
),
|
||||
);
|
||||
container.append(button);
|
||||
|
||||
button = document.createElement("button");
|
||||
button.className =
|
||||
"btn btn-outline-secondary btn-action bg-danger";
|
||||
button.innerHTML = '<i class="fa fa-xmark text-white"></i>';
|
||||
button.title = this.$p.t(
|
||||
"classSchedule",
|
||||
"btn_deleteClassTimeSlotValidityPeriod",
|
||||
);
|
||||
button.addEventListener("click", () => {
|
||||
let isDeletionConfirmed = confirm(
|
||||
this.$p.t(
|
||||
"ui",
|
||||
"deleteClassTimeSlotValidityPeriodConfirmation",
|
||||
),
|
||||
);
|
||||
if (!isDeletionConfirmed) return;
|
||||
|
||||
this.deleteClassTimeSlotValidityPeriod(
|
||||
cell.getData().unterrichtszeitengueltigkeit_id,
|
||||
);
|
||||
});
|
||||
container.append(button);
|
||||
|
||||
return container;
|
||||
},
|
||||
frozen: true,
|
||||
},
|
||||
],
|
||||
};
|
||||
return options;
|
||||
},
|
||||
tabulatorEvents() {
|
||||
const events = [
|
||||
{
|
||||
event: "tableBuilt",
|
||||
handler: async () => {
|
||||
const setHeader = (field, text) => {
|
||||
const col =
|
||||
this.$refs.classTimeSlotValidityPeriodsTable.tabulator.getColumn(
|
||||
field,
|
||||
);
|
||||
if (!col) return;
|
||||
|
||||
const el = col.getElement();
|
||||
if (!el || !el.querySelector) return;
|
||||
|
||||
const titleEl = el.querySelector(".tabulator-col-title");
|
||||
if (titleEl) {
|
||||
titleEl.textContent = text;
|
||||
}
|
||||
};
|
||||
|
||||
setHeader("nummer", this.$p.t("wawi", "nummer"));
|
||||
setHeader("anmerkung", this.$p.t("global", "anmerkung"));
|
||||
setHeader("retouram", this.$p.t("wawi", "retourdatum"));
|
||||
setHeader("beschreibung", this.$p.t("global", "beschreibung"));
|
||||
setHeader("kaution", this.$p.t("infocenter", "kaution"));
|
||||
setHeader("ausgegebenam", this.$p.t("wawi", "ausgabedatum"));
|
||||
setHeader("person_id", this.$p.t("person", "person_id"));
|
||||
setHeader("uid", this.$p.t("person", "uid"));
|
||||
},
|
||||
},
|
||||
];
|
||||
return events;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
showClassTimeSlotValidityPeriodModal() {
|
||||
this.isClassTimeSlotValidityPeriodModalVisible = true;
|
||||
},
|
||||
editClassTimeSlotValidityPeriod(classTimeSlotValidityPeriodId) {
|
||||
this.editedClassTimeSlotValidityPeriodId = classTimeSlotValidityPeriodId;
|
||||
},
|
||||
deleteClassTimeSlotValidityPeriod(classTimeSlotValidityPeriodId) {
|
||||
return this.$api
|
||||
.call(
|
||||
ApiClassSchedule.deleteClassTimeSlotValidityPeriod(
|
||||
this.id,
|
||||
classTimeSlotValidityPeriodId,
|
||||
),
|
||||
)
|
||||
.then((response) => {
|
||||
this.$fhcAlert.alertSuccess(this.$p.t("ui", "successDelete"));
|
||||
window.scrollTo(0, 0);
|
||||
this.$refs.classTimeSlotValidityPeriodsTable.reloadTable();
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error(
|
||||
"Error deleting class time slot validity period:",
|
||||
error,
|
||||
);
|
||||
this.$fhcAlert.handleSystemError(error);
|
||||
});
|
||||
},
|
||||
showClassTimeSlotTypeModal() {
|
||||
this.isClassTimeSlotTypeModalVisible = true;
|
||||
},
|
||||
resetClassTimeSlotTypeModal() {
|
||||
this.isClassTimeSlotTypeModalVisible = false;
|
||||
},
|
||||
resetClassTimeSlotValidityPeriodModal() {
|
||||
this.isClassTimeSlotValidityPeriodModalVisible = false;
|
||||
},
|
||||
},
|
||||
async created() {
|
||||
let getAllClassTimeValidityPeriodsResponse = await this.$api.call(
|
||||
ApiClassSchedule.getAllClassTimeValidityPeriods(),
|
||||
);
|
||||
if (getAllClassTimeValidityPeriodsResponse.meta.status === "success") {
|
||||
this.classTimeSlotValidityPeriods =
|
||||
getAllClassTimeValidityPeriodsResponse.data;
|
||||
} else {
|
||||
console.error(
|
||||
"Error fetching class time slot validity periods:",
|
||||
getAllClassTimeValidityPeriodsResponse.meta.message,
|
||||
);
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.$p
|
||||
.loadCategory(["global", "lehre", "ui", "gruppenmanagement"])
|
||||
.then(() => {
|
||||
this.phrasesLoaded = true;
|
||||
});
|
||||
},
|
||||
template: `
|
||||
<div class="container mt-4">
|
||||
<h1 class='mb-5'>{{ $p.t("ui", "classScheduleOverviewHeading") }}</h1>
|
||||
<div class="row mb-3">
|
||||
<div class="col d-flex justify-content-end">
|
||||
<a class="btn btn-primary mb-3" @click="showClassTimeSlotTypeModal">{{$p.t('ui', 'addClassTimeSlotTypeButton')}}</a>
|
||||
</div>
|
||||
</div>
|
||||
<class-schedule-type-modal
|
||||
:isVisible="isClassTimeSlotTypeModalVisible"
|
||||
@hideBsModal="resetClassTimeSlotTypeModal"
|
||||
/>
|
||||
<class-schedule-validity-period-modal
|
||||
:isVisible="isClassTimeSlotValidityPeriodModalVisible"
|
||||
:editedClassTimeSlotValidityPeriodId="editedClassTimeSlotValidityPeriodId"
|
||||
@hideBsModal="() => { resetClassTimeSlotValidityPeriodModal(); editedClassTimeSlotValidityPeriodId = null; }"
|
||||
@classTimeSlotValidityPeriodCreated="() => {
|
||||
$refs.classTimeSlotValidityPeriodsTable.reloadTable();
|
||||
resetClassTimeSlotValidityPeriodModal();
|
||||
this.editedClassTimeSlotValidityPeriodId = null;
|
||||
}"
|
||||
@classTimeSlotValidityPeriodUpdated="() => {
|
||||
$refs.classTimeSlotValidityPeriodsTable.reloadTable();
|
||||
resetClassTimeSlotValidityPeriodModal();
|
||||
this.editedClassTimeSlotValidityPeriodId = null;
|
||||
}"
|
||||
/>
|
||||
<core-filter-cmpt
|
||||
v-if="phrasesLoaded"
|
||||
ref="classTimeSlotValidityPeriodsTable"
|
||||
table-only
|
||||
:side-menu="false"
|
||||
:tabulator-options="tabulatorOptions"
|
||||
:tabulator-events="[{ event: 'cellEdited'}]"
|
||||
:new-btn-label="$p.t('ui', 'addClassTimeSlotValidityPeriodButton')"
|
||||
new-btn-show
|
||||
reload
|
||||
@click:new="showClassTimeSlotValidityPeriodModal"
|
||||
></core-filter-cmpt>
|
||||
</div>
|
||||
`,
|
||||
};
|
||||
@@ -0,0 +1,252 @@
|
||||
import { CoreFilterCmpt } from "../filter/Filter.js";
|
||||
import ApiClassSchedule from "../../../js/api/factory/classSchedule.js";
|
||||
|
||||
import BsModal from "../Bootstrap/Modal.js";
|
||||
import CoreForm from "../Form/Form.js";
|
||||
import FormInput from "../Form/Input.js";
|
||||
|
||||
export default {
|
||||
name: "ClassScheduleValidityPeriodForm",
|
||||
components: {
|
||||
BsModal,
|
||||
CoreForm,
|
||||
FormInput,
|
||||
},
|
||||
inject: {
|
||||
hasLehreUnterrichtszeitenTypWPermission:
|
||||
"hasLehreUnterrichtszeitenTypWPermission",
|
||||
},
|
||||
props: {
|
||||
isVisible: {
|
||||
type: Boolean,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
isVisible(newValue) {
|
||||
if (newValue) {
|
||||
this.$refs.classScheduleTypeModal.show();
|
||||
} else {
|
||||
this.$refs.classScheduleTypeModal.hide();
|
||||
}
|
||||
},
|
||||
},
|
||||
data: () => {
|
||||
return {
|
||||
isFormVisible: false,
|
||||
isEditInProgress: false,
|
||||
editedClassScheduleType: null,
|
||||
classTimeSlotTypeFormData: {
|
||||
isActive: true,
|
||||
shortCode: "",
|
||||
descriptions: [
|
||||
{ lang: "de", value: "" },
|
||||
{ lang: "en", value: "" },
|
||||
],
|
||||
},
|
||||
classScheduleTypes: [],
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
async getAllClassScheduleTypes() {
|
||||
let getAllClassScheduleTypeResponse = await this.$api.call(
|
||||
ApiClassSchedule.getAllClassScheduleTypes(),
|
||||
);
|
||||
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 });
|
||||
}
|
||||
return {
|
||||
...type,
|
||||
bezeichnung_mehrsprachig: descriptions,
|
||||
};
|
||||
},
|
||||
);
|
||||
} else {
|
||||
console.error(
|
||||
"Error fetching class schedule types:",
|
||||
getAllClassScheduleTypeResponse.meta.message,
|
||||
);
|
||||
}
|
||||
},
|
||||
createClassTimeSlotType() {
|
||||
return this.$refs.classTimeSlotTypeForm
|
||||
.call(
|
||||
ApiClassSchedule.createClassTimeSlotType({
|
||||
isActive: this.classTimeSlotTypeFormData.isActive,
|
||||
shortCode: this.classTimeSlotTypeFormData.shortCode,
|
||||
descriptions: this.classTimeSlotTypeFormData.descriptions,
|
||||
}),
|
||||
)
|
||||
.then((response) => {
|
||||
this.$fhcAlert.alertSuccess(this.$p.t("ui", "successSave"));
|
||||
this.$emit("classTimeSlotTypeCreated");
|
||||
this.getAllClassScheduleTypes();
|
||||
this.resetClassTimeSlotTypeForm();
|
||||
});
|
||||
},
|
||||
editClassTimeSlotType(classScheduleType) {
|
||||
this.isEditInProgress = true;
|
||||
this.isFormVisible = true;
|
||||
this.editedClassScheduleType = classScheduleType;
|
||||
this.classTimeSlotTypeFormData = {
|
||||
isActive: classScheduleType.aktiv,
|
||||
shortCode: classScheduleType.unterrichtszeitentyp_kurzbz,
|
||||
descriptions: classScheduleType.bezeichnung_mehrsprachig.map(
|
||||
(desc) => ({
|
||||
lang: desc.lang,
|
||||
value: desc.value,
|
||||
}),
|
||||
),
|
||||
};
|
||||
},
|
||||
updateClassTimeSlotType() {
|
||||
return this.$refs.classTimeSlotTypeForm
|
||||
.call(
|
||||
ApiClassSchedule.updateClassTimeSlotType(
|
||||
this.classTimeSlotTypeFormData.shortCode,
|
||||
{
|
||||
isActive: this.classTimeSlotTypeFormData.isActive,
|
||||
descriptions: this.classTimeSlotTypeFormData.descriptions,
|
||||
},
|
||||
),
|
||||
)
|
||||
.then((response) => {
|
||||
this.$fhcAlert.alertSuccess(this.$p.t("ui", "successSave"));
|
||||
this.$emit("classTimeSlotTypeUpdated");
|
||||
this.getAllClassScheduleTypes();
|
||||
this.resetClassTimeSlotTypeForm();
|
||||
});
|
||||
},
|
||||
deleteClassTimeSlotType(classScheduleTypeShortCode) {
|
||||
let isConfirmed = confirm(
|
||||
this.$p.t("ui", "confirmDeleteClassTimeSlotType"),
|
||||
);
|
||||
if (!isConfirmed) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
return this.$api
|
||||
.call(
|
||||
ApiClassSchedule.deleteClassTimeSlotType(
|
||||
this.id,
|
||||
classScheduleTypeShortCode,
|
||||
),
|
||||
)
|
||||
.then((response) => {
|
||||
this.$fhcAlert.alertSuccess(this.$p.t("ui", "successDelete"));
|
||||
window.scrollTo(0, 0);
|
||||
this.getAllClassScheduleTypes();
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("Error deleting class time slot type:", error);
|
||||
this.$fhcAlert.handleSystemError(error);
|
||||
});
|
||||
},
|
||||
showClassTimeSlotTypeForm() {
|
||||
this.isFormVisible = true;
|
||||
},
|
||||
hideClassTimeSlotTypeForm() {
|
||||
this.resetClassTimeSlotTypeForm();
|
||||
},
|
||||
resetClassTimeSlotTypeForm() {
|
||||
this.isEditInProgress = false;
|
||||
this.isFormVisible = false;
|
||||
this.classTimeSlotTypeFormData = {
|
||||
isActive: true,
|
||||
shortCode: "",
|
||||
descriptions: [
|
||||
{ lang: "de", value: "" },
|
||||
{ lang: "en", value: "" },
|
||||
],
|
||||
};
|
||||
},
|
||||
},
|
||||
async created() {
|
||||
await this.getAllClassScheduleTypes();
|
||||
},
|
||||
template: `
|
||||
<bs-modal ref="classScheduleTypeModal" size="md" @hideBsModal="() => { $emit('hideBsModal'); resetClassTimeSlotTypeForm(); }">
|
||||
<template #title>
|
||||
<p v-if="hasLehreUnterrichtszeitenTypWPermission" class="fw-bold mt-3">{{$p.t('ui', 'editClassTimeSlotTypeModalTitle')}}</p>
|
||||
<p v-else class="fw-bold mt-3">{{$p.t('ui', 'existingClassScheduleTypesLabel')}}</p>
|
||||
</template>
|
||||
<div v-if="!isFormVisible && hasLehreUnterrichtszeitenTypWPermission" class="row mb-3">
|
||||
<div class="col d-flex justify-content-end">
|
||||
<button @click="showClassTimeSlotTypeForm" type="button" class="btn btn-primary">{{$p.t('global', 'create')}}</button>
|
||||
</div>
|
||||
</div>
|
||||
<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
|
||||
type="text"
|
||||
name="shortCode"
|
||||
:label="$p.t('ui/shortName')"
|
||||
v-model="classTimeSlotTypeFormData.shortCode"
|
||||
>
|
||||
</form-input>
|
||||
</div>
|
||||
<div v-else class="row mb-3">
|
||||
<p class="mb-0"><span class="fw-bold">{{$p.t('ui/shortName')}}:</span> {{editedClassScheduleType.unterrichtszeitentyp_kurzbz}}</p>
|
||||
</div>
|
||||
<div class="row mb-3">
|
||||
<form-input
|
||||
v-for="description in classTimeSlotTypeFormData.descriptions"
|
||||
:key="description.lang"
|
||||
type="textarea"
|
||||
:name="description.lang"
|
||||
:label="$p.t('ui/description') + ' (' + description.lang + ')'"
|
||||
v-model="description.value"
|
||||
>
|
||||
</form-input>
|
||||
</div>
|
||||
|
||||
<div class="row mb-3">
|
||||
<div class="col d-flex align-items-center justify-content-end">
|
||||
<form-input
|
||||
type="checkbox"
|
||||
name="isActive"
|
||||
:label="$p.t('ui/isActive')"
|
||||
v-model="classTimeSlotTypeFormData.isActive"
|
||||
>
|
||||
</form-input>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col d-flex justify-content-end gap-2">
|
||||
<button type="button" class="btn btn-primary" @click="isEditInProgress ? updateClassTimeSlotType() : createClassTimeSlotType()">{{$p.t('ui', 'speichern')}}</button>
|
||||
<button type="button" class="btn btn-secondary" @click="hideClassTimeSlotTypeForm">{{$p.t('ui', 'abbrechen')}}</button>
|
||||
</div>
|
||||
</core-form>
|
||||
<div class="row mb-3">
|
||||
<p v-if="hasLehreUnterrichtszeitenTypWPermission" class="fw-bold mb-2">{{$p.t('ui', 'existingClassScheduleTypesLabel')}}</p>
|
||||
<div
|
||||
>
|
||||
<div
|
||||
v-for="classScheduleType in classScheduleTypes"
|
||||
:key="classScheduleType.unterrichtszeitentyp_kurzbz"
|
||||
:value="classScheduleType.unterrichtszeitentyp_kurzbz"
|
||||
:class='{"opacity-50": !classScheduleType.aktiv}'
|
||||
class=" shadow-sm p-2 mb-2 bg-body rounded"
|
||||
>
|
||||
<div class="d-flex justify-content-between align-items-center mb-2">
|
||||
<span class="badge bg-secondary me-2">
|
||||
{{classScheduleType.unterrichtszeitentyp_kurzbz}}
|
||||
</span>
|
||||
<div v-if="hasLehreUnterrichtszeitenTypWPermission" class="d-flex justify-content-between align-items-center gap-2">
|
||||
<a href="#" @click.prevent="editClassTimeSlotType(classScheduleType)"><i class="fa fa-edit"></i></a>
|
||||
<a href="#" @click.prevent="deleteClassTimeSlotType(classScheduleType.unterrichtszeitentyp_kurzbz)"><i class="fa fa-trash text-danger"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
<p>
|
||||
{{classScheduleType.bezeichnung_mehrsprachig[0].value}} / {{classScheduleType.bezeichnung_mehrsprachig[1].value}}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</bs-modal>
|
||||
`,
|
||||
};
|
||||
@@ -0,0 +1,241 @@
|
||||
import { CoreFilterCmpt } from "../filter/Filter.js";
|
||||
import ApiClassSchedule from "../../../js/api/factory/classSchedule.js";
|
||||
|
||||
import BsModal from "../Bootstrap/Modal.js";
|
||||
import CoreForm from "../Form/Form.js";
|
||||
import FormInput from "../Form/Input.js";
|
||||
import ClassScheduleValidityPeriodFormTimeSlot from "./ClassScheduleValidityPeriodFormTimeSlot.js";
|
||||
|
||||
export default {
|
||||
name: "ClassScheduleValidityPeriodForm",
|
||||
components: {
|
||||
BsModal,
|
||||
CoreForm,
|
||||
FormInput,
|
||||
CoreFilterCmpt,
|
||||
ClassScheduleValidityPeriodFormTimeSlot,
|
||||
},
|
||||
props: {
|
||||
classTimeSlotValidityPeriod: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
editedClassTimeSlots: {
|
||||
type: Array,
|
||||
required: false,
|
||||
default: () => [],
|
||||
},
|
||||
},
|
||||
emits: ["hideForm", "classTimeSlotsCreated", "classTimeSlotsEdited"],
|
||||
watch: {
|
||||
editedClassTimeSlots: {
|
||||
handler(newVal) {
|
||||
console.log("editedClassTimeSlots changed:", newVal);
|
||||
this.classTimeSlots = JSON.parse(JSON.stringify(newVal));
|
||||
console.log(
|
||||
"classTimeSlots updated from editedClassTimeSlots:",
|
||||
this.classTimeSlots,
|
||||
);
|
||||
},
|
||||
immediate: true,
|
||||
},
|
||||
},
|
||||
data: () => {
|
||||
return {
|
||||
classTimeSlots: [],
|
||||
classTimeSlotTypes: [],
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
areClassTimeSlotsEdited() {
|
||||
return this.editedClassTimeSlots && this.editedClassTimeSlots.length > 0;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
hideForm() {
|
||||
this.$emit("hideForm");
|
||||
this.classTimeSlots = [];
|
||||
},
|
||||
addClassTimeSlotPerDay(day) {
|
||||
this.classTimeSlots.push({
|
||||
identifier: Math.random().toString(36).substr(2, 9),
|
||||
wochentag: this.getWeekdayNumberFromDay(day),
|
||||
startTime: "08:00",
|
||||
endTime: "10:00",
|
||||
classTimeSlotTypeShortcode: null,
|
||||
});
|
||||
},
|
||||
removeClassTimeSlotPerDay(day, identifier) {
|
||||
this.classTimeSlots = this.classTimeSlots.filter(
|
||||
(slot) =>
|
||||
!(
|
||||
slot.wochentag === this.getWeekdayNumberFromDay(day) &&
|
||||
slot.identifier === identifier
|
||||
),
|
||||
);
|
||||
},
|
||||
createClassTimeSlots() {
|
||||
return this.$refs.classTimeSlotData
|
||||
.call(
|
||||
ApiClassSchedule.createClassTimeSlotsForValidityPeriod(
|
||||
this.id,
|
||||
this.$props.classTimeSlotValidityPeriod
|
||||
.unterrichtszeitengueltigkeit_id,
|
||||
{
|
||||
classTimeSlots: this.classTimeSlots,
|
||||
},
|
||||
),
|
||||
)
|
||||
.then((response) => {
|
||||
this.$fhcAlert.alertSuccess(this.$p.t("ui", "successSave"));
|
||||
this.classTimeSlots = [];
|
||||
this.$emit("classTimeSlotsCreated");
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error(
|
||||
"Error creating class time slot validity period:",
|
||||
error,
|
||||
);
|
||||
this.$fhcAlert.handleSystemError(error);
|
||||
});
|
||||
},
|
||||
editClassTimeSlots() {
|
||||
return this.$refs.classTimeSlotData
|
||||
.call(
|
||||
ApiClassSchedule.editClassTimeSlotsForValidityPeriod(
|
||||
this.id,
|
||||
this.$props.classTimeSlotValidityPeriod
|
||||
.unterrichtszeitengueltigkeit_id,
|
||||
{
|
||||
classTimeSlots: this.classTimeSlots,
|
||||
},
|
||||
),
|
||||
)
|
||||
.then((response) => {
|
||||
this.$fhcAlert.alertSuccess(this.$p.t("ui", "successSave"));
|
||||
this.classTimeSlots = [];
|
||||
this.$emit("classTimeSlotsEdited");
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error(
|
||||
"Error editing class time slot validity period:",
|
||||
error,
|
||||
);
|
||||
this.$fhcAlert.handleSystemError(error);
|
||||
});
|
||||
},
|
||||
getWeekdayNumberFromDay(day) {
|
||||
const days = {
|
||||
monday: 1,
|
||||
tuesday: 2,
|
||||
wednesday: 3,
|
||||
thursday: 4,
|
||||
friday: 5,
|
||||
saturday: 6,
|
||||
sunday: 7,
|
||||
};
|
||||
return days[day.toLowerCase()] || null;
|
||||
},
|
||||
},
|
||||
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 {
|
||||
console.error(
|
||||
"Error fetching class time slot types:",
|
||||
getAllClassTimeSlotTypesResponse.meta.message,
|
||||
);
|
||||
}
|
||||
},
|
||||
template: `
|
||||
<core-form ref="classTimeSlotData" class="shadow rounded p-2 row g-3">
|
||||
<div class="d-flex gap-2">
|
||||
<div class="col">
|
||||
<div class="d-flex align-items-center gap-2">
|
||||
<h3>Monday</h3>
|
||||
<a class="ml-auto" @click="addClassTimeSlotPerDay('monday')"><i class="fa fa-plus-circle fs-4"></i></a>
|
||||
</div>
|
||||
<class-schedule-validity-period-form-time-slot
|
||||
v-for="(timeSlot, index) in classTimeSlots.filter(slot => slot.wochentag === 1)"
|
||||
:key="index"
|
||||
:class-time-slot-types="classTimeSlotTypes"
|
||||
@removeClassTimeSlot="removeClassTimeSlotPerDay('monday', timeSlot.identifier)"
|
||||
v-model="timeSlot"
|
||||
/>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="d-flex align-items-center gap-2">
|
||||
<h3>Tuesday</h3>
|
||||
<a class="ml-auto" @click="addClassTimeSlotPerDay('tuesday')"><i class="fa fa-plus-circle fs-4"></i></a>
|
||||
</div>
|
||||
<class-schedule-validity-period-form-time-slot
|
||||
v-for="(timeSlot, index) in classTimeSlots.filter(slot => slot.wochentag === 2)"
|
||||
:key="index"
|
||||
:class-time-slot-types="classTimeSlotTypes"
|
||||
@removeClassTimeSlot="removeClassTimeSlotPerDay('tuesday', timeSlot.identifier)"
|
||||
v-model="timeSlot"
|
||||
/>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="d-flex align-items-center gap-2">
|
||||
<h3>Wednesday</h3>
|
||||
<a class="ml-auto" @click="addClassTimeSlotPerDay('wednesday')"><i class="fa fa-plus-circle fs-4"></i></a>
|
||||
</div>
|
||||
<class-schedule-validity-period-form-time-slot
|
||||
v-for="(timeSlot, index) in classTimeSlots.filter(slot => slot.wochentag === 3)"
|
||||
:key="index"
|
||||
:class-time-slot-types="classTimeSlotTypes"
|
||||
@removeClassTimeSlot="removeClassTimeSlotPerDay('wednesday', timeSlot.identifier)"
|
||||
v-model="timeSlot"
|
||||
/>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="d-flex align-items-center gap-2">
|
||||
<h3>Thursday</h3>
|
||||
<a class="ml-auto" @click="addClassTimeSlotPerDay('thursday')"><i class="fa fa-plus-circle fs-4"></i></a>
|
||||
</div>
|
||||
<class-schedule-validity-period-form-time-slot
|
||||
v-for="(timeSlot, index) in classTimeSlots.filter(slot => slot.wochentag === 4)"
|
||||
:key="index"
|
||||
:class-time-slot-types="classTimeSlotTypes"
|
||||
@removeClassTimeSlot="removeClassTimeSlotPerDay('thursday', timeSlot.identifier)"
|
||||
v-model="timeSlot"
|
||||
/>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="d-flex align-items-center gap-2">
|
||||
<h3>Friday</h3>
|
||||
<a class="ml-auto" @click="addClassTimeSlotPerDay('friday')"><i class="fa fa-plus-circle fs-4"></i></a>
|
||||
</div>
|
||||
<class-schedule-validity-period-form-time-slot
|
||||
v-for="(timeSlot, index) in classTimeSlots.filter(slot => slot.wochentag === 5)"
|
||||
:key="index"
|
||||
:class-time-slot-types="classTimeSlotTypes"
|
||||
@removeClassTimeSlot="removeClassTimeSlotPerDay('friday', timeSlot.identifier)"
|
||||
v-model="timeSlot"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<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>
|
||||
</div>
|
||||
</core-form>
|
||||
`,
|
||||
};
|
||||
@@ -0,0 +1,84 @@
|
||||
import { CoreFilterCmpt } from "../filter/Filter.js";
|
||||
import ApiClassSchedule from "../../../js/api/factory/classSchedule.js";
|
||||
|
||||
import BsModal from "../Bootstrap/Modal.js";
|
||||
import CoreForm from "../Form/Form.js";
|
||||
import FormInput from "../Form/Input.js";
|
||||
|
||||
export default {
|
||||
name: "ClassScheduleValidityPeriodForm",
|
||||
components: {
|
||||
BsModal,
|
||||
CoreForm,
|
||||
FormInput,
|
||||
CoreFilterCmpt,
|
||||
},
|
||||
props: {
|
||||
modelValue: Object,
|
||||
classTimeSlotTypes: Array,
|
||||
},
|
||||
emits: ["update:modelValue", "removeClassTimeSlot"],
|
||||
data: () => {
|
||||
return {
|
||||
classTimeSlots: [],
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
selectedClassTimeSlotType() {
|
||||
return this.classTimeSlotTypes.find(
|
||||
(type) =>
|
||||
type.unterrichtszeitentyp_kurzbz ===
|
||||
this.classTimeSlot.classTimeSlotTypeShortcode,
|
||||
);
|
||||
},
|
||||
classTimeSlot: {
|
||||
get() {
|
||||
return this.modelValue;
|
||||
},
|
||||
set(value) {
|
||||
this.$emit("update:modelValue", value);
|
||||
},
|
||||
},
|
||||
},
|
||||
methods: {},
|
||||
template: `
|
||||
<div class="d-flex align-items-center mb-2">
|
||||
<div
|
||||
:style='[
|
||||
{backgroundColor: selectedClassTimeSlotType ? selectedClassTimeSlotType.hintergrundfarbe : "#fff"}
|
||||
]'
|
||||
class="p-2 shadow d-flex flex-column gap-2 position-relative">
|
||||
<a class="text-classTimeSlot position-absolute top-0 end-0 p-2 z-3" @click="$emit('removeClassTimeSlot', 'monday', classTimeSlot.identifier)"><i class="fa fa-trash text-danger"></i></a>
|
||||
<form-input
|
||||
type="select"
|
||||
name="classTimeSlotType"
|
||||
:label="$p.t('ui/classTimeSlotType')"
|
||||
v-model="classTimeSlot.classTimeSlotTypeShortcode"
|
||||
>
|
||||
<option
|
||||
v-for="classTimeSlotType in $props.classTimeSlotTypes"
|
||||
:key="classTimeSlotType.unterrichtszeitentyp_kurzbz"
|
||||
:value="classTimeSlotType.unterrichtszeitentyp_kurzbz"
|
||||
>
|
||||
{{classTimeSlotType.unterrichtszeitentyp_kurzbz}} - {{classTimeSlotType.bezeichnung_mehrsprachig[0].value}} / ({{classTimeSlotType.bezeichnung_mehrsprachig[1].value}})
|
||||
</option>
|
||||
</form-input>
|
||||
<div class="d-flex rounded align-items-center justify-content-between gap-1">
|
||||
<form-input
|
||||
type="time"
|
||||
name="classTimeSlotValidityPeriodFrom"
|
||||
v-model="classTimeSlot.startTime"
|
||||
|
||||
/>
|
||||
<div > - </div>
|
||||
<form-input
|
||||
type="time"
|
||||
name="classTimeSlotValidityPeriodTo"
|
||||
v-model="classTimeSlot.endTime"
|
||||
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`,
|
||||
};
|
||||
@@ -0,0 +1,305 @@
|
||||
import ApiClassSchedule from "../../../js/api/factory/classSchedule.js";
|
||||
import ApiStudiengang from "../../../js/api/factory/studiengang.js";
|
||||
|
||||
import BsModal from "../Bootstrap/Modal.js";
|
||||
import CoreForm from "../Form/Form.js";
|
||||
import FormInput from "../Form/Input.js";
|
||||
import FormValidation from "../Form/Validation.js";
|
||||
import ApiStudienPlan from "../../../js/api/factory/studienplan.js";
|
||||
|
||||
export default {
|
||||
name: "ClassScheduleValidityPeriodModal",
|
||||
components: {
|
||||
BsModal,
|
||||
CoreForm,
|
||||
FormInput,
|
||||
FormValidation,
|
||||
},
|
||||
props: {
|
||||
isVisible: {
|
||||
type: Boolean,
|
||||
required: true,
|
||||
},
|
||||
editedClassTimeSlotValidityPeriodId: {
|
||||
type: Number,
|
||||
default: null,
|
||||
},
|
||||
},
|
||||
emits: [
|
||||
"hideBsModal",
|
||||
"classTimeSlotValidityPeriodCreated",
|
||||
"classTimeSlotValidityPeriodUpdated",
|
||||
],
|
||||
watch: {
|
||||
isVisible(newValue) {
|
||||
if (newValue) {
|
||||
this.$refs.classTimeSlotValidityPeriodModal.show();
|
||||
} else {
|
||||
this.$refs.classTimeSlotValidityPeriodModal.hide();
|
||||
}
|
||||
},
|
||||
editedClassTimeSlotValidityPeriodId(newValue) {
|
||||
if (!newValue) return;
|
||||
|
||||
return this.$api
|
||||
.call(ApiClassSchedule.getClassTimeValidityPeriod(newValue))
|
||||
.then((response) => {
|
||||
let validityPeriodData = response.data[0];
|
||||
this.classTimeSlotValidityPeriodFormData = {
|
||||
id: validityPeriodData.unterrichtszeitengueltigkeit_id,
|
||||
degreeProgramShortcode: validityPeriodData.oe_kurzbz,
|
||||
studyPlanId: validityPeriodData.studienplan_id,
|
||||
classTimeSlotTypeShortcode:
|
||||
validityPeriodData.unterrichtszeitentyp_kurzbz,
|
||||
validityPeriodFrom: validityPeriodData.gueltig_von,
|
||||
validityPeriodTo: validityPeriodData.gueltig_bis,
|
||||
semester: validityPeriodData.ausbildungssemester,
|
||||
description: validityPeriodData.anmerkung,
|
||||
};
|
||||
this.$refs.classTimeSlotValidityPeriodModal.show();
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error(
|
||||
"Error fetching class time slot validity period details:",
|
||||
error,
|
||||
);
|
||||
this.$fhcAlert.handleSystemError(error);
|
||||
});
|
||||
},
|
||||
},
|
||||
data: () => {
|
||||
return {
|
||||
isFormVisible: false,
|
||||
isEditInProgress: false,
|
||||
degreePrograms: [],
|
||||
studyPlans: [],
|
||||
classTimeSlotTypes: [],
|
||||
classTimeSlotValidityPeriodFormData: {
|
||||
id: null,
|
||||
degreeProgramShortcode: null,
|
||||
studyPlanId: null,
|
||||
classTimeSlotTypeShortcode: null,
|
||||
validityPeriodFrom: null,
|
||||
validityPeriodTo: null,
|
||||
semester: null,
|
||||
description: null,
|
||||
},
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
createClassTimeSlotValidityPeriod() {
|
||||
return this.$refs.classTimeSlotValidityPeriodData
|
||||
.call(
|
||||
ApiClassSchedule.createClassTimeSlotValidityPeriod(
|
||||
this.id,
|
||||
this.classTimeSlotValidityPeriodFormData,
|
||||
),
|
||||
)
|
||||
.then((response) => {
|
||||
this.$fhcAlert.alertSuccess(this.$p.t("ui", "successSave"));
|
||||
this.$refs.classTimeSlotValidityPeriodModal.hide();
|
||||
this.resetClassTimeSlotValidityPeriodModal();
|
||||
window.scrollTo(0, 0);
|
||||
this.$emit("classTimeSlotValidityPeriodCreated");
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error(
|
||||
"Error creating class time slot validity period:",
|
||||
error,
|
||||
);
|
||||
this.$fhcAlert.handleSystemError(error);
|
||||
});
|
||||
},
|
||||
updateClassTimeSlotValidityPeriod() {
|
||||
return this.$refs.classTimeSlotValidityPeriodData
|
||||
.call(
|
||||
ApiClassSchedule.updateClassTimeSlotValidityPeriod(
|
||||
this.id,
|
||||
this.classTimeSlotValidityPeriodFormData.id,
|
||||
this.classTimeSlotValidityPeriodFormData,
|
||||
),
|
||||
)
|
||||
.then((response) => {
|
||||
this.$fhcAlert.alertSuccess(this.$p.t("ui", "successSave"));
|
||||
this.$refs.classTimeSlotValidityPeriodModal.hide();
|
||||
this.resetClassTimeSlotValidityPeriodModal();
|
||||
window.scrollTo(0, 0);
|
||||
this.$emit("classTimeSlotValidityPeriodUpdated");
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error(
|
||||
"Error updating class time slot validity period:",
|
||||
error,
|
||||
);
|
||||
this.$fhcAlert.handleSystemError(error);
|
||||
});
|
||||
},
|
||||
resetClassTimeSlotValidityPeriodModal() {
|
||||
this.$refs.classTimeSlotValidityPeriodData?.clearValidation();
|
||||
this.classTimeSlotValidityPeriodFormData = {
|
||||
id: null,
|
||||
degreeProgramShortcode: null,
|
||||
studyPlanId: null,
|
||||
classTimeSlotTypeShortcode: null,
|
||||
validityPeriodFrom: null,
|
||||
validityPeriodTo: null,
|
||||
semester: null,
|
||||
description: null,
|
||||
};
|
||||
},
|
||||
},
|
||||
async created() {
|
||||
let getAllDegreeProgramsResponse = await this.$api.call(
|
||||
ApiStudiengang.getAllDegreePrograms(),
|
||||
);
|
||||
if (getAllDegreeProgramsResponse.meta.status === "success") {
|
||||
this.degreePrograms = getAllDegreeProgramsResponse.data;
|
||||
} else {
|
||||
console.error(
|
||||
"Error fetching degree programs:",
|
||||
getAllDegreeProgramsResponse.meta.message,
|
||||
);
|
||||
}
|
||||
|
||||
let getAllStudyPlansResponse = await this.$api.call(
|
||||
ApiStudienPlan.getAllStudyPlans(),
|
||||
);
|
||||
if (getAllStudyPlansResponse.meta.status === "success") {
|
||||
this.studyPlans = getAllStudyPlansResponse.data;
|
||||
} else {
|
||||
console.error(
|
||||
"Error fetching study plans:",
|
||||
getAllStudyPlansResponse.meta.message,
|
||||
);
|
||||
}
|
||||
|
||||
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 {
|
||||
console.error(
|
||||
"Error fetching class time slot types:",
|
||||
getAllClassTimeSlotTypesResponse.meta.message,
|
||||
);
|
||||
}
|
||||
},
|
||||
template: `
|
||||
<bs-modal ref="classTimeSlotValidityPeriodModal" @hideBsModal="() => { $emit('hideBsModal'); resetClassTimeSlotValidityPeriodModal(); }" size="md">
|
||||
<template #title>
|
||||
<p v-if="!classTimeSlotValidityPeriodFormData.id" class="fw-bold mt-3">{{$p.t('ui', 'addClassTimeSlotValidityPeriodModalTitle')}}</p>
|
||||
<p v-else class="fw-bold mt-3">{{$p.t('ui', 'editClassTimeSlotValidityPeriodModalTitle')}}</p>
|
||||
</template>
|
||||
<core-form class="row g-3" ref="classTimeSlotValidityPeriodData">
|
||||
<form-validation />
|
||||
<div class="row mb-3">
|
||||
<form-input
|
||||
type="select"
|
||||
name="degreeProgramShortcode"
|
||||
:label="$p.t('lehre/studiengang') + ' *'"
|
||||
v-model="classTimeSlotValidityPeriodFormData.degreeProgramShortcode"
|
||||
>
|
||||
<option
|
||||
v-for="degreeProgram in degreePrograms"
|
||||
:key="degreeProgram.studiengang_kz"
|
||||
:value="degreeProgram.studiengang_kz"
|
||||
>
|
||||
{{degreeProgram.kurzbzlang}} - {{degreeProgram.bezeichnung}})
|
||||
</option>
|
||||
</form-input>
|
||||
</div>
|
||||
<div class="row mb-3">
|
||||
<form-input
|
||||
type="select"
|
||||
name="studyPlan"
|
||||
:label="$p.t('lehre/studienplan')"
|
||||
v-model="classTimeSlotValidityPeriodFormData.studyPlanId"
|
||||
>
|
||||
<option
|
||||
v-for="studyPlan in studyPlans"
|
||||
:key="studyPlan.studienplan_id"
|
||||
:value="studyPlan.studienplan_id"
|
||||
>
|
||||
{{studyPlan.orgform_kurzbz}} - {{studyPlan.sprache}} - {{studyPlan.semesterwochen}}
|
||||
</option>
|
||||
</form-input>
|
||||
</div>
|
||||
<div class="row mb-3">
|
||||
<form-input
|
||||
type="select"
|
||||
name="classTimeSlotType"
|
||||
:label="$p.t('ui/classTimeSlotType')"
|
||||
v-model="classTimeSlotValidityPeriodFormData.classTimeSlotTypeShortcode"
|
||||
>
|
||||
<option
|
||||
v-for="classTimeSlotType in classTimeSlotTypes"
|
||||
:key="classTimeSlotType.unterrichtszeitentyp_kurzbz"
|
||||
:value="classTimeSlotType.unterrichtszeitentyp_kurzbz"
|
||||
>
|
||||
{{classTimeSlotType.unterrichtszeitentyp_kurzbz}} - {{classTimeSlotType.bezeichnung_mehrsprachig[0].value}} / ({{classTimeSlotType.bezeichnung_mehrsprachig[1].value}})
|
||||
</option>
|
||||
</form-input>
|
||||
</div>
|
||||
<div class="row mb-3">
|
||||
<div class="col-12 mb-3">
|
||||
<label>{{$p.t('ui', 'validityPeriod')}}</label>
|
||||
</div>
|
||||
<div class="col">
|
||||
<form-input
|
||||
type="date"
|
||||
name="validityPeriodFrom"
|
||||
:label="$p.t('ui/von') + ' *'"
|
||||
v-model="classTimeSlotValidityPeriodFormData.validityPeriodFrom"
|
||||
/>
|
||||
</div>
|
||||
<div class="col">
|
||||
<form-input
|
||||
type="date"
|
||||
name="validityPeriodTo"
|
||||
:label="$p.t('global/bis') + ' *'"
|
||||
v-model="classTimeSlotValidityPeriodFormData.validityPeriodTo"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-3">
|
||||
<form-input
|
||||
type="select"
|
||||
id="ausbildungssemester"
|
||||
name="semester"
|
||||
:label="$p.t('lehre', 'ausbildungssemester')+ '*'"
|
||||
v-model="classTimeSlotValidityPeriodFormData.semester"
|
||||
>
|
||||
<option v-for="sem in Array.from({length:8}).map((u,i) => i+1)" :key="sem" :value="sem">{{sem}}. Semester</option>
|
||||
</form-input>
|
||||
</div>
|
||||
<div class="row mb-3">
|
||||
<form-input
|
||||
type="textarea"
|
||||
name="beschreibung"
|
||||
:label="$p.t('global/beschreibung')"
|
||||
v-model="classTimeSlotValidityPeriodFormData.description"
|
||||
>
|
||||
</form-input>
|
||||
</div>
|
||||
</core-form>
|
||||
|
||||
<template #footer>
|
||||
<button v-if="!classTimeSlotValidityPeriodFormData.id" type="button" class="btn btn-primary" @click="createClassTimeSlotValidityPeriod">{{$p.t('ui', 'speichern')}}</button>
|
||||
<button v-else type="button" class="btn btn-primary" @click="updateClassTimeSlotValidityPeriod">{{$p.t('ui', 'btnAktualisieren')}}</button>
|
||||
</template>
|
||||
</bs-modal>
|
||||
`,
|
||||
};
|
||||
@@ -0,0 +1,386 @@
|
||||
import { CoreFilterCmpt } from "../filter/Filter.js";
|
||||
import ApiClassSchedule from "../../../js/api/factory/classSchedule.js";
|
||||
|
||||
import BsModal from "../Bootstrap/Modal.js";
|
||||
import CoreForm from "../Form/Form.js";
|
||||
import FormInput from "../Form/Input.js";
|
||||
import ClassScheduleValidityPeriodForm from "./ClassScheduleValidityPeriodForm.js";
|
||||
import ClassScheduleValidityPeriodModal from "./ClassScheduleValidityPeriodModal.js";
|
||||
|
||||
export default {
|
||||
name: "ClassScheduleValidityPeriodOverview",
|
||||
components: {
|
||||
BsModal,
|
||||
CoreForm,
|
||||
FormInput,
|
||||
CoreFilterCmpt,
|
||||
ClassScheduleValidityPeriodForm,
|
||||
ClassScheduleValidityPeriodModal,
|
||||
},
|
||||
data: () => {
|
||||
return {
|
||||
isClassTimeSlotFormVisible: false,
|
||||
classTimeSlotValidityPeriodId: null,
|
||||
classTimeSlotValidityPeriod: null,
|
||||
classTimeSlots: [],
|
||||
classTimeSlotTypes: [],
|
||||
editedClassTimeSlots: [],
|
||||
isClassTimeSlotValidityPeriodModalVisible: false,
|
||||
editedClassTimeSlotValidityPeriodId: null,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
classScheduleValidityPeriodStartDate() {
|
||||
if (!this.classTimeSlotValidityPeriod) return null;
|
||||
|
||||
let dateParts = this.classTimeSlotValidityPeriod.gueltig_von
|
||||
.split("-")
|
||||
.reverse();
|
||||
return dateParts.join("/");
|
||||
},
|
||||
classScheduleValidityPeriodEndDate() {
|
||||
if (!this.classTimeSlotValidityPeriod) return null;
|
||||
let dateParts = this.classTimeSlotValidityPeriod.gueltig_bis
|
||||
.split("-")
|
||||
.reverse();
|
||||
return dateParts.join("/");
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
async fetchClassTimeValidityPeriod() {
|
||||
let getClassTimeValidityPeriodResponse = await this.$api.call(
|
||||
ApiClassSchedule.getClassTimeValidityPeriod(
|
||||
this.classTimeSlotValidityPeriodId,
|
||||
),
|
||||
);
|
||||
if (getClassTimeValidityPeriodResponse.meta.status === "success") {
|
||||
this.classTimeSlotValidityPeriod =
|
||||
getClassTimeValidityPeriodResponse.data[0];
|
||||
|
||||
if (!this.classTimeSlotValidityPeriod) {
|
||||
this.$fhcAlert.alertError(
|
||||
this.$p.t("ui", "classTimeSlotValidityPeriodNotFound"),
|
||||
);
|
||||
this.$router.push({ name: "overview" });
|
||||
}
|
||||
} else {
|
||||
console.error(
|
||||
"Error fetching class time slot validity period:",
|
||||
getClassTimeValidityPeriodResponse.meta.message,
|
||||
);
|
||||
}
|
||||
},
|
||||
async fetchClassTimeSlots() {
|
||||
let getClassTimeSlotsForValidityPeriodResponse = await this.$api.call(
|
||||
ApiClassSchedule.getClassTimeSlotsForValidityPeriod(
|
||||
this.classTimeSlotValidityPeriodId,
|
||||
),
|
||||
);
|
||||
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;
|
||||
} else {
|
||||
console.error(
|
||||
"Error fetching class time slots for validity period:",
|
||||
this.classTimeSlots,
|
||||
);
|
||||
}
|
||||
},
|
||||
showClassTimeSlotForm() {
|
||||
this.isClassTimeSlotFormVisible = true;
|
||||
},
|
||||
async editClassTimeSlotsForValidityPeriodPerGroup(groupIdentifikator) {
|
||||
console.log("Editing class time slots for group:", groupIdentifikator);
|
||||
await this.fetchClassTimeSlots();
|
||||
console.log(
|
||||
this.classTimeSlots.filter(
|
||||
(group) => group.groupIdentifikator === groupIdentifikator,
|
||||
),
|
||||
);
|
||||
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,
|
||||
};
|
||||
}) || [];
|
||||
console.log(this.editedClassTimeSlots);
|
||||
this.showClassTimeSlotForm();
|
||||
},
|
||||
deleteClassTimeSlotsForValidityPeriodPerGroup(groupIdentifikator) {
|
||||
let isDeletionConfirmed = confirm(
|
||||
this.$p.t("ui", "confirmDeleteClassTimeSlotsForGroup"),
|
||||
);
|
||||
if (!isDeletionConfirmed) {
|
||||
return;
|
||||
}
|
||||
|
||||
return this.$api
|
||||
.call(
|
||||
ApiClassSchedule.deleteClassTimeSlotsForValidityPeriodPerGroup(
|
||||
this.id,
|
||||
this.classTimeSlotValidityPeriodId,
|
||||
groupIdentifikator,
|
||||
),
|
||||
)
|
||||
.then((response) => {
|
||||
this.$fhcAlert.alertSuccess(this.$p.t("ui", "successDelete"));
|
||||
this.classTimeSlots = [];
|
||||
this.fetchClassTimeSlots();
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("Error deleting class time slots per group:", error);
|
||||
this.$fhcAlert.handleSystemError(error);
|
||||
});
|
||||
},
|
||||
getClassTimeSlotType(classTimeSlot) {
|
||||
let classTimeSlotType = this.classTimeSlotTypes.find(
|
||||
(type) =>
|
||||
type.unterrichtszeitentyp_kurzbz ===
|
||||
classTimeSlot.unterrichtszeitentyp_kurzbz,
|
||||
);
|
||||
|
||||
return classTimeSlotType;
|
||||
},
|
||||
getClassTimeSlotBackgroundColor(classTimeSlot) {
|
||||
let classTimeSlotType = this.classTimeSlotTypes.find(
|
||||
(type) =>
|
||||
type.unterrichtszeitentyp_kurzbz ===
|
||||
classTimeSlot.unterrichtszeitentyp_kurzbz,
|
||||
);
|
||||
|
||||
return classTimeSlotType ? classTimeSlotType.hintergrundfarbe : "#fff";
|
||||
},
|
||||
editClassTimeSlotValidityPeriod(classTimeSlotValidityPeriodId) {
|
||||
this.editedClassTimeSlotValidityPeriodId = classTimeSlotValidityPeriodId;
|
||||
},
|
||||
deleteClassTimeSlotValidityPeriod(classTimeSlotValidityPeriodId) {
|
||||
let isDeletionConfirmed = confirm(
|
||||
this.$p.t("ui", "deleteClassTimeSlotValidityPeriodConfirmation"),
|
||||
);
|
||||
if (!isDeletionConfirmed) return;
|
||||
|
||||
return this.$api
|
||||
.call(
|
||||
ApiClassSchedule.deleteClassTimeSlotValidityPeriod(
|
||||
this.id,
|
||||
classTimeSlotValidityPeriodId,
|
||||
),
|
||||
)
|
||||
.then((response) => {
|
||||
this.$fhcAlert.alertSuccess(this.$p.t("ui", "successDelete"));
|
||||
this.$router.push({ name: "overview" });
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error(
|
||||
"Error deleting class time slot validity period:",
|
||||
error,
|
||||
);
|
||||
this.$fhcAlert.handleSystemError(error);
|
||||
});
|
||||
},
|
||||
resetClassTimeSlotValidityPeriodModal() {
|
||||
this.isClassTimeSlotValidityPeriodModalVisible = false;
|
||||
},
|
||||
},
|
||||
async created() {
|
||||
this.classTimeSlotValidityPeriodId =
|
||||
this.$route.params.classTimeSlotValidityPeriodId;
|
||||
|
||||
this.fetchClassTimeValidityPeriod();
|
||||
|
||||
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 {
|
||||
console.error(
|
||||
"Error fetching class time slot types:",
|
||||
getAllClassTimeSlotTypesResponse.meta.message,
|
||||
);
|
||||
}
|
||||
|
||||
this.fetchClassTimeSlots();
|
||||
},
|
||||
template: `
|
||||
<div class="container mt-4">
|
||||
<div class='mb-5'>
|
||||
<div class="d-flex align-items-center justify-content-between mb-2">
|
||||
<div class="d-flex align-items-center gap-3">
|
||||
<h1 class='m-0'>
|
||||
{{ $p.t("ui", "classScheduleValidityPeriodOverviewHeading") }}
|
||||
</h1>
|
||||
<span class="m-0 badge bg-secondary">{{ classTimeSlotValidityPeriod?.orgform_kurzbz }}</span>
|
||||
</div>
|
||||
<div class="d-flex align-items-center gap-2">
|
||||
<a
|
||||
@click="editClassTimeSlotValidityPeriod(classTimeSlotValidityPeriodId)"
|
||||
class="btn btn-link fs-3 p-0">
|
||||
<i class="fa fa-edit"></i></a>
|
||||
<a @click="deleteClassTimeSlotValidityPeriod(classTimeSlotValidityPeriodId)" class="btn btn-link text-danger fs-3 p-0"><i class="fa fa-trash"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
<h2>{{ classScheduleValidityPeriodStartDate }} - {{ classScheduleValidityPeriodEndDate }}</h2>
|
||||
<p v-html="classTimeSlotValidityPeriod?.anmerkung"></p>
|
||||
</div>
|
||||
<div>
|
||||
<div v-if='!isClassTimeSlotFormVisible' 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
|
||||
: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 = []; }"
|
||||
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">
|
||||
<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>
|
||||
</div>
|
||||
<div class="col">
|
||||
<h3>Monday</h3>
|
||||
<div v-for="(classTimeSlot, innerIndex) in classTimeSlotsPerWeek.slots.filter(slot => slot.wochentag === 1)" :key="innerIndex" class="d-flex align-items-center mb-2">
|
||||
<p
|
||||
class='p-2 m-0 rounded'
|
||||
:style="{backgroundColor: getClassTimeSlotBackgroundColor(classTimeSlot)}"
|
||||
:title="getClassTimeSlotType(classTimeSlot) ? getClassTimeSlotType(classTimeSlot).bezeichnung_mehrsprachig.find(desc => desc.lang === 'de').value : ''"
|
||||
>
|
||||
{{ classTimeSlot.uhrzeit_von }} - {{ classTimeSlot.uhrzeit_bis }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<h3>Tuesday</h3>
|
||||
<div v-for="(classTimeSlot, innerIndex) in classTimeSlotsPerWeek.slots.filter(slot => slot.wochentag === 2)" :key="innerIndex" class="d-flex align-items-center mb-2">
|
||||
<p
|
||||
class='p-2 m-0 rounded'
|
||||
:style="{backgroundColor: getClassTimeSlotBackgroundColor(classTimeSlot)}"
|
||||
:title="getClassTimeSlotType(classTimeSlot) ? getClassTimeSlotType(classTimeSlot).bezeichnung_mehrsprachig.find(desc => desc.lang === 'de').value : ''"
|
||||
>
|
||||
{{ classTimeSlot.uhrzeit_von }} - {{ classTimeSlot.uhrzeit_bis }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<h3>Wednesday</h3>
|
||||
<div v-for="(classTimeSlot, innerIndex) in classTimeSlotsPerWeek.slots.filter(slot => slot.wochentag === 3)" :key="innerIndex" class="d-flex align-items-center mb-2">
|
||||
<p
|
||||
class='p-2 m-0 rounded'
|
||||
:style="{backgroundColor: getClassTimeSlotBackgroundColor(classTimeSlot)}"
|
||||
:title="getClassTimeSlotType(classTimeSlot) ? getClassTimeSlotType(classTimeSlot).bezeichnung_mehrsprachig.find(desc => desc.lang === 'de').value : ''"
|
||||
>
|
||||
{{ classTimeSlot.uhrzeit_von }} - {{ classTimeSlot.uhrzeit_bis }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<h3>Thursday</h3>
|
||||
<div v-for="(classTimeSlot, innerIndex) in classTimeSlotsPerWeek.slots.filter(slot => slot.wochentag === 4)" :key="innerIndex" class="d-flex align-items-center mb-2">
|
||||
<p
|
||||
class='p-2 m-0 rounded'
|
||||
:style="{backgroundColor: getClassTimeSlotBackgroundColor(classTimeSlot)}"
|
||||
:title="getClassTimeSlotType(classTimeSlot) ? getClassTimeSlotType(classTimeSlot).bezeichnung_mehrsprachig.find(desc => desc.lang === 'de').value : ''"
|
||||
>
|
||||
{{ classTimeSlot.uhrzeit_von }} - {{ classTimeSlot.uhrzeit_bis }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<h3>Friday</h3>
|
||||
<div v-for="(classTimeSlot, innerIndex) in classTimeSlotsPerWeek.slots.filter(slot => slot.wochentag === 5)" :key="innerIndex" class="d-flex align-items-center mb-2">
|
||||
<p
|
||||
class='p-2 m-0 rounded'
|
||||
:style="{backgroundColor: getClassTimeSlotBackgroundColor(classTimeSlot)}"
|
||||
:title="getClassTimeSlotType(classTimeSlot) ? getClassTimeSlotType(classTimeSlot).bezeichnung_mehrsprachig.find(desc => desc.lang === 'de').value : ''"
|
||||
>
|
||||
{{ classTimeSlot.uhrzeit_von }} - {{ classTimeSlot.uhrzeit_bis }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<h3>Saturday</h3>
|
||||
<div v-for="(classTimeSlot, innerIndex) in classTimeSlotsPerWeek.slots.filter(slot => slot.wochentag === 6)" :key="innerIndex" class="d-flex align-items-center mb-2">
|
||||
<p
|
||||
class='p-2 m-0 rounded'
|
||||
:style="{backgroundColor: getClassTimeSlotBackgroundColor(classTimeSlot)}"
|
||||
:title="getClassTimeSlotType(classTimeSlot) ? getClassTimeSlotType(classTimeSlot).bezeichnung_mehrsprachig.find(desc => desc.lang === 'de').value : ''"
|
||||
>
|
||||
{{ classTimeSlot.uhrzeit_von }} - {{ classTimeSlot.uhrzeit_bis }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<h3>Sunday</h3>
|
||||
<div v-for="(classTimeSlot, innerIndex) in classTimeSlotsPerWeek.slots.filter(slot => slot.wochentag === 7)" :key="innerIndex" class="d-flex align-items-center mb-2">
|
||||
<p
|
||||
class='p-2 m-0 rounded'
|
||||
:style="{backgroundColor: getClassTimeSlotBackgroundColor(classTimeSlot)}"
|
||||
:title="getClassTimeSlotType(classTimeSlot) ? getClassTimeSlotType(classTimeSlot).bezeichnung_mehrsprachig.find(desc => desc.lang === 'de').value : ''"
|
||||
>
|
||||
{{ classTimeSlot.uhrzeit_von }} - {{ classTimeSlot.uhrzeit_bis }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="d-flex align-items-center justify-content-center border rounded p-4 mt-4">
|
||||
<p>{{ $p.t("ui", "noClassScheduleValidityPeriodTimeSlotsFound") }}</p>
|
||||
</div>
|
||||
</div>
|
||||
<class-schedule-validity-period-modal
|
||||
:isVisible="isClassTimeSlotValidityPeriodModalVisible"
|
||||
:editedClassTimeSlotValidityPeriodId="editedClassTimeSlotValidityPeriodId"
|
||||
@hideBsModal="() => { resetClassTimeSlotValidityPeriodModal(); editedClassTimeSlotValidityPeriodId = null; }"
|
||||
@classTimeSlotValidityPeriodUpdated="() => {
|
||||
resetClassTimeSlotValidityPeriodModal();
|
||||
this.editedClassTimeSlotValidityPeriodId = null;
|
||||
fetchClassTimeValidityPeriod();
|
||||
}"
|
||||
/>
|
||||
</div>
|
||||
`,
|
||||
};
|
||||
@@ -57276,6 +57276,586 @@ I have been informed that I am under no obligation to consent to the transmissio
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'ui',
|
||||
'phrase' => 'montag',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'Montag',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => 'Monday',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'ui',
|
||||
'phrase' => 'dienstag',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'Dienstag',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => 'Tuesday',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'ui',
|
||||
'phrase' => 'mittwoch',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'Mittwoch',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => 'Wednesday',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'ui',
|
||||
'phrase' => 'donnerstag',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'Donnerstag',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => 'Thursday',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'ui',
|
||||
'phrase' => 'freitag',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'Freitag',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => 'Friday',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'ui',
|
||||
'phrase' => 'samstag',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'Samstag',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => 'Saturday',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'ui',
|
||||
'phrase' => 'sonntag',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'Sonntag',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => 'Sunday',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'ui',
|
||||
'phrase' => 'deleteClassTimeSlotValidityPeriodConfirmation',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'Möchten Sie wirklich diese Unterrichtszeitgültigkeit löschen?',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => 'Do you really want to delete this class time slot validity period?',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'ui',
|
||||
'phrase' => 'classScheduleValidityPeriodOverviewHeading',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'Übersicht Unterrichtszeitgültigkeiten',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => 'Class Time Slot Validity Period Overview',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'ui',
|
||||
'phrase' => 'addClassTimeSlotValidityPeriodModalTitle',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'Unterrichtszeitgültigkeit hinzufügen',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => 'Add Class Time Slot Validity Period',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'ui',
|
||||
'phrase' => 'addClassTimeSlotValidityPeriodButton',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'Unterrichtszeitgültigkeit hinzufügen',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => 'Add Class Time Slot Validity Period',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'ui',
|
||||
'phrase' => 'editClassTimeSlotValidityPeriodModalTitle',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'Unterrichtszeitgültigkeit bearbeiten',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => 'Edit Class Time Slot Validity Period',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'ui',
|
||||
'phrase' => 'confirmDeleteClassTimeSlotsForGroup',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'Möchten Sie wirklich diese Unterrichtszeiten löschen?',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => 'Do you really want to delete these class time slots?',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'ui',
|
||||
'phrase' => 'addClassTimeSlotTypeModalTitle',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'Unterrichtszeittyp hinzufügen',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => 'Add Class Time Slot Type',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'ui',
|
||||
'phrase' => 'editClassTimeSlotTypeModalTitle',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'Unterrichtszeittyp bearbeiten',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => 'Edit Class Time Slot Type',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'ui',
|
||||
'phrase' => 'shortName',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'kurzbezeichnung',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => 'short name',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'ui',
|
||||
'phrase' => 'description',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'beschreibung',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => 'description',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'ui',
|
||||
'phrase' => 'existingClassScheduleTypesLabel',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'Vorhandene Unterrichtszeittypen',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => 'Existing Class Schedule Types',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'ui',
|
||||
'phrase' => 'confirmDeleteClassTimeSlotType',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'Möchten Sie wirklich diesen Unterrichtszeittyp löschen?',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => 'Do you really want to delete this class time slot type?',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'ui',
|
||||
'phrase' => 'classTimeSlotType',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'Unterrichtszeittyp',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => 'Class Time Slot Type',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'ui',
|
||||
'phrase' => 'isActive',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'Aktiv',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => 'Active',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'ui',
|
||||
'phrase' => 'validityPeriod',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'Gültigkeitszeitraum',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => 'Validity Period',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'ui',
|
||||
'phrase' => 'addClassTimeSlotTypeButton',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'Unterrichtszeittyp hinzufügen',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => 'Add Class Time Slot Type',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'ui',
|
||||
'phrase' => 'addClassTimeSlotTypeButton',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'Unterrichtszeittyp hinzufügen',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => 'Add Class Time Slot Type',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'ui',
|
||||
'phrase' => 'classScheduleValidityPeriodTimeSlots',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'Unterrichtszeiten für diesen Gültigkeitszeitraum',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => 'Class time slots for this validity period',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'ui',
|
||||
'phrase' => 'noClassScheduleValidityPeriodTimeSlotsFound',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'Keine Unterrichtszeiten für diesen Gültigkeitszeitraum gefunden',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => 'No class time slots found for this validity period',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'ui',
|
||||
'phrase' => 'classScheduleOverviewHeading',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'Übersicht Unterrichtszeiten',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => 'Class Schedule Overview',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'ui',
|
||||
'phrase' => 'addClassTimeSlotButton',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'Unterrichtszeit hinzufügen',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => 'Add Class Time Slot',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'ui',
|
||||
'phrase' => 'classTimeSlotValidityPeriodNotFound',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'Kein Gültigkeitszeitraum für diese Unterrichtszeit gefunden',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => 'No validity period found for this class time slot',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
)
|
||||
),
|
||||
// ### Phrases Dashboard Admin END
|
||||
);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user