re commit

This commit is contained in:
Jay
2017-03-22 13:35:45 +08:00
commit 8947715671
109 changed files with 161369 additions and 0 deletions
@@ -0,0 +1,40 @@
import React from 'react';
import {Table, Input, Form, Button} from 'semantic-ui-react';
const AIOForm = ({i18n, open, type, data, onSubmit, onClose}) => {
if(!open) return null;
let input = {
name: data.name || '',
portnum: data.portnum || '',
scale_min: data.scale_min || 0,
scale_max: data.scale_max || 0,
range_min: data.range_min || 0,
range_max: data.range_max || 0
}
return (
<Table.Row>
<Table.Cell><Input name="name" onChange={(e,d)=>{input.name = d.value}} defaultValue={data.name || ''}/></Table.Cell>
<Table.Cell><Input name="portnum" onChange={(e,d)=>{input.portnum = d.value}} defaultValue={data.portnum || ''}/></Table.Cell>
<Table.Cell>
<Input name="range_min" size="small" label="Min" onChange={(e,d)=>{input.range_min = d.value}} defaultValue={data.range_min || '0'}/>
<Input name="range_max" size="small" label="Max" onChange={(e,d)=>{input.range_max = d.value}} defaultValue={data.range_max || '0'}/>
</Table.Cell>
<Table.Cell>
<Input name="scale_min" size="small" label="Min" onChange={(e,d)=>{input.scale_min = d.value}} defaultValue={data.scale_min || '0'}/>
<Input name="scale_max" size="small" label="Max" onChange={(e,d)=>{input.scale_max = d.value}} defaultValue={data.scale_max || '0'}/>
</Table.Cell>
<Table.Cell>
<Button basic size="tiny" content="Submit" type="button" onClick={()=>{
let json = {
...input,
id: data.uid || ''
}
onSubmit(type, json);
}} />
<Button basic size="tiny" content="Cancel" type="button" onClick={()=>{onClose()}} />
</Table.Cell>
</Table.Row>
)
}
export default AIOForm;
@@ -0,0 +1,20 @@
import React from 'react';
import {Table, Button} from 'semantic-ui-react';
const AIOListItem = ({i18n, data, editAIO, delAIO}) => {
return (
<Table.Row>
<Table.Cell>{data.name || ''}</Table.Cell>
<Table.Cell>{data.portnum || ''}</Table.Cell>
<Table.Cell>{data.range_min || 0} ~ {data.range_max || 0}</Table.Cell>
<Table.Cell>{data.scale_min || 0} ~ {data.scale_max || 0}</Table.Cell>
<Table.Cell>
<Button type="button" basic size="tiny" content="Edit" onClick={()=>{editAIO(1, data)}} />
<Button type="button" basic size="tiny" content="Delete" onClick={()=>{delAIO(data.uid || '')}} />
</Table.Cell>
</Table.Row>
)
}
export default AIOListItem;
@@ -0,0 +1,72 @@
import React from 'react';
import {Modal, Table, Button, Input, Form} from 'semantic-ui-react';
import ListItem from './AIOListItem';
import AIOForm from './AIOForm';
class AIOModal extends React.Component {
state = {
editMode: false,
data: {},
type: 0
}
openEditField = (type, data = {}) => {
this.closeEditField(()=>{
this.setState({
editMode: true,
data,
type
});
});
}
closeEditField = (cb) => {
this.setState({
editMode: false,
data: {}
}, ()=>{
if(cb && typeof cb == 'function') cb()
});
}
submitAIO = (type, data) => {
data.iouid = this.props.iouid;
this.props.onSubmit(type, data);
this.closeEditField();
}
render() {
let {i18n, iouid, open, list, onClose, delAIO} = this.props;
return (
<Modal size="large" open={open} onClose={()=>{onClose()}}>
<Modal.Content className="clearfix">
<Button basic size="tiny" color="green" floated="right" style={{marginBottom: '10px'}} icon="plus" content="Add Set" onClick={()=>{
this.openEditField(0);
}}/>
<Table size="small">
<Table.Header>
<Table.Row>
<Table.HeaderCell>名稱</Table.HeaderCell>
<Table.HeaderCell>接口號碼</Table.HeaderCell>
<Table.HeaderCell>Range(Min-Max)</Table.HeaderCell>
<Table.HeaderCell>Scale(Min-Max)</Table.HeaderCell>
<Table.HeaderCell>操作</Table.HeaderCell>
</Table.Row>
</Table.Header>
<Table.Body>
{
list.map((t,idx) => (
<ListItem key={idx} i18n={i18n} data={t} editAIO={this.openEditField} delAIO={delAIO}/>
))
}
</Table.Body>
<Table.Footer>
<AIOForm i18n={i18n} open={this.state.editMode} type={this.state.type} data={this.state.data} onSubmit={this.submitAIO} onClose={this.closeEditField}/>
</Table.Footer>
</Table>
</Modal.Content>
</Modal>
)
}
}
export default AIOModal;
@@ -0,0 +1,25 @@
import React from 'react';
import {Menu, Header} from 'semantic-ui-react';
import DevListItem from './DeviceListItem';
const DeviceList = ({i18n, list, delModbus, editModbus, showDev, selectDevToShow}) => {
return (
<Menu vertical={true}>
<Menu.Item>
<Menu.Header content="裝置列表" />
<Menu.Menu>
{
list.map((t, idx) => {
return (
<DevListItem key={idx} i18n={i18n} idx={idx} data={t} delModbus={delModbus} editModbus={editModbus} showDev={showDev} selectDevToShow={selectDevToShow}/>
)
})
}
</Menu.Menu>
</Menu.Item>
</Menu>
)
}
export default DeviceList;
@@ -0,0 +1,19 @@
import React from 'react';
import {List, Button, Icon} from 'semantic-ui-react';
const DeviceListItem = ({i18n, idx, data, delModbus, editModbus, showDev, selectDevToShow}) =>{
return (
<List.Item active={data.uid == showDev}>
<span style={{cursor: 'pointer'}} onClick={() => {
selectDevToShow(data.uid);
}}>
{data.name} / Node:{data.node}
</span>
<Icon style={{cursor: 'pointer'}} name="trash" onClick={()=>{delModbus(data.uid || '')}}/>
<Icon style={{cursor: 'pointer'}} name="write" onClick={()=>{editModbus(1, data)}}/>
</List.Item>
)
}
export default DeviceListItem;
@@ -0,0 +1,63 @@
import React from 'react';
import {Modal, Form, Button, Grid, Input } from 'semantic-ui-react';
const IOModal = ({i18n, open, type, data, onSubmit, onClose}) => {
let iotype = i18n&&i18n.getResource&&i18n.language ? i18n.getResource(i18n.language + '.translation.porttype') : [];
return (
<Modal open={open}>
<Modal.Header content={type == 1 ? '修改資料' : '新增資料'} />
<Modal.Content>
<Form onSubmit={(e,d)=>{
e.preventDefault();
onSubmit(type, d.formData);
}} serializer={e=>{
let json = {
id: data.uid || '',
addr: '',
num: '',
type: ''
};
let addr = e.querySelector('input[name="addr"]');
if(addr && 'value' in addr) json.addr = addr.value;
let num = e.querySelector('input[name="num"]');
if(num && 'value' in num) json.num = num.value;
let type = e.querySelector('select[name="io_type"]');
if(type && 'value' in type) json.type = type.value;
return json;
}}>
<Form.Field>
<label>接口類型</label>
<select name="io_type" defaultValue={data.type || ''} disabled={type == 1}>
<option value="">請選擇類型</option>
{
iotype.map((t,idx) => (
<option key={idx} value={t.code}>{t.name}</option>
))
}
</select>
</Form.Field>
<Form.Field>
<Input name="addr" label="起始位址" defaultValue={data.addr || ''} />
</Form.Field>
<Form.Field>
<Input name="num" label="數量" defaultValue={data.num || ''} />
</Form.Field>
<Grid columns={2}>
<Grid.Column>
<Button type="submit" fluid content="Submit" />
</Grid.Column>
<Grid.Column>
<Button type="button" fluid content="Cancel" onClick={()=>{onClose()}}/>
</Grid.Column>
</Grid>
</Form>
</Modal.Content>
</Modal>
)
}
export default IOModal ;
@@ -0,0 +1,89 @@
import React from 'react';
import {Menu, Segment, Table, Header, Label} from 'semantic-ui-react';
import {convertTime} from '../../../tools';
import IOPanelListItem from './IOPanelListItem';
class IOPanel extends React.Component {
state = {
tabIdx: '1'
}
tabItemClick = (e, el) => {
this.setState({
tabIdx: el.name
}, ()=>{
this.props.getStatus({id: this.props.data.uid || '', type: this.state.tabIdx});
});
}
componentWillReceiveProps(nprops) {
if(nprops.data && nprops.data.uid) {
if(this.props.data && this.props.data.uid){
if(this.props.data.uid != nprops.data.uid) {
this.props.getStatus({id: nprops.data.uid, type: this.state.tabIdx});
}
}else{
this.props.getStatus({id: nprops.data.uid, type: this.state.tabIdx});
}
}
}
render(){
let {i18n, show, data, ioModal, delIOList, showAIOSet} = this.props;
if(!show) return null;
let iolist = data.iolist || [];
let ios = iolist.filter(t => {
if(t.type == this.state.tabIdx) return t;
});
let status = data.status || {};
let ss = status[this.state.tabIdx] || [];
return (
<div>
<Menu attached="top" tabular>
<Menu.Item content="DigitOutput" name="1" active={this.state.tabIdx == "1"} onClick={this.tabItemClick} />
<Menu.Item content="DigitInput" name="2" active={this.state.tabIdx == "2"} onClick={this.tabItemClick} />
<Menu.Item content="AnalogyOutput" name="3" active={this.state.tabIdx == "3"} onClick={this.tabItemClick} />
<Menu.Item content="AnalogyInput" name="4" active={this.state.tabIdx == "4"} onClick={this.tabItemClick} />
<Menu.Menu position="right">
<Menu.Item content="AddIO" icon="plus" onClick={()=>{ioModal(0)}}/>
</Menu.Menu>
</Menu>
<Segment attached="bottom">
<Table>
<Table.Header>
<Table.Row>
<Table.HeaderCell>起始位置</Table.HeaderCell>
<Table.HeaderCell>接口數量</Table.HeaderCell>
<Table.HeaderCell>操作</Table.HeaderCell>
</Table.Row>
</Table.Header>
<Table.Body>
{
ios.map((t,idx) => (
<IOPanelListItem key={idx} i18n={i18n} data={t} ioModal={ioModal} delIOList={delIOList} showAIOSet={showAIOSet} />
))
}
</Table.Body>
</Table>
<Segment>
<Header as="h3" content="接口資訊"/>
{
ss.map((t,idx) => (
<div key={idx}>
<Label basic color="blue" content={`PortNum:${t.port}`}/>
<Label basic color="blue" content={`原始數值:${t.value}`}/>
<Label basic color="blue" content={`轉換數值:${t.value2}`}/>
<Label basic color="green" content={`最後更新於:${convertTime(t.tst, true)}`}/>
</div>
))
}
</Segment>
</Segment>
</div>
)
}
}
export default IOPanel;
@@ -0,0 +1,24 @@
import React from 'react';
import {Table, Button} from 'semantic-ui-react';
const IOPanelListItem = ({i18n, data, ioModal, delIOList, showAIOSet}) => {
return (
<Table.Row>
<Table.Cell>{data.addr || ''}</Table.Cell>
<Table.Cell>{data.num || ''}</Table.Cell>
<Table.Cell>
<Button type="button" basic content="修改" onClick={()=>{ioModal(1, data)}}/>
<Button type="button" basic content="刪除" onClick={()=>{delIOList(data.uid || '')}}/>
{
data.type == 3 || data.type == 4 ?
(
<Button type="button" basic content="顯示設定" onClick={()=>{showAIOSet(data.uid)}} />
):null
}
</Table.Cell>
</Table.Row>
)
}
export default IOPanelListItem;
@@ -0,0 +1,49 @@
import React from 'react';
import {Modal, Form, Input, Grid, Button} from 'semantic-ui-react';
const ModbusModal = ({i18n, open, type, data, onSubmit, onClose}) => {
if(!i18n || Object.keys(i18n).length == 0) return null;
return (
<Modal open={open}>
<Modal.Header content={type == 1 ? '修改裝置' : '新增裝置'} />
<Modal.Content>
<Form onSubmit={(e, d) => {
e.preventDefault();
onSubmit(type, d.formData);
}} serializer={e => {
let json = {
name: '',
node: '',
id: data.uid || '',
original_node: data.node || ''
};
let n = e.querySelector('input[name="name"]');
if(n && 'value' in n) json.name = n.value;
let nn = e.querySelector('input[name="node"]');
if(nn && 'value' in nn) json.node = nn.value;
return json ;
}}>
<Form.Field>
<Input name="name" defaultValue={data.name || ''} label="Name"/>
</Form.Field>
<Form.Field>
<Input name="node" defaultValue={data.node || ''} label="Node"/>
</Form.Field>
<Grid columns={2}>
<Grid.Column>
<Button content="Submit" fluid type="submit" />
</Grid.Column>
<Grid.Column>
<Button content="Cancel" fluid type="button" onClick={()=>{onClose()}} />
</Grid.Column>
</Grid>
</Form>
</Modal.Content>
</Modal>
)
}
export default ModbusModal;
+210
View File
@@ -0,0 +1,210 @@
import React from 'react';
import {Container, Segment, List, Menu, Item, Grid} from 'semantic-ui-react';
import DeviceList from './DeviceList';
import ModbusModal from './ModbusModal';
import IOPanel from './IOPanel';
import IOModal from './IOModal';
import AIOModal from './AIOModal';
const defIOModalState = {
open: false,
data: {},
type: 0
}
const defAIOModalState = {
open: false,
list: [],
iouid: 0
}
class ModbusPage extends React.Component {
state = {
mbModal: false,
mbType: 0,
mbData: {},
showDev: "",
ioModal:{
...defIOModalState
},
aioModal:{
...defAIOModalState
}
}
componentDidMount() {
this.props.getList();
this.props.router.setRouteLeaveHook(this.props.route, () => {
this.props.clearList();
});
}
componentWillReceiveProps(nprop) {
if(this.state.aioModal.open) {
this.openAIOModal(this.state.aioModal.iouid, nprop.list);
}
}
delModbus = id => {
if(!id) return ;
this.props.delModbus({id});
}
openModbusModal = (type, data = {}) => {
this.setState({
mbModal: true,
mbType: type,
mbData: data
});
}
closeModbusModal = () => {
this.setState({
mbModal: false,
mbData: {}
})
}
submitModbusModal = (type, data = {}) => {
let {i18n} = this.props;
if(type == 1 && (!data.id)) return this.props.showDialog(i18n&&i18n.t ? i18n.t('tip.input_empty') : '');
if(!data.name || !('node' in data) || data.node.length == 0) return this.props.showDialog(i18n&&i18n.t ? i18n.t('tip.input_empty') : '');
if(type == 1){
this.props.editModbus(data);
}else{
this.props.addModbus(data);
}
this.closeModbusModal();
}
selectDevToShow = (uid) => {
this.setState({
showDev: uid
});
this.props.getMBData({id: uid});
}
openIOModal = (type, data = {}) => {
this.setState({
ioModal: {
open: true,
type,
data
}
});
}
closeIOModal = () =>{
this.setState({
ioModal: {
...defIOModalState
}
})
}
submitIOModal = (type, data) => {
let {i18n} = this.props;
if((type == 1 && !data.id) || !('addr' in data) || !('num' in data) || !('type' in data)) return this.props.showDialog(i18n.t('tip.input_empty'));
data.devuid = this.state.showDev;
if(type == 1){
this.props.editIOList(data);
}else{
data.id = this.state.showDev;
this.props.addIOList(data);
}
this.closeIOModal();
}
delIOList = (id) => {
if(!id) return ;
this.props.delIOList({id, devuid: this.state.showDev});
}
openAIOModal = (id, nlist = []) => {
if(!id) return ;
let slist = nlist.length == 0 ? this.props.list : nlist;
let dev = slist.filter(t => {
if(t.uid == this.state.showDev) return t;
});
if(dev.length == 0) return ;
let aio = dev[0].aioset || [];
let list = aio.filter(t => {
if(t.iouid == id) return t;
});
this.setState({
aioModal:{
open: true,
list,
iouid: id
}
});
}
closeAIOModal = () => {
this.setState({
aioModal:{
...defAIOModalState
}
});
}
submitAIO = (type, data) => {
data.devuid = this.state.showDev;
if(type == 1){
this.props.editAIO(data);
}else{
this.props.addAIO(data);
}
// this.closeAIOModal();
}
delAIO = (id) => {
if(!id) return ;
this.props.delAIO({id, devuid: this.state.showDev});
}
render() {
let {i18n, list} = this.props;
let dev = list.filter(t => {
if(t.uid == this.state.showDev) return t;
});
return (
<Container>
<Menu>
<Menu.Menu position="right">
<Menu.Item name="新增裝置" icon="plus" onClick={()=>{this.openModbusModal(0)}}/>
</Menu.Menu>
</Menu>
<Grid>
<Grid.Column width={4}>
<DeviceList i18n={i18n}
list={list}
delModbus={this.delModbus}
editModbus={this.openModbusModal}
showDev={this.state.showDev}
selectDevToShow={this.selectDevToShow}/>
</Grid.Column>
<Grid.Column width={12}>
<IOPanel i18n={i18n}
show={dev.length > 0}
data={dev[0]}
ioModal={this.openIOModal}
delIOList={this.delIOList}
getStatus={this.props.getMBIOStatus}
showAIOSet={this.openAIOModal} />
</Grid.Column>
</Grid>
<ModbusModal i18n={i18n} open={this.state.mbModal} data={this.state.mbData} type={this.state.mbType} onSubmit={this.submitModbusModal} onClose={this.closeModbusModal} />
<IOModal i18n={i18n}
open={this.state.ioModal.open}
type={this.state.ioModal.type}
data={this.state.ioModal.data}
onClose={this.closeIOModal}
onSubmit={this.submitIOModal} />
<AIOModal i18n={i18n}
open={this.state.aioModal.open}
iouid={this.state.aioModal.iouid}
list={this.state.aioModal.list}
onSubmit={this.submitAIO}
delAIO={this.delAIO}
onClose={this.closeAIOModal} />
</Container>
)
}
}
export default ModbusPage;