style migrate v3

pull/289/head
vapao 2020-11-28 23:14:26 +08:00
parent 2ccf04e387
commit 55b4ea6b6f
7 changed files with 381 additions and 403 deletions

View File

@ -5,156 +5,13 @@
*/
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 = () => (
<Select style={{width: 90}} value={this.state.sitePrefix} onChange={v => this.setState({sitePrefix: v})}>
<Select.Option value="http://">http://</Select.Option>
<Select.Option value="https://">https://</Select.Option>
</Select>
);
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();
export default observer(function () {
return (
<Modal
visible
@ -163,149 +20,12 @@ class ComForm extends React.Component {
title={store.record.id ? '编辑任务' : '新建任务'}
onCancel={() => store.formVisible = false}
footer={null}>
<Steps current={page} className={styles.steps}>
<Steps current={store.page} className={styles.steps}>
<Steps.Step key={0} title="创建任务"/>
<Steps.Step key={1} title="设置规则"/>
</Steps>
<Form labelCol={{span: 6}} wrapperCol={{span: 14}}>
<div style={{display: page === 0 ? 'block' : 'none'}}>
<Form.Item label="监控类型" help={this.helpMap[getFieldValue('type') || '1']}>
{getFieldDecorator('type', {initialValue: info['type'] || '1'})(
<Select placeholder="请选择监控类型">
<Select.Option value="1">站点检测</Select.Option>
<Select.Option value="2">端口检测</Select.Option>
<Select.Option value="5">Ping检测</Select.Option>
<Select.Option value="3">进程检测</Select.Option>
<Select.Option value="4">自定义脚本</Select.Option>
</Select>
)}
</Form.Item>
<Form.Item required label="任务名称">
{getFieldDecorator('name', {initialValue: info['name']})(
<Input placeholder="请输入任务名称"/>
)}
</Form.Item>
<Form.Item required label="监控地址" style={this.getStyle('domain')}>
<Input value={domain} addonBefore={this.siteBefore()} placeholder="请输入监控地址"
onChange={e => this.handleInput('domain', e.target.value)}/>
</Form.Item>
<Form.Item required label="监控地址" style={this.getStyle('addr')}>
<Input value={addr} placeholder="请输入监控地址IP/域名)"
onChange={e => this.handleInput('addr', e.target.value)}/>
</Form.Item>
<Form.Item required label="监控主机" style={this.getStyle('host')}>
<Select
showSearch
value={host}
placeholder="请选择主机"
optionFilterProp="children"
filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0}
onChange={v => this.handleInput('host', v)}>
{hostStore.records.filter(x => x.id === Number(host) || hasHostPermission(x.id)).map(item => (
<Select.Option value={String(item.id)} key={item.id}>
{`${item.name}(${item.hostname}:${item.port})`}
</Select.Option>
))}
</Select>
</Form.Item>
<Form.Item required label="检测端口" style={this.getStyle('port')}>
<Input value={port} placeholder="请输入端口号" onChange={e => this.handleInput('port', e.target.value)}/>
</Form.Item>
<Form.Item required label="进程名称" style={this.getStyle('process')} help="执行 ps -ef 看到的进程名称。">
<Input value={process} placeholder="请输入进程名称" onChange={e => this.handleInput('process', e.target.value)}/>
</Form.Item>
<Form.Item
required
label="脚本内容"
style={this.getStyle('command')}
extra={<LinkButton onClick={() => this.setState({showTmp: true})}>从模板添加</LinkButton>}>
<ACEditor
mode="sh"
value={command}
width="100%"
height="200px"
onChange={e => this.handleInput('command', cleanCommand(e))}/>
</Form.Item>
<Form.Item label="备注信息">
{getFieldDecorator('desc', {initialValue: info['desc']})(
<Input.TextArea placeholder="请输入备注信息"/>
)}
</Form.Item>
</div>
<div style={{display: page === 1 ? 'block' : 'none'}}>
<Form.Item label="监控频率">
{getFieldDecorator('rate', {initialValue: info['rate'] || 5})(
<Radio.Group>
<Radio value={1}>1分钟</Radio>
<Radio value={5}>5分钟</Radio>
<Radio value={15}>15分钟</Radio>
<Radio value={30}>30分钟</Radio>
<Radio value={60}>60分钟</Radio>
</Radio.Group>
)}
</Form.Item>
<Form.Item label="报警阈值">
{getFieldDecorator('threshold', {initialValue: info['threshold'] || 3})(
<Radio.Group>
<Radio value={1}>1</Radio>
<Radio value={2}>2</Radio>
<Radio value={3}>3</Radio>
<Radio value={4}>4</Radio>
<Radio value={5}>5</Radio>
</Radio.Group>
)}
</Form.Item>
<Form.Item required label="报警联系人组">
{getFieldDecorator('notify_grp', {valuePropName: 'targetKeys', initialValue: info['notify_grp']})(
<Transfer
lazy={false}
rowKey={item => item.id}
titles={['已有联系组', '已选联系组']}
listStyle={{width: 199}}
dataSource={groupStore.records}
render={item => item.name}/>
)}
</Form.Item>
<Form.Item required label="报警方式">
{getFieldDecorator('notify_mode', {initialValue: info['notify_mode']})(
<Checkbox.Group options={this.modeOptions}/>
)}
</Form.Item>
<Form.Item label="通道沉默" help="相同的告警信息,沉默期内只发送一次。">
{getFieldDecorator('quiet', {initialValue: info['quiet'] || 24 * 60})(
<Select placeholder="请选择">
<Select.Option value={5}>5分钟</Select.Option>
<Select.Option value={10}>10分钟</Select.Option>
<Select.Option value={15}>15分钟</Select.Option>
<Select.Option value={30}>30分钟</Select.Option>
<Select.Option value={60}>60分钟</Select.Option>
<Select.Option value={3 * 60}>3小时</Select.Option>
<Select.Option value={6 * 60}>6小时</Select.Option>
<Select.Option value={12 * 60}>12小时</Select.Option>
<Select.Option value={24 * 60}>24小时</Select.Option>
</Select>
)}
</Form.Item>
</div>
<Form.Item wrapperCol={{span: 14, offset: 6}}>
{page === 1 &&
<Button disabled={!b2} type="primary" onClick={this.handleSubmit} loading={loading}>提交</Button>}
{page === 0 && (
<div>
<Button disabled={!b1} type="primary" onClick={() => this.setState({page: page + 1})}>下一步</Button>
<Button disabled={!b1} type="link" loading={loading} style={{marginLeft: 20}} onClick={this.handleTest}>执行测试</Button>
</div>
)}
{page !== 0 &&
<Button style={{marginLeft: 20}} onClick={() => this.setState({page: page - 1})}>上一步</Button>}
</Form.Item>
</Form>
{showTmp && <TemplateSelector
onOk={v => this.handleInput('command', command + v)}
onCancel={() => this.setState({showTmp: false})}/>}
{store.page === 0 && <Step1/>}
{store.page === 1 && <Step2/>}
</Modal>
)
}
}
export default Form.create()(ComForm)
})

