WIP: Improve admin dashboard
This commit is contained in:
parent
c59d7d941a
commit
ed17636fb9
|
@ -562,6 +562,7 @@ metrics: "メトリクス"
|
||||||
overview: "概要"
|
overview: "概要"
|
||||||
logs: "ログ"
|
logs: "ログ"
|
||||||
delayed: "遅延"
|
delayed: "遅延"
|
||||||
|
database: "データベース"
|
||||||
|
|
||||||
_sidebar:
|
_sidebar:
|
||||||
full: "フル"
|
full: "フル"
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="ukygtjoj _panel" :class="{ naked, hideHeader: !showHeader, scrollable }" v-size="{ max: [380], el: resizeBaseEl }">
|
<div class="ukygtjoj _panel" :class="{ naked, hideHeader: !showHeader, scrollable, closed: !showBody }" v-size="{ max: [380], el: resizeBaseEl }">
|
||||||
<header v-if="showHeader">
|
<header v-if="showHeader" ref="header">
|
||||||
<div class="title"><slot name="header"></slot></div>
|
<div class="title"><slot name="header"></slot></div>
|
||||||
<slot name="func"></slot>
|
<slot name="func"></slot>
|
||||||
<button class="_button" v-if="bodyTogglable" @click="() => showBody = !showBody">
|
<button class="_button" v-if="bodyTogglable" @click="() => showBody = !showBody">
|
||||||
|
@ -62,6 +62,18 @@ export default Vue.extend({
|
||||||
faAngleUp, faAngleDown
|
faAngleUp, faAngleDown
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
mounted() {
|
||||||
|
this.$watch('showBody', showBody => {
|
||||||
|
this.$el.style.minHeight = `${this.$refs.header.offsetHeight}px`;
|
||||||
|
if (showBody) {
|
||||||
|
this.$el.style.flexBasis = `auto`;
|
||||||
|
} else {
|
||||||
|
this.$el.style.flexBasis = `${this.$refs.header.offsetHeight}px`;
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
immediate: true
|
||||||
|
});
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
toggleContent(show: boolean) {
|
toggleContent(show: boolean) {
|
||||||
if (!this.bodyTogglable) return;
|
if (!this.bodyTogglable) return;
|
||||||
|
|
|
@ -6,11 +6,11 @@
|
||||||
<mk-folder>
|
<mk-folder>
|
||||||
<template #header><fa :icon="faTachometerAlt"/> {{ $t('overview') }}</template>
|
<template #header><fa :icon="faTachometerAlt"/> {{ $t('overview') }}</template>
|
||||||
|
|
||||||
<div class="sboqnrfi">
|
<div class="sboqnrfi" :style="{ gridTemplateRows: overviewHeight }">
|
||||||
<mk-instance-stats :chart-limit="300" :detailed="true"/>
|
<mk-instance-stats :chart-limit="300" :detailed="true" class="stats" ref="stats"/>
|
||||||
|
|
||||||
<div class="column">
|
<div class="column">
|
||||||
<mk-container :body-togglable="false" :resize-base-el="() => $el">
|
<mk-container :body-togglable="true" :resize-base-el="() => $el" class="info">
|
||||||
<template #header><fa :icon="faInfoCircle"/>{{ $t('instanceInfo') }}</template>
|
<template #header><fa :icon="faInfoCircle"/>{{ $t('instanceInfo') }}</template>
|
||||||
|
|
||||||
<div class="_content">
|
<div class="_content">
|
||||||
|
@ -22,8 +22,16 @@
|
||||||
<div class="_keyValue"><b>Redis</b><span>v{{ serverInfo.redis }}</span></div>
|
<div class="_keyValue"><b>Redis</b><span>v{{ serverInfo.redis }}</span></div>
|
||||||
</div>
|
</div>
|
||||||
</mk-container>
|
</mk-container>
|
||||||
|
|
||||||
|
<mk-container :body-togglable="true" :scrollable="true" :resize-base-el="() => $el" class="db">
|
||||||
|
<template #header><fa :icon="faDatabase"/>{{ $t('database') }}</template>
|
||||||
|
|
||||||
<mkw-federation/>
|
<div class="_content" v-if="dbInfo">
|
||||||
|
<div class="_keyValue" v-for="table in Object.entries(dbInfo)"><b>{{ table[0] }}</b><span>{{ table[1].count | number }}</span><span>{{ table[1].size | bytes }}</span></div>
|
||||||
|
</div>
|
||||||
|
</mk-container>
|
||||||
|
|
||||||
|
<mkw-federation class="fed"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</mk-folder>
|
</mk-folder>
|
||||||
|
@ -161,7 +169,7 @@
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
import { faServer, faExchangeAlt, faMicrochip, faHdd, faStream, faTrashAlt, faInfoCircle, faExclamationTriangle, faTachometerAlt, faHeartbeat, faClipboardList } from '@fortawesome/free-solid-svg-icons';
|
import { faDatabase, faServer, faExchangeAlt, faMicrochip, faHdd, faStream, faTrashAlt, faInfoCircle, faExclamationTriangle, faTachometerAlt, faHeartbeat, faClipboardList } from '@fortawesome/free-solid-svg-icons';
|
||||||
import Chart from 'chart.js';
|
import Chart from 'chart.js';
|
||||||
import VueJsonPretty from 'vue-json-pretty';
|
import VueJsonPretty from 'vue-json-pretty';
|
||||||
import MkInstanceStats from '../../components/instance-stats.vue';
|
import MkInstanceStats from '../../components/instance-stats.vue';
|
||||||
|
@ -218,7 +226,9 @@ export default Vue.extend({
|
||||||
logLevel: 'all',
|
logLevel: 'all',
|
||||||
logDomain: '',
|
logDomain: '',
|
||||||
modLogs: [],
|
modLogs: [],
|
||||||
faServer, faExchangeAlt, faMicrochip, faHdd, faStream, faTrashAlt, faInfoCircle, faExclamationTriangle, faTachometerAlt, faHeartbeat, faClipboardList,
|
dbInfo: null,
|
||||||
|
overviewHeight: '1fr',
|
||||||
|
faDatabase, faServer, faExchangeAlt, faMicrochip, faHdd, faStream, faTrashAlt, faInfoCircle, faExclamationTriangle, faTachometerAlt, faHeartbeat, faClipboardList,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -485,6 +495,20 @@ export default Vue.extend({
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.$root.api('admin/get-table-stats', {}).then(res => {
|
||||||
|
this.dbInfo = res;
|
||||||
|
});
|
||||||
|
|
||||||
|
this.$nextTick(() => {
|
||||||
|
const ro = new ResizeObserver((entries, observer) => {
|
||||||
|
if (this.$refs.stats) {
|
||||||
|
this.overviewHeight = this.$refs.stats.$el.offsetHeight + 'px';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
ro.observe(this.$refs.stats.$el);
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
|
@ -590,11 +614,32 @@ export default Vue.extend({
|
||||||
grid-template-rows: 1fr;
|
grid-template-rows: 1fr;
|
||||||
gap: 16px 16px;
|
gap: 16px 16px;
|
||||||
|
|
||||||
|
> .stats {
|
||||||
|
height: min-content;
|
||||||
|
}
|
||||||
|
|
||||||
> .column {
|
> .column {
|
||||||
display: grid;
|
display: flex;
|
||||||
grid-template-columns: 1fr;
|
flex-direction: column;
|
||||||
grid-template-rows: auto 1fr;
|
|
||||||
gap: 16px 16px;
|
> .info {
|
||||||
|
flex-shrink: 0;
|
||||||
|
flex-grow: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
> .db {
|
||||||
|
flex: 1;
|
||||||
|
flex-grow: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
> .fed {
|
||||||
|
flex: 1;
|
||||||
|
flex-grow: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
> *:not(:last-child) {
|
||||||
|
margin-bottom: var(--margin);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -608,7 +653,7 @@ export default Vue.extend({
|
||||||
.vkyrmkwb {
|
.vkyrmkwb {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: 0.5fr 1fr 1fr;
|
grid-template-columns: 0.5fr 1fr 1fr;
|
||||||
grid-template-rows: 385px;
|
grid-template-rows: 400px;
|
||||||
gap: 16px 16px;
|
gap: 16px 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue