diff --git a/application/controllers/api/frontend/v1/stv/Config.php b/application/controllers/api/frontend/v1/stv/Config.php index d52016943..4d3a5f8ee 100644 --- a/application/controllers/api/frontend/v1/stv/Config.php +++ b/application/controllers/api/frontend/v1/stv/Config.php @@ -33,6 +33,8 @@ class Config extends FHCAPI_Controller { // TODO(chris): permissions parent::__construct([ + 'get' => ['admin:r', 'assistenz:r'], + 'set' => ['admin:r', 'assistenz:r'], 'student' => ['admin:r', 'assistenz:r'], 'students' => ['admin:r', 'assistenz:r'] ]); @@ -52,6 +54,65 @@ class Config extends FHCAPI_Controller $this->load->config('stv'); } + /** + * get App config + */ + public function get() + { + $this->load->model('system/Variable_model', 'VariableModel'); + $this->load->config('stv'); + + $config = []; + + $result = $this->VariableModel->getVariables(getAuthUID(), ['number_displayed_past_studiensemester']); + $data = $this->getDataOrTerminateWithError($result); + + $number_displayed_past_studiensemester_default = $this->config->item('number_displayed_past_studiensemester_default'); + + $config['number_displayed_past_studiensemester'] = [ + "type" => "number", + "label" => "Anzahl angezeigter vergangender Studiensemester",// TODO(chris): phrase + "value" => $data['number_displayed_past_studiensemester'] + ?? $number_displayed_past_studiensemester_default + ]; + + // TODO(chris): Event + + $this->terminateWithSuccess($config); + } + + /** + * set App config + */ + public function set() + { + // TODO(chris): rewrite to batch saving + $this->load->model('system/Variable_model', 'VariableModel'); + $this->load->library('form_validation'); + + $this->form_validation->set_rules( + 'number_displayed_past_studiensemester', + "Anzahl angezeigter vergangender Studiensemester",// TODO(chris): phrase + 'required|integer' + ); + + // TODO(chris): Event + + if (!$this->form_validation->run()) + $this->terminateWithValidationErrors($this->form_validation->error_array()); + + + $this->VariableModel->setVariable( + getAuthUID(), + 'number_displayed_past_studiensemester', + $this->input->post('number_displayed_past_studiensemester') + ); + + // TODO(chris): Event + + $this->terminateWithSuccess(); + } + public function student() { $result = []; diff --git a/application/controllers/api/frontend/v1/stv/Verband.php b/application/controllers/api/frontend/v1/stv/Verband.php index 6487b6263..030593293 100644 --- a/application/controllers/api/frontend/v1/stv/Verband.php +++ b/application/controllers/api/frontend/v1/stv/Verband.php @@ -188,6 +188,7 @@ class Verband extends FHCAPI_Controller array_unshift($list, [ 'name' => 'PreStudent', 'link' => $link . 'prestudent', + 'no_sem_reload' => true, 'stg_kz' => (int)$studiengang_kz, 'children' => $this->getStdSem($link . 'prestudent/', $studiengang_kz) ]); diff --git a/public/js/api/factory/stv/config.js b/public/js/api/factory/stv/config.js new file mode 100644 index 000000000..c54b2f8b2 --- /dev/null +++ b/public/js/api/factory/stv/config.js @@ -0,0 +1,32 @@ +/** + * 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 { + get() { + return { + method: 'get', + url: 'api/frontend/v1/stv/config/get' + }; + }, + set(params) { + return { + method: 'post', + url: 'api/frontend/v1/stv/config/set', + params + }; + } +}; \ No newline at end of file diff --git a/public/js/components/Stv/Studentenverwaltung.js b/public/js/components/Stv/Studentenverwaltung.js index d53d9a789..9db3f9e7b 100644 --- a/public/js/components/Stv/Studentenverwaltung.js +++ b/public/js/components/Stv/Studentenverwaltung.js @@ -22,6 +22,7 @@ import StvVerband from "./Studentenverwaltung/Verband.js"; import StvList from "./Studentenverwaltung/List.js"; import StvDetails from "./Studentenverwaltung/Details.js"; import StvStudiensemester from "./Studentenverwaltung/Studiensemester.js"; +import StvConfig from "./Studentenverwaltung/Config.js"; import ApiSearchbar from "../../api/factory/searchbar.js"; import ApiStv from "../../api/factory/stv.js"; @@ -37,7 +38,8 @@ export default { StvVerband, StvList, StvDetails, - StvStudiensemester + StvStudiensemester, + StvConfig }, props: { defaultSemester: String, @@ -78,11 +80,13 @@ export default { }, configShowAufnahmegruppen: this.config.showAufnahmegruppen, configAllowUebernahmePunkte: this.config.allowUebernahmePunkte, - configUseReihungstestPunkte: this.config.useReihungstestPunkte + configUseReihungstestPunkte: this.config.useReihungstestPunkte, + appConfig: Vue.computed(() => this.appconfig) } }, data() { return { + appconfig: {}, selected: [], searchbaroptions: { origin: 'stv', @@ -380,6 +384,17 @@ export default { class="dropdown-menu dropdown-menu-dark dropdown-menu-end rounded-0 text-center m-0" aria-labelledby="nav-user-btn" > +
  • + +
  • +
  • + ` }; diff --git a/public/js/components/Stv/Studentenverwaltung/Config.js b/public/js/components/Stv/Studentenverwaltung/Config.js new file mode 100644 index 000000000..f7a6363cd --- /dev/null +++ b/public/js/components/Stv/Studentenverwaltung/Config.js @@ -0,0 +1,96 @@ +/** + * 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 . + */ + +import BsModal from "../../Bootstrap/Modal.js"; +import FhcForm from "../../Form/Form.js"; +import FormInput from "../../Form/Input.js"; + +import ApiStvConfig from '../../../api/factory/stv/config.js'; + + +export default { + name: 'StvConfig', + components: { + BsModal, + FhcForm, + FormInput + }, + emits: [ + 'update:modelValue' + ], + props: { + modelValue: Object + }, + data() { + return { + setup: {}, + tempValues: {} + }; + }, + methods: { + update() { + this.$refs.form + .call(ApiStvConfig.set(this.tempValues)) + .then(() => { + // TODO(chris): phrase + this.$emit('update:modelValue', { ...this.tempValues }); + this.$refs.modal.hide(); + this.$fhcAlert.alertSuccess('config updated'); + }) + .catch(this.$fhcAlert.handleSystemErrors); + } + }, + created() { + this.$api + .call(ApiStvConfig.get()) + .then(res => { + this.setup = {}; + Object.keys(res.data).forEach(key => { + const conf = { ...res.data[key] }; + this.tempValues[key] = conf.value; + delete conf.value; + this.setup[key] = conf; + }); + this.$emit('update:modelValue', { ...this.tempValues }); + }) + .catch(this.$fhcAlert.handleSystemErrors); + }, + template: /* html */` + + + + + + + ` +}; diff --git a/public/js/components/Stv/Studentenverwaltung/Verband.js b/public/js/components/Stv/Studentenverwaltung/Verband.js index 072e0e952..4ebc7866a 100644 --- a/public/js/components/Stv/Studentenverwaltung/Verband.js +++ b/public/js/components/Stv/Studentenverwaltung/Verband.js @@ -5,6 +5,9 @@ export default { PvTreetable: primevue.treetable, PvColumn: primevue.column }, + inject: [ + 'appConfig' + ], emits: [ 'selectVerband' ], @@ -34,6 +37,9 @@ export default { return this.nodes.filter(node => this.favorites.list.includes(node.key)); return this.nodes; + }, + noSemReloadNodes() { + return this.nodes.reduce(this.mapNodesToNoSemReloadNodes, []); } }, watch: { @@ -41,6 +47,14 @@ export default { if (newVal !== oldVal) { this.setPreselection(); } + }, + 'appConfig.number_displayed_past_studiensemester'(newVal, oldVal) { + if (oldVal !== undefined) { + this.noSemReloadNodes.forEach(node => { + delete node.children; + this.onExpandTreeNode(node); + }); + } } }, methods: { @@ -98,6 +112,13 @@ export default { if (node.data.link) this.$emit('selectVerband', {link: node.data.link, studiengang_kz: node.data.stg_kz}); }, + mapNodesToNoSemReloadNodes(result, node) { + if (node.data.no_sem_reload) + result.push(node); + if (node.children) + result = node.children.reduce(this.mapNodesToNoSemReloadNodes, result); + return result; + }, mapResultToTreeData(el) { const cp = { key: ("" + el.link).replace('/', '-'), diff --git a/system/phrasesupdate.php b/system/phrasesupdate.php index 97b62a0d9..8f6421a39 100644 --- a/system/phrasesupdate.php +++ b/system/phrasesupdate.php @@ -1795,6 +1795,26 @@ $phrases = array( ) ) ), + array( + 'app' => 'core', + 'category' => 'ui', + 'phrase' => 'settings', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Einstellungen', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Settings', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), array( 'app' => 'core', 'category' => 'ui',