diff --git a/application/config/routes.php b/application/config/routes.php index 9fad59d88..b1dcc13fb 100644 --- a/application/config/routes.php +++ b/application/config/routes.php @@ -63,6 +63,9 @@ $route['api/v1/system/[S|s]prache/(:any)'] = 'api/v1/system/sprache2/$1'; $route['studentenverwaltung/(:any)/(:any)'] = 'Studentenverwaltung/index'; +$route['public/js/components/primevue/(:any)/(:any)'] = 'public/Primevue/index/$1/$2'; +$route['public/js/components/primevue/(:any)/(:any)/(:any)'] = 'public/Primevue/index/$2/$3/$1'; + // load routes from extensions $subdir = 'application/config/extensions'; $dirlist = scandir($subdir); diff --git a/application/controllers/components/stv/Verband.php b/application/controllers/components/stv/Verband.php index 42efe1e4c..f08419328 100644 --- a/application/controllers/components/stv/Verband.php +++ b/application/controllers/components/stv/Verband.php @@ -67,6 +67,7 @@ class Verband extends FHC_Controller $this->StudiengangModel->addSelect('erhalter_kz'); $this->StudiengangModel->addSelect('typ'); $this->StudiengangModel->addSelect('kurzbz'); + $this->StudiengangModel->addSelect('studiengang_kz'); $this->StudiengangModel->addOrder('erhalter_kz'); $this->StudiengangModel->addOrder('typ'); diff --git a/application/controllers/public/Primevue.php b/application/controllers/public/Primevue.php new file mode 100644 index 000000000..a1ae40692 --- /dev/null +++ b/application/controllers/public/Primevue.php @@ -0,0 +1,46 @@ +output->set_content_type('text/javascript'); + $this->output->set_output($contents); + } +} diff --git a/application/views/Studentenverwaltung.php b/application/views/Studentenverwaltung.php index 50a8ed3c4..157c50466 100644 --- a/application/views/Studentenverwaltung.php +++ b/application/views/Studentenverwaltung.php @@ -5,7 +5,7 @@ 'bootstrap5' => true, 'fontawesome6' => true, 'vue3' => true, - 'primevue3' => true, + #'primevue3' => true, 'filtercomponent' => true, 'tabulator5' => true, 'phrases' => [], @@ -14,7 +14,8 @@ 'public/css/components/vue-datepicker.css' ], 'customJSs' => [ - 'vendor/npm-asset/primevue/toast/toast.min.js' + #'vendor/npm-asset/primevue/tree/tree.min.js', + #'vendor/npm-asset/primevue/toast/toast.min.js' ], 'customJSModules' => [ 'public/js/apps/Studentenverwaltung.js' @@ -28,6 +29,7 @@ tr > td { display: flex; padding-top: .25rem!important; @@ -51,6 +65,15 @@ flex: 1 1 auto; } + +.stv-verband.p-tree { + /*overflow: auto;*/ +} +.stv-verband.p-tree .p-treenode-icon { + display: none; +} + + .stv-list { display: flex; flex-direction: column; diff --git a/public/js/apps/Studentenverwaltung.js b/public/js/apps/Studentenverwaltung.js index 2b6cc4c46..c676011c3 100644 --- a/public/js/apps/Studentenverwaltung.js +++ b/public/js/apps/Studentenverwaltung.js @@ -18,6 +18,8 @@ import FhcStudentenverwaltung from "../components/Stv/Studentenverwaltung.js"; import fhcapifactory from "./api/fhcapifactory.js"; +import PvConfig from "../../../index.ci.php/public/js/components/primevue/config/config.esm.min.js"; + Vue.$fhcapi = fhcapifactory; const ciPath = FHC_JS_DATA_STORAGE_OBJECT.app_root.replace(/(https:|)(^|\/\/)(.*?\/)/g, '') + FHC_JS_DATA_STORAGE_OBJECT.ci_router; @@ -35,6 +37,7 @@ const app = Vue.createApp(); app .use(router) - .use(primevue.config.default) + .use(PvConfig) + .use(ErrorHandling) .mount('#main'); diff --git a/public/js/components/Stv/Studentenverwaltung.js b/public/js/components/Stv/Studentenverwaltung.js index 45fef2e1f..0d1556f45 100644 --- a/public/js/components/Stv/Studentenverwaltung.js +++ b/public/js/components/Stv/Studentenverwaltung.js @@ -36,6 +36,7 @@ export default { defaultSemester: String, config: Object, permissions: Object, + stvRoot: String, cisRoot: String, activeAddons: String // semicolon separated list of active addons }, @@ -107,7 +108,7 @@ export default { }, template: ` diff --git a/public/js/components/Stv/Studentenverwaltung/Details/Details.js b/public/js/components/Stv/Studentenverwaltung/Details/Details.js index dc4edf1ab..ef36aebaf 100644 --- a/public/js/components/Stv/Studentenverwaltung/Details/Details.js +++ b/public/js/components/Stv/Studentenverwaltung/Details/Details.js @@ -2,11 +2,15 @@ import VueDatePicker from '../../../vueDatepicker.js.php'; import FormUploadImage from '../../../Form/Upload/Image.js'; import {CoreRESTClient} from '../../../../RESTClient.js'; + +import PvToast from "../../../../../../index.ci.php/public/js/components/primevue/toast/toast.esm.min.js"; + + export default { components: { VueDatePicker, FormUploadImage, - PvToast: primevue.toast + PvToast }, inject: { showBpk: { diff --git a/public/js/components/Stv/Studentenverwaltung/Verband.js b/public/js/components/Stv/Studentenverwaltung/Verband.js index b670d0875..3220f78dc 100644 --- a/public/js/components/Stv/Studentenverwaltung/Verband.js +++ b/public/js/components/Stv/Studentenverwaltung/Verband.js @@ -1,16 +1,25 @@ import {CoreRESTClient} from '../../../RESTClient.js'; + +import PvTree from "../../../../../index.ci.php/public/js/components/primevue/tree/tree.esm.min.js"; +import PvTreetable from "../../../../../index.ci.php/public/js/components/primevue/treetable/treetable.esm.min.js"; +import PvColumn from "../../../../../index.ci.php/public/js/components/primevue/column/column.esm.min.js"; + + export default { components: { - TreeTable: primevue.treetable, - TreeColumn: primevue.column + PvTree, + PvTreetable, + PvColumn }, emits: [ 'selectVerband' ], data() { return { + debug_version: 1, // NOTE(chris): switch between tree/treetable and filter/favorites... loading: true, + selected: {}, // NOTE(chris): tree only nodes: [] } }, @@ -18,6 +27,12 @@ export default { onExpandTreeNode(node) { if (!node.children) { if (node.data.link) { + let activeEl = null; + this.$nextTick(() => { + this.$nextTick(() => { + activeEl = document.activeElement; + }); + }); this.loading = true; CoreRESTClient .get("components/stv/verband/" + node.data.link) @@ -25,6 +40,21 @@ export default { .then(result => { const subNodes = result.map(this.mapResultToTreeData); node.children = subNodes; + + let treeitem = this.$refs.tree.$el.querySelector('[data-tree-item-key="' + node.key + '"]'); + if (!this.debug_version) // NOTE(chris): tree only + treeitem = treeitem.closest('[role="treeitem"]'); + else // NOTE(chris): treetable only + treeitem = treeitem.closest('[role="row"]'); + + this.$nextTick(() => { + if (activeEl == document.activeElement) + treeitem.dispatchEvent(new KeyboardEvent('keydown', { + code: 'ArrowDown', + key: 'ArrowDown' + })); + }); + this.loading = false; }) .catch(error => { @@ -40,7 +70,8 @@ export default { mapResultToTreeData(el) { const cp = { key: ("" + el.link).replace('/', '-'), - data: el + data: el, + label: el.name }; if (el.children) @@ -49,6 +80,15 @@ export default { cp.leaf = el.leaf || false; return cp; + }, + onFilterKeydown(data) { + // NOTE(chris): tree only + // TODO(chris): we can online search here + }, + markFav(key) { + // NOTE(chris): treetable only + // TODO(chris): IMPLEMENT + // TODO(chris): make clickable with keyboard } }, mounted() { @@ -64,7 +104,48 @@ export default { }); }, template: ` - - - ` +
+ + + +
+
+ + + + + + + + +
` }; \ No newline at end of file