U 优化监控中心总览

pull/462/head
vapao 2022-03-12 14:01:38 +08:00
parent 8ebedda67f
commit f421729752
3 changed files with 36 additions and 41 deletions

View File

@ -8,7 +8,6 @@ import { observer } from 'mobx-react';
import { Card, Input, Select, Space, Tooltip, Spin, message } from 'antd'; import { Card, Input, Select, Space, Tooltip, Spin, message } from 'antd';
import { FrownOutlined, RedoOutlined, SyncOutlined } from '@ant-design/icons'; import { FrownOutlined, RedoOutlined, SyncOutlined } from '@ant-design/icons';
import styles from './index.module.less'; import styles from './index.module.less';
import { http, includes } from 'libs';
import store from './store'; import store from './store';
const StyleMap = { const StyleMap = {
@ -16,7 +15,7 @@ const StyleMap = {
'1': {background: '#16a98733', border: '2px solid #16a987', color: '#16a987'}, '1': {background: '#16a98733', border: '2px solid #16a987', color: '#16a987'},
'2': {background: '#ffba0033', border: '2px solid #ffba00', color: '#ffba00'}, '2': {background: '#ffba0033', border: '2px solid #ffba00', color: '#ffba00'},
'3': {background: '#f2655d33', border: '2px solid #f2655d', color: '#f2655d'}, '3': {background: '#f2655d33', border: '2px solid #f2655d', color: '#f2655d'},
'10': {background: '#99999919', border: '2px dashed #999999'} '10': {background: '#99999919', border: '2px dashed #999999', color: '#999999'}
} }
const StatusMap = { const StatusMap = {
@ -27,18 +26,16 @@ const StatusMap = {
'10': '待调度' '10': '待调度'
} }
let AutoReload = null
function CardItem(props) { function CardItem(props) {
const {status, type, desc, name, target, latest_run_time} = props.data const {status, type, desc, name, target, latest_run_time} = props.data
const title = ( const title = (
<div> <div>
<div>类型: {type}</div> <div>类型: {type}</div>
<div>名称: {name}</div> <div>名称: {name}</div>
<div>描述: {desc}</div>
<div>目标: {target}</div> <div>目标: {target}</div>
<div>状态: {StatusMap[status]}</div> <div>状态: {StatusMap[status]}</div>
<div>更新: {latest_run_time || '---'}</div> <div>更新: {latest_run_time || '---'}</div>
<div>描述: {desc}</div>
</div> </div>
) )
return ( return (
@ -49,48 +46,24 @@ function CardItem(props) {
} }
function MonitorCard() { function MonitorCard() {
const [fetching, setFetching] = useState(true);
const [autoReload, setAutoReload] = useState(false); const [autoReload, setAutoReload] = useState(false);
const [status, setStatus] = useState(); const [status, setStatus] = useState();
const [records, setRecords] = useState([]);
const [dataSource, setDataSource] = useState([]);
useEffect(() => { useEffect(() => {
fetchRecords() store.fetchOverviews()
return () => AutoReload = null return () => store.autoReload = null
// eslint-disable-next-line react-hooks/exhaustive-deps // eslint-disable-next-line react-hooks/exhaustive-deps
}, []) }, [])
function fetchRecords() {
if (AutoReload === false) return
setFetching(true);
return http.get('/api/monitor/overview/')
.then(res => setRecords(res))
.finally(() => {
setFetching(false)
if (AutoReload) setTimeout(fetchRecords, 5000)
})
}
useEffect(() => {
const data = records.filter(x =>
(!store.f_type || x.type === store.f_type) &&
(!store.f_group || x.group === store.f_group) &&
(!store.f_name || includes(x.name, store.f_name))
)
setDataSource(data)
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [records, store.f_type, store.f_group, store.f_name])
function handleAutoReload() { function handleAutoReload() {
AutoReload = !autoReload store.autoReload = !autoReload
message.info(autoReload ? '关闭自动刷新' : '开启自动刷新') message.info(autoReload ? '关闭自动刷新' : '开启自动刷新')
if (!autoReload) fetchRecords() if (!autoReload) store.fetchOverviews()
setAutoReload(!autoReload) setAutoReload(!autoReload)
} }
const filteredRecords = dataSource.filter(x => !status || x.status === status) const filteredRecords = store.ovDataSource.filter(x => !status || x.status === status)
return ( return (
<Card title="总览" style={{marginBottom: 24}} extra={( <Card title="总览" style={{marginBottom: 24}} extra={(
<Space size="middle"> <Space size="middle">
@ -116,18 +89,17 @@ function MonitorCard() {
</Space> </Space>
</Space> </Space>
)}> )}>
<Spin spinning={fetching}> <Spin spinning={store.ovFetching}>
<div className={styles.header}> <div className={styles.header}>
{Object.entries(StyleMap).map(([s, style]) => { {Object.entries(StyleMap).map(([s, style]) => {
if (s === '10') return null const count = store.ovDataSource.filter(x => x.status === s).length;
const count = dataSource.filter(x => x.status === s).length;
return count ? ( return count ? (
<div <div
key={s} key={s}
className={styles.item} className={styles.item}
style={s === status ? style : {...style, background: '#fff'}} style={s === status ? style : {...style, background: '#fff'}}
onClick={() => setStatus(s === status ? '' : s)}> onClick={() => setStatus(s === status ? '' : s)}>
{dataSource.filter(x => x.status === s).length} {store.ovDataSource.filter(x => x.status === s).length}
</div> </div>
) : null ) : null
})} })}

View File

@ -42,7 +42,8 @@ export default observer(function () {
message.success('操作成功'); message.success('操作成功');
store.record = {}; store.record = {};
store.formVisible = false; store.formVisible = false;
store.fetchRecords() store.fetchRecords();
store.fetchOverviews()
}, () => setLoading(false)) }, () => setLoading(false))
} }

View File

@ -4,18 +4,21 @@
* Released under the AGPL-3.0 License. * Released under the AGPL-3.0 License.
*/ */
import { observable, computed } from 'mobx'; import { observable, computed } from 'mobx';
import http from 'libs/http'; import { http, includes } from 'libs';
import moment from 'moment'; import moment from 'moment';
import lds from 'lodash'; import lds from 'lodash';
class Store { class Store {
autoReload = null;
@observable records = []; @observable records = [];
@observable record = {}; @observable record = {};
@observable types = []; @observable types = [];
@observable groups = []; @observable groups = [];
@observable overviews = [];
@observable page = 0; @observable page = 0;
@observable isFetching = false; @observable isFetching = false;
@observable formVisible = false; @observable formVisible = false;
@observable ovFetching = false;
@observable f_name; @observable f_name;
@observable f_type; @observable f_type;
@ -25,12 +28,20 @@ class Store {
@computed get dataSource() { @computed get dataSource() {
let records = this.records; let records = this.records;
if (this.f_active) records = records.filter(x => x.is_active === (this.f_active === '1')); if (this.f_active) records = records.filter(x => x.is_active === (this.f_active === '1'));
if (this.f_name) records = records.filter(x => x.name.toLowerCase().includes(this.f_name.toLowerCase())); if (this.f_name) records = records.filter(x => includes(x.name, this.f_name));
if (this.f_type) records = records.filter(x => x.type_alias === this.f_type); if (this.f_type) records = records.filter(x => x.type_alias === this.f_type);
if (this.f_group) records = records.filter(x => x.group === this.f_group); if (this.f_group) records = records.filter(x => x.group === this.f_group);
return records return records
} }
@computed get ovDataSource() {
let records = this.overviews;
if (this.f_type) records = records.filter(x => x.type === this.f_type);
if (this.f_group) records = records.filter(x => x.group === this.f_group);
if (this.f_name) records = records.filter(x => includes(x.name, this.f_name));
return records
}
fetchRecords = () => { fetchRecords = () => {
this.isFetching = true; this.isFetching = true;
http.get('/api/monitor/') http.get('/api/monitor/')
@ -49,6 +60,17 @@ class Store {
.finally(() => this.isFetching = false) .finally(() => this.isFetching = false)
}; };
fetchOverviews = () => {
if (this.autoReload === false) return
this.ovFetching = true;
return http.get('/api/monitor/overview/')
.then(res => this.overviews = res)
.finally(() => {
this.ovFetching = false;
if (this.autoReload) setTimeout(this.fetchOverviews, 5000)
})
}
showForm = (info) => { showForm = (info) => {
if (info) { if (info) {
this.record = lds.cloneDeep(info) this.record = lds.cloneDeep(info)