re commit
This commit is contained in:
@@ -0,0 +1,52 @@
|
||||
import React from 'react';
|
||||
import {Modal, Form, Header, Grid, Button, Input} from 'semantic-ui-react';
|
||||
|
||||
const CmdModal = ({i18n, open, id, devname, cmd, onSubmit, onClose}) => {
|
||||
let actlist = i18n&&i18n.getResource&&i18n.language ? i18n.getResource(i18n.language + '.translation.action_list') : [];
|
||||
let act = actlist.filter(t => t.cmd == cmd);
|
||||
|
||||
return (
|
||||
<Modal open={open} closeOnDimmerClick={false}>
|
||||
<Modal.Content>
|
||||
<Form onSubmit={(e, d) => {
|
||||
e.preventDefault();
|
||||
onSubmit(d.formData);
|
||||
}} serializer={e => {
|
||||
let json = {
|
||||
devs: `le${id}`
|
||||
};
|
||||
|
||||
json.cmd = cmd;
|
||||
if(json.cmd == 2){
|
||||
let el = e.querySelector('input[name="temp"]');
|
||||
if(el && 'value' in el){
|
||||
json.cmd = `${json.cmd} ${el.value}`
|
||||
}
|
||||
}
|
||||
|
||||
return json;
|
||||
}}>
|
||||
<Header as="h4" content={devname || ''}/>
|
||||
<Header as="h4" content={`${i18n&&i18n.t?i18n.t('page.leone.form.label.run_command'):''} ${act[0] ? act[0].name : ''}`} />
|
||||
{
|
||||
cmd && cmd == '2' ?
|
||||
(<Form.Field>
|
||||
<Input fluid name="temp" label={i18n&&i18n.t ? i18n.t('page.leone.form.label.temp') : ''}/>
|
||||
</Form.Field>) :
|
||||
null
|
||||
}
|
||||
<Grid columns={2} style={{marginTop: '15px'}}>
|
||||
<Grid.Column>
|
||||
<Button fluid type="submit" content={i18n&&i18n.t?i18n.t('page.leone.form.button.submit'):''}/>
|
||||
</Grid.Column>
|
||||
<Grid.Column>
|
||||
<Button fluid type="button" content={i18n&&i18n.t?i18n.t('page.leone.form.button.cancel'):''} onClick={() => {onClose()}}/>
|
||||
</Grid.Column>
|
||||
</Grid>
|
||||
</Form>
|
||||
</Modal.Content>
|
||||
</Modal>
|
||||
)
|
||||
}
|
||||
|
||||
export default CmdModal;
|
||||
@@ -0,0 +1,46 @@
|
||||
import React from 'react';
|
||||
import {Modal, Form, Input, Grid, Button} from 'semantic-ui-react';
|
||||
|
||||
const LeOneModal = ({i18n, open, type, data, onSubmit, onClose}) => {
|
||||
|
||||
return (
|
||||
<Modal open={open}>
|
||||
<Modal.Header content={i18n&&i18n.t ? (type == 1 ? i18n.t('page.leone.form.title.edit') : i18n.t('page.leone.form.title.add')) : '' } />
|
||||
<Modal.Content>
|
||||
<Form onSubmit={(e,d) => {
|
||||
e.preventDefault();
|
||||
onSubmit(type, d.formData);
|
||||
}} serializer={e => {
|
||||
let json = {
|
||||
id: data.leonelistuid || 0,
|
||||
name: e.querySelector('input[name="name"]').value,
|
||||
ip: e.querySelector('input[name="ip"]').value,
|
||||
password: e.querySelector('input[name="password"]').value
|
||||
};
|
||||
|
||||
return json ;
|
||||
}}>
|
||||
<Form.Field>
|
||||
<Input label={i18n&&i18n.t?i18n.t('page.leone.form.label.name'):''} name="name" defaultValue={data.leonename || ''} />
|
||||
</Form.Field>
|
||||
<Form.Field>
|
||||
<Input label={i18n&&i18n.t?i18n.t('page.leone.form.label.ip'):''} name="ip" disabled={type == 1} defaultValue={data.leoneip || ''} />
|
||||
</Form.Field>
|
||||
<Form.Field>
|
||||
<Input label={i18n&&i18n.t?i18n.t('page.leone.form.label.password'):''} name="password" defaultValue={data.leonepassword || ''} />
|
||||
</Form.Field>
|
||||
<Grid columns={2}>
|
||||
<Grid.Column>
|
||||
<Button fluid type="submit" content={i18n&&i18n.t?i18n.t('page.leone.form.button.submit'):''}/>
|
||||
</Grid.Column>
|
||||
<Grid.Column>
|
||||
<Button fluid type="button" content={i18n&&i18n.t?i18n.t('page.leone.form.button.cancel'):''} onClick={() => {onClose()}}/>
|
||||
</Grid.Column>
|
||||
</Grid>
|
||||
</Form>
|
||||
</Modal.Content>
|
||||
</Modal>
|
||||
)
|
||||
}
|
||||
|
||||
export default LeOneModal;
|
||||
@@ -0,0 +1,46 @@
|
||||
import React from 'react';
|
||||
import {Table, Button} from 'semantic-ui-react';
|
||||
|
||||
const ListItem = ({i18n, data, status, delLeone, editLeone, runCmd}) => {
|
||||
let stats = i18n&&i18n.getResource&&i18n.language ? i18n.getResource(i18n.language + '.translation.leone_stats') : [];
|
||||
let actlist = i18n&&i18n.getResource&&i18n.language ? i18n.getResource(i18n.language + '.translation.action_list') : [];
|
||||
let st = stats.filter(t => t.mode == status.mode);
|
||||
let tunit = i18n&&i18n.t ? [i18n.t('time_unit.sec'), i18n.t('time_unit.min'), i18n.t('time_unit.hour'), i18n.t('time_unit.day')] : [];
|
||||
let idx = 0;
|
||||
let mtime = Math.floor(Date.now() / 1000) - status.mtime;
|
||||
while(idx < 3){
|
||||
if(mtime >= 60){
|
||||
mtime = Math.floor(mtime / 60);
|
||||
idx++;
|
||||
}else{
|
||||
break;
|
||||
}
|
||||
}
|
||||
return (
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
<Button type="button" basic size="tiny" color="red" content={i18n&&i18n.t ? i18n.t('page.leone.table.button.del') : ''} onClick={() => {delLeone(data.leonelistuid)}} />
|
||||
<Button type="button" basic size="tiny" color="blue" content={i18n&&i18n.t ? i18n.t('page.leone.table.button.edit') : ''} onClick={() => {editLeone(1, data)}} />
|
||||
</Table.Cell>
|
||||
<Table.Cell>{data.leonename}</Table.Cell>
|
||||
<Table.Cell>{data.leoneip}</Table.Cell>
|
||||
<Table.Cell>{`${status.ts == '9999' || !isFinite(status.ts) ? '-' : `${status.ts} ${String.fromCharCode(8451)}`} / ${status.hs == '9999' || !isFinite(status.hs) ? '-' : `${status.hs} %`}`}</Table.Cell>
|
||||
<Table.Cell>{st[0]&&st[0].name ? st[0].name : status.mode}</Table.Cell>
|
||||
<Table.Cell>{data.leonepassword}</Table.Cell>
|
||||
<Table.Cell>{`${mtime}${tunit[idx]}${i18n&&i18n.t? i18n.t('time_unit.ago') : ''}`}</Table.Cell>
|
||||
<Table.Cell>
|
||||
<select onChange={(e)=>{
|
||||
runCmd(data.leonelistuid, data.leonename, e.target.value);
|
||||
e.target.selectedIndex = 0;
|
||||
}}>
|
||||
<option value="">{i18n&&i18n.t ? i18n.t('tip.select_action') : ''}</option>
|
||||
{
|
||||
actlist.map((t, idx) => <option key={idx} value={t.cmd}>{t.name}</option>)
|
||||
}
|
||||
</select>
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
)
|
||||
}
|
||||
|
||||
export default ListItem;
|
||||
@@ -0,0 +1,52 @@
|
||||
import React from 'react';
|
||||
import {Container, Table, Segment, Form, Grid, Button, Input} from 'semantic-ui-react';
|
||||
|
||||
const ScanForm = ({i18n, onSubmit}) => {
|
||||
|
||||
return (
|
||||
<Form onSubmit={(e, data) => {
|
||||
e.preventDefault();
|
||||
onSubmit(data.formData);
|
||||
}} serializer={e => {
|
||||
let json = {
|
||||
ip1: e.querySelector('input[name="ip1"]').value,
|
||||
ip2: e.querySelector('input[name="ip2"]').value,
|
||||
ip3: e.querySelector('input[name="ip3"]').value,
|
||||
password: e.querySelector('input[name="pass"]').value
|
||||
};
|
||||
|
||||
return json;
|
||||
}}>
|
||||
<Grid verticalAlign="middle">
|
||||
<Grid.Column computer={8} mobile={16}>
|
||||
<Form.Group inline={true}>
|
||||
<Form.Field>
|
||||
<label>{i18n&&i18n.t ? i18n.t('page.leone.form.label.ip') : ''}</label>
|
||||
<Input style={{width: '60px'}} defaultValue="192" name="ip1"/>
|
||||
</Form.Field>
|
||||
<Form.Field>
|
||||
<Input style={{width: '60px'}} defaultValue="168" name="ip2"/>
|
||||
</Form.Field>
|
||||
<Form.Field>
|
||||
<Input style={{width: '60px'}} defaultValue="1" name="ip3"/>
|
||||
</Form.Field>
|
||||
<Form.Field>
|
||||
<Input style={{width: '60px'}} defaultValue="*" disabled/>
|
||||
</Form.Field>
|
||||
</Form.Group>
|
||||
<Form.Group inline={true}>
|
||||
<Form.Field>
|
||||
<label>{i18n&&i18n.t ? i18n.t('page.leone.form.label.password') : ''}</label>
|
||||
<Input name="pass" />
|
||||
</Form.Field>
|
||||
</Form.Group>
|
||||
</Grid.Column>
|
||||
<Grid.Column computer={8} mobile={16}>
|
||||
<Button type="submit" fluid icon="search" content={i18n&&i18n.t ? i18n.t('page.leone.form.button.scan') : ''} />
|
||||
</Grid.Column>
|
||||
</Grid>
|
||||
</Form>
|
||||
)
|
||||
}
|
||||
|
||||
export default ScanForm;
|
||||
@@ -0,0 +1,123 @@
|
||||
import React from 'react';
|
||||
import {Modal, Grid, Label, Button, Table, Checkbox} from 'semantic-ui-react';
|
||||
import ScanItem from './SelectScanItem';
|
||||
|
||||
class SelectScan extends React.Component {
|
||||
|
||||
state = {
|
||||
list: [],
|
||||
page: 1,
|
||||
per: 10,
|
||||
totalpage: 1
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
if(this.state.list.length !== nextProps.list) {
|
||||
let totalpage = Math.ceil( nextProps.list.length / this.state.per ) || 1;
|
||||
this.setState({
|
||||
list: nextProps.list,
|
||||
totalpage
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
onItemSelect = (idx, checked) => {
|
||||
let list = [...this.state.list];
|
||||
if(list[idx]){
|
||||
list[idx].checked = checked;
|
||||
this.setState({
|
||||
list
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
changePage = (p = 1) => {
|
||||
p = p < 1 ? 1 : p;
|
||||
p = p > this.state.totalpage ? this.state.totalpage : p;
|
||||
this.setState({
|
||||
page: p
|
||||
});
|
||||
}
|
||||
|
||||
calSelect = () => {
|
||||
let a = this.state.list.filter(t => t.checked);
|
||||
return a.length;
|
||||
}
|
||||
|
||||
checkAllSelect = (s, e) => {
|
||||
let arr = this.state.list.slice(s,e);
|
||||
let tmp = arr.filter(t => !t.checked);
|
||||
if(tmp.length > 0) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
changeAllCheck = (s, e, chk) => {
|
||||
let arr = [...this.state.list];
|
||||
for(let i=s; i<e; i++){
|
||||
arr[i].checked = chk;
|
||||
}
|
||||
this.setState({
|
||||
list: arr
|
||||
});
|
||||
}
|
||||
|
||||
submitData = () => {
|
||||
let json = {
|
||||
id: []
|
||||
};
|
||||
for(let i in this.state.list) {
|
||||
if(this.state.list[i].leonelistuid) json.id.push(this.state.list[i].leonelistuid)
|
||||
}
|
||||
|
||||
this.props.onSubmit(json);
|
||||
}
|
||||
|
||||
render () {
|
||||
let {i18n, onClose} = this.props;
|
||||
|
||||
let sIdx = this.state.per * (this.state.page - 1);
|
||||
let eIdx = sIdx + this.state.per;
|
||||
eIdx = eIdx > this.state.list.length ? this.state.list.length : eIdx;
|
||||
let arr = this.state.list.slice(sIdx, eIdx);
|
||||
|
||||
return (
|
||||
<Modal open={this.state.list.length > 0 ? true : false} closeOnDimmerClick={false} >
|
||||
<Modal.Header content={i18n&&i18n.t ? i18n.t('page.leone.form.title.select-dev') : ''} />
|
||||
<Modal.Content>
|
||||
<div className="clearfix">
|
||||
<Label content={`${i18n&&i18n.t?i18n.t('page.leone.form.label.select_num') : ''} ${this.calSelect()}`} basic color="blue"/>
|
||||
<div style={{float: 'right'}}>
|
||||
<Button type="button" content={i18n&&i18n.t?i18n.t('page.leone.form.button.prevpage') : ''} onClick={() => {this.changePage(this.state.page - 1)}} size="tiny" basic color="blue"/>
|
||||
<Label basic content={`${this.state.page} / ${this.state.totalpage}`}/>
|
||||
<Button type="button" content={i18n&&i18n.t?i18n.t('page.leone.form.button.nextpage') : ''} onClick={() => {this.changePage(this.state.page + 1)}} size="tiny" basic color="blue"/>
|
||||
</div>
|
||||
</div>
|
||||
<Table>
|
||||
<Table.Header>
|
||||
<Table.Row>
|
||||
<Table.HeaderCell><Checkbox checked={this.checkAllSelect(sIdx, eIdx)} onChange={(e,d)=>{ this.changeAllCheck(sIdx, eIdx, d.checked) }} /></Table.HeaderCell>
|
||||
<Table.HeaderCell>{i18n&&i18n.t ? i18n.t('page.leone.form.label.name') : ''}</Table.HeaderCell>
|
||||
<Table.HeaderCell>{i18n&&i18n.t ? i18n.t('page.leone.form.label.name') : ''}</Table.HeaderCell>
|
||||
</Table.Row>
|
||||
</Table.Header>
|
||||
<Table.Body>
|
||||
{
|
||||
arr.map((t, idx) => <ScanItem key={idx} i18n={i18n} data={t} idx={idx} onChange={this.onItemSelect}/>)
|
||||
}
|
||||
</Table.Body>
|
||||
</Table>
|
||||
<Grid columns={2}>
|
||||
<Grid.Column>
|
||||
<Button content={i18n&&i18n.t ? i18n.t('page.leone.form.button.submit') : ''} fluid onClick={() => {this.submitData()}}/>
|
||||
</Grid.Column>
|
||||
<Grid.Column>
|
||||
<Button content={i18n&&i18n.t ? i18n.t('page.leone.form.button.cancel') : ''} fluid onClick={() => {onClose()}} />
|
||||
</Grid.Column>
|
||||
</Grid>
|
||||
</Modal.Content>
|
||||
</Modal>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default SelectScan;
|
||||
@@ -0,0 +1,12 @@
|
||||
import React from 'react';
|
||||
import {Table, Checkbox} from 'semantic-ui-react';
|
||||
|
||||
const ScanItem = ({i18n, data, idx, onChange}) => (
|
||||
<Table.Row>
|
||||
<Table.Cell><Checkbox onChange={(e,d) => {onChange(idx, d.checked)}} checked={data.checked} /></Table.Cell>
|
||||
<Table.Cell>{data.leonename}</Table.Cell>
|
||||
<Table.Cell>{data.leoneip}</Table.Cell>
|
||||
</Table.Row>
|
||||
)
|
||||
|
||||
export default ScanItem;
|
||||
@@ -0,0 +1,174 @@
|
||||
import React from 'react';
|
||||
import {Container, Table, Segment, Form, Grid, Button} from 'semantic-ui-react';
|
||||
import ScanForm from './ScanForm';
|
||||
import {add_dialog_msg} from '../../../actions';
|
||||
import SelectScan from './SelectScan';
|
||||
import ListItem from './ListItem';
|
||||
import LeOneModal from './LeOneModal';
|
||||
import CmdModal from './CmdModal';
|
||||
|
||||
class LeOnePage extends React.Component {
|
||||
state = {
|
||||
modal: false,
|
||||
modalType: 0,
|
||||
modalData: {},
|
||||
cmd: false,
|
||||
cmdData: {
|
||||
id: 0,
|
||||
name: '',
|
||||
cmd: ''
|
||||
}
|
||||
}
|
||||
|
||||
scanSubmit = (data) => {
|
||||
let {i18n} = this.props;
|
||||
|
||||
if(!data.ip1.trim() || !data.ip2.trim() || !data.ip3.trim() || !data.password.trim())
|
||||
return this.props.showDialog(i18n&&i18n.t ? i18n.t('tip.input_empty') : '');
|
||||
|
||||
// send to scan
|
||||
let json = {
|
||||
ip: `${data.ip1}.${data.ip2}.${data.ip3}`,
|
||||
password: data.password
|
||||
};
|
||||
|
||||
this.props.scanLeOne(json);
|
||||
}
|
||||
|
||||
doDelLeOne = (id) => {
|
||||
let {i18n} = this.props;
|
||||
if(!id) return;
|
||||
this.props.delLeOne({id});
|
||||
}
|
||||
|
||||
openModal = (type, data = {}) => {
|
||||
this.setState({
|
||||
modal: true,
|
||||
modalType: type == 1 ? 1 : 0,
|
||||
modalData: data
|
||||
});
|
||||
}
|
||||
|
||||
closeModal = () => {
|
||||
this.setState({
|
||||
modal: false,
|
||||
modalData: {}
|
||||
});
|
||||
}
|
||||
|
||||
submitModal = (type, data ={}) => {
|
||||
let {i18n} = this.props;
|
||||
if((type == 1 && !data.id) || !data.name || !data.password || (type == 0 && !data.ip)) return this.props.showDialog(i18n&&i18n.t?i18n.t('tip.input_empty') : '')
|
||||
|
||||
if(type == 0){
|
||||
this.props.addLeOne(data);
|
||||
}else{
|
||||
this.props.editLeOne(data);
|
||||
}
|
||||
|
||||
this.closeModal();
|
||||
}
|
||||
|
||||
openCmdModal = (id, name, cmd) => {
|
||||
this.setState({
|
||||
cmd: true,
|
||||
cmdData: {
|
||||
id,name,cmd
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
closeCmdModal = () => {
|
||||
this.setState({
|
||||
cmd: false,
|
||||
cmdData: {
|
||||
id: 0,
|
||||
name: '',
|
||||
cmd: ''
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
submitCmdModal = (data) => {
|
||||
let {i18n} = this.props;
|
||||
if(!data.devs || !data.cmd) return this.props.showDialog(i18n&&i18n.t ? i18n.t('tip.input_empty') : '');
|
||||
if(data.cmd.trim() == 2) return this.props.showDialog(i18n&&i18n.t ? i18n.t('tip.input_empty_temp') : '');
|
||||
|
||||
let cmds = data.cmd.split(' ');
|
||||
if(cmds.length != 2) return this.props.showDialog(i18n&&i18n.t ? i18n.t('tip.input_empty') : '');
|
||||
if(cmds[0] == 2 && (cmds[1] <16 || cmds[1] > 30) ) return this.props.showDialog(i18n&&i18n.t ? i18n.t('tip.temp_format') : '');
|
||||
this.props.runCmd(data);
|
||||
this.closeCmdModal()
|
||||
}
|
||||
|
||||
tick = null;
|
||||
|
||||
runTick = () => {
|
||||
if(!this.props.scanning){
|
||||
this.props.getLeOneList(0);
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.props.getLeOneList();
|
||||
this.tick = setInterval(this.runTick, 10000);
|
||||
this.props.router.setRouteLeaveHook(this.props.route, () => {
|
||||
this.props.clearList();
|
||||
})
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
clearInterval(this.tick);
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
|
||||
}
|
||||
|
||||
render () {
|
||||
let {i18n, scanList, clearScan, addScanLeOne, list, status} = this.props;
|
||||
return (
|
||||
<Container>
|
||||
<Segment>
|
||||
<ScanForm i18n={i18n} onSubmit={this.scanSubmit} />
|
||||
</Segment>
|
||||
<Segment className="clearfix">
|
||||
<Button type="button" basic color="green" content={i18n&&i18n.t ? i18n.t('page.leone.table.button.add') : ''} style={{marginBottom: '10px'}} icon="plus" floated="right" onClick={() => {this.openModal(0)}} />
|
||||
<Table>
|
||||
<Table.Header>
|
||||
<Table.Row>
|
||||
<Table.HeaderCell>{i18n&&i18n.t ? i18n.t('page.leone.table.operate') : ''}</Table.HeaderCell>
|
||||
<Table.HeaderCell>{i18n&&i18n.t ? i18n.t('page.leone.table.name') : ''}</Table.HeaderCell>
|
||||
<Table.HeaderCell>{i18n&&i18n.t ? i18n.t('page.leone.table.ip') : ''}</Table.HeaderCell>
|
||||
<Table.HeaderCell>{i18n&&i18n.t ? i18n.t('page.leone.table.hsts') : ''}</Table.HeaderCell>
|
||||
<Table.HeaderCell>{i18n&&i18n.t ? i18n.t('page.leone.table.mode') : ''}</Table.HeaderCell>
|
||||
<Table.HeaderCell>{i18n&&i18n.t ? i18n.t('page.leone.table.password') : ''}</Table.HeaderCell>
|
||||
<Table.HeaderCell>{i18n&&i18n.t ? i18n.t('page.leone.table.update_time') : ''}</Table.HeaderCell>
|
||||
<Table.HeaderCell>{i18n&&i18n.t ? i18n.t('page.leone.table.control') : ''}</Table.HeaderCell>
|
||||
</Table.Row>
|
||||
</Table.Header>
|
||||
<Table.Body>
|
||||
{
|
||||
list.map(t => {
|
||||
let st = {};
|
||||
for(let i in status){
|
||||
if(status[i].ip == t.leoneip) {
|
||||
st = status[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
return <ListItem i18n={i18n} key={t.leonelistuid} status={st} data={t} delLeone={this.doDelLeOne} editLeone={this.openModal} runCmd={this.openCmdModal}/>
|
||||
})
|
||||
}
|
||||
</Table.Body>
|
||||
</Table>
|
||||
</Segment>
|
||||
<SelectScan i18n={i18n} list={scanList} onClose={clearScan} onSubmit={addScanLeOne}/>
|
||||
<LeOneModal i18n={i18n} open={this.state.modal} type={this.state.modalType} data={this.state.modalData} onSubmit={this.submitModal} onClose={this.closeModal} />
|
||||
<CmdModal i18n={i18n} open={this.state.cmd} id={this.state.cmdData.id} devname={this.state.cmdData.name} cmd={this.state.cmdData.cmd} onSubmit={this.submitCmdModal} onClose={this.closeCmdModal} />
|
||||
</Container>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default LeOnePage;
|
||||
Reference in New Issue
Block a user