[Feature][UI Next] Add monitor master. (#7917)
parent
7bc1591ef0
commit
f5aca0f11b
|
|
@ -28,12 +28,15 @@ const props = {
|
|||
type: [String, Number] as PropType<string | number>,
|
||||
default: 400,
|
||||
},
|
||||
data: {
|
||||
type: [String, Number] as PropType<string | number>,
|
||||
},
|
||||
}
|
||||
|
||||
const GaugeChart = defineComponent({
|
||||
name: 'GaugeChart',
|
||||
props,
|
||||
setup() {
|
||||
setup(props) {
|
||||
const gaugeChartRef: Ref<HTMLDivElement | null> = ref(null)
|
||||
|
||||
const option = {
|
||||
|
|
@ -73,12 +76,12 @@ const GaugeChart = defineComponent({
|
|||
},
|
||||
detail: {
|
||||
valueAnimation: true,
|
||||
formatter: '{value} km/h',
|
||||
formatter: '{value} %',
|
||||
color: 'auto',
|
||||
},
|
||||
data: [
|
||||
{
|
||||
value: 70,
|
||||
value: props.data,
|
||||
},
|
||||
],
|
||||
},
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@
|
|||
display: flex;
|
||||
justify-content: flex-end;
|
||||
|
||||
button:first-child {
|
||||
margin-right: 20px;
|
||||
button:last-child {
|
||||
margin-left: 20px;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,6 +32,10 @@ const props = {
|
|||
cancelText: {
|
||||
type: String as PropType<string>,
|
||||
},
|
||||
cancelShow: {
|
||||
type: Boolean as PropType<boolean>,
|
||||
default: true,
|
||||
},
|
||||
confirmText: {
|
||||
type: String as PropType<string>,
|
||||
},
|
||||
|
|
@ -72,9 +76,11 @@ const Modal = defineComponent({
|
|||
default: () => renderSlot($slots, 'default'),
|
||||
footer: () => (
|
||||
<div class={styles['btn-box']}>
|
||||
<NButton quaternary size='small' onClick={onCancel}>
|
||||
{this.cancelText || t('modal.cancel')}
|
||||
</NButton>
|
||||
{this.cancelShow && (
|
||||
<NButton quaternary size='small' onClick={onCancel}>
|
||||
{this.cancelText || t('modal.cancel')}
|
||||
</NButton>
|
||||
)}
|
||||
<NButton
|
||||
type='info'
|
||||
size='small'
|
||||
|
|
|
|||
|
|
@ -38,7 +38,6 @@ const Sidebar = defineComponent({
|
|||
|
||||
const { handleMenuClick } = useMenuClick()
|
||||
|
||||
|
||||
return { collapsedRef, defaultExpandedKeys, handleMenuClick }
|
||||
},
|
||||
render() {
|
||||
|
|
|
|||
|
|
@ -56,11 +56,11 @@ const Content = defineComponent({
|
|||
const genSideMenu = (state: any) => {
|
||||
const key = menuStore.getMenuKey
|
||||
state.sideMenuOptions =
|
||||
state.menuOptions.filter((menu: { key: string }) => menu.key === key)[0]
|
||||
.children || []
|
||||
state.isShowSide =
|
||||
state.menuOptions.filter((menu: { key: string }) => menu.key === key)[0]
|
||||
.isShowSide || false
|
||||
state.menuOptions.filter((menu: { key: string }) => menu.key === key)[0]
|
||||
.children || []
|
||||
state.isShowSide =
|
||||
state.menuOptions.filter((menu: { key: string }) => menu.key === key)[0]
|
||||
.isShowSide || false
|
||||
}
|
||||
|
||||
const getSideMenuOptions = (item: any) => {
|
||||
|
|
|
|||
|
|
@ -116,6 +116,16 @@ const profile = {
|
|||
}
|
||||
|
||||
const monitor = {
|
||||
master: {
|
||||
cpu_usage: 'CPU Usage',
|
||||
memory_usage: 'Memory Usage',
|
||||
load_average: 'Load Average',
|
||||
create_time: 'Create Time',
|
||||
last_heartbeat_time: 'Last Heartbeat Time',
|
||||
directory_detail: 'Directory Detail',
|
||||
host: 'Host',
|
||||
directory: 'Directory',
|
||||
},
|
||||
db: {
|
||||
health_state: 'Health State',
|
||||
max_connections: 'Max Connections',
|
||||
|
|
|
|||
|
|
@ -115,6 +115,16 @@ const profile = {
|
|||
}
|
||||
|
||||
const monitor = {
|
||||
master: {
|
||||
cpu_usage: '处理器使用量',
|
||||
memory_usage: '内存使用量',
|
||||
load_average: '平均负载量',
|
||||
create_time: '创建时间',
|
||||
last_heartbeat_time: '最后心跳时间',
|
||||
directory_detail: '目录详情',
|
||||
host: '主机',
|
||||
directory: '注册目录',
|
||||
},
|
||||
db: {
|
||||
health_state: '健康状态',
|
||||
max_connections: '最大连接数',
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ export default {
|
|||
{
|
||||
path: '/monitor/servers/master',
|
||||
name: 'servers-master',
|
||||
component: components['home'],
|
||||
component: components['master'],
|
||||
meta: {
|
||||
title: '服务管理-Master',
|
||||
},
|
||||
|
|
|
|||
|
|
@ -25,4 +25,14 @@ interface DatabaseRes {
|
|||
date: string
|
||||
}
|
||||
|
||||
export { DatabaseRes }
|
||||
interface MasterRes {
|
||||
id: number
|
||||
host: string
|
||||
port: number
|
||||
zkDirectory: string
|
||||
resInfo: string
|
||||
createTime: string
|
||||
lastHeartbeatTime: string
|
||||
}
|
||||
|
||||
export { DatabaseRes, MasterRes }
|
||||
|
|
|
|||
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
@mixin base {
|
||||
font-size: 100px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
min-height: 400px;
|
||||
}
|
||||
|
||||
.header-card {
|
||||
margin-bottom: 8px;
|
||||
|
||||
.content {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
|
||||
.left {
|
||||
margin-right: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.link-btn {
|
||||
color: #579cd8;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
color: #80bef7;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.card {
|
||||
@include base;
|
||||
}
|
||||
|
||||
.load-average {
|
||||
@include base;
|
||||
color: dodgerblue;
|
||||
}
|
||||
|
|
@ -0,0 +1,136 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { defineComponent, ref } from 'vue'
|
||||
import { NGrid, NGi, NCard, NNumberAnimation, NDataTable } from 'naive-ui'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { useMaster } from './use-master'
|
||||
import styles from './index.module.scss'
|
||||
import Card from '@/components/card'
|
||||
import Gauge from '@/components/chart/modules/Gauge'
|
||||
import Modal from '@/components/modal'
|
||||
import type { MasterRes } from '@/service/modules/monitor/types'
|
||||
import type { Ref } from 'vue'
|
||||
import type { TableColumns } from 'naive-ui/es/data-table/src/interface'
|
||||
|
||||
const master = defineComponent({
|
||||
name: 'master',
|
||||
setup() {
|
||||
let showModalRef = ref(false)
|
||||
const { t } = useI18n()
|
||||
const { getMaster } = useMaster()
|
||||
const masterRef: Ref<Array<MasterRes>> = ref(getMaster())
|
||||
const columnsRef: TableColumns<any> = [
|
||||
{ title: '#', key: 'id' },
|
||||
{ title: t('monitor.master.directory'), key: 'directory' },
|
||||
]
|
||||
|
||||
return { t, masterRef, showModalRef, columnsRef }
|
||||
},
|
||||
render() {
|
||||
const { t, masterRef, columnsRef } = this
|
||||
|
||||
return (
|
||||
<div>
|
||||
<NCard class={styles['header-card']}>
|
||||
<div class={styles['content']}>
|
||||
<p>
|
||||
<span class={styles.left}>{`${t('monitor.master.host')}: ${
|
||||
masterRef[0] ? masterRef[0].host : ' - '
|
||||
}`}</span>
|
||||
<span
|
||||
class={styles['link-btn']}
|
||||
onClick={() => (this.showModalRef = true)}
|
||||
>
|
||||
{t('monitor.master.directory_detail')}
|
||||
</span>
|
||||
</p>
|
||||
<p>
|
||||
<span class={styles.left}>{`${t('monitor.master.create_time')}: ${
|
||||
masterRef[0] ? masterRef[0].createTime : ' - '
|
||||
}`}</span>
|
||||
<span>{`${t('monitor.master.last_heartbeat_time')}: ${
|
||||
masterRef[0] ? masterRef[0].lastHeartbeatTime : ' - '
|
||||
}`}</span>
|
||||
</p>
|
||||
</div>
|
||||
</NCard>
|
||||
<NGrid x-gap='12' cols='3'>
|
||||
<NGi>
|
||||
<Card title={t('monitor.master.cpu_usage')}>
|
||||
<div class={styles.card}>
|
||||
{masterRef[0] && (
|
||||
<Gauge
|
||||
data={(
|
||||
JSON.parse(masterRef[0].resInfo).cpuUsage * 100
|
||||
).toFixed(2)}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</Card>
|
||||
</NGi>
|
||||
<NGi>
|
||||
<Card title={t('monitor.master.memory_usage')}>
|
||||
<div class={styles.card}>
|
||||
{masterRef[0] && (
|
||||
<Gauge
|
||||
data={(
|
||||
JSON.parse(masterRef[0].resInfo).memoryUsage * 100
|
||||
).toFixed(2)}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</Card>
|
||||
</NGi>
|
||||
<NGi>
|
||||
<Card title={t('monitor.master.load_average')}>
|
||||
<div class={[styles.card, styles['load-average']]}>
|
||||
{masterRef[0] && (
|
||||
<NNumberAnimation
|
||||
precision={2}
|
||||
from={0}
|
||||
to={JSON.parse(masterRef[0].resInfo).loadAverage}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</Card>
|
||||
</NGi>
|
||||
</NGrid>
|
||||
<Modal
|
||||
title={t('monitor.master.directory_detail')}
|
||||
show={this.showModalRef}
|
||||
cancelShow={false}
|
||||
onConfirm={() => (this.showModalRef = false)}
|
||||
>
|
||||
{{
|
||||
default: () =>
|
||||
masterRef[0] && (
|
||||
<NDataTable
|
||||
columns={columnsRef}
|
||||
data={[{ id: 1, directory: masterRef[0].zkDirectory }]}
|
||||
striped
|
||||
size={'small'}
|
||||
/>
|
||||
),
|
||||
}}
|
||||
</Modal>
|
||||
</div>
|
||||
)
|
||||
},
|
||||
})
|
||||
|
||||
export default master
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { useAsyncState } from '@vueuse/core'
|
||||
import { listMaster } from '@/service/modules/monitor'
|
||||
|
||||
export function useMaster() {
|
||||
const getMaster = () => {
|
||||
const { state } = useAsyncState(listMaster(), [])
|
||||
return state
|
||||
}
|
||||
|
||||
return { getMaster }
|
||||
}
|
||||
Loading…
Reference in New Issue