#238 [admin] optimise the list of users, pagination and all

This commit is contained in:
Avris 2021-11-26 17:08:10 +01:00
parent 846ddfeea0
commit b9a9524f1d
2 changed files with 43 additions and 37 deletions

View File

@ -48,8 +48,7 @@
<template v-slot:row="s"> <template v-slot:row="s">
<td> <td>
<Avatar :user="s.el" dsize="2rem"/> <a :href="'https://pronouns.page/@ + s.el.username'">@{{s.el.username}}</a>
{{s.el.username}}
</td> </td>
<td> <td>
<p> <p>
@ -57,11 +56,13 @@
{{s.el.email}} {{s.el.email}}
</a> </a>
</p> </p>
<!--
<ul v-if="s.el.socialConnections.length" class="list-inline"> <ul v-if="s.el.socialConnections.length" class="list-inline">
<li v-for="conn in s.el.socialConnections" class="list-inline-item"> <li v-for="conn in s.el.socialConnections" class="list-inline-item">
<Icon :v="socialProviders[conn].icon || conn" set="b"/> <Icon :v="socialProviders[conn].icon || conn" set="b"/>
</li> </li>
</ul> </ul>
-->
</td> </td>
<td> <td>
<Roles :user="s.el"/> <Roles :user="s.el"/>
@ -201,9 +202,12 @@
return { return {
socialProviders, socialProviders,
userFilter: '', userFilter: '',
userFilterDelayed: '',
userFilterDelayHandle: undefined,
localeFilter: true, localeFilter: true,
adminsFilter: false, adminsFilter: false,
users: undefined, users: undefined,
visibleUsers: [],
} }
}, },
async asyncData({ app, store }) { async asyncData({ app, store }) {
@ -225,7 +229,10 @@
methods: { methods: {
async loadUsers() { async loadUsers() {
if (this.users === undefined) { if (this.users === undefined) {
this.users = await this.$axios.$get(`/admin/users`); this.users = (await this.$axios.$get(`/admin/users`)).map(u => {
u.profiles = u.profiles ? u.profiles.split(',') : [];
return u;
});
} }
}, },
async handleReport(id) { async handleReport(id) {
@ -236,18 +243,18 @@
return r; return r;
}); });
}, },
}, calcVisibleUsers() {
computed: {
visibleUsers() {
if (this.users === undefined) { if (this.users === undefined) {
return []; return [];
} }
return Object.values(this.users).filter(u => return this.users.filter(u =>
u.username.toLowerCase().includes(this.userFilter.toLowerCase()) u.username.toLowerCase().includes(this.userFilterDelayed.toLowerCase())
&& (!this.adminsFilter || u.roles !== '') && (!this.adminsFilter || u.roles !== '')
&& (!this.localeFilter || u.profiles.includes(this.config.locale)) && (!this.localeFilter || u.profiles.includes(this.config.locale))
); );
}, },
},
computed: {
profilesByLocale() { profilesByLocale() {
const r = {}; const r = {};
for (let locale of Object.values(this.stats.locales).sort((a, b) => b.profiles - a.profiles)) { for (let locale of Object.values(this.stats.locales).sort((a, b) => b.profiles - a.profiles)) {
@ -256,6 +263,29 @@
return r; return r;
}, },
}, },
watch: {
userFilter() {
if (this.userFilterDelayHandle !== undefined) {
clearInterval(this.userFilterDelayHandle);
}
this.userFilterDelayHandle = setTimeout(() => {
this.userFilterDelayed = this.userFilter;
}, 500);
},
userFilterDelayed() {
this.visibleUsers = this.calcVisibleUsers();
},
localeFilter() {
this.visibleUsers = this.calcVisibleUsers();
},
adminsFilter() {
this.visibleUsers = this.calcVisibleUsers();
},
users() {
this.visibleUsers = this.calcVisibleUsers();
},
},
head() { head() {
return head({ return head({
title: this.$t('admin.header'), title: this.$t('admin.header'),

View File

@ -74,38 +74,14 @@ router.get('/admin/users', handleErrorAsync(async (req, res) => {
} }
const users = await req.db.all(SQL` const users = await req.db.all(SQL`
SELECT u.id, u.username, u.email, u.roles, u.avatarSource, p.locale SELECT u.id, u.username, u.email, u.roles, u.avatarSource, group_concat(p.locale) AS profiles
FROM users u FROM users u
LEFT JOIN profiles p ON p.userId = u.id LEFT JOIN profiles p ON p.userId = u.id
GROUP BY u.id
ORDER BY u.id DESC ORDER BY u.id DESC
`); `);
const authenticators = await req.db.all(SQL` return res.json(users);
SELECT userId, type FROM authenticators
WHERE type IN (`.append(Object.keys(socialLoginConfig).map(k => `'${k}'`).join(',')).append(SQL`)
AND (validUntil IS NULL OR validUntil > ${now()})
`));
const groupedUsers = {};
for (let user of users) {
if (groupedUsers[user.id] === undefined) {
groupedUsers[user.id] = {
...user,
locale: undefined,
profiles: user.locale ? [user.locale] : [],
avatar: await avatar(req.db, user),
socialConnections: [],
}
} else {
groupedUsers[user.id].profiles.push(user.locale);
}
}
for (let auth of authenticators) {
groupedUsers[auth.userId].socialConnections.push(auth.type);
}
return res.json(groupedUsers);
})); }));
router.get('/admin/stats', handleErrorAsync(async (req, res) => { router.get('/admin/stats', handleErrorAsync(async (req, res) => {