You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
wiki/ux/src/pages/AdminInstances.vue

213 lines
5.2 KiB

<template lang='pug'>
q-page.admin-terminal
.row.q-pa-md.items-center
.col-auto
img.admin-icon.animated.fadeInLeft(src='/_assets/icons/fluent-network.svg')
.col.q-pl-md
.text-h5.text-primary.animated.fadeInLeft {{ t('admin.instances.title') }}
.text-subtitle1.text-grey.animated.fadeInLeft.wait-p2s {{ t('admin.instances.subtitle') }}
.col-auto.flex
q-btn.q-mr-sm.acrylic-btn(
icon='las la-question-circle'
flat
color='grey'
:aria-label='t(`common.actions.viewDocs`)'
:href='siteStore.docsBase + `/admin/instances`'
target='_blank'
type='a'
)
q-tooltip {{ t(`common.actions.viewDocs`) }}
q-btn.q-mr-sm.acrylic-btn(
icon='las la-redo-alt'
flat
color='secondary'
:loading='state.loading > 0'
:aria-label='t(`common.actions.refresh`)'
@click='load'
)
q-tooltip {{ t(`common.actions.refresh`) }}
q-separator(inset)
.q-pa-md.q-gutter-md
q-card
q-table(
:rows='state.instances'
:columns='instancesHeaders'
row-key='name'
flat
hide-bottom
:rows-per-page-options='[0]'
:loading='state.loading > 0'
)
template(v-slot:body-cell-icon='props')
q-td(:props='props')
q-icon(name='las la-server', color='positive', size='sm')
template(v-slot:body-cell-id='props')
q-td(:props='props')
strong {{props.value}}
div: small.text-grey: strong {{props.row.ip}}
div: small.text-grey {{props.row.dbUser}}
template(v-slot:body-cell-cons='props')
q-td(:props='props')
q-chip(
icon='las la-plug'
square
size='md'
color='blue'
text-color='white'
)
span.font-robotomono {{ props.value }}
template(v-slot:body-cell-subs='props')
q-td(:props='props')
q-chip(
icon='las la-broadcast-tower'
square
size='md'
color='green'
text-color='white'
)
small.text-uppercase {{ props.value }}
template(v-slot:body-cell-firstseen='props')
q-td(:props='props')
span {{props.value}}
div: small.text-grey {{humanizeDate(props.row.dbFirstSeen)}}
template(v-slot:body-cell-lastseen='props')
q-td(:props='props')
span {{props.value}}
div: small.text-grey {{humanizeDate(props.row.dbLastSeen)}}
</template>
<script setup>
import { onMounted, reactive } from 'vue'
import { useMeta, useQuasar } from 'quasar'
import { useI18n } from 'vue-i18n'
import gql from 'graphql-tag'
import { DateTime, Duration, Interval } from 'luxon'
import { useSiteStore } from 'src/stores/site'
// QUASAR
const $q = useQuasar()
// STORES
const siteStore = useSiteStore()
// I18N
const { t } = useI18n()
// META
useMeta({
title: t('admin.instances.title')
})
// DATA
const state = reactive({
instances: [],
loading: 0
})
const instancesHeaders = [
{
align: 'center',
field: 'id',
name: 'icon',
sortable: false,
style: 'width: 15px; padding-right: 0;'
},
{
label: t('common.field.id'),
align: 'left',
field: 'id',
name: 'id',
sortable: true
},
{
label: t('admin.instances.activeConnections'),
align: 'left',
field: 'activeConnections',
name: 'cons',
sortable: true
},
{
label: t('admin.instances.activeListeners'),
align: 'left',
field: 'activeListeners',
name: 'subs',
sortable: true
},
{
label: t('admin.instances.firstSeen'),
align: 'left',
field: 'dbFirstSeen',
name: 'firstseen',
sortable: true,
format: v => DateTime.fromISO(v).toRelative()
},
{
label: t('admin.instances.lastSeen'),
align: 'left',
field: 'dbLastSeen',
name: 'lastseen',
sortable: true,
format: v => DateTime.fromISO(v).toRelative()
}
]
// METHODS
function humanizeDate (val) {
return DateTime.fromISO(val).toFormat('fff')
}
function humanizeDuration (start, end) {
const dur = Interval.fromDateTimes(DateTime.fromISO(start), DateTime.fromISO(end))
.toDuration(['hours', 'minutes', 'seconds', 'milliseconds'])
return Duration.fromObject({
...dur.hours > 0 && { hours: dur.hours },
...dur.minutes > 0 && { minutes: dur.minutes },
...dur.seconds > 0 && { seconds: dur.seconds },
...dur.milliseconds > 0 && { milliseconds: dur.milliseconds }
}).toHuman({ unitDisplay: 'narrow', listStyle: 'short' })
}
async function load () {
state.loading++
try {
const resp = await APOLLO_CLIENT.query({
query: gql`
query getSystemInstances {
systemInstances {
id
activeConnections
activeListeners
dbUser
dbFirstSeen
dbLastSeen
ip
}
}
`,
fetchPolicy: 'network-only'
})
state.instances = resp?.data?.systemInstances
} catch (err) {
$q.notify({
type: 'negative',
message: 'Failed to load list of instances.',
caption: err.message
})
}
state.loading--
}
// MOUNTED
onMounted(() => {
load()
})
</script>