feat: admin dashboard last logins

This commit is contained in:
NGPixel 2020-04-13 15:54:10 -04:00 committed by Nicolas Giard
parent 514d31a46d
commit 9a93ac28f2
5 changed files with 75 additions and 43 deletions

View File

@ -60,7 +60,7 @@
v-spacer v-spacer
v-data-table.pb-2( v-data-table.pb-2(
:items='recentPages' :items='recentPages'
:headers='headers' :headers='recentPagesHeaders'
:loading='recentPagesLoading' :loading='recentPagesLoading'
hide-default-footer hide-default-footer
hide-default-header hide-default-header
@ -77,23 +77,20 @@
v-card.radius-7.animated.fadeInUp.wait-p4s v-card.radius-7.animated.fadeInUp.wait-p4s
v-toolbar(:color='$vuetify.theme.dark ? `grey darken-2` : `grey lighten-5`', dense, flat) v-toolbar(:color='$vuetify.theme.dark ? `grey darken-2` : `grey lighten-5`', dense, flat)
v-spacer v-spacer
.overline {{$t('admin:dashboard.mostPopularPages')}} .overline {{$t('admin:dashboard.lastLogins')}}
v-spacer v-spacer
v-data-table.pb-2( v-data-table.pb-2(
:items='popularPages' :items='lastLogins'
:headers='headers' :headers='lastLoginsHeaders'
:loading='popularPagesLoading' :loading='lastLoginsLoading'
hide-default-footer hide-default-footer
hide-default-header hide-default-header
) )
template(slot='item', slot-scope='props') template(slot='item', slot-scope='props')
tr.is-clickable(:active='props.selected', @click='$router.push(`/pages/` + props.item.id)') tr.is-clickable(:active='props.selected', @click='$router.push(`/users/` + props.item.id)')
td td
.body-2: strong {{ props.item.title }} .body-2: strong {{ props.item.name }}
td.admin-pages-path td.text-right.caption(width='250') {{ props.item.lastLoginAt | moment('calendar') }}
v-chip(label, small, :color='$vuetify.theme.dark ? `grey darken-4` : `grey lighten-4`') {{ props.item.locale }}
span.ml-2.grey--text(:class='$vuetify.theme.dark ? `text--lighten-1` : `text--darken-2`') / {{ props.item.path }}
td.text-right.caption(width='250') {{ props.item.updatedAt | moment('calendar') }}
v-flex(xs12) v-flex(xs12)
v-card.dashboard-contribute.animated.fadeInUp.wait-p4s v-card.dashboard-contribute.animated.fadeInUp.wait-p4s
@ -112,8 +109,7 @@
import _ from 'lodash' import _ from 'lodash'
import AnimatedNumber from 'animated-number-vue' import AnimatedNumber from 'animated-number-vue'
import { get } from 'vuex-pathify' import { get } from 'vuex-pathify'
import gql from 'graphql-tag'
import recentPagesQuery from 'gql/admin/dashboard/dashboard-query-recentpages.gql'
export default { export default {
components: { components: {
@ -123,13 +119,16 @@ export default {
return { return {
recentPages: [], recentPages: [],
recentPagesLoading: false, recentPagesLoading: false,
popularPages: [], recentPagesHeaders: [
popularPagesLoading: false,
headers: [
{ text: 'ID', value: 'id', width: 80 },
{ text: 'Title', value: 'title' }, { text: 'Title', value: 'title' },
{ text: 'Path', value: 'path' }, { text: 'Path', value: 'path' },
{ text: 'Last Updated', value: 'updatedAt', width: 250 } { text: 'Last Updated', value: 'updatedAt', width: 250 }
],
lastLogins: [],
lastLoginsLoading: false,
lastLoginsHeaders: [
{ text: 'User', value: 'displayName' },
{ text: 'Last Login', value: 'lastLoginAt', width: 250 }
] ]
} }
}, },
@ -154,12 +153,49 @@ export default {
}, },
apollo: { apollo: {
recentPages: { recentPages: {
query: recentPagesQuery, query: gql`
query {
pages {
list(limit: 10, orderBy: UPDATED, orderByDirection: DESC) {
id
locale
path
title
description
contentType
isPublished
isPrivate
privateNS
createdAt
updatedAt
}
}
}
`,
update: (data) => data.pages.list, update: (data) => data.pages.list,
watchLoading (isLoading) { watchLoading (isLoading) {
this.recentPagesLoading = isLoading this.recentPagesLoading = isLoading
this.$store.commit(`loading${isLoading ? 'Start' : 'Stop'}`, 'admin-dashboard-recentpages') this.$store.commit(`loading${isLoading ? 'Start' : 'Stop'}`, 'admin-dashboard-recentpages')
} }
},
lastLogins: {
query: gql`
query {
users {
lastLogins {
id
name
lastLoginAt
}
}
}
`,
fetchPolicy: 'network-only',
update: (data) => data.users.lastLogins,
watchLoading (isLoading) {
this.lastLoginsLoading = isLoading
this.$store.commit(`loading${isLoading ? 'Start' : 'Stop'}`, 'admin-dashboard-lastlogins')
}
} }
} }
} }

View File

@ -1,17 +0,0 @@
query {
pages {
list(limit: 10, orderBy: UPDATED, orderByDirection: DESC) {
id
locale
path
title
description
contentType
isPublished
isPrivate
privateNS
createdAt
updatedAt
}
}
}

View File

@ -1,6 +1,6 @@
<template lang="pug"> <template lang="pug">
div div
.blue.darken-3.pa-3.d-flex .blue.darken-3.pa-3.d-flex(v-if='navMode === `MIXED`')
v-btn(depressed, color='blue darken-2', style='min-width:0;', href='/') v-btn(depressed, color='blue darken-2', style='min-width:0;', href='/')
v-icon(size='20') mdi-home v-icon(size='20') mdi-home
v-btn.ml-3(v-if='currentMode === `custom`', depressed, color='blue darken-2', style='flex: 1 1 100%;', @click='switchMode(`browse`)') v-btn.ml-3(v-if='currentMode === `custom`', depressed, color='blue darken-2', style='flex: 1 1 100%;', @click='switchMode(`browse`)')
@ -61,10 +61,6 @@ export default {
type: Array, type: Array,
default: () => [] default: () => []
}, },
mode: {
type: String,
default: 'browse'
},
navMode: { navMode: {
type: String, type: String,
default: 'MIXED' default: 'MIXED'
@ -72,7 +68,7 @@ export default {
}, },
data() { data() {
return { return {
currentMode: 'browse', currentMode: 'custom',
currentItems: [], currentItems: [],
currentParent: { currentParent: {
id: 0, id: 0,
@ -193,9 +189,11 @@ export default {
} }
}, },
mounted () { mounted () {
this.currentMode = this.mode if (this.navMode === 'TREE') {
if (this.mode === 'browse') { this.currentMode = 'browse'
this.loadFromCurrentPath() this.loadFromCurrentPath()
} else {
this.currentMode = 'custom'
} }
} }
} }

View File

@ -46,6 +46,13 @@ module.exports = {
usr.tfaSecret = '' usr.tfaSecret = ''
return usr return usr
},
async lastLogins (obj, args, context, info) {
return WIKI.models.users.query()
.select('id', 'name', 'lastLoginAt')
.whereNotNull('lastLoginAt')
.orderBy('lastLoginAt', 'desc')
.limit(10)
} }
}, },
UserMutation: { UserMutation: {

View File

@ -29,6 +29,8 @@ type UserQuery {
): User @auth(requires: ["manage:users", "manage:system"]) ): User @auth(requires: ["manage:users", "manage:system"])
profile: UserProfile profile: UserProfile
lastLogins: [UserLastLogin] @auth(requires: ["write:groups", "manage:groups", "write:users", "manage:users", "manage:system"])
} }
# ----------------------------------------------- # -----------------------------------------------
@ -99,6 +101,12 @@ type UserResponse {
user: User user: User
} }
type UserLastLogin {
id: Int!
name: String!
lastLoginAt: Date!
}
type UserMinimal { type UserMinimal {
id: Int! id: Int!
name: String! name: String!