WIP: Improve admin dashboard
This commit is contained in:
		
							parent
							
								
									c59d7d941a
								
							
						
					
					
						commit
						ed17636fb9
					
				
					 3 changed files with 71 additions and 13 deletions
				
			
		|  | @ -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"> | ||||||
|  | @ -23,7 +23,15 @@ | ||||||
| 					</div> | 					</div> | ||||||
| 				</mk-container> | 				</mk-container> | ||||||
| 				 | 				 | ||||||
| 				<mkw-federation/> | 				<mk-container :body-togglable="true" :scrollable="true" :resize-base-el="() => $el" class="db"> | ||||||
|  | 					<template #header><fa :icon="faDatabase"/>{{ $t('database') }}</template> | ||||||
|  | 
 | ||||||
|  | 					<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…
	
	Add table
		Add a link
		
	
		Reference in a new issue