#238 [admin] optimise the list of users, pagination and all
This commit is contained in:
parent
846ddfeea0
commit
b9a9524f1d
|
@ -48,8 +48,7 @@
|
|||
|
||||
<template v-slot:row="s">
|
||||
<td>
|
||||
<Avatar :user="s.el" dsize="2rem"/>
|
||||
{{s.el.username}}
|
||||
<a :href="'https://pronouns.page/@ + s.el.username'">@{{s.el.username}}</a>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
|
@ -57,11 +56,13 @@
|
|||
{{s.el.email}}
|
||||
</a>
|
||||
</p>
|
||||
<!--
|
||||
<ul v-if="s.el.socialConnections.length" class="list-inline">
|
||||
<li v-for="conn in s.el.socialConnections" class="list-inline-item">
|
||||
<Icon :v="socialProviders[conn].icon || conn" set="b"/>
|
||||
</li>
|
||||
</ul>
|
||||
-->
|
||||
</td>
|
||||
<td>
|
||||
<Roles :user="s.el"/>
|
||||
|
@ -201,9 +202,12 @@
|
|||
return {
|
||||
socialProviders,
|
||||
userFilter: '',
|
||||
userFilterDelayed: '',
|
||||
userFilterDelayHandle: undefined,
|
||||
localeFilter: true,
|
||||
adminsFilter: false,
|
||||
users: undefined,
|
||||
visibleUsers: [],
|
||||
}
|
||||
},
|
||||
async asyncData({ app, store }) {
|
||||
|
@ -225,7 +229,10 @@
|
|||
methods: {
|
||||
async loadUsers() {
|
||||
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) {
|
||||
|
@ -236,18 +243,18 @@
|
|||
return r;
|
||||
});
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
visibleUsers() {
|
||||
calcVisibleUsers() {
|
||||
if (this.users === undefined) {
|
||||
return [];
|
||||
}
|
||||
return Object.values(this.users).filter(u =>
|
||||
u.username.toLowerCase().includes(this.userFilter.toLowerCase())
|
||||
&& (!this.adminsFilter || u.roles !== '')
|
||||
&& (!this.localeFilter || u.profiles.includes(this.config.locale))
|
||||
return this.users.filter(u =>
|
||||
u.username.toLowerCase().includes(this.userFilterDelayed.toLowerCase())
|
||||
&& (!this.adminsFilter || u.roles !== '')
|
||||
&& (!this.localeFilter || u.profiles.includes(this.config.locale))
|
||||
);
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
profilesByLocale() {
|
||||
const r = {};
|
||||
for (let locale of Object.values(this.stats.locales).sort((a, b) => b.profiles - a.profiles)) {
|
||||
|
@ -256,6 +263,29 @@
|
|||
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() {
|
||||
return head({
|
||||
title: this.$t('admin.header'),
|
||||
|
|
|
@ -74,38 +74,14 @@ router.get('/admin/users', handleErrorAsync(async (req, res) => {
|
|||
}
|
||||
|
||||
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
|
||||
LEFT JOIN profiles p ON p.userId = u.id
|
||||
GROUP BY u.id
|
||||
ORDER BY u.id DESC
|
||||
`);
|
||||
|
||||
const authenticators = await req.db.all(SQL`
|
||||
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);
|
||||
return res.json(users);
|
||||
}));
|
||||
|
||||
router.get('/admin/stats', handleErrorAsync(async (req, res) => {
|
||||
|
|
Reference in New Issue