diff --git a/application/controllers/components/stv/Favorites.php b/application/controllers/components/stv/Favorites.php new file mode 100644 index 000000000..9d70f0b29 --- /dev/null +++ b/application/controllers/components/stv/Favorites.php @@ -0,0 +1,57 @@ +load->model('system/Variable_model', 'VariableModel'); + + // Load libraries + $this->load->library('AuthLib'); + + // TODO(chris): variable table might be to small to store favorites! + } + + public function index() + { + $result = $this->VariableModel->getVariables(getAuthUID(), ['stv_favorites']); + + if (isError($result)) { + $this->output->set_status_header(REST_Controller::HTTP_INTERNAL_SERVER_ERROR); + return $this->outputJson(getError($result)); + } + + $this->outputJson(getData($result)['stv_favorites']); + } + + public function set() + { + $_POST = json_decode(utf8_encode($this->input->raw_input_stream), true); + + $this->load->library('form_validation'); + + $this->form_validation->set_rules('favorites', 'Favorites', 'required'); + + if ($this->form_validation->run() == false) { + $this->output->set_status_header(REST_Controller::HTTP_BAD_REQUEST); + return $this->outputJson($this->form_validation->error_array()); + } + + $favorites = $this->input->post('favorites'); + + $result = $this->VariableModel->setVariable(getAuthUID(), 'stv_favorites', $favorites); + + if (isError($result)) { + $this->output->set_status_header(REST_Controller::HTTP_INTERNAL_SERVER_ERROR); + return $this->outputJson(getError($result)); + } + + $this->outputJsonSuccess(true); + } +} diff --git a/public/js/components/Stv/Studentenverwaltung/Verband.js b/public/js/components/Stv/Studentenverwaltung/Verband.js index 3220f78dc..8ad3bebdb 100644 --- a/public/js/components/Stv/Studentenverwaltung/Verband.js +++ b/public/js/components/Stv/Studentenverwaltung/Verband.js @@ -20,7 +20,15 @@ export default { debug_version: 1, // NOTE(chris): switch between tree/treetable and filter/favorites... loading: true, selected: {}, // NOTE(chris): tree only - nodes: [] + nodes: [], + favnodes: [], + favorites: {on: false, list: []} + } + }, + computed: { + filteredNodes() { + // TODO(chris): what to display actually? + return this.favorites.on ? this.favnodes : this.nodes; } }, methods: { @@ -85,9 +93,62 @@ export default { // NOTE(chris): tree only // TODO(chris): we can online search here }, - markFav(key) { + async filterFav() { // NOTE(chris): treetable only - // TODO(chris): IMPLEMENT + 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; + CoreRESTClient.post("components/stv/favorites/set", {favorites: JSON.stringify(this.favorites)}); + this.loading = false; + }, + async loadNodes(links) { + // NOTE(chris): treetable only + 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(CoreRESTClient.get("components/stv/verband/" + (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]); + }, + async markFav(key) { + // NOTE(chris): treetable only + 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 + ''); + } + + CoreRESTClient.post("components/stv/favorites/set", {favorites: JSON.stringify(this.favorites)}); // TODO(chris): make clickable with keyboard } }, @@ -102,6 +163,29 @@ export default { .catch(error => { console.error(error); }); + // NOTE(chris): treetable only + if (this.debug_version) + CoreRESTClient + .get("components/stv/favorites") + .then(result => result.data) + .then(result => { + if (result) { + let f = JSON.parse(result); + console.log(f); + 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; + } + }) + .catch(error => { + console.error(error); + }); }, template: `