diff --git a/application/config/studierendenantrag.php b/application/config/studierendenantrag.php index ef2098aca..9d1e7a1c8 100644 --- a/application/config/studierendenantrag.php +++ b/application/config/studierendenantrag.php @@ -197,3 +197,11 @@ $config['unterbrechung_enabled'] = true; */ $config['wiederholung_enabled'] = true; +/** + * Modal with Infotext of TLC + * if true, there will be shown an info modal in the studentsView after the first button ABMELDUNG + * + * @var boolean + */ +$config['showInfoModalAbmeldung'] = true; + diff --git a/application/config/stv.php b/application/config/stv.php index e6266c4e8..b12153eda 100644 --- a/application/config/stv.php +++ b/application/config/stv.php @@ -177,6 +177,8 @@ $config['stv_prestudent_tags'] = [ 'unterbrecher_auto' => ['readonly' => true], 'stbtr_erh_auto' => ['readonly' => true], 'jgv_auto' => ['readonly' => true], + 'in_auto' => ['readonly' => true], + 'preabbr_auto' => ['readonly' => true], ]; $config['userAutomatedTags'] = 'sftest'; diff --git a/application/config/treemenu/custom/lvvw.php b/application/config/treemenu/custom/lvvw.php index a1f270e05..977c0459e 100644 --- a/application/config/treemenu/custom/lvvw.php +++ b/application/config/treemenu/custom/lvvw.php @@ -22,10 +22,10 @@ if (!defined('BASEPATH')) exit('No direct script access allowed'); $config['root'] = [ 'stg' => [ 'semester' => [ - /*'group', + 'group', 'verband' => [ 'group' - ]*/ + ] ], 'orgform' ] diff --git a/application/controllers/api/frontend/v1/TabulatorPresets.php b/application/controllers/api/frontend/v1/TabulatorPresets.php new file mode 100644 index 000000000..cb8e23ade --- /dev/null +++ b/application/controllers/api/frontend/v1/TabulatorPresets.php @@ -0,0 +1,162 @@ +. + */ + +if (! defined('BASEPATH')) exit('No direct script access allowed'); + +/** + * This controller operates between (interface) the JS (GUI) and the PhrasesLib (back-end) + * Provides data to the ajax get calls about the Phrasen plugin + * This controller works with JSON calls on the HTTP GET and the output is always JSON + */ +class TabulatorPresets extends FHCAPI_Controller +{ + public function __construct() + { + parent::__construct([ + 'getTabulatorPresets' => self::PERM_LOGGED, + 'createTabulatorPreset' => self::PERM_LOGGED, + 'updateTabulatorPreset' => self::PERM_LOGGED, + 'deleteTabulatorPreset' => self::PERM_LOGGED, + ]); + + $this->load->model('tabulator/Tabulator_preset_model', 'TabulatorPresetModel'); + + $this->loadPhrases([ + 'global', + 'tabulator_presets' + ]); + } + + //------------------------------------------------------------------------------------------------------------------ + // Public methods + + public function getTabulatorPresets() + { + $tableName = $this->input->get("tableName"); + if (!$tableName) { + $this->terminateWithError(error($this->p->t("tabulator_presets", "invalid_params_err_msg"))); + } + + $uid = getAuthUID(); + $presets = $this->TabulatorPresetModel->getTabulatorPresetsByUserAndTable($uid, $tableName); + $presetsData = $this->getDataOrTerminateWithError($presets) ?? []; + + $this->terminateWithSuccess($presetsData); + } + + public function createTabulatorPreset() + { + $tableName = $this->input->post("tableName"); + $presetName = $this->input->post("presetName"); + $preset = $this->input->post("preset"); + + if (!$tableName || !$presetName || !$preset) { + $this->terminateWithError($this->p->t("tabulator_presets", "invalid_params_err_msg"), "general", 400); + } + + $uid = getAuthUID(); + + $existingPresetsResult = $this->TabulatorPresetModel->getTabulatorPresetsByUserAndTable($uid, $tableName); + $existingPresets = $this->getDataOrTerminateWithError($existingPresetsResult) ?? []; + + if (count($existingPresets) > 19) { + $this->terminateWithError($this->p->t("tabulator_presets", "max_presets_count_err_msg"), "general", 409); + } + + $existingPresetNames = array_map(function($presetInfo) { + return $presetInfo->preset_name; + }, $existingPresets); + + if (in_array($presetName, $existingPresetNames)) { + $this->terminateWithError($this->p->t("tabulator_presets", "preset_name_duplicate_err_msg"), "general", 409); + } + + $presetCreationResult = $this->TabulatorPresetModel->createTabulatorPreset($uid, $tableName, $presetName, $preset); + + if (isError($presetCreationResult)) { + $this->terminateWithError($presetCreationResult->retval); + } + + $newPresetData = $this->TabulatorPresetModel->getTabulatorPreset($presetCreationResult->retval); + $newPresetArray = $this->getDataOrTerminateWithError($newPresetData) ?? [null]; + $newPreset = $newPresetArray[0]; + + $this->terminateWithSuccess($newPreset); + } + + public function updateTabulatorPreset() + { + $presetId = $this->input->post("presetId"); + $preset = $this->input->post("preset"); + + if (!$presetId || !$preset) { + $this->terminateWithError($this->p->t("tabulator_presets", "invalid_params_err_msg"), "general", 400); + } + + $existingPresetData = $this->TabulatorPresetModel->getTabulatorPreset($presetId); + $existingPresetArray = $this->getDataOrTerminateWithError($existingPresetData) ?? [null]; + $existingPreset = $existingPresetArray[0]; + if (!$existingPreset) { + $this->terminateWithError($this->p->t("tabulator_presets", "preset_not_found_err_msg"), "general", 404); + } + + $uid = getAuthUID(); + if ($existingPreset->benutzer_uid !== $uid) { + $this->terminateWithError($this->p->t("tabulator_presets", "preset_not_own_update_err_msg"), "general", 403); + } + + $presetUpdateResult = $this->TabulatorPresetModel->updateTabulatorPreset($presetId, $preset); + if (isError($presetUpdateResult)) { + $this->terminateWithError($presetUpdateResult->retval); + } + + $updatedPresetData = $this->TabulatorPresetModel->getTabulatorPreset($presetId); + $updatedPresetArray = $this->getDataOrTerminateWithError($updatedPresetData) ?? [null]; + $updatedPreset = $updatedPresetArray[0]; + + $this->terminateWithSuccess($updatedPreset); + } + + public function deleteTabulatorPreset() + { + $presetId = $this->input->post("presetId"); + if (!$presetId) { + $this->terminateWithError($this->p->t("tabulator_presets", "invalid_params_err_msg"), "general", 400); + } + + $presetData = $this->TabulatorPresetModel->getTabulatorPreset($presetId); + $presetArray = $this->getDataOrTerminateWithError($presetData) ?? [null]; + $preset = $presetArray[0]; + if (!$preset) { + $this->terminateWithError($this->p->t("tabulator_presets", "preset_not_found_err_msg"), "general", 404); + } + + $uid = getAuthUID(); + if ($preset->benutzer_uid !== $uid) { + $this->terminateWithError($this->p->t("tabulator_presets", "preset_not_own_delete_err_msg"), "general", 403); + } + + $presetDeletionResult = $this->TabulatorPresetModel->deleteTabulatorPreset($presetId); + if (isError($presetDeletionResult)) { + $this->terminateWithError($presetDeletionResult->retval); + } + + $this->terminateWithSuccess(); + } + +} \ No newline at end of file diff --git a/application/controllers/api/frontend/v1/stv/Students.php b/application/controllers/api/frontend/v1/stv/Students.php index 2994f6ac4..39ed72072 100644 --- a/application/controllers/api/frontend/v1/stv/Students.php +++ b/application/controllers/api/frontend/v1/stv/Students.php @@ -756,6 +756,8 @@ class Students extends FHCAPI_Controller 'studiensemester_kurzbz' => $studiensemester_kurzbz )); + $studiensemester_kurzbz = $this->getStudiensemesterKurzbz($studiensemester_kurzbz); + $this->load->library('SearchLib', [ 'config' => 'searchstv' ]); $this->load->library('form_validation'); diff --git a/application/controllers/components/Cis/Mylv.php b/application/controllers/components/Cis/Mylv.php index 1fdb7e2a1..30544b647 100644 --- a/application/controllers/components/Cis/Mylv.php +++ b/application/controllers/components/Cis/Mylv.php @@ -14,11 +14,11 @@ class Mylv extends Auth_Controller public function __construct() { parent::__construct([ - 'Student' => ['student/anrechnung_beantragen:r','user:r'], // TODO(chris): permissions? - 'Studiensemester' => ['student/anrechnung_beantragen:r','user:r'], // TODO(chris): permissions? - 'Lvs' => ['student/anrechnung_beantragen:r','user:r'], // TODO(chris): permissions? - 'Info' => ['student/anrechnung_beantragen:r','user:r'], // TODO(chris): permissions? - 'Pruefungen' => ['student/anrechnung_beantragen:r','user:r'] // TODO(chris): permissions? + 'Student' => self::PERM_LOGGED, + 'Studiensemester' => self::PERM_LOGGED, + 'Lvs' => self::PERM_LOGGED, + 'Info' => self::PERM_LOGGED, + 'Pruefungen' => self::PERM_LOGGED ]); } diff --git a/application/controllers/jobs/AntragJob.php b/application/controllers/jobs/AntragJob.php index 5b72518d2..8bcb898a9 100644 --- a/application/controllers/jobs/AntragJob.php +++ b/application/controllers/jobs/AntragJob.php @@ -125,7 +125,7 @@ class AntragJob extends JOB_Controller $stgLeitungen[$leitung->uid]['stgs'][] = $antrag->studiengang_kz; } - $result = $this->StudierendenantragModel->getStgAndSem($antrag->studierendenantrag_id); + $result = $this->StudierendenantragModel->getStgAndDetails($antrag->studierendenantrag_id); if (isError($result)) { $this->logError(getError($result)); diff --git a/application/controllers/lehre/Studierendenantrag.php b/application/controllers/lehre/Studierendenantrag.php index ebc1d2eaa..ad333679d 100644 --- a/application/controllers/lehre/Studierendenantrag.php +++ b/application/controllers/lehre/Studierendenantrag.php @@ -25,7 +25,8 @@ class Studierendenantrag extends FHC_Controller // Load language phrases $this->loadPhrases([ - 'studierendenantrag' + 'studierendenantrag', + 'ui' ]); $this->load->config('studierendenantrag'); diff --git a/application/core/Tag_Controller.php b/application/core/Tag_Controller.php index 9d2f4cf6a..c4b6edb81 100644 --- a/application/core/Tag_Controller.php +++ b/application/core/Tag_Controller.php @@ -349,16 +349,27 @@ class Tag_Controller extends FHCAPI_Controller public function rebuildTagsForTypeId() { - $id = $this->input->post('id'); + $ids = $this->input->post('ids'); $typeId = $this->input->post('typeId'); $semester = $this->input->post('sem'); - $result = $this->taglib->rebuildTagsForTypeId($typeId, $id, $semester); + $idsSuccess = []; + $idsError = []; + $outputResult = []; - if (isError($result)) - return error ('Error occurred during updateAutomatedTags'); + foreach ($ids as $id) + { + $result = $this->taglib->rebuildTagsForTypeId($typeId, $id, $semester); - $this->terminateWithSuccess($result); + if (isError($result)) + $idsError[] = $id; + else + $idsSuccess[] = $id; + + $outputResult[] = $result; + } + + $this->terminateWithSuccess([$outputResult, $idsSuccess, $idsError]); } private function _setAuthUID() @@ -401,4 +412,4 @@ class Tag_Controller extends FHCAPI_Controller )); } -} \ No newline at end of file +} diff --git a/application/helpers/hlp_header_helper.php b/application/helpers/hlp_header_helper.php index 53a5f5ba3..eb2cd9f85 100644 --- a/application/helpers/hlp_header_helper.php +++ b/application/helpers/hlp_header_helper.php @@ -111,7 +111,8 @@ function generateJSDataStorageObject($indexPage, $calledPath, $calledMethod) 'theme' => [ 'name'=>$ci->config->item('theme_name'), 'modes'=>$ci->config->item('theme_modes'), - ] + ], + 'domain' => DOMAIN ); $toPrint = "\n"; diff --git a/application/libraries/TagLib.php b/application/libraries/TagLib.php index c4107f416..637431360 100644 --- a/application/libraries/TagLib.php +++ b/application/libraries/TagLib.php @@ -37,7 +37,7 @@ class TagLib $this->_ci->load->library('PermissionLib'); $this->_ci->load->library('PrestudentLib'); - $batchUser = $this->_ci->config->item('userAutomatedTags'); + $this->batchUser = $this->_ci->config->item('userAutomatedTags'); } public function updateAutomatedTags($paramsTag) diff --git a/application/libraries/tags/CoreIncomingTagLib.php b/application/libraries/tags/CoreIncomingTagLib.php new file mode 100644 index 000000000..26d7dad0b --- /dev/null +++ b/application/libraries/tags/CoreIncomingTagLib.php @@ -0,0 +1,63 @@ +ci = get_instance(); + $this->ci->load->model('codex/Bisio_model', 'BisioModel'); + } + + public function getZuordnungIds(array $params) + { + if(!isset($params['studiensemester_kurzbz'])) + { + return (object) array( + 'idArray' => [] + ); + } + + $semester = $params['studiensemester_kurzbz']; + + $result = $this->ci->BisioModel->getIncomingsOfSemester($semester); + + $data = $result->retval; + + $outgoing_data = array_map(function($item) { + return [ + 'id' => $item->prestudent_id, + 'von' => $item->von, + 'bis' => $item->bis + ]; + }, $data); + + return (object) array( + 'data' => $outgoing_data, + 'typeId' => 'prestudent_id', + ); + } + + public function isCriteriaSetFor(array $params) + { + if ( !isset($params['id'], $params['studiensemester_kurzbz'], $params['typeId']) || $params['typeId'] !== 'prestudent_id') + return false; + + $semester = $params['studiensemester_kurzbz']; + $prestudent_id = $params['id']; + + $result = $this->ci->BisioModel->isPrestudentIncoming($semester, $prestudent_id); + + if (hasData($result)) { + return $result; + } + else + return null; + } + +} diff --git a/application/libraries/tags/CorePreabbrecherTagLib.php b/application/libraries/tags/CorePreabbrecherTagLib.php new file mode 100644 index 000000000..41712ac3b --- /dev/null +++ b/application/libraries/tags/CorePreabbrecherTagLib.php @@ -0,0 +1,80 @@ +ci = get_instance(); + $this->ci->load->model('education/Studierendenantrag_model', 'StudierendenantragModel'); + } + + public function getZuordnungIds(array $params) + { + if(!isset($params['studiensemester_kurzbz'])) + { + return (object) array( + 'idArray' => [] + ); + } + + $semester = $params['studiensemester_kurzbz']; + + $this->ci->StudierendenantragModel->addJoin('public.tbl_studiensemester', 'studiensemester_kurzbz'); + $this->ci->StudierendenantragModel->db->where_in('typ', self::TYP_ABMELDUNG); + $this->ci->StudierendenantragModel->db->where('studiensemester_kurzbz', $semester); + $result = $this->ci->StudierendenantragModel->getWithLastStatusWhere([ + 'studierendenantrag_statustyp_kurzbz' => Studierendenantragstatus_model::STATUS_CREATED + ]); + + $data = $result->retval; + + $prewiederholer_data = array_map(function($item) { + return [ + 'id' => $item->prestudent_id, + 'von' => $item->start, + 'bis' => $item->ende + ]; + }, $data); + + return (object) array( + 'data' => $prewiederholer_data, + 'typeId' => 'prestudent_id', + ); + } + + public function isCriteriaSetFor(array $params) + { + if ( !isset($params['id'], $params['studiensemester_kurzbz'], $params['typeId']) || $params['typeId'] !== 'prestudent_id') + return false; + + $semester = $params['studiensemester_kurzbz']; + $prestudent_id = $params['id']; + + $this->ci->StudierendenantragModel->addSelect('prestudent_id'); + $this->ci->StudierendenantragModel->addSelect('start as von'); + $this->ci->StudierendenantragModel->addSelect('ende as bis'); + + $this->ci->StudierendenantragModel->addJoin('public.tbl_studiensemester', 'studiensemester_kurzbz'); + $this->ci->StudierendenantragModel->db->where_in('typ', self::TYP_ABMELDUNG); + $this->ci->StudierendenantragModel->db->where('studiensemester_kurzbz', $semester); + $this->ci->StudierendenantragModel->db->where('prestudent_id', $prestudent_id); + $result = $this->ci->StudierendenantragModel->getWithLastStatusWhere([ + 'studierendenantrag_statustyp_kurzbz' => Studierendenantragstatus_model::STATUS_CREATED + ]); + + if(hasData($result)) + { + return $result; + } + else + return null; + } + +} diff --git a/application/models/codex/Bisio_model.php b/application/models/codex/Bisio_model.php index 9a9fd37fb..972661c8b 100644 --- a/application/models/codex/Bisio_model.php +++ b/application/models/codex/Bisio_model.php @@ -73,6 +73,34 @@ class Bisio_model extends DB_Model return $this->execQuery($query, array($studiensemester_kurzbz)); } + /** + * Gets incoming students of certain Semester + * @param String studiensemester_kurzbz + * @return array of prestudent_ids + */ + public function getIncomingsOfSemester($studiensemester_kurzbz) + { + $query = " + SELECT DISTINCT ps.prestudent_id, tbl_bisio.von, tbl_bisio.bis + FROM bis.tbl_bisio + JOIN public.tbl_student USING (student_uid) + JOIN public.tbl_prestudent ps USING (prestudent_id) + JOIN public.tbl_prestudentstatus pss ON (ps.prestudent_id = pss.prestudent_id) + JOIN public.tbl_studiensemester ss ON (pss.studiensemester_kurzbz = ss.studiensemester_kurzbz) + WHERE ss.studiensemester_kurzbz = ? + AND nation_code = 'A' + AND ( + tbl_bisio.von <= ss.ende + AND ( + tbl_bisio.bis >= ss.start + OR tbl_bisio.bis IS NULL + ) + ) + "; + + return $this->execQuery($query, array($studiensemester_kurzbz)); + } + public function isPrestudentOutgoing($studiensemester_kurzbz, $prestudent_id) { $query = " @@ -97,4 +125,29 @@ class Bisio_model extends DB_Model return $this->execQuery($query, array($studiensemester_kurzbz, $prestudent_id)); } + + public function isPrestudentIncoming($studiensemester_kurzbz, $prestudent_id) + { + $query = " + SELECT + ps.prestudent_id, tbl_bisio.von, tbl_bisio.bis + FROM bis.tbl_bisio + JOIN public.tbl_student USING (student_uid) + JOIN public.tbl_prestudent ps USING (prestudent_id) + JOIN public.tbl_prestudentstatus pss ON (ps.prestudent_id = pss.prestudent_id) + JOIN public.tbl_studiensemester ss ON (pss.studiensemester_kurzbz = ss.studiensemester_kurzbz) + WHERE ss.studiensemester_kurzbz = ? + AND nation_code = 'A' + AND ( + tbl_bisio.von <= ss.ende + AND ( + tbl_bisio.bis >= ss.start + OR tbl_bisio.bis IS NULL + ) + ) + AND ps.prestudent_id = ? + "; + + return $this->execQuery($query, array($studiensemester_kurzbz, $prestudent_id)); + } } diff --git a/application/models/education/Studierendenantrag_model.php b/application/models/education/Studierendenantrag_model.php index 40224ffc9..c18d18053 100644 --- a/application/models/education/Studierendenantrag_model.php +++ b/application/models/education/Studierendenantrag_model.php @@ -188,6 +188,7 @@ class Studierendenantrag_model extends DB_Model * Get the studiengang and ausbildungssemester the student was in * for the studiensemester the antrag was committed for * + * * @param integer $antrag_id * * @return stdClass @@ -242,6 +243,28 @@ class Studierendenantrag_model extends DB_Model ); } + /** + * Get the studiengang and the studienplan the student is in + * + * @param integer $antrag_id + * + * @return stdClass + */ + public function getStgAndDetails($antrag_id) + { + $this->addSelect('p.studiengang_kz'); + $this->addSelect('stg.orgform_kurzbz'); + $this->addSelect('stg.bezeichnung'); + $this->addJoin('public.tbl_prestudent p', 'prestudent_id'); + $this->addJoin('public.tbl_studiengang stg', 'studiengang_kz'); + + $this->addLimit(1); + + return $this->load( + $antrag_id + ); + } + public function getStgEmail($antrag_id) { $this->addJoin('public.tbl_prestudent p', 'prestudent_id'); diff --git a/application/models/tabulator/Tabulator_preset_model.php b/application/models/tabulator/Tabulator_preset_model.php new file mode 100644 index 000000000..a3c45739d --- /dev/null +++ b/application/models/tabulator/Tabulator_preset_model.php @@ -0,0 +1,83 @@ +dbTable = 'public.tbl_tabulator_presets'; + $this->pk = ['preset_id']; + $this->hasSequence = true; + + + $this->load->model('person/Benutzer_model', 'BenutzerModel'); + } + + public function getTabulatorPreset($presetId) + { + $query = " + SELECT * + FROM public.tbl_tabulator_presets + WHERE preset_id = ? + LIMIT 1 + "; + return $this->execQuery($query, array($presetId)); + } + + public function getTabulatorPresetsByUserAndTable($uid, $tableName) + { + $query = ' + SELECT * + FROM public.tbl_tabulator_presets + WHERE benutzer_uid = ? + AND table_name = ? + ORDER BY preset_id ASC + '; + return $this->execQuery($query, array($uid, $tableName)); + } + + public function createTabulatorPreset($uid, $tableName, $presetName, $preset) + { + $presetCreationResult = $this->insert([ + "benutzer_uid" => $uid, + "table_name" => $tableName, + "preset_name" => $presetName, + "preset_json" => json_encode($preset), + ]); + + if (isError($presetCreationResult)) + { + return error('Something went wrong during preset creation!'); + } + + return success($presetCreationResult->retval); + } + + public function updateTabulatorPreset($presetId, $preset) + { + $presetUpdateResult = $this->update(["preset_id" => $presetId], ["preset_json" => json_encode($preset)]); + + if (isError($presetUpdateResult)) + { + return error('Something went wrong during preset update!'); + } + + return success($presetUpdateResult->retval); + } + + public function deleteTabulatorPreset($presetId) + { + $presetDeletionReseult = $this->delete(["preset_id" => $presetId]); + + if (isError($presetDeletionReseult)) + { + return error('Something went wrong during preset deletion!'); + } + + return success($presetDeletionReseult->retval); + } + +} diff --git a/application/views/Studentenverwaltung.php b/application/views/Studentenverwaltung.php index 8dd2dd93d..5b6138ff8 100644 --- a/application/views/Studentenverwaltung.php +++ b/application/views/Studentenverwaltung.php @@ -56,12 +56,13 @@ $configArray = [ diff --git a/application/views/lehre/Antrag/Student/List.php b/application/views/lehre/Antrag/Student/List.php index 6d769dafe..884d1f391 100644 --- a/application/views/lehre/Antrag/Student/List.php +++ b/application/views/lehre/Antrag/Student/List.php @@ -30,6 +30,12 @@ if(defined('CIS4')){ } ?> +load->config('studierendenantrag'); + $showInfoModalAbmeldung = $this->config->item('showInfoModalAbmeldung'); +?> +
@@ -43,17 +49,75 @@ if(defined('CIS4')){

()

+
-

p->t('studierendenantrag', 'calltoaction_' . $type); ?>

-
- - p->t('studierendenantrag', 'antrag_typ_' . $type); ?> - +

p->t('studierendenantrag', 'calltoaction_' . $type); ?>

+
+ + + + data-bs-toggle="modal" + + > + p->t('studierendenantrag', 'antrag_typ_' . $type); ?> + + + +
- + + + + @@ -205,7 +269,7 @@ if(defined('CIS4')){ p->t('studierendenantrag', 'my_lvs'); ?> diff --git a/application/views/templates/FHC-Footer.php b/application/views/templates/FHC-Footer.php index d2eb229f1..66ed4bd51 100644 --- a/application/views/templates/FHC-Footer.php +++ b/application/views/templates/FHC-Footer.php @@ -154,6 +154,7 @@ generateJSsInclude('vendor/npm-asset/primevue/confirmdialog/confirmdialog.min.js'); generateJSsInclude('vendor/npm-asset/primevue/confirmationservice/confirmationservice.min.js'); generateJSsInclude('vendor/npm-asset/primevue/tieredmenu/tieredmenu.min.js'); + generateJSsInclude('vendor/npm-asset/primevue/progressbar/progressbar.min.js'); } if($vuedatepicker11) generateJSsInclude('vendor/vuejs/vuedatepicker_js11/vue-datepicker.iife.js'); diff --git a/composer.json b/composer.json index 4d37abdbb..0feee3c63 100644 --- a/composer.json +++ b/composer.json @@ -109,9 +109,9 @@ "type": "package", "package": { "name": "fortawesome/font-awesome6", - "version": "6.1.1", + "version": "6.7.2", "dist": { - "url": "https://github.com/FortAwesome/Font-Awesome/archive/refs/tags/6.1.1.zip", + "url": "https://github.com/FortAwesome/Font-Awesome/archive/refs/tags/6.7.2.zip", "type": "zip" } } @@ -468,7 +468,7 @@ "fgelinas/timepicker": "0.3.3", "fortawesome/font-awesome4": "4.7.*", - "fortawesome/font-awesome6": "6.1.*", + "fortawesome/font-awesome6": "6.7.*", "fzaninotto/faker": "1.*", "firebase/php-jwt": "^6.0", @@ -496,7 +496,7 @@ "netcarver/textile": "3.7.*", "nicolaskruchten/pivottable": "2.23.0", "npm-asset/primevue": "3.29.1", - "npm-asset/primeicons": "5.0.0", + "npm-asset/primeicons": "6.0.1", "olifolkerd/tabulator4": "4.9.*", "olifolkerd/tabulator5": "5.5.*", diff --git a/composer.lock b/composer.lock index 212eea3be..39042460f 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "869cbc35bd1ba90ab90934fcb41b0f51", + "content-hash": "bc21de2a48b960781c1ed028c4b8d7b9", "packages": [ { "name": "afarkas/html5shiv", @@ -960,10 +960,10 @@ }, { "name": "fortawesome/font-awesome6", - "version": "6.1.1", + "version": "6.7.2", "dist": { "type": "zip", - "url": "https://github.com/FortAwesome/Font-Awesome/archive/refs/tags/6.1.1.zip" + "url": "https://github.com/FortAwesome/Font-Awesome/archive/refs/tags/6.7.2.zip" }, "type": "library" }, @@ -1565,10 +1565,10 @@ }, { "name": "npm-asset/primeicons", - "version": "5.0.0", + "version": "6.0.1", "dist": { "type": "tar", - "url": "https://registry.npmjs.org/primeicons/-/primeicons-5.0.0.tgz" + "url": "https://registry.npmjs.org/primeicons/-/primeicons-6.0.1.tgz" }, "type": "npm-asset", "license": [ diff --git a/public/css/tags.css b/public/css/tags.css index 3b3377d5d..0634c5ce3 100644 --- a/public/css/tags.css +++ b/public/css/tags.css @@ -91,6 +91,15 @@ color: black; } +.tag_skyblue { + background-color: #90D5FF; + color: black; +} +.tag_blush { + background-color: #A83E3E; + color: white; +} + .tag_done { text-decoration: line-through; } diff --git a/public/js/api/factory/tabulatorPresets.js b/public/js/api/factory/tabulatorPresets.js new file mode 100644 index 000000000..1653ccb40 --- /dev/null +++ b/public/js/api/factory/tabulatorPresets.js @@ -0,0 +1,58 @@ +/** + * Copyright (C) 2025 fhcomplete.org + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +export default { + getTabulatorPresets(tableName) { + return { + method: "get", + url: + "/api/frontend/v1/TabulatorPresets/getTabulatorPresets?tableName=" + + tableName, + }; + }, + createTabulatorPreset(tableName, presetName, preset) { + return { + method: "post", + url: "/api/frontend/v1/TabulatorPresets/createTabulatorPreset", + params: { + tableName, + presetName, + preset, + }, + }; + }, + updateTabulatorPreset(presetId, preset) { + return { + method: "post", + url: "/api/frontend/v1/TabulatorPresets/updateTabulatorPreset", + params: { + presetId, + preset, + }, + }; + }, + deleteTabulatorPreset(tabulatorPresetId) { + return { + method: "post", + url: + "/api/frontend/v1/TabulatorPresets/deleteTabulatorPreset", + params: { + presetId: tabulatorPresetId, + }, + }; + }, +}; diff --git a/public/js/components/Cis/Profil/MitarbeiterProfil.js b/public/js/components/Cis/Profil/MitarbeiterProfil.js index 9a6d12e3f..68a3a0d75 100644 --- a/public/js/components/Cis/Profil/MitarbeiterProfil.js +++ b/public/js/components/Cis/Profil/MitarbeiterProfil.js @@ -469,6 +469,7 @@ export default { :tabulator-options="betriebsmittel_table_options" tableOnly :sideMenu="false" + :isUsingPresets="true" /> diff --git a/public/js/components/Cis/Profil/MitarbeiterViewProfil.js b/public/js/components/Cis/Profil/MitarbeiterViewProfil.js index 07a21fcca..3d23e7714 100644 --- a/public/js/components/Cis/Profil/MitarbeiterViewProfil.js +++ b/public/js/components/Cis/Profil/MitarbeiterViewProfil.js @@ -43,6 +43,7 @@ export default { maxWidth: 40, headerClick: this.collapseFunction, visible: true, + responsive: 0, }, { title: "placeholder", @@ -51,6 +52,7 @@ export default { headerFilter: true, minWidth: 200, visible: true, + responsive: 0, }, { title: "placeholder", @@ -59,6 +61,7 @@ export default { headerFilter: true, minWidth: 200, visible: true, + responsive: 1, }, { title: "placeholder", @@ -71,6 +74,7 @@ export default { visible: true, formatter: "datetime", formatterParams: this.datetimeFormatterParams(), + responsive: 4, }, { title: "placeholder", @@ -83,6 +87,7 @@ export default { visible: true, formatter: "datetime", formatterParams: this.datetimeFormatterParams(), + responsive: 3, }, { title: "placeholder", @@ -91,6 +96,7 @@ export default { headerFilter: true, minWidth: 200, visible: true, + responsive: 2, }, ], }, diff --git a/public/js/components/Cis/Profil/Profil.js b/public/js/components/Cis/Profil/Profil.js index ab7eb0f3d..cba34951c 100644 --- a/public/js/components/Cis/Profil/Profil.js +++ b/public/js/components/Cis/Profil/Profil.js @@ -176,7 +176,6 @@ export const Profil = { this.data = data.profil_data.data; this.calendarSyncUrls = data.calendar_sync_urls ?? []; this.authPermissions = data.permissions; - console.log(data.profil_data); }, zustellAdressenCount() { if (!this.data || !this.data.adressen) { diff --git a/public/js/components/DetailHeader/DetailHeader.js b/public/js/components/DetailHeader/DetailHeader.js index 595586a39..5bf49731b 100644 --- a/public/js/components/DetailHeader/DetailHeader.js +++ b/public/js/components/DetailHeader/DetailHeader.js @@ -326,8 +326,10 @@ export default { this.reload(); }, rebuildPrestudentTags(){ + const id = [this.headerData[0].prestudent_id]; + const params = { - id : this.headerData[0].prestudent_id, + ids: id, typeId: 'prestudent_id', sem: this.currentSemester }; diff --git a/public/js/components/LVVerwaltung/LVVerwaltung.js b/public/js/components/LVVerwaltung/LVVerwaltung.js index 90e6266bb..6d9331d38 100644 --- a/public/js/components/LVVerwaltung/LVVerwaltung.js +++ b/public/js/components/LVVerwaltung/LVVerwaltung.js @@ -6,6 +6,7 @@ import BaseTreemenu from '../Base/Treemenu.js'; import StvStudiensemester from "../Stv/Studentenverwaltung/Studiensemester.js"; import LvTable from "./Setup/Table.js"; import LvTabs from "./Setup/Tabs.js"; +import NavLanguage from "../navigation/Language.js"; import ApiDetails from "../../api/lehrveranstaltung/details.js"; import ApiLektor from "../../api/lehrveranstaltung/lektor.js"; @@ -25,7 +26,8 @@ export default { StvStudiensemester, LvTable, LvTabs, - AppConfig + AppConfig, + NavLanguage }, props: { avatarUrl: String, @@ -47,10 +49,13 @@ export default { permissionLehrveranstaltung: this.permissions['lehre/lehrveranstaltung'], permissionGruppenEntfernen: this.permissions['lv-plan/gruppenentfernen'], permissionLektorEntfernen: this.permissions['lv-plan/lektorentfernen'], + language: Vue.computed(() => this.$p.user_language), + isMobile: false, } }, data() { return { + sidebarCollapsed: false, appconfig:{}, configEndpoints: ApiLvConfig, selected: [], diff --git a/public/js/components/LVVerwaltung/Tabs/Noten.js b/public/js/components/LVVerwaltung/Tabs/Noten.js index 8b01a017d..07a428d01 100644 --- a/public/js/components/LVVerwaltung/Tabs/Noten.js +++ b/public/js/components/LVVerwaltung/Tabs/Noten.js @@ -25,18 +25,34 @@ export default { return { stdsem: '', endpoint: ApiLVNoten, - tabulatorOptions: { + tabulatorOptionsZeugnis: { visibleColumns: { vorname: true, nachname: true, + uid: true, lehrveranstaltung_bezeichnung: false }, headerFilter: { vorname: true, nachname: true, + uid: true, lehrveranstaltung_bezeichnung: false }, persistenceZeugnisID: 'lv-details-noten-zeugnis-2025120401', + }, + tabulatorOptionsTeacher: { + visibleColumns: { + vorname: true, + nachname: true, + student_uid: true, + lehrveranstaltung_bezeichnung: false + }, + headerFilter: { + vorname: true, + nachname: true, + student_uid: true, + lehrveranstaltung_bezeichnung: false + }, persistenceTeacherID: 'lv-details-noten-teacher-2025120401', }, zeugnisLoaded: false, @@ -98,7 +114,7 @@ export default { :id="modelValue.lehrveranstaltung_id" :all-semester="!!stdsem" :endpoint="endpoint" - :optionalTabulatorOptions="tabulatorOptions" + :optionalTabulatorOptions="tabulatorOptionsZeugnis" @loaded="onZeugnisLoaded"/>
@@ -108,7 +124,7 @@ export default { :all-semester="!!stdsem" :endpoint="endpoint" @copied="reload" - :optionalTabulatorOptions="tabulatorOptions" + :optionalTabulatorOptions="tabulatorOptionsTeacher" @loaded="onTeacherLoaded"/>
diff --git a/public/js/components/Stv/Studentenverwaltung.js b/public/js/components/Stv/Studentenverwaltung.js index a926bb858..b9ee54526 100644 --- a/public/js/components/Stv/Studentenverwaltung.js +++ b/public/js/components/Stv/Studentenverwaltung.js @@ -54,7 +54,8 @@ export default { cisRoot: String, avatarUrl: String, logoutUrl: String, - activeAddons: String // semicolon separated list of active addons + activeAddons: String, // semicolon separated list of active addons + authUid: String }, provide() { return { @@ -88,7 +89,9 @@ export default { hasZGVMasterPermission: this.permissions['student/editMakkZgv'], hasZGVDoctorPermission: this.permissions['student/editDokZgv'], hasBismeldenPermission: this.permissions['student/editBismelden'], - + authUid: this.authUid, + language: Vue.computed(() => this.$p.user_language), + isMobile: false, } }, data() { @@ -216,6 +219,28 @@ export default { return extraItems; }, + appMenuBisItems() { + const extraItems = []; + + if (this.studiengangKz !== undefined) { + const studiengang_kz = String(this.studiengangKz); + + extraItems.push({ + link: FHC_JS_DATA_STORAGE_OBJECT.app_root + + 'vilesci/bis/studentenmeldung.php?' + + 'stg_kz=' + studiengang_kz, + description: 'stv/bis_stud_meldung' + }); + extraItems.push({ + link: FHC_JS_DATA_STORAGE_OBJECT.app_root + + 'system/checkStudenten.php?' + + 'stg_kz=' + studiengang_kz, + description: 'stv/bis_stud_plausicheck' + }); + } + + return extraItems; + }, linkRt(){ return FHC_JS_DATA_STORAGE_OBJECT.app_root + '/vilesci/stammdaten/reihungstestverwaltung.php' }, @@ -289,6 +314,11 @@ export default { sidebarCollapsed(newVal) { if(newVal) this.$refs.hSplit.collapseLeft() else this.$refs.hSplit.showBoth() + }, + studiengangKz(newVal, oldVal) { + if (newVal !== oldVal) { + this.$refs.stvList.clearSelection(); + } } }, methods: { @@ -401,6 +431,9 @@ export default { showAlertNoGroupChosen(){ this.$fhcAlert.alertError(this.$p.t('ui', 'alert_chooseGroupSem')); }, + showAlertNoDegreeProgramChosen(){ + this.$fhcAlert.alertError(this.$p.t('ui', 'alert_chooseDegreeProgram')); + }, showMenu(refName) { bootstrap.Dropdown.getOrCreateInstance(this.$refs[refName]).show(); }, @@ -613,13 +646,13 @@ export default { -
  • {{ $p.t('stv/lvplanung') }} -