mirror of
https://github.com/FH-Complete/FHC-Core.git
synced 2026-06-12 01:29:28 +00:00
reworked StV favorites (only 1st tier version)
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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 */`
|
||||
<div class="overflow-auto" tabindex="-1">
|
||||
<pv-treetable
|
||||
ref="tree"
|
||||
@@ -225,35 +192,64 @@ export default {
|
||||
@focusin="setFavFocus"
|
||||
@focusout="unsetFavFocus"
|
||||
:filters="filters"
|
||||
>
|
||||
<pv-column
|
||||
field="name"
|
||||
expander
|
||||
class="text-break"
|
||||
>
|
||||
<pv-column field="name" expander>
|
||||
<template #header>
|
||||
<div class="text-right">
|
||||
<div class="p-input-icon-left">
|
||||
<i class="pi pi-search"></i>
|
||||
<input type="text" v-model="filters['global']" class="form-control ps-5" placeholder="Search" />
|
||||
<input
|
||||
type="text"
|
||||
v-model="filters['global']"
|
||||
class="form-control ps-5"
|
||||
placeholder="Search"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #body="{node}">
|
||||
<span :data-tree-item-key="node.key" :title="node.data.studiengang_kz">
|
||||
<template #body="{ node }">
|
||||
<span
|
||||
:data-tree-item-key="node.key"
|
||||
:title="node.data.studiengang_kz"
|
||||
>
|
||||
{{node.data.name}}
|
||||
</span>
|
||||
</template>
|
||||
</pv-column>
|
||||
<pv-column field="fav" headerStyle="flex: 0 0 auto" style="flex: 0 0 auto">
|
||||
<pv-column
|
||||
field="fav"
|
||||
class="flex-shrink-0 flex-grow-0"
|
||||
header-class="flex-shrink-0 flex-grow-0"
|
||||
>
|
||||
<template #header>
|
||||
<a href="#" @click.prevent="filterFav"><i :class="favorites.on ? 'fa-solid' : 'fa-regular'" class="fa-star"></i></a>
|
||||
</template>
|
||||
<template #body="{node, column}">
|
||||
<a
|
||||
v-if="favorites.on || favorites.list.length"
|
||||
href="#"
|
||||
@click.prevent="filterFav"
|
||||
>
|
||||
<i
|
||||
:class="favorites.on ? 'fa-solid' : 'fa-regular'"
|
||||
class="fa-star"
|
||||
></i>
|
||||
</a>
|
||||
</template>
|
||||
<template #body="{ node }">
|
||||
<a
|
||||
v-if="node.data.root"
|
||||
href="#"
|
||||
@click.prevent="markFav(node)"
|
||||
@keydown.enter.stop.prevent="markFav(node)"
|
||||
tabindex="-1"
|
||||
data-link-fav-add
|
||||
>
|
||||
<i :class="favorites.list.includes(node.data.link + '') ? 'fa-solid' : 'fa-regular'" class="fa-star"></i>
|
||||
@click.prevent="markFav(node)"
|
||||
@keydown.enter.stop.prevent="markFav(node)"
|
||||
>
|
||||
<i
|
||||
:class="favorites.list.includes(node.data.link + '') ? 'fa-solid' : 'fa-regular'"
|
||||
class="fa-star"
|
||||
></i>
|
||||
</a>
|
||||
</template>
|
||||
</pv-column>
|
||||
|
||||
@@ -36650,6 +36650,26 @@ array(
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'stv',
|
||||
'phrase' => 'warn_removed_favs',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'Zu viele Favoriten! Die folgenden Einträge wurden entfernt: {items}',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => 'Too many favorites! The following entries were removed: {items}',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'stv',
|
||||
|
||||
Reference in New Issue
Block a user