diff --git a/application/controllers/api/frontend/v1/stv/Favorites.php b/application/controllers/api/frontend/v1/stv/Favorites.php index b8fe6f3d7..ca8b62da6 100644 --- a/application/controllers/api/frontend/v1/stv/Favorites.php +++ b/application/controllers/api/frontend/v1/stv/Favorites.php @@ -35,8 +35,6 @@ class Favorites extends FHCAPI_Controller // Load models $this->load->model('system/Variable_model', 'VariableModel'); - - // TODO(chris): variable table might be to small to store favorites! } public function index() @@ -62,6 +60,17 @@ class Favorites extends FHCAPI_Controller $favorites = $this->input->post('favorites'); + $removed = []; + while (strlen($favorites) > 64) { + $favObj = json_decode($favorites); + if (!$favObj->list) + break; + $removed[] = array_shift($favObj->list); + $favorites = json_encode($favObj); + } + if ($removed) + $this->addMeta('removed', $removed); + $result = $this->VariableModel->setVariable(getAuthUID(), 'stv_favorites', $favorites); $this->getDataOrTerminateWithError($result); diff --git a/public/js/components/Stv/Studentenverwaltung/Verband.js b/public/js/components/Stv/Studentenverwaltung/Verband.js index 8ae2b6b40..762d92858 100644 --- a/public/js/components/Stv/Studentenverwaltung/Verband.js +++ b/public/js/components/Stv/Studentenverwaltung/Verband.js @@ -1,17 +1,9 @@ -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"; - import ApiStvVerband from '../../../api/factory/stv/verband.js'; export default { components: { - PvTree, - PvTreetable, - PvColumn + PvTreetable: primevue.treetable, + PvColumn: primevue.column }, emits: [ 'selectVerband' @@ -22,14 +14,15 @@ export default { nodes: [], selectedKey: [], filters: {}, // TODO(chris): filter only 1st level? - favnodes: [], favorites: {on: false, list: []} } }, computed: { filteredNodes() { - // TODO(chris): what to display actually? - return this.favorites.on ? this.favnodes : this.nodes; + if (this.favorites.on) + return this.nodes.filter(node => this.favorites.list.includes(node.key)); + + return this.nodes; } }, methods: { @@ -102,69 +95,49 @@ export default { return cp; }, async filterFav() { - if (!this.favorites.on && !this.favnodes.length && this.favorites.list.length) { - this.loading = true; - this.favnodes = await this.loadNodes(this.favorites.list); - } this.favorites.on = !this.favorites.on; this.$api .call(ApiStvVerband.favorites.set( JSON.stringify(this.favorites) - )); - this.loading = false; - }, - async loadNodes(links) { - let sortedInParents = links.reduce((o, link) => { - link = link + ''; - let parent, - parts = link.split('/'); - if (parts.length == 1) { - parent = '_'; - } else { - parts.pop(); - parent = parts.join('/'); - } - if (!o[parent]) - o[parent] = [link]; - else - o[parent].push(link); - return o; - }, {}); - - let promises = []; - for (let parent in sortedInParents) - promises.push( - this.$api - .call(ApiStvVerband.get(parent == '_' ? '' : parent)) - .then(res => res.data) - .then(res => res.filter(node => sortedInParents[parent].includes(node.link + ''))) - ); - - // NOTE(chris): merge the resulting arrays and transform them to an associative one - let result = [].concat.apply([], await Promise.all(promises)).reduce((o, node) => { - o[node.link + ''] = this.mapResultToTreeData({...node, leaf: true, children: undefined}); - return o; - }, {}); - - return links.map(link => result[link]); + )) + .then(result => { + if (result.meta?.removed) { + this.favorites.list = this.favorites.list + .filter(fav => !result.meta.removed.includes(fav)); + const items = result.meta.removed.map( + rem => this.nodes.find( + node => node.data.link == rem + ).label + ).join(',\n'); + this.$fhcAlert.alertWarning(this.$p.t('stv/warn_removed_favs', { items })); + } + }); }, async markFav(key) { let index = this.favorites.list.indexOf(key.data.link + ''); if (index != -1) { - if (this.favnodes.length) - this.favnodes = this.favnodes.filter(node => node.data.link != key.data.link); this.favorites.list.splice(index, 1); } else { - if (this.favnodes.length || this.favorites.on) - this.favnodes.push((await this.loadNodes([key.data.link])).pop()); this.favorites.list.push(key.data.link + ''); } this.$api .call(ApiStvVerband.favorites.set( JSON.stringify(this.favorites) - )); + )) + .then(result => { + if (result.meta?.removed) { + this.favorites.list = this.favorites.list + .filter(fav => !result.meta.removed.includes(fav)); + const items = "\n" + result.meta.removed.map( + rem => this.nodes.find( + node => node.data.link == rem + ).label + ).join(",\n"); + this.$fhcAlert.alertWarning(this.$p.t('stv/warn_removed_favs', { items })); + } + }); }, unsetFavFocus(e) { if (e.target.dataset?.linkFavAdd !== undefined) { @@ -187,7 +160,10 @@ export default { this.$api .call(ApiStvVerband.get()) .then(result => { - this.nodes = result.data.map(this.mapResultToTreeData); + this.nodes = result.data.map(el => { + el.root = true; + return this.mapResultToTreeData(el); + }); this.loading = false; }) .catch(this.$fhcAlert.handleSystemError); @@ -196,21 +172,12 @@ export default { .call(ApiStvVerband.favorites.get()) .then(result => { if (result.data) { - let f = JSON.parse(result.data); - if (f.on) { - this.loading = true; - this.favorites = f; - this.loadNodes(this.favorites.list).then(res => { - this.favnodes = res; - this.loading = false; - }); - } else - this.favorites = f; + this.favorites = JSON.parse(result.data); } }) .catch(this.$fhcAlert.handleSystemError); }, - template: ` + template: /* html */`
+ - -