View File

@ -0,0 +1,150 @@
/**
* Copyright (c) OpenSpug Organization. https://github.com/openspug/spug
* Copyright (c) <spug.dev@gmail.com>
* 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 = (
<Select style={{width: 90}} value={store.record.sitePrefix} onChange={v => store.record.sitePrefix = v}>
<Select.Option value="http://">http://</Select.Option>
<Select.Option value="https://">https://</Select.Option>
</Select>
)
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 (
<Form labelCol={{span: 6}} wrapperCol={{span: 14}}>
<Form.Item label="监控类型" help={helpMap[type]}>
<Select placeholder="请选择监控类型" value={type} onChange={handleChangeType}>
<Select.Option value="1">站点检测</Select.Option>
<Select.Option value="2">端口检测</Select.Option>
<Select.Option value="5">Ping检测</Select.Option>
<Select.Option value="3">进程检测</Select.Option>
<Select.Option value="4">自定义脚本</Select.Option>
</Select>
</Form.Item>
<Form.Item required label="任务名称">
<Input value={name} onChange={e => store.record.name = e.target.value} placeholder="请输入任务名称"/>
</Form.Item>
<Form.Item required label="监控地址" style={getStyle(['1'])}>
<Input
value={domain}
addonBefore={SiteBefore}
placeholder="请输入监控地址"
onChange={e => store.record.domain = e.target.value}/>
</Form.Item>
<Form.Item required label="监控地址" style={getStyle(['2', '5'])}>
<Input value={addr} placeholder="请输入监控地址IP/域名)" onChange={e => store.record.addr = e.target.value}/>
</Form.Item>
<Form.Item required label="监控主机" style={getStyle(['3', '4'])}>
<Select
showSearch
value={addr}
placeholder="请选择主机"
optionFilterProp="children"
filterOption={(input, option) => option.children.toLowerCase().indexOf(input.toLowerCase()) >= 0}
onChange={v => store.record.addr = v}>
{hostStore.records.filter(x => x.id === Number(addr) || hasHostPermission(x.id)).map(item => (
<Select.Option value={String(item.id)} key={item.id}>
{`${item.name}(${item.hostname}:${item.port})`}
</Select.Option>
))}
</Select>
</Form.Item>
<Form.Item required label="检测端口" style={getStyle(['2'])}>
<Input value={extra} placeholder="请输入端口号" onChange={e => store.record.extra = e.target.value}/>
</Form.Item>
<Form.Item required label="进程名称" help="执行 ps -ef 看到的进程名称。" style={getStyle(['3'])}>
<Input value={extra} placeholder="请输入进程名称" onChange={e => store.record.extra = e.target.value}/>
</Form.Item>
<Form.Item
required
label="脚本内容"
style={getStyle(['4'])}
extra={<LinkButton onClick={() => setShowTmp(true)}>从模板添加</LinkButton>}>
<ACEditor
mode="sh"
value={extra || ''}
width="100%"
height="200px"
onChange={e => store.record.extra = cleanCommand(e)}/>
</Form.Item>
<Form.Item label="备注信息">
<Input.TextArea value={desc} onChange={e => store.record.desc = e.target.value} placeholder="请输入备注信息"/>
</Form.Item>
<Form.Item wrapperCol={{span: 14, offset: 6}} style={{marginTop: 12}}>
<Button disabled={!canNext()} type="primary" onClick={toNext}>下一步</Button>
<Button disabled={false} type="link" loading={loading} onClick={handleTest}>执行测试</Button>
</Form.Item>
{showTmp && <TemplateSelector onOk={v => store.record.extra += v} onCancel={() => setShowTmp(false)}/>}
</Form>
)
})

View File

@ -0,0 +1,108 @@
/**
* Copyright (c) OpenSpug Organization. https://github.com/openspug/spug
* Copyright (c) <spug.dev@gmail.com>
* 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 (
<Form form={form} labelCol={{span: 6}} wrapperCol={{span: 14}}>
<Form.Item name="rate" initialValue={info.rate || 5} label="监控频率">
<Radio.Group>
<Radio value={1}>1分钟</Radio>
<Radio value={5}>5分钟</Radio>
<Radio value={15}>15分钟</Radio>
<Radio value={30}>30分钟</Radio>
<Radio value={60}>60分钟</Radio>
</Radio.Group>
</Form.Item>
<Form.Item name="threshold" initialValue={info.threshold || 3} label="报警阈值">
<Radio.Group>
<Radio value={1}>1</Radio>
<Radio value={2}>2</Radio>
<Radio value={3}>3</Radio>
<Radio value={4}>4</Radio>
<Radio value={5}>5</Radio>
</Radio.Group>
</Form.Item>
<Form.Item required name="notify_grp" valuePropName="targetKeys" initialValue={info.notify_grp} label="报警联系人组">
<Transfer
lazy={false}
rowKey={item => item.id}
titles={['已有联系组', '已选联系组']}
listStyle={{width: 199}}
dataSource={groupStore.records}
render={item => item.name}/>
</Form.Item>
<Form.Item required name="notify_mode" initialValue={info.notify_mode} label="报警方式">
<Checkbox.Group options={modeOptions}/>
</Form.Item>
<Form.Item name="quiet" initialValue={info.quiet || 24 * 60} label="通道沉默" help="相同的告警信息,沉默期内只发送一次。">
<Select placeholder="请选择">
<Select.Option value={5}>5分钟</Select.Option>
<Select.Option value={10}>10分钟</Select.Option>
<Select.Option value={15}>15分钟</Select.Option>
<Select.Option value={30}>30分钟</Select.Option>
<Select.Option value={60}>60分钟</Select.Option>
<Select.Option value={3 * 60}>3小时</Select.Option>
<Select.Option value={6 * 60}>6小时</Select.Option>
<Select.Option value={12 * 60}>12小时</Select.Option>
<Select.Option value={24 * 60}>24小时</Select.Option>
</Select>
</Form.Item>
<Form.Item shouldUpdate wrapperCol={{span: 14, offset: 6}} style={{marginTop: 12}}>
{() => (
<React.Fragment>
<Button disabled={!canNext()} loading={loading} type="primary" onClick={handleSubmit}>提交</Button>
<Button style={{marginLeft: 20}} onClick={() => store.page -= 1}>上一步</Button>
</React.Fragment>
)}
</Form.Item>
</Form>
)
})

View File

@ -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,30 +70,25 @@ 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 (
<React.Fragment>
<Table
<TableCard
rowKey="id"
title="监控任务"
loading={store.isFetching}
dataSource={data}
dataSource={store.dataSource}
onReload={store.fetchRecords}
actions={[
<AuthButton
auth="monitor.monitor.add"
type="primary"
icon={<PlusOutlined/>}
onClick={() => store.showForm()}>新建</AuthButton>,
<Radio.Group value={store.f_active} onChange={e => store.f_active = e.target.value}>
<Radio.Button value="">全部</Radio.Button>
<Radio.Button value="1">已激活</Radio.Button>
<Radio.Button value="0">未激活</Radio.Button>
</Radio.Group>
]}
pagination={{
showSizeChanger: true,
showLessItems: true,
@ -126,6 +121,7 @@ class ComTable extends React.Component {
}}/>
<Table.Column title="更新于" dataIndex="latest_run_time_alias"
sorter={(a, b) => a.latest_run_time.localeCompare(b.latest_run_time)}/>
<Table.Column hide title="描述" dataIndex="desc"/>
{hasPermission('monitor.monitor.edit|monitor.monitor.del') && (
<Table.Column width={180} title="操作" render={info => (
<Action>
@ -136,9 +132,7 @@ class ComTable extends React.Component {
</Action>
)}/>
)}
</Table>
{store.formVisible && <ComForm/>}
</React.Fragment>
</TableCard>
)
}
}

View File

@ -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 (
<AuthCard auth="monitor.monitor.view">
<AuthDiv auth="monitor.monitor.view">
<Breadcrumb>
<Breadcrumb.Item>首页</Breadcrumb.Item>
<Breadcrumb.Item>监控中心</Breadcrumb.Item>
</Breadcrumb>
<SearchForm>
<SearchForm.Item span={6} title="任务名称">
<SearchForm.Item span={7} title="任务名称">
<Input allowClear value={store.f_name} onChange={e => store.f_name = e.target.value} placeholder="请输入"/>
</SearchForm.Item>
<SearchForm.Item span={6} title="检测类型">
<SearchForm.Item span={7} title="检测类型">
<Select allowClear value={store.f_type} onChange={v => store.f_type = v} placeholder="请选择">
{store.types.map(item => <Select.Option key={item} value={item}>{item}</Select.Option>)}
</Select>
</SearchForm.Item>
<SearchForm.Item span={6} title="任务状态">
<SearchForm.Item span={7} title="任务状态">
<Select allowClear value={store.f_status} onChange={v => store.f_status = v} placeholder="请选择">
<Select.Option value={-3}>未激活</Select.Option>
<Select.Option value={-2}>已激活</Select.Option>
<Select.Option value={-1}>待检测</Select.Option>
<Select.Option value={0}>正常</Select.Option>
<Select.Option value={1}>异常</Select.Option>
</Select>
</SearchForm.Item>
<SearchForm.Item span={6}>
<Button type="primary" icon="sync" onClick={store.fetchRecords}>刷新</Button>
</SearchForm.Item>
</SearchForm>
<AuthDiv auth="monitor.monitor.add" style={{marginBottom: 16}}>
<Button type="primary" icon="plus" onClick={() => store.showForm()}>新建</Button>
</AuthDiv>
<ComTable/>
</AuthCard>
{store.formVisible && <ComForm/>}
</AuthDiv>
)
})

View File

@ -1,12 +0,0 @@
/**
* Copyright (c) OpenSpug Organization. https://github.com/openspug/spug
* Copyright (c) <spug.dev@gmail.com>
* Released under the AGPL-3.0 License.
*/
import { makeRoute } from "../../libs/router";
import Index from './index';
export default [
makeRoute('', Index),
]

View File

@ -3,20 +3,38 @@
* Copyright (c) <spug.dev@gmail.com>
* 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
}
}