未验证 提交 836f1a3b 编写于 作者: S songjianet 提交者: GitHub

[Feature][UI Next] Add monitor db. (#7893)

上级 65322155
...@@ -10,41 +10,41 @@ ...@@ -10,41 +10,41 @@
"prettier": "prettier --config .prettier.js --write src/**/*.{vue,ts,tsx}" "prettier": "prettier --config .prettier.js --write src/**/*.{vue,ts,tsx}"
}, },
"dependencies": { "dependencies": {
"@vueuse/core": "^7.2.2", "@vueuse/core": "^7.5.3",
"axios": "^0.24.0", "axios": "^0.24.0",
"date-fns": "^2.27.0", "date-fns": "^2.28.0",
"echarts": "^5.2.2", "echarts": "^5.2.2",
"lodash": "^4.17.21", "lodash": "^4.17.21",
"naive-ui": "^2.21.5", "naive-ui": "2.23.2",
"nprogress": "^0.2.0", "nprogress": "^0.2.0",
"pinia": "^2.0.0-rc.10", "pinia": "^2.0.9",
"pinia-plugin-persistedstate": "^1.0.3", "pinia-plugin-persistedstate": "^1.0.3",
"qs": "^6.10.2", "qs": "^6.10.2",
"vfonts": "^0.1.0", "vfonts": "^0.1.0",
"vue": "^3.2.23", "vue": "^3.2.26",
"vue-i18n": "^9.2.0-beta.23", "vue-i18n": "^9.2.0-beta.26",
"vue-router": "^4.0.12" "vue-router": "^4.0.12"
}, },
"devDependencies": { "devDependencies": {
"@types/node": "^16.11.13", "@types/node": "^16.11.19",
"@types/nprogress": "^0.2.0", "@types/nprogress": "^0.2.0",
"@types/qs": "^6.9.7", "@types/qs": "^6.9.7",
"@typescript-eslint/eslint-plugin": "^5.6.0", "@typescript-eslint/eslint-plugin": "^5.9.0",
"@typescript-eslint/parser": "^5.6.0", "@typescript-eslint/parser": "^5.9.0",
"@vicons/antd": "^0.11.0", "@vicons/antd": "^0.11.0",
"@vitejs/plugin-vue": "^1.10.2", "@vitejs/plugin-vue": "^1.10.2",
"@vitejs/plugin-vue-jsx": "^1.3.1", "@vitejs/plugin-vue-jsx": "^1.3.3",
"dart-sass": "^1.25.0", "dart-sass": "^1.25.0",
"eslint": "^8.4.1", "eslint": "^8.6.0",
"eslint-config-prettier": "^8.3.0", "eslint-config-prettier": "^8.3.0",
"eslint-plugin-prettier": "^4.0.0", "eslint-plugin-prettier": "^4.0.0",
"eslint-plugin-vue": "^8.2.0", "eslint-plugin-vue": "^8.2.0",
"prettier": "^2.5.1", "prettier": "^2.5.1",
"sass": "^1.44.0", "sass": "^1.47.0",
"sass-loader": "^12.4.0", "sass-loader": "^12.4.0",
"typescript": "^4.4.4", "typescript": "^4.5.4",
"typescript-plugin-css-modules": "^3.4.0", "typescript-plugin-css-modules": "^3.4.0",
"vite": "^2.7.0", "vite": "^2.7.10",
"vite-plugin-compression": "^0.3.6", "vite-plugin-compression": "^0.3.6",
"vue-tsc": "^0.28.10" "vue-tsc": "^0.28.10"
} }
......
...@@ -19,7 +19,7 @@ import { defineComponent, PropType } from 'vue' ...@@ -19,7 +19,7 @@ import { defineComponent, PropType } from 'vue'
import { NCard } from 'naive-ui' import { NCard } from 'naive-ui'
const headerStyle = { const headerStyle = {
borderBottom: '1px solid var(--border-color)', borderBottom: '1px solid var(--n-border-color)',
} }
const contentStyle = { const contentStyle = {
......
...@@ -30,7 +30,12 @@ const Content = defineComponent({ ...@@ -30,7 +30,12 @@ const Content = defineComponent({
const menuStore = useMenuStore() const menuStore = useMenuStore()
const { locale } = useI18n() const { locale } = useI18n()
const localesStore = useLocalesStore() const localesStore = useLocalesStore()
const { state, changeMenuOption, changeHeaderMenuOptions, changeUserDropdown } = useDataList() const {
state,
changeMenuOption,
changeHeaderMenuOptions,
changeUserDropdown,
} = useDataList()
locale.value = localesStore.getLocales locale.value = localesStore.getLocales
......
...@@ -77,7 +77,7 @@ export function useDataList() { ...@@ -77,7 +77,7 @@ export function useDataList() {
label: t('menu.home'), label: t('menu.home'),
key: 'home', key: 'home',
icon: renderIcon(HomeOutlined), icon: renderIcon(HomeOutlined),
isShowSide: false isShowSide: false,
}, },
{ {
label: t('menu.project'), label: t('menu.project'),
...@@ -152,7 +152,7 @@ export function useDataList() { ...@@ -152,7 +152,7 @@ export function useDataList() {
label: t('menu.datasource'), label: t('menu.datasource'),
key: 'datasource', key: 'datasource',
icon: renderIcon(DatabaseOutlined), icon: renderIcon(DatabaseOutlined),
isShowSide: false isShowSide: false,
}, },
{ {
label: t('menu.monitor'), label: t('menu.monitor'),
...@@ -245,12 +245,17 @@ export function useDataList() { ...@@ -245,12 +245,17 @@ export function useDataList() {
const changeHeaderMenuOptions = (state: any) => { const changeHeaderMenuOptions = (state: any) => {
state.headerMenuOptions = state.menuOptions.map( state.headerMenuOptions = state.menuOptions.map(
(item: { label: string; key: string; icon: any, isShowSide: boolean }) => { (item: {
label: string
key: string
icon: any
isShowSide: boolean
}) => {
return { return {
label: item.label, label: item.label,
key: item.key, key: item.key,
icon: item.icon, icon: item.icon,
isShowSide: item.isShowSide isShowSide: item.isShowSide,
} }
} }
) )
...@@ -280,6 +285,6 @@ export function useDataList() { ...@@ -280,6 +285,6 @@ export function useDataList() {
state, state,
changeHeaderMenuOptions, changeHeaderMenuOptions,
changeMenuOption, changeMenuOption,
changeUserDropdown changeUserDropdown,
} }
} }
...@@ -115,6 +115,15 @@ const profile = { ...@@ -115,6 +115,15 @@ const profile = {
disable: 'Disable', disable: 'Disable',
} }
const monitor = {
db: {
health_state: 'Health State',
max_connections: 'Max Connections',
threads_connections: 'Threads Connections',
threads_running_connections: 'Threads Running Connections',
},
}
export default { export default {
login, login,
modal, modal,
...@@ -124,4 +133,5 @@ export default { ...@@ -124,4 +133,5 @@ export default {
home, home,
password, password,
profile, profile,
monitor,
} }
...@@ -114,6 +114,15 @@ const profile = { ...@@ -114,6 +114,15 @@ const profile = {
disable: '禁用', disable: '禁用',
} }
const monitor = {
db: {
health_state: '健康状态',
max_connections: '最大连接数',
threads_connections: '当前连接数',
threads_running_connections: '数据库当前活跃连接数',
},
}
export default { export default {
login, login,
modal, modal,
...@@ -123,4 +132,5 @@ export default { ...@@ -123,4 +132,5 @@ export default {
home, home,
password, password,
profile, profile,
monitor,
} }
...@@ -45,5 +45,13 @@ export default { ...@@ -45,5 +45,13 @@ export default {
title: '服务管理-Worker', title: '服务管理-Worker',
}, },
}, },
{
path: '/monitor/servers/db',
name: 'servers-db',
component: components['db'],
meta: {
title: '服务管理-DB',
},
},
], ],
} }
...@@ -14,3 +14,15 @@ ...@@ -14,3 +14,15 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
interface DatabaseRes {
dbType: string
state: string
maxConnections: number
maxUsedConnections: number
threadsConnections: number
threadsRunningConnections: number
date: string
}
export { DatabaseRes }
/*
* 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: 160px;
}
.health {
@include base;
}
.health-success {
color: limegreen;
}
.health-error {
color: indianred;
}
.connections {
@include base;
color: dodgerblue;
}
/*
* 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, NNumberAnimation, NIcon } from 'naive-ui'
import { useI18n } from 'vue-i18n'
import { useDatabase } from '@/views/monitor/servers/db/use-database'
import { CheckCircleOutlined, CloseCircleOutlined } from '@vicons/antd'
import Card from '@/components/card'
import styles from './index.module.scss'
import type { Ref } from 'vue'
import type { DatabaseRes } from '@/service/modules/monitor/types'
const db = defineComponent({
name: 'db',
setup() {
const { t } = useI18n()
const { getDatabase } = useDatabase()
const databaseRef: Ref<DatabaseRes[]> = ref(getDatabase())
return { t, databaseRef }
},
render() {
const { t, databaseRef } = this
return (
<NGrid x-gap='12' y-gap='8' cols='2 xl:4' responsive='screen'>
<NGi>
<Card title={t('monitor.db.health_state')}>
<div class={styles.health}>
{databaseRef[0] &&
(databaseRef[0].state ? (
<NIcon class={styles['health-success']}>
<CheckCircleOutlined />
</NIcon>
) : (
<NIcon class={styles['health-error']}>
<CloseCircleOutlined />
</NIcon>
))}
</div>
</Card>
</NGi>
<NGi>
<Card
title={`${t('monitor.db.max_connections')}${
databaseRef[0] ? ' - ' + databaseRef[0].date : ''
}`}
>
<div class={styles.connections}>
{databaseRef[0] && (
<NNumberAnimation from={0} to={databaseRef[0].maxConnections} />
)}
</div>
</Card>
</NGi>
<NGi>
<Card title={t('monitor.db.threads_connections')}>
<div class={styles.connections}>
{databaseRef[0] && (
<NNumberAnimation
from={0}
to={databaseRef[0].threadsConnections}
/>
)}
</div>
</Card>
</NGi>
<NGi>
<Card title={t('monitor.db.threads_running_connections')}>
<div class={styles.connections}>
{databaseRef[0] && (
<NNumberAnimation
from={0}
to={databaseRef[0].threadsRunningConnections}
/>
)}
</div>
</Card>
</NGi>
</NGrid>
)
},
})
export default db
/*
* 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 { queryDatabaseState } from '@/service/modules/monitor'
import { useAsyncState } from '@vueuse/core'
export function useDatabase() {
const getDatabase = () => {
const { state } = useAsyncState(queryDatabaseState(), [])
return state
}
return { getDatabase }
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册