feat: admin users search + pagination

pull/7004/head
NGPixel 9 months ago
parent da9d252948
commit 81e0a67f68
No known key found for this signature in database
GPG Key ID: B755FB6870B30F63

@ -28,7 +28,8 @@ export default {
} }
// -> Fetch Users // -> Fetch Users
return WIKI.db.users.query() const total = await WIKI.db.users.query().count('id').first()
const users = await WIKI.db.users.query()
.select('id', 'email', 'name', 'isSystem', 'isActive', 'createdAt', 'lastLoginAt') .select('id', 'email', 'name', 'isSystem', 'isActive', 'createdAt', 'lastLoginAt')
.where(builder => { .where(builder => {
if (args.filter) { if (args.filter) {
@ -39,6 +40,11 @@ export default {
.orderBy(args.orderBy ?? 'name', args.orderByDirection ?? 'asc') .orderBy(args.orderBy ?? 'name', args.orderByDirection ?? 'asc')
.offset((offset - 1) * limit) .offset((offset - 1) * limit)
.limit(limit) .limit(limit)
return {
users,
total: total.count
}
}, },
/** /**
* FETCH A SINGLE USER * FETCH A SINGLE USER

@ -10,7 +10,7 @@ extend type Query {
orderByDirection: OrderByDirection orderByDirection: OrderByDirection
# Filter by name / email # Filter by name / email
filter: String filter: String
): [UserMinimal] ): UserResults
userById( userById(
id: UUID! id: UUID!
@ -122,6 +122,11 @@ type UserLastLogin {
lastLoginAt: Date lastLoginAt: Date
} }
type UserResults {
users: [UserMinimal]
total: Int
}
type UserMinimal { type UserMinimal {
id: UUID id: UUID
name: String name: String

@ -64,13 +64,13 @@ q-page.admin-groups
:rows-per-page-options='[0]' :rows-per-page-options='[0]'
:loading='state.loading > 0' :loading='state.loading > 0'
) )
template(v-slot:body-cell-id='props') template(#body-cell-id='props')
q-td(:props='props') q-td(:props='props')
q-icon(name='las la-user', color='primary', size='sm') q-icon(name='las la-user', color='primary', size='sm')
template(v-slot:body-cell-name='props') template(#body-cell-name='props')
q-td(:props='props') q-td(:props='props')
.flex.items-center .flex.items-center
strong {{props.value}} strong {{ props.value }}
q-icon.q-ml-sm( q-icon.q-ml-sm(
v-if='props.row.isSystem' v-if='props.row.isSystem'
name='las la-lock' name='las la-lock'
@ -81,10 +81,10 @@ q-page.admin-groups
name='las la-ban' name='las la-ban'
color='pink' color='pink'
) )
template(v-slot:body-cell-email='props') template(#body-cell-email='props')
q-td(:props='props') q-td(:props='props')
em {{ props.value }} em {{ props.value }}
template(v-slot:body-cell-date='props') template(#body-cell-date='props')
q-td(:props='props') q-td(:props='props')
i18n-t.text-caption(keypath='admin.users.createdAt', tag='div') i18n-t.text-caption(keypath='admin.users.createdAt', tag='div')
template(#date) template(#date)
@ -96,7 +96,7 @@ q-page.admin-groups
) )
template(#date) template(#date)
strong {{ humanizeDate(props.row.lastLoginAt) }} strong {{ humanizeDate(props.row.lastLoginAt) }}
template(v-slot:body-cell-edit='props') template(#body-cell-edit='props')
q-td(:props='props') q-td(:props='props')
q-btn.acrylic-btn.q-mr-sm( q-btn.acrylic-btn.q-mr-sm(
v-if='!props.row.isSystem' v-if='!props.row.isSystem'
@ -114,11 +114,19 @@ q-page.admin-groups
color='negative' color='negative'
@click='deleteUser(props.row)' @click='deleteUser(props.row)'
) )
.flex.flex-center.q-mt-lg(v-if='state.totalPages > 1')
q-pagination(
v-model='state.currentPage'
:max='state.totalPages'
:max-pages='9'
boundary-numbers
direction-links
)
</template> </template>
<script setup> <script setup>
import gql from 'graphql-tag' import gql from 'graphql-tag'
import { cloneDeep } from 'lodash-es' import { cloneDeep, debounce } from 'lodash-es'
import { DateTime } from 'luxon' import { DateTime } from 'luxon'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import { useMeta, useQuasar } from 'quasar' import { useMeta, useQuasar } from 'quasar'
@ -162,7 +170,10 @@ useMeta({
const state = reactive({ const state = reactive({
users: [], users: [],
loading: 0, loading: 0,
search: '' search: '',
currentPage: 1,
pageSize: 20,
totalPages: 15
}) })
const headers = [ const headers = [
@ -214,28 +225,52 @@ watch(() => adminStore.overlay, (newValue, oldValue) => {
watch(() => route.params.id, checkOverlay) watch(() => route.params.id, checkOverlay)
watch(() => state.search, debounce(() => {
load({ page: 1 })
}, 400))
watch(() => state.currentPage, (newValue) => {
load({ page: newValue })
})
// METHODS // METHODS
async function load () { async function load ({ page } = {}) {
state.loading++ state.loading++
$q.loading.show() $q.loading.show()
const resp = await APOLLO_CLIENT.query({ const resp = await APOLLO_CLIENT.query({
query: gql` query: gql`
query getUsers { query getUsers(
users { $page: Int
id $pageSize: Int
name $filter: String
email ) {
isSystem users(
isActive page: $page
createdAt pageSize: $pageSize
lastLoginAt filter: $filter
) {
total
users {
id
name
email
isSystem
isActive
createdAt
lastLoginAt
}
} }
} }
`, `,
fetchPolicy: 'network-only' fetchPolicy: 'network-only',
variables: {
page: page ?? state.currentPage ?? 1,
pageSize: state.pageSize ?? 20,
filter: state.search ?? ''
}
}) })
state.users = cloneDeep(resp?.data?.users) state.totalPages = Math.ceil((resp?.data?.users?.total || 1) / state.pageSize)
state.users = cloneDeep(resp?.data?.users?.users)
$q.loading.hide() $q.loading.hide()
state.loading-- state.loading--
} }
@ -281,7 +316,7 @@ function deleteUser (usr) {
onMounted(() => { onMounted(() => {
checkOverlay() checkOverlay()
load() load({ page: 1 })
}) })
// BEFORE UNMOUNT // BEFORE UNMOUNT

Loading…
Cancel
Save