Added StatsWidget

This commit is contained in:
Douglas Barone 2020-12-10 10:11:36 -04:00
parent 1cd561bd62
commit 3200b8624b
8 changed files with 165 additions and 21 deletions

View File

@ -2,6 +2,7 @@ import { replacePassword } from '../utils/activedirectory/passwordUtils'
import { User } from '../classes/User' import { User } from '../classes/User'
import { ResetToken } from '../classes/ResetToken' import { ResetToken } from '../classes/ResetToken'
import { updateDevicesInfo } from '../utils/wifiUtils'
import { updateUserIdMappings } from '../utils/paloalto' import { updateUserIdMappings } from '../utils/paloalto'
const Mutation = { const Mutation = {
@ -31,6 +32,10 @@ const Mutation = {
return 'A importação está sendo feita. Isso pode demorar alguns minutos.' return 'A importação está sendo feita. Isso pode demorar alguns minutos.'
}, },
async updateWifiDevices() {
return updateDevicesInfo()
},
async updateUserIdMappings() { async updateUserIdMappings() {
return updateUserIdMappings() return updateUserIdMappings()
} }

View File

@ -37,7 +37,10 @@ const Stats = {
totalUsers: async () => prisma.user.count(), totalUsers: async () => prisma.user.count(),
totalWifiDevices: async () => prisma.wifiDevice.count() totalWifiDevices: async () => prisma.wifiDevice.count(),
onlineWifiDevices: async () =>
prisma.wifiDevice.count({ where: { status: 'ONLINE' } })
} }
export { Stats } export { Stats }

View File

@ -43,6 +43,7 @@ const typeDefs = gql`
@auth(roles: ["superAdmin", "tokenCreator"]) @auth(roles: ["superAdmin", "tokenCreator"])
useResetToken(data: UseResetTokenInput!): Boolean! useResetToken(data: UseResetTokenInput!): Boolean!
importUsers: String! @auth(roles: ["superAdmin"]) importUsers: String! @auth(roles: ["superAdmin"])
updateWifiDevices: String! @auth(roles: ["superAdmin"])
updateUserIdMappings: String! @auth(roles: ["superAdmin"]) updateUserIdMappings: String! @auth(roles: ["superAdmin"])
} }
@ -149,6 +150,7 @@ const typeDefs = gql`
offlineUsers: Int! offlineUsers: Int!
totalUsers: Int! totalUsers: Int!
totalWifiDevices: Int! totalWifiDevices: Int!
onlineWifiDevices: Int!
} }
type WifiDevice { type WifiDevice {

View File

@ -0,0 +1,117 @@
<template>
<Widget
v-if="me && me.isSuperAdmin && stats"
title="Status"
widget-icon="mdi-counter"
>
<v-list two-line>
<v-list-item>
<v-list-item-avatar>
<v-icon>mdi-account-check</v-icon>
</v-list-item-avatar>
<v-list-item-content>
<v-list-item-title>
{{ stats.onlineUsers }}
</v-list-item-title>
<v-list-item-subtitle>
Usuários conectados à Wi-Fi agora
</v-list-item-subtitle>
</v-list-item-content>
</v-list-item>
<v-list-item>
<v-list-item-avatar>
<v-icon>mdi-wifi</v-icon>
</v-list-item-avatar>
<v-list-item-content>
<v-list-item-title>
{{ stats.offlineUsers }}
</v-list-item-title>
<v-list-item-subtitle>
Usuários usaram a rede Wi-Fi
</v-list-item-subtitle>
</v-list-item-content>
</v-list-item>
<v-list-item>
<v-list-item-avatar>
<v-icon>mdi-account-group</v-icon>
</v-list-item-avatar>
<v-list-item-content>
<v-list-item-title>
{{ stats.totalUsers }}
</v-list-item-title>
<v-list-item-subtitle>
Usuários ativos no Active Directory
</v-list-item-subtitle>
</v-list-item-content>
</v-list-item>
<v-list-item>
<v-list-item-avatar> <v-icon>mdi-devices</v-icon> </v-list-item-avatar>
<v-list-item-content>
<v-list-item-title>
{{ stats.onlineWifiDevices }}
</v-list-item-title>
<v-list-item-subtitle>
Dispositivos conectados à rede Wi-Fi
</v-list-item-subtitle>
</v-list-item-content>
</v-list-item>
<v-list-item>
<v-list-item-avatar> <v-icon>mdi-devices</v-icon> </v-list-item-avatar>
<v-list-item-content>
<v-list-item-title>
{{ stats.totalWifiDevices }}
</v-list-item-title>
<v-list-item-subtitle>
Dispositivos que se conectaram à rede Wi-Fi agora
</v-list-item-subtitle>
</v-list-item-content>
</v-list-item>
</v-list>
</Widget>
</template>
<script>
import Widget from './Widget'
import gql from 'graphql-tag'
export default {
name: 'StatsWidget',
components: { Widget },
apollo: {
$subscribe: {
userPresenceUpdated: {
query: gql`
subscription {
userPresenceUpdated
}
`,
result(data) {
this.$apollo.queries.stats.refresh()
}
}
},
me: gql`
query {
me {
sAMAccountName
isSuperAdmin
}
}
`,
stats: gql`
query {
stats {
onlineUsers
offlineUsers
totalUsers
onlineWifiDevices
totalWifiDevices
}
}
`
}
}
</script>
<style scoped></style>

View File

@ -10,9 +10,11 @@
<v-icon>mdi-qrcode</v-icon> <v-icon>mdi-qrcode</v-icon>
</v-list-item-avatar> </v-list-item-avatar>
<v-list-item-content> <v-list-item-content>
<v-list-item-title> Tokens criados até agora </v-list-item-title> <v-list-item-title>
<v-list-item-subtitle>
{{ stats.tokenCountTotal }} {{ stats.tokenCountTotal }}
</v-list-item-title>
<v-list-item-subtitle>
Tokens criados até agora
</v-list-item-subtitle> </v-list-item-subtitle>
</v-list-item-content> </v-list-item-content>
</v-list-item> </v-list-item>
@ -22,10 +24,10 @@
<v-icon>mdi-checkbox-marked-circle-outline</v-icon> <v-icon>mdi-checkbox-marked-circle-outline</v-icon>
</v-list-item-avatar> </v-list-item-avatar>
<v-list-item-content> <v-list-item-content>
<v-list-item-title> Tokens usados até agora </v-list-item-title> <v-list-item-title>
<v-list-item-subtitle>
{{ stats.tokenCountUsed }} {{ stats.tokenCountUsed }}
</v-list-item-subtitle> </v-list-item-title>
<v-list-item-subtitle> Tokens usados até agora </v-list-item-subtitle>
</v-list-item-content> </v-list-item-content>
</v-list-item> </v-list-item>
@ -34,10 +36,10 @@
<v-icon>mdi-clock-alert-outline</v-icon> <v-icon>mdi-clock-alert-outline</v-icon>
</v-list-item-avatar> </v-list-item-avatar>
<v-list-item-content> <v-list-item-content>
<v-list-item-title> Tokens expirados </v-list-item-title> <v-list-item-title>
<v-list-item-subtitle>
{{ stats.tokenCountExpired }} {{ stats.tokenCountExpired }}
</v-list-item-subtitle> </v-list-item-title>
<v-list-item-subtitle> Tokens expirados </v-list-item-subtitle>
</v-list-item-content> </v-list-item-content>
</v-list-item> </v-list-item>
@ -46,10 +48,10 @@
<v-icon>mdi-clock-outline</v-icon> <v-icon>mdi-clock-outline</v-icon>
</v-list-item-avatar> </v-list-item-avatar>
<v-list-item-content> <v-list-item-content>
<v-list-item-title> Tokens aguardando uso </v-list-item-title> <v-list-item-title>
<v-list-item-subtitle>
{{ stats.tokenCountNotUsed }} {{ stats.tokenCountNotUsed }}
</v-list-item-subtitle> </v-list-item-title>
<v-list-item-subtitle> Tokens aguardando uso </v-list-item-subtitle>
</v-list-item-content> </v-list-item-content>
</v-list-item> </v-list-item>
</v-list> </v-list>
@ -60,7 +62,7 @@
import Widget from './Widget' import Widget from './Widget'
import gql from 'graphql-tag' import gql from 'graphql-tag'
export default { export default {
name: 'ActionsWidget', name: 'TokenStatsWidget',
components: { Widget }, components: { Widget },
apollo: { apollo: {
me: gql` me: gql`

View File

@ -2,8 +2,11 @@
<v-card v-bind="$attrs" outlined class="fill-height widged"> <v-card v-bind="$attrs" outlined class="fill-height widged">
<v-toolbar flat class="font-weight-light headline"> <v-toolbar flat class="font-weight-light headline">
<v-icon v-if="widgetIcon" left>{{ widgetIcon }}</v-icon> <v-icon v-if="widgetIcon" left>{{ widgetIcon }}</v-icon>
{{ title }} <span class="ml-2">
{{ title }}
</span>
</v-toolbar> </v-toolbar>
<v-divider />
<v-card-text> <v-card-text>
<slot /> <slot />
</v-card-text> </v-card-text>
@ -27,7 +30,8 @@ export default {
</script> </script>
<style scoped> <style scoped>
.fill-height.v-card.v-sheet.v-sheet--outlined.theme--light { .v-card.v-sheet.v-sheet--outlined.theme--light,
.v-card.v-sheet.v-sheet--outlined.theme--dark {
box-shadow: 1.5px 1.5px 12px rgba(0, 0, 0, 0.05); box-shadow: 1.5px 1.5px 12px rgba(0, 0, 0, 0.05);
} }
</style> </style>

View File

@ -31,3 +31,7 @@
.bottom-border { .bottom-border {
border-bottom: 1px solid rgba(0, 0, 0, 0.12) !important; border-bottom: 1px solid rgba(0, 0, 0, 0.12) !important;
} }
.light-shadow {
box-shadow: 1.5px 1.5px 12px rgba(0, 0, 0, 0.05) !important;
}

View File

@ -1,15 +1,21 @@
<template> <template>
<v-container class="home" fluid> <v-container class="home" fluid>
<v-row> <v-row>
<v-col cols="12" md="6"> <v-col cols="12" md="6" lg="4">
<UserInfoWidget /> <UserInfoWidget />
</v-col> </v-col>
<v-col v-if="me && me.isTokenCreator" cols="12" md="6">
<TokenStatsWidget /> <v-col cols="12" md="6" lg="4" class="flex-grow-1">
</v-col>
<v-col cols="12" md="6" class="flex-grow-1">
<DevicesWidget /> <DevicesWidget />
</v-col> </v-col>
<v-col v-if="me && me.isSuperAdmin" cols="12" md="6" lg="4">
<StatsWidget />
</v-col>
<v-col v-if="me && me.isTokenCreator" cols="12" md="6" lg="4">
<TokenStatsWidget />
</v-col>
</v-row> </v-row>
</v-container> </v-container>
</template> </template>
@ -18,11 +24,12 @@
import UserInfoWidget from '../components/widgets/UserInfoWidget' import UserInfoWidget from '../components/widgets/UserInfoWidget'
import TokenStatsWidget from '../components/widgets/TokenStatsWidget' import TokenStatsWidget from '../components/widgets/TokenStatsWidget'
import DevicesWidget from '../components/widgets/DevicesWidget' import DevicesWidget from '../components/widgets/DevicesWidget'
import StatsWidget from '../components/widgets/StatsWidget'
import gql from 'graphql-tag' import gql from 'graphql-tag'
export default { export default {
name: 'Home', name: 'Home',
components: { DevicesWidget, TokenStatsWidget, UserInfoWidget }, components: { DevicesWidget, TokenStatsWidget, UserInfoWidget, StatsWidget },
data: () => ({ data: () => ({
searchText: '' searchText: ''
}), }),