Refactoring
This commit is contained in:
parent
920016402a
commit
fcd61655ce
|
@ -25,7 +25,9 @@ export async function wifiDevices(parent, { take = 50, skip = 0, search, sortBy,
|
||||||
}),
|
}),
|
||||||
data: prisma.wifiDevice.findMany({
|
data: prisma.wifiDevice.findMany({
|
||||||
where,
|
where,
|
||||||
orderBy: [{ [sortBy || 'hostname']: sortDesc ? 'desc' : 'asc' }, { ip: 'asc' }],
|
orderBy: [
|
||||||
|
{ status: 'asc' },
|
||||||
|
{ [sortBy || 'hostname']: sortDesc ? 'desc' : 'asc' }],
|
||||||
include: { user: true, accessPoint: true },
|
include: { user: true, accessPoint: true },
|
||||||
take,
|
take,
|
||||||
skip
|
skip
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
<template>
|
<template>
|
||||||
<v-avatar :size="size" class="avatar" :class="{ left, right }">
|
<v-avatar :size="size" class="avatar" :class="{ left, right }">
|
||||||
<v-img v-if="src" :src="src" class="avatar--img" />
|
<v-img v-if="src" :src="src" class="avatar--img" />
|
||||||
<v-icon v-else-if="noAuth" :size="size">mdi-account-cancel</v-icon>
|
<v-icon v-else-if="noAuth" :size="size">mdi-account-off</v-icon>
|
||||||
<v-icon v-else :size="size">mdi-account-check</v-icon>
|
<v-icon v-else :size="size">mdi-account-circle</v-icon>
|
||||||
</v-avatar>
|
</v-avatar>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
|
@ -2,19 +2,15 @@
|
||||||
<div>
|
<div>
|
||||||
<v-data-table
|
<v-data-table
|
||||||
sort-by="signalStrength"
|
sort-by="signalStrength"
|
||||||
:items="wifiDevices"
|
:items="items"
|
||||||
:headers="pickedHeaders"
|
:headers="headers"
|
||||||
:search="filter"
|
:search="filter"
|
||||||
:hide-default-footer="!paginate"
|
:hide-default-footer="!paginate"
|
||||||
:disable-pagination="!paginate"
|
:disable-pagination="!paginate"
|
||||||
no-data-text="Nenhum cliente conectado à este AP"
|
no-data-text="Nenhum cliente conectado à este AP"
|
||||||
>
|
>
|
||||||
<template #[`item.user`]="{ item: { user } }">
|
<template #[`item.combinedUser`]="{ item: { user } }">
|
||||||
<span v-if="user">
|
<UserTD :user="user" />
|
||||||
<Avatar left :src="user.thumbnailPhoto" size="24" />
|
|
||||||
{{ user.displayName }} ({{ user.sAMAccountName }})
|
|
||||||
</span>
|
|
||||||
<span v-else><Avatar left size="24" /> Não logado</span>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #[`item.mac`]="{ item: { mac } }">
|
<template #[`item.mac`]="{ item: { mac } }">
|
||||||
|
@ -38,7 +34,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #[`item.usage`]="{ item: { usage } }">
|
<template #[`item.usage`]="{ item: { usage } }">
|
||||||
{{ usage | bytes }}
|
<Bytes :value="usage" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #[`item.protocol`]="{ item: { protocol } }">
|
<template #[`item.protocol`]="{ item: { protocol } }">
|
||||||
|
@ -54,11 +50,12 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import Avatar from '../Avatar.vue'
|
|
||||||
import SignalStrength from '../signalStrength.vue'
|
import SignalStrength from '../signalStrength.vue'
|
||||||
|
import UserTD from './UserTD.vue'
|
||||||
|
import Bytes from '../ui/Bytes.vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: { Avatar, SignalStrength },
|
components: { Bytes, UserTD, SignalStrength, Bytes },
|
||||||
props: {
|
props: {
|
||||||
wifiDevices: {
|
wifiDevices: {
|
||||||
type: Array,
|
type: Array,
|
||||||
|
@ -71,32 +68,16 @@ export default {
|
||||||
paginate: {
|
paginate: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false
|
||||||
},
|
|
||||||
headers: {
|
|
||||||
type: Array,
|
|
||||||
default: () => [
|
|
||||||
'hostname',
|
|
||||||
'mac',
|
|
||||||
'ip',
|
|
||||||
'essid',
|
|
||||||
'uptime',
|
|
||||||
'user',
|
|
||||||
'signalStrength',
|
|
||||||
'frequency',
|
|
||||||
'protocol',
|
|
||||||
'speed',
|
|
||||||
'usage'
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data: () => ({
|
data: () => ({
|
||||||
availableHeaders: [
|
headers: [
|
||||||
{ text: 'Hostname', value: 'hostname' },
|
{ text: 'Hostname', value: 'hostname' },
|
||||||
{ text: 'MAC', value: 'mac' },
|
{ text: 'MAC', value: 'mac' },
|
||||||
{ text: 'IP', value: 'ip' },
|
{ text: 'IP', value: 'ip' },
|
||||||
{ text: 'ESSID', value: 'essid' },
|
{ text: 'ESSID', value: 'essid' },
|
||||||
{ text: 'Uptime', value: 'uptime' },
|
{ text: 'Uptime', value: 'uptime' },
|
||||||
{ text: 'Usuário', value: 'user' },
|
{ text: 'Usuário', value: 'combinedUser' },
|
||||||
{ text: 'Sinal', value: 'signalStrength' },
|
{ text: 'Sinal', value: 'signalStrength' },
|
||||||
{ text: 'Frequência', value: 'frequency', align: 'end' },
|
{ text: 'Frequência', value: 'frequency', align: 'end' },
|
||||||
{ text: 'Protocolo', value: 'protocol' },
|
{ text: 'Protocolo', value: 'protocol' },
|
||||||
|
@ -105,12 +86,14 @@ export default {
|
||||||
]
|
]
|
||||||
}),
|
}),
|
||||||
computed: {
|
computed: {
|
||||||
pickedHeaders() {
|
items() {
|
||||||
return this.availableHeaders.filter(({ value }) =>
|
return this.wifiDevices.map(item => ({
|
||||||
this.headers.includes(value)
|
...item,
|
||||||
)
|
combinedUser: `${item.user?.displayName} ${item.user?.sAMAccountName}` // For search purposes only
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
setClipboard(text) {
|
setClipboard(text) {
|
||||||
navigator.clipboard.writeText(text)
|
navigator.clipboard.writeText(text)
|
||||||
|
|
32
web/src/components/DataTables/UserTD.vue
Normal file
32
web/src/components/DataTables/UserTD.vue
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
<template>
|
||||||
|
<div v-if="user" class="d-flex">
|
||||||
|
<Avatar
|
||||||
|
class="flex-column center-block"
|
||||||
|
left
|
||||||
|
:src="user.thumbnailPhoto"
|
||||||
|
size="28"
|
||||||
|
/>
|
||||||
|
<small class="d-block text-no-wrap">
|
||||||
|
{{ user.displayName }} <br />
|
||||||
|
{{ user.sAMAccountName }}
|
||||||
|
</small>
|
||||||
|
</div>
|
||||||
|
<span v-else>
|
||||||
|
<Avatar left size="28" no-auth /><small>Não autenticado</small>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import Avatar from '../Avatar.vue'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: { Avatar },
|
||||||
|
props: {
|
||||||
|
user: {
|
||||||
|
type: Object
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style></style>
|
|
@ -28,11 +28,11 @@
|
||||||
<template #[`item.essid`]="{ item: { essid } }">
|
<template #[`item.essid`]="{ item: { essid } }">
|
||||||
<small>{{ essid }}</small>
|
<small>{{ essid }}</small>
|
||||||
</template>
|
</template>
|
||||||
<template #[`item.signalStrength`]="{ item: { signalStrength } }">
|
<template #[`item.signalStrength`]="{ item: { signalStrength, status } }">
|
||||||
<SignalStrength :value="signalStrength" no-signal-text="" />
|
<SignalStrength :value="signalStrength" :offline="status != 'ONLINE'" />
|
||||||
</template>
|
</template>
|
||||||
<template #[`item.usage`]="{ item: { usage } }">
|
<template #[`item.usage`]="{ item: { usage } }">
|
||||||
{{ usage | bytes }}
|
<Bytes :value="usage" />
|
||||||
</template>
|
</template>
|
||||||
<template #[`item.oui`]="{ item: { oui } }">
|
<template #[`item.oui`]="{ item: { oui } }">
|
||||||
<small> {{ oui }}</small>
|
<small> {{ oui }}</small>
|
||||||
|
@ -71,9 +71,10 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import SignalStrength from '../signalStrength.vue'
|
import SignalStrength from '../signalStrength.vue'
|
||||||
|
import Bytes from '../ui/Bytes.vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: { SignalStrength },
|
components: { SignalStrength, Bytes },
|
||||||
props: {
|
props: {
|
||||||
wifiDevices: {
|
wifiDevices: {
|
||||||
type: Array,
|
type: Array,
|
||||||
|
@ -94,7 +95,7 @@ export default {
|
||||||
{ text: 'Primeira aparição', value: 'firstSeen' },
|
{ text: 'Primeira aparição', value: 'firstSeen' },
|
||||||
{ text: 'Última aparição', value: 'lastSeen' },
|
{ text: 'Última aparição', value: 'lastSeen' },
|
||||||
{ text: 'AccessPoint', value: 'apName' },
|
{ text: 'AccessPoint', value: 'apName' },
|
||||||
{ text: 'Uso', value: 'usage' }
|
{ text: 'Uso', value: 'usage', align: 'end' }
|
||||||
]
|
]
|
||||||
}),
|
}),
|
||||||
computed: {
|
computed: {
|
||||||
|
|
|
@ -14,21 +14,7 @@
|
||||||
@update:sort-desc="$emit('update:sort-desc', $event)"
|
@update:sort-desc="$emit('update:sort-desc', $event)"
|
||||||
>
|
>
|
||||||
<template #[`item.user`]="{ item: { user } }">
|
<template #[`item.user`]="{ item: { user } }">
|
||||||
<div v-if="user" class="d-flex">
|
<UserTD :user="user" />
|
||||||
<Avatar
|
|
||||||
class="flex-column center-block"
|
|
||||||
left
|
|
||||||
:src="user.thumbnailPhoto"
|
|
||||||
size="28"
|
|
||||||
/>
|
|
||||||
<small class="d-block text-no-wrap">
|
|
||||||
{{ user.displayName }} <br />
|
|
||||||
{{ user.sAMAccountName }}
|
|
||||||
</small>
|
|
||||||
</div>
|
|
||||||
<span v-else>
|
|
||||||
<Avatar left size="28" no-auth /><small>Não autenticado</small>
|
|
||||||
</span>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #[`item.mac`]="{ item: { mac } }">
|
<template #[`item.mac`]="{ item: { mac } }">
|
||||||
|
@ -47,8 +33,8 @@
|
||||||
<small> {{ uptime | durationFromSeconds }}</small>
|
<small> {{ uptime | durationFromSeconds }}</small>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #[`item.signalStrength`]="{ item: { signalStrength } }">
|
<template #[`item.signalStrength`]="{ item: { signalStrength, status } }">
|
||||||
<SignalStrength :value="signalStrength" />
|
<SignalStrength :offline="status != 'ONLINE'" :value="signalStrength" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #[`item.speed`]="{ item: { speed } }">
|
<template #[`item.speed`]="{ item: { speed } }">
|
||||||
|
@ -56,7 +42,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #[`item.usage`]="{ item: { usage } }">
|
<template #[`item.usage`]="{ item: { usage } }">
|
||||||
<span> {{ usage | bytes }}</span>
|
<Bytes :value="usage" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #[`item.protocol`]="{ item: { protocol } }">
|
<template #[`item.protocol`]="{ item: { protocol } }">
|
||||||
|
@ -88,11 +74,12 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import Avatar from '../Avatar.vue'
|
|
||||||
import SignalStrength from '../signalStrength.vue'
|
import SignalStrength from '../signalStrength.vue'
|
||||||
|
import UserTD from './UserTD.vue'
|
||||||
|
import Bytes from '../ui/Bytes.vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: { Avatar, SignalStrength },
|
components: { SignalStrength, UserTD, Bytes },
|
||||||
props: {
|
props: {
|
||||||
wifiDevices: {
|
wifiDevices: {
|
||||||
type: Array,
|
type: Array,
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
open-delay="400"
|
open-delay="400"
|
||||||
>
|
>
|
||||||
<template #activator="{ on, attrs }">
|
<template #activator="{ on, attrs }">
|
||||||
<template v-if="value < 0">
|
<template v-if="value < 0 && !offline">
|
||||||
<v-chip
|
<v-chip
|
||||||
:color="signalStrengthColor(value) + ' lighten-5'"
|
:color="signalStrengthColor(value) + ' lighten-5'"
|
||||||
small
|
small
|
||||||
|
@ -22,7 +22,8 @@
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<v-chip small color="grey lighten-4">
|
<v-chip small color="grey lighten-4">
|
||||||
<v-icon small left color="grey">mdi-signal-off</v-icon>
|
<v-icon small left color="grey">mdi-signal-off</v-icon>
|
||||||
<small>{{ noSignalText }}</small>
|
<small v-if="offline">Offline</small>
|
||||||
|
<small v-else>{{ noSignalText }}</small>
|
||||||
</v-chip>
|
</v-chip>
|
||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
|
@ -40,6 +41,10 @@ export default {
|
||||||
noSignalText: {
|
noSignalText: {
|
||||||
type: String,
|
type: String,
|
||||||
default: 'Aguarde...'
|
default: 'Aguarde...'
|
||||||
|
},
|
||||||
|
offline: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
|
33
web/src/components/ui/Bytes.vue
Normal file
33
web/src/components/ui/Bytes.vue
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
<template>
|
||||||
|
<span>
|
||||||
|
{{ amount }} <small>{{ unit }}</small>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { destructedBytes } from '../../plugins/format-bytes'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
value: {
|
||||||
|
type: Number,
|
||||||
|
default: 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
destructedBytes() {
|
||||||
|
return destructedBytes(this.value)
|
||||||
|
},
|
||||||
|
|
||||||
|
amount() {
|
||||||
|
return this.destructedBytes.amount
|
||||||
|
},
|
||||||
|
|
||||||
|
unit() {
|
||||||
|
return this.destructedBytes.unit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style></style>
|
|
@ -1,6 +1,6 @@
|
||||||
import Vue from 'vue'
|
import Vue from 'vue'
|
||||||
|
|
||||||
function bytes(bytes, kib, maxUnit) {
|
export function destructedBytes(bytes, kib, maxUnit) {
|
||||||
const decimals = 1
|
const decimals = 1
|
||||||
|
|
||||||
kib = kib || false
|
kib = kib || false
|
||||||
|
@ -24,7 +24,16 @@ function bytes(bytes, kib, maxUnit) {
|
||||||
if (index != -1) i = index
|
if (index != -1) i = index
|
||||||
}
|
}
|
||||||
|
|
||||||
return parseFloat((bytes / Math.pow(k, i)).toFixed(decimals)) + ' ' + sizes[i]
|
return {
|
||||||
|
amount: parseFloat((bytes / Math.pow(k, i)).toFixed(decimals)),
|
||||||
|
unit: sizes[i]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function bytes(bytes) {
|
||||||
|
const bytesObject = destructedBytes(bytes)
|
||||||
|
|
||||||
|
return `${bytesObject.amount} ${bytesObject.unit}`
|
||||||
}
|
}
|
||||||
|
|
||||||
Vue.filter('bytes', bytes)
|
Vue.filter('bytes', bytes)
|
||||||
|
|
|
@ -76,7 +76,7 @@ export default {
|
||||||
watch: {
|
watch: {
|
||||||
showDialog() {
|
showDialog() {
|
||||||
this.filter = ''
|
this.filter = ''
|
||||||
this.$router.push({ name: 'access-points' })
|
this.$router.back()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -121,7 +121,7 @@ export default {
|
||||||
},
|
},
|
||||||
apollo: {
|
apollo: {
|
||||||
wifiDevices: {
|
wifiDevices: {
|
||||||
fetchPolicy: 'cache-and-network',
|
fetchPolicy: 'network-only',
|
||||||
pollInterval: 10000,
|
pollInterval: 10000,
|
||||||
query: gql`
|
query: gql`
|
||||||
query wifiDevices(
|
query wifiDevices(
|
||||||
|
@ -140,12 +140,6 @@ export default {
|
||||||
) {
|
) {
|
||||||
total
|
total
|
||||||
data {
|
data {
|
||||||
accessPoint {
|
|
||||||
id
|
|
||||||
name
|
|
||||||
hostname
|
|
||||||
local
|
|
||||||
}
|
|
||||||
id
|
id
|
||||||
hostname
|
hostname
|
||||||
essid
|
essid
|
||||||
|
@ -158,11 +152,20 @@ export default {
|
||||||
protocol
|
protocol
|
||||||
speed
|
speed
|
||||||
usage
|
usage
|
||||||
|
status
|
||||||
|
|
||||||
user {
|
user {
|
||||||
displayName
|
displayName
|
||||||
sAMAccountName
|
sAMAccountName
|
||||||
thumbnailPhoto
|
thumbnailPhoto
|
||||||
}
|
}
|
||||||
|
|
||||||
|
accessPoint {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
hostname
|
||||||
|
local
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -106,7 +106,10 @@
|
||||||
</v-expansion-panel-header>
|
</v-expansion-panel-header>
|
||||||
<v-expansion-panel-content>
|
<v-expansion-panel-content>
|
||||||
<v-expansion-panels accordion>
|
<v-expansion-panels accordion>
|
||||||
<UserWifiDevicesDataTable :wifi-devices="user.wifiDevices" />
|
<UserWifiDevicesDataTable
|
||||||
|
class="grow"
|
||||||
|
:wifi-devices="user.wifiDevices"
|
||||||
|
/>
|
||||||
</v-expansion-panels>
|
</v-expansion-panels>
|
||||||
</v-expansion-panel-content>
|
</v-expansion-panel-content>
|
||||||
</v-expansion-panel>
|
</v-expansion-panel>
|
||||||
|
|
Loading…
Reference in New Issue
Block a user