From 55b4ea6b6f60e4e7a2f671011f6c2afcdd01ecba Mon Sep 17 00:00:00 2001 From: vapao Date: Sat, 28 Nov 2020 23:14:26 +0800 Subject: [PATCH] style migrate v3 --- spug_web/src/pages/monitor/Form.js | 322 ++------------------------- spug_web/src/pages/monitor/Step1.js | 150 +++++++++++++ spug_web/src/pages/monitor/Step2.js | 108 +++++++++ spug_web/src/pages/monitor/Table.js | 136 ++++++----- spug_web/src/pages/monitor/index.js | 28 ++- spug_web/src/pages/monitor/routes.js | 12 - spug_web/src/pages/monitor/store.js | 28 ++- 7 files changed, 381 insertions(+), 403 deletions(-) create mode 100644 spug_web/src/pages/monitor/Step1.js create mode 100644 spug_web/src/pages/monitor/Step2.js delete mode 100644 spug_web/src/pages/monitor/routes.js diff --git a/spug_web/src/pages/monitor/Form.js b/spug_web/src/pages/monitor/Form.js index ff262e8..406201f 100644 --- a/spug_web/src/pages/monitor/Form.js +++ b/spug_web/src/pages/monitor/Form.js @@ -5,307 +5,27 @@ */ import React from 'react'; import { observer } from 'mobx-react'; -import { Modal, Form, Input, Select, Radio, message, Steps, Button, Transfer, Checkbox } from 'antd'; -import TemplateSelector from '../exec/task/TemplateSelector'; -import { LinkButton, ACEditor } from 'components'; -import { http, cleanCommand, hasHostPermission } from 'libs'; +import { Modal, Steps } from 'antd'; +import Step1 from './Step1'; +import Step2 from './Step2'; import store from './store'; -import hostStore from '../host/store'; -import groupStore from '../alarm/group/store'; import styles from './index.module.css'; -import lds from 'lodash'; -@observer -class ComForm extends React.Component { - constructor(props) { - super(props); - this.fieldMap = { - '1': ['domain'], - '2': ['addr', 'port'], - '3': ['host', 'process'], - '4': ['host', 'command'], - '5': ['addr'], - } - this.modeOptions = [ - {label: '微信', 'value': '1'}, - {label: '短信', 'value': '2', disabled: true}, - {label: '钉钉', 'value': '3'}, - {label: '邮件', 'value': '4'}, - {label: '企业微信', 'value': '5'}, - ] - this.helpMap = { - '1': '返回HTTP状态码200-399则判定为正常,其他为异常。', - '4': '脚本执行退出状态码为 0 则判定为正常,其他为异常。' - } - this.state = { - loading: false, - sitePrefix: 'http://', - domain: undefined, - addr: undefined, - port: undefined, - host: undefined, - process: undefined, - command: '', - showTmp: false, - page: 0, - } - } - - componentDidMount() { - const {type, addr, extra} = store.record; - switch (type) { - case '1': - if (addr.startsWith('http://')) { - this.setState({sitePrefix: 'http://', domain: addr.replace('http://', '')}) - } else { - this.setState({sitePrefix: 'https://', domain: addr.replace('https://', '')}) - } - break; - case '2': - this.setState({addr, port: extra}); - break; - case '3': - this.setState({host: addr, process: extra}); - break; - case '4': - this.setState({host: addr, command: extra}); - break; - case '5': - this.setState({addr}); - break; - default: - } - } - - _getFieldsValue = (type) => { - const {sitePrefix, domain, addr, host, port, command, process} = this.state; - switch (type) { - case '1': - return {addr: sitePrefix + domain} - case '2': - return {addr, extra: port} - case '3': - return {addr: host, extra: process} - case '4': - return {addr: host, extra: command} - case '5': - return {addr} - default: - throw Error('unknown type') - } - } - - handleSubmit = () => { - this.setState({loading: true}); - const formData = this.props.form.getFieldsValue(); - const type = formData['type']; - formData['id'] = store.record.id; - Object.assign(formData, this._getFieldsValue(type)) - http.post('/api/monitor/', formData) - .then(() => { - message.success('操作成功'); - store.formVisible = false; - store.fetchRecords() - }, () => this.setState({loading: false})) - }; - - handleTest = () => { - this.setState({loading: true}); - const type = this.props.form.getFieldValue('type'); - const formData = this._getFieldsValue(type); - formData['type'] = type; - http.post('/api/monitor/test/', formData, {timeout: 120000}) - .then(res => { - if (res.is_success) { - Modal.success({content: res.message}) - } else { - Modal.warning({content: res.message}) - } - }) - .finally(() => this.setState({loading: false})) - } - - getStyle = (t) => { - const type = this.props.form.getFieldValue('type'); - return this.fieldMap[type].includes(t) ? {display: 'block'} : {display: 'none'} - }; - - handleInput = (key, value) => { - this.setState({[key]: value}) - } - - siteBefore = () => ( - - ); - - verifyButtonStatus = () => { - const data = this.props.form.getFieldsValue(); - const {notify_grp, notify_mode, type, name} = data; - const fields = Object.values(lds.pick(this.state, this.fieldMap[type])).filter(x => x) - const b1 = name && fields.length === this.fieldMap[type].length - const b2 = notify_grp && notify_grp.length && notify_mode && notify_mode.length; - return [b1, b2]; - }; - - render() { - const info = store.record; - const {loading, domain, host, port, process, command, addr, showTmp, page} = this.state; - const {getFieldDecorator, getFieldValue} = this.props.form; - const [b1, b2] = this.verifyButtonStatus(); - return ( - store.formVisible = false} - footer={null}> - - - - -
-
- - {getFieldDecorator('type', {initialValue: info['type'] || '1'})( - - )} - - - {getFieldDecorator('name', {initialValue: info['name']})( - - )} - - - this.handleInput('domain', e.target.value)}/> - - - this.handleInput('addr', e.target.value)}/> - - - - - - this.handleInput('port', e.target.value)}/> - - - this.handleInput('process', e.target.value)}/> - - this.setState({showTmp: true})}>从模板添加}> - this.handleInput('command', cleanCommand(e))}/> - - - {getFieldDecorator('desc', {initialValue: info['desc']})( - - )} - -
-
- - {getFieldDecorator('rate', {initialValue: info['rate'] || 5})( - - 1分钟 - 5分钟 - 15分钟 - 30分钟 - 60分钟 - - )} - - - {getFieldDecorator('threshold', {initialValue: info['threshold'] || 3})( - - 1次 - 2次 - 3次 - 4次 - 5次 - - )} - - - {getFieldDecorator('notify_grp', {valuePropName: 'targetKeys', initialValue: info['notify_grp']})( - item.id} - titles={['已有联系组', '已选联系组']} - listStyle={{width: 199}} - dataSource={groupStore.records} - render={item => item.name}/> - )} - - - {getFieldDecorator('notify_mode', {initialValue: info['notify_mode']})( - - )} - - - {getFieldDecorator('quiet', {initialValue: info['quiet'] || 24 * 60})( - - )} - -
- - {page === 1 && - } - {page === 0 && ( -
- - -
- )} - {page !== 0 && - } -
-
- {showTmp && this.handleInput('command', command + v)} - onCancel={() => this.setState({showTmp: false})}/>} -
- ) - } -} - -export default Form.create()(ComForm) +export default observer(function () { + return ( + store.formVisible = false} + footer={null}> + + + + + {store.page === 0 && } + {store.page === 1 && } + + ) +}) diff --git a/spug_web/src/pages/monitor/Step1.js b/spug_web/src/pages/monitor/Step1.js new file mode 100644 index 0000000..0453ea5 --- /dev/null +++ b/spug_web/src/pages/monitor/Step1.js @@ -0,0 +1,150 @@ +/** + * Copyright (c) OpenSpug Organization. https://github.com/openspug/spug + * Copyright (c) + * Released under the AGPL-3.0 License. + */ +import React, { useState, useEffect } from 'react'; +import { observer } from 'mobx-react'; +import { Modal, Form, Input, Select, Button } from 'antd'; +import TemplateSelector from '../exec/task/TemplateSelector'; +import { LinkButton, ACEditor } from 'components'; +import { http, cleanCommand, hasHostPermission } from 'libs'; +import store from './store'; +import hostStore from '../host/store'; + +const helpMap = { + '1': '返回HTTP状态码200-399则判定为正常,其他为异常。', + '4': '脚本执行退出状态码为 0 则判定为正常,其他为异常。' +} + +export default observer(function () { + const [loading, setLoading] = useState(false); + const [showTmp, setShowTmp] = useState(false); + + useEffect(() => { + const {type, addr} = store.record; + if (type === '1' && addr) { + store.record.sitePrefix = addr.startsWith('http://') ? 'http://' : 'https://'; + store.record.domain = store.record.addr.replace(store.record.sitePrefix, '') + } + }, []) + + function handleTest() { + setLoading(true) + const {type, sitePrefix, domain} = store.record; + if (type === '1') store.record.addr = sitePrefix + domain; + http.post('/api/monitor/test/', store.record, {timeout: 120000}) + .then(res => { + if (res.is_success) { + Modal.success({content: res.message}) + } else { + Modal.warning({content: res.message}) + } + }) + .finally(() => setLoading(false)) + } + + function handleChangeType(v) { + store.record.type = v; + store.record.addr = undefined; + store.record.extra = undefined; + } + + const SiteBefore = ( + + ) + + function canNext() { + const {type, addr, extra, domain} = store.record; + if (type === '1') { + return name && domain + } else if (type === '5') { + return name && addr + } else { + return name && addr && extra + } + } + + function toNext() { + store.page += 1; + const {type, sitePrefix, domain} = store.record; + if (type === '1') store.record.addr = sitePrefix + domain; + } + + function getStyle(t) { + return t.includes(store.record.type) ? {display: 'flex'} : {display: 'none'} + } + + const {name, desc, type, addr, extra, domain} = store.record; + return ( +
+ + + + + store.record.name = e.target.value} placeholder="请输入任务名称"/> + + + store.record.domain = e.target.value}/> + + + store.record.addr = e.target.value}/> + + + + + + store.record.extra = e.target.value}/> + + + store.record.extra = e.target.value}/> + + setShowTmp(true)}>从模板添加}> + store.record.extra = cleanCommand(e)}/> + + + store.record.desc = e.target.value} placeholder="请输入备注信息"/> + + + + + + + {showTmp && store.record.extra += v} onCancel={() => setShowTmp(false)}/>} + + ) +}) \ No newline at end of file diff --git a/spug_web/src/pages/monitor/Step2.js b/spug_web/src/pages/monitor/Step2.js new file mode 100644 index 0000000..a65815d --- /dev/null +++ b/spug_web/src/pages/monitor/Step2.js @@ -0,0 +1,108 @@ +/** + * Copyright (c) OpenSpug Organization. https://github.com/openspug/spug + * Copyright (c) + * Released under the AGPL-3.0 License. + */ +import React, { useState, useEffect } from 'react'; +import { observer } from 'mobx-react'; +import { Form, Select, Radio, Transfer, Checkbox, Button, message } from 'antd'; +import { http } from 'libs'; +import groupStore from '../alarm/group/store'; +import store from './store'; +import lds from 'lodash'; + +const modeOptions = [ + {label: '微信', 'value': '1'}, + {label: '短信', 'value': '2', disabled: true}, + {label: '钉钉', 'value': '3'}, + {label: '邮件', 'value': '4'}, + {label: '企业微信', 'value': '5'}, +]; + +export default observer(function () { + const [form] = Form.useForm(); + const [loading, setLoading] = useState(false); + + useEffect(() => { + const {type, addr} = store.record; + if (type === '1' && addr) { + store.record.sitePrefix = addr.startsWith('http://') ? 'http://' : 'https://'; + store.record.domain = store.record.addr.replace(store.record.sitePrefix, '') + } + }, []) + + function handleSubmit() { + setLoading(true) + const formData = form.getFieldsValue(); + Object.assign(formData, lds.pick(store.record, ['id', 'name', 'desc', 'addr', 'extra', 'type'])) + formData['id'] = store.record.id; + http.post('/api/monitor/', formData) + .then(() => { + message.success('操作成功'); + store.formVisible = false; + store.fetchRecords() + }, () => setLoading(false)) + } + + function canNext() { + const {notify_grp, notify_mode} = form.getFieldsValue(); + return notify_grp && notify_grp.length && notify_mode && notify_mode.length; + } + + const info = store.record; + return ( +
+ + + 1分钟 + 5分钟 + 15分钟 + 30分钟 + 60分钟 + + + + + 1次 + 2次 + 3次 + 4次 + 5次 + + + + item.id} + titles={['已有联系组', '已选联系组']} + listStyle={{width: 199}} + dataSource={groupStore.records} + render={item => item.name}/> + + + + + + + + + {() => ( + + + + + )} + +
+ ) +}) \ No newline at end of file diff --git a/spug_web/src/pages/monitor/Table.js b/spug_web/src/pages/monitor/Table.js index 8a401a4..1a38136 100644 --- a/spug_web/src/pages/monitor/Table.js +++ b/spug_web/src/pages/monitor/Table.js @@ -5,14 +5,14 @@ */ import React from 'react'; import { observer } from 'mobx-react'; -import { Table, Modal, Tag, message } from 'antd'; -import { Action } from 'components'; -import ComForm from './Form'; +import { Table, Modal, Radio, Tag, message } from 'antd'; +import { PlusOutlined } from '@ant-design/icons'; +import { Action, AuthButton, TableCard } from 'components'; import { http, hasPermission } from 'libs'; -import store from './store'; +import groupStore from '../alarm/group/store'; import hostStore from '../host/store'; +import store from './store'; import lds from 'lodash'; -import groupStore from "pages/alarm/group/store"; @observer class ComTable extends React.Component { @@ -70,75 +70,69 @@ class ComTable extends React.Component { }; render() { - let data = store.records; - if (store.f_name) { - data = data.filter(item => item['name'].toLowerCase().includes(store.f_name.toLowerCase())) - } - if (store.f_type) { - data = data.filter(item => item['type_alias'] === store.f_type) - } - if (store.f_status !== undefined) { - if (store.f_status === -3) { - data = data.filter(item => !item['is_active']) - } else if (store.f_status === -2) { - data = data.filter(item => item['is_active']) - } else if (store.f_status === -1) { - data = data.filter(item => item['is_active'] && !item['latest_status_alias']) - } else { - data = data.filter(item => item['latest_status'] === store.f_status) - } - } return ( - - `共 ${total} 条`, - pageSizeOptions: ['10', '20', '50', '100'] - }}> - - - { - if ('34'.includes(info.type)) { - return lds.get(this.state.hosts, `${info.addr}.name`) + } + onClick={() => store.showForm()}>新建, + store.f_active = e.target.value}> + 全部 + 已激活 + 未激活 + + ]} + pagination={{ + showSizeChanger: true, + showLessItems: true, + hideOnSinglePage: true, + showTotal: total => `共 ${total} 条`, + pageSizeOptions: ['10', '20', '50', '100'] + }}> + + + { + if ('34'.includes(info.type)) { + return lds.get(this.state.hosts, `${info.addr}.name`) + } else { + return info.addr + } + }}/> + `${value}分钟`}/> + { + if (info.is_active) { + if (info['latest_status'] === 0) { + return 正常 + } else if (info['latest_status'] === 1) { + return 异常 } else { - return info.addr + return 待检测 } - }}/> - `${value}分钟`}/> - { - if (info.is_active) { - if (info['latest_status'] === 0) { - return 正常 - } else if (info['latest_status'] === 1) { - return 异常 - } else { - return 待检测 - } - } else { - return 未启用 - } - }}/> - a.latest_run_time.localeCompare(b.latest_run_time)}/> - {hasPermission('monitor.monitor.edit|monitor.monitor.del') && ( - ( - - this.handleActive(info)}>{info['is_active'] ? '禁用' : '启用'} - store.showForm(info)}>编辑 - this.handleDelete(info)}>删除 - - )}/> - )} -
- {store.formVisible && } -
+ } else { + return 未启用 + } + }}/> + a.latest_run_time.localeCompare(b.latest_run_time)}/> + + {hasPermission('monitor.monitor.edit|monitor.monitor.del') && ( + ( + + this.handleActive(info)}>{info['is_active'] ? '禁用' : '启用'} + store.showForm(info)}>编辑 + this.handleDelete(info)}>删除 + + )}/> + )} + ) } } diff --git a/spug_web/src/pages/monitor/index.js b/spug_web/src/pages/monitor/index.js index 68ce40c..e658dce 100644 --- a/spug_web/src/pages/monitor/index.js +++ b/spug_web/src/pages/monitor/index.js @@ -5,40 +5,38 @@ */ import React from 'react'; import { observer } from 'mobx-react'; -import { Input, Select, Button } from 'antd'; -import { SearchForm, AuthDiv, AuthCard } from 'components'; +import { Input, Select } from 'antd'; +import { SearchForm, AuthDiv, Breadcrumb } from 'components'; import ComTable from './Table'; +import ComForm from './Form'; import store from './store'; export default observer(function () { return ( - + + + 首页 + 监控中心 + - + store.f_name = e.target.value} placeholder="请输入"/> - + - + - - - - - - - + {store.formVisible && } + ) }) diff --git a/spug_web/src/pages/monitor/routes.js b/spug_web/src/pages/monitor/routes.js deleted file mode 100644 index 43e6585..0000000 --- a/spug_web/src/pages/monitor/routes.js +++ /dev/null @@ -1,12 +0,0 @@ -/** - * Copyright (c) OpenSpug Organization. https://github.com/openspug/spug - * Copyright (c) - * Released under the AGPL-3.0 License. - */ -import { makeRoute } from "../../libs/router"; -import Index from './index'; - - -export default [ - makeRoute('', Index), -] diff --git a/spug_web/src/pages/monitor/store.js b/spug_web/src/pages/monitor/store.js index 2dd5686..a985c25 100644 --- a/spug_web/src/pages/monitor/store.js +++ b/spug_web/src/pages/monitor/store.js @@ -3,20 +3,38 @@ * Copyright (c) * Released under the AGPL-3.0 License. */ -import { observable } from "mobx"; +import { observable, computed } from 'mobx'; import http from 'libs/http'; -import moment from "moment"; +import moment from 'moment'; +import lds from 'lodash'; class Store { @observable records = []; @observable record = {}; @observable types = []; + @observable page = 0; @observable isFetching = false; @observable formVisible = false; @observable f_name; @observable f_type; @observable f_status; + @observable f_active = ''; + + @computed get dataSource() { + let records = this.records; + 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_type) records = records.filter(x => x.type_alias === this.f_type); + if (this.f_status !== undefined) { + if (this.f_status === -1) { + records = records.filter(x => x.is_active && !x.latest_status_alias); + } else { + records = records.filter(x => x.latest_status === this.f_status) + } + } + return records + } fetchRecords = () => { this.isFetching = true; @@ -35,9 +53,11 @@ class Store { .finally(() => this.isFetching = false) }; - showForm = (info = {}) => { + showForm = (info) => { + info = info || {type: '1', sitePrefix: 'http://'}; + this.page = 0; + this.record = lds.cloneDeep(info); this.formVisible = true; - this.record = info } }