add MachineRecordTable;
authorHongyuan Ma <CS_MaleicAcid@163.com>
Mon, 9 Jul 2018 14:38:08 +0000 (22:38 +0800)
committerHongyuan Ma <CS_MaleicAcid@163.com>
Mon, 9 Jul 2018 14:38:08 +0000 (22:38 +0800)
19 files changed:
front-end/src/app.jsx
front-end/src/component/farmer-detail-card/index.jsx [new file with mode: 0644]
front-end/src/component/nav-top/index.jsx
front-end/src/page/login/index.jsx
front-end/src/page/machineInfo/index.css [new file with mode: 0644]
front-end/src/page/machineInfo/index.jsx
front-end/src/page/machineInfo/index.scss [deleted file]
front-end/src/page/portal/index.jsx
front-end/src/service/record-service.jsx
front-end/src/util/constant.jsx
front-end/src/util/machine-record-table/index.css [new file with mode: 0644]
front-end/src/util/machine-record-table/index.jsx [new file with mode: 0644]
front-end/src/util/machine-table/index.css
front-end/src/util/machine-table/index.jsx
front-end/src/util/util.jsx
web/apps/test_records/serializer.py
web/apps/test_records/views.py
web/apps/user_operation/serializer.py
web/pgperffarm/urls.py

index 78443b1b68a05ccc185d460d12923b500b8325e3..6606564be510f0719f86a3c16051c5d6fd2d009c 100644 (file)
@@ -1,6 +1,6 @@
 import React from 'react';
 import ReactDom from 'react-dom';
-import {BrowserRouter as Router, Route, Link, Redirect, Switch} from 'react-router-dom';
+import {HashRouter as Router, Route, Link, Redirect, Switch} from 'react-router-dom';
 import createHistory from 'history/createHashHistory'
 const history = createHistory()
 import {spring, AnimatedRoute, AnimatedSwitch} from 'react-router-transition';
@@ -13,6 +13,7 @@ import Home from './page/home/index.jsx'
 import Status from './page/status/index.jsx'
 import PPolicy from './page/ppolicy/index.jsx'
 import DetailInfo from './page/detailInfo/index.jsx'
+import MachinelInfo from './page/machineInfo/index.jsx'
 
 import Portal from './page/portal/index.jsx'
 // we need to map the `scale` prop we define below
@@ -69,7 +70,7 @@ class App extends React.Component {
 
                     <Route exact path="/portal/" component={Portal}/>
                     <Route path="/detailInfo/:uuid" component={DetailInfo}/>
-                    {/*<Route path="/detail/:uuid" component={DetailInfo}/>*/}
+                    <Route path="/machineInfo/:machine_sn" component={MachinelInfo}/>
                     {/*<Redirect exact from="/order" to="/order/index"/>*/}
                     {/*<Redirect exact from="/user" to="/user/index"/>*/}
                     {/*<Route component={ErrorPage}/>*/}
diff --git a/front-end/src/component/farmer-detail-card/index.jsx b/front-end/src/component/farmer-detail-card/index.jsx
new file mode 100644 (file)
index 0000000..9e328d5
--- /dev/null
@@ -0,0 +1,47 @@
+import React from 'react';
+
+import NavTop from 'component/nav-top/index.jsx';
+// import './index.css';
+import {Image, Card, Button, List, Icon} from 'semantic-ui-react'
+class FarmerDetailCard extends React.Component {
+    constructor(props){
+        super(props);
+    }
+    render(){
+        let machine = this.props.machine || {}
+        let system = machine.os_name + ' ' + machine.os_version;
+        let camp = machine.comp_name + ' ' + machine.comp_version;
+        return (
+
+            <div className="farmer-card">
+                <Card>
+                    <Card.Content>
+                        <Image floated='right' size='mini'
+                               src={machine.avatar}/>
+                        <Card.Header>Farmer: {machine.alias}</Card.Header>
+                        <Card.Meta>report num: {machine.reports}</Card.Meta>
+                        <Card.Description>
+                            <List>
+                                <List.Item icon='computer' content={system} />
+                                <List.Item icon='microchip' content={camp} />
+                                <List.Item
+                                    icon='mail'
+                                    content={<a href={machine.owner}>{machine.owner}</a>}
+                                />
+                            </List>
+                        </Card.Description>
+                    </Card.Content>
+                    {/*<Card.Content extra>*/}
+                        {/*<div className='ui buttons'>*/}
+                            {/*/!*todo link to machine page*!/*/}
+                            {/*<Button basic color='blue'>*/}
+                                {/*Other records*/}
+                            {/*</Button>*/}
+                        {/*</div>*/}
+                    {/*</Card.Content>*/}
+                </Card>
+            </div>
+        );
+    }
+}export default FarmerDetailCard;
+
index f4740757a57180ee44e8e2f0045aa34a5ae8dd7f..2fa02a2e4dd1e2e9f16a87de858a51407e67ac1d 100644 (file)
@@ -12,7 +12,8 @@ class NavTop extends React.Component {
     constructor(props) {
         super(props);
         this.state = {
-            username: _util.getStorage('userInfo').username || '',
+            // username: _util.getStorage('userInfo').username || '',
+            userinfo: _util.getStorage('userInfo')|| {},
             isLoggedIn: true
         }
     }
@@ -23,8 +24,21 @@ class NavTop extends React.Component {
         window.location.href = '/login';
     }
 
+    componentWillMount(){
+        this.setState({
+            isLoggedIn: this.isLoggedIn(),
+        });
+    }
+
+    isLoggedIn() {
+        if(this.state.userinfo.token){
+            return true;
+        }
+        return false;
+    }
+
     render() {
-        const isLoggedIn = this.state.isLoggedIn;
+        let isLoggedIn = this.state.isLoggedIn;
 
         let button = null;
         if (isLoggedIn) {
@@ -54,9 +68,9 @@ class NavTop extends React.Component {
             </li>;
         } else {
             button = <li className="dropdown sign-in">
-                <a className="" href="/login" aria-expanded="false">
+                <Link to="/login" aria-expanded="false">
                     Sign in
-                </a>
+                </Link>
             </li>;
         }
 
index bbf6bb44085dcc1e12dbdaad8754344889cd1435..317690e708664d018a049fffb2bdb75dbcbece5f 100644 (file)
@@ -1,6 +1,7 @@
 import React from 'react';
 // import './index.css';
 import PGUtil    from 'util/util.jsx'
+import PGConstant from 'util/constant.jsx'
 const _util = new PGUtil();
 import User         from 'service/user-service.jsx'
 const _user = new User();
@@ -17,6 +18,12 @@ class Login extends React.Component {
 
     componentWillMount() {
         document.title = 'LOGIN';
+        let userinfo = _util.getStorage('userInfo')|| {};
+        if(userinfo.token){
+            this.props.history.push('/portal')
+            // window.location.href = '/portal';
+        }
+
     }
 
     onInputChange(e) {
@@ -42,16 +49,22 @@ class Login extends React.Component {
         // check success
         if (checkResult.status) {
             _user.login(loginInfo).then((res) => {
-                console.dir(res)
+                // console.dir(res)
                 _util.setStorage('userInfo', res);
-                this.props.history.push(this.state.redirect);
-            }, (errMsg) => {
-                // console.log(errMsg)
-                _util.errorTips(errMsg);
+                // this.props.history.push(this.state.redirect);
+                window.location.href = this.state.redirect;
+            }, (err) => {
+                // console.log(err)
+                if (PGConstant.AuthorizedErrorCode === err) {
+                    _util.errorTips('username or password is mistake!');
+                }else{
+                    _util.errorTips('login fail');
+                }
             });
         }
         // check failure
         else {
+
             _util.errorTips(checkResult.msg);
         }
 
diff --git a/front-end/src/page/machineInfo/index.css b/front-end/src/page/machineInfo/index.css
new file mode 100644 (file)
index 0000000..14cbbe9
--- /dev/null
@@ -0,0 +1,12 @@
+.machine-info-divier-div{
+    margin-left: 15px!important;
+    float: left;
+}
+.machine-info-divier{
+    float: left;
+}
+.blank{
+    float: left;
+    width: 15px;
+    height: 2px;
+}
\ No newline at end of file
index 0c9740ecad5cac26ef66e777fba0abbfdb62b444..8e54e4c6a278c22fd1670d273b0e6c8118f85724 100644 (file)
@@ -1,29 +1,29 @@
 import React from 'react';
 // import './index.css';
-import ResultFilter from 'component/result-filter/index.jsx';
-import BasicTable    from 'util/basic-table/index.jsx';
+import {Table, Divider, Segment, Icon} from 'semantic-ui-react'
+import FarmerDetailCard      from 'component/farmer-detail-card/index.jsx'
 import Record      from 'service/record-service.jsx'
 import PGUtil        from 'util/util.jsx'
-
+import MachineRecordTable from 'util/machine-record-table/index.jsx'
 const _util = new PGUtil();
 const _record = new Record();
 class MachineInfo extends React.Component {
     constructor(props) {
         super(props);
         this.state = {
+            machineNo: this.props.match.params.machine_sn,
+            machineInfo: {},
             isLoading: false,
             currentPage: 1,
             total:3,
             filter: {},
             list: [
             ]
-
         },
-
+        console.dir(this.props.match.params)
         this.onPageChange = this.onPageChange.bind(this);
-        this.onIsLoadingChange = this.onIsLoadingChange.bind(this);
         this.handleApplyBtnClick = this.handleApplyBtnClick.bind(this);
-        this.loadRecordList = this.loadRecordList.bind(this);
+        this.loadHistoryRecordList = this.loadHistoryRecordList.bind(this);
     }
 
     componentDidMount() {
@@ -40,20 +40,21 @@ class MachineInfo extends React.Component {
     }
 
     // load history record list
-    loadHistoryRecordList(page=1) {
+    loadHistoryRecordList() {
         let _this = this;
         let listParam = {};
-        listParam= this.state.filter;
-        listParam.page = page;
-
-        _record.getRecordList(listParam).then(res => {
+        // listParam= this.state.filter;
+        // listParam.page = page;
+        listParam.machine_sn = this.state.machineNo;
+        _record.getHistoryRecordList(listParam).then(res => {
             console.log('res is:' + res)
             this.setState({
-                list: res.results,
-                total: res.count,
+                machineInfo: res.machine_info || {},
+                list: res.reports || [],
+                // total: res.count,
                 isLoading: false
             });
-            _this.changeIsLoading(false);
+            // _this.changeIsLoading(false);
         }, errMsg => {
             this.setState({
                 list: []
@@ -82,8 +83,33 @@ class MachineInfo extends React.Component {
         };
 
         return (
-            <div id="page-wrapper">
-                <BasicTable list={this.state.list} total={this.state.total} current={this.state.currentPage} loadfunc={this.loadRecordList}/>
+            <div className="container-fluid detail-container">
+                <div className="record-title">
+
+                    <div className="record-title-top">
+                        <span>NO: {this.state.machineNo}</span>
+                        {/*<span>Add Date: {this.state.machineInfo.addtime}</span>*/}
+                    </div>
+                    <h2 >Farmer: {this.state.machineInfo.alias}</h2>
+                </div>
+
+                <div className="machine-info-divier-div">
+                    <div className="blank"></div>
+                    <Divider className="machine-info-divier"></Divider>
+                </div>
+                <div className="col-md-3">
+                    <Segment vertical>Farmer Info</Segment>
+                    <FarmerDetailCard machine={this.state.machineInfo}></FarmerDetailCard>
+                </div>
+
+                <div className="col-md-9">
+                    {/*<div className="card-container row">*/}
+
+                    <div className="info-container col-md-12 col-md-offset-1">
+                        <MachineRecordTable list={this.state.list} total={this.state.total} current={this.state.currentPage} loadfunc={this.loadRecordList}/>
+                    </div>
+
+                </div>
             </div>
         )
     }
diff --git a/front-end/src/page/machineInfo/index.scss b/front-end/src/page/machineInfo/index.scss
deleted file mode 100644 (file)
index e69de29..0000000
index 14061905d533db44b9d1dfb0f13dc36b543f0d96..9e292c60908b93ff84d267b84dbdedeb3047174e 100644 (file)
@@ -1,5 +1,6 @@
 import React from 'react';
 import './index.css';
+import { hashHistory } from 'react-router'
 import ResultFilter from 'component/result-filter/index.jsx';
 import MachineTable    from 'util/machine-table/index.jsx';
 import UserInfoCard from 'component/userinfo-card/index.jsx'
@@ -22,6 +23,7 @@ class Portal extends React.Component {
 
     }
     componentDidMount(){
+
         let user = _util.getStorage('userInfo')
         this.setState({
             username: user.username,
@@ -54,7 +56,9 @@ class Portal extends React.Component {
     }
     onLogout(){
         _util.removeStorage('userInfo');
-        window.location.href = '/login';
+        // this.props.history.push('/login')
+        // hashHistory.push('/login')
+        window.location.href = '/';
         // _user.logout().then(res => {
         //     _util.removeStorage('userInfo');
         //     window.location.href = '/login';
index c45e7669ba23aed7a11cdf3b03073e7568a3bbef..6e79a217fec118724195334eaf1974bec26d2c20 100644 (file)
@@ -30,6 +30,22 @@ class Record{
             // data    : {'Ldw7RrdP7jj4q89kgXCfeY'}
         });
     }
+
+    // get history record list
+    getHistoryRecordList(listParam){
+        let url = PGConstant.base_url + '/machine-records/' + listParam.machine_sn;
+
+        let data = {};
+        // data = listParam;
+
+        console.log('final data')
+        console.dir(listParam);
+        return _util.request({
+            type    : 'get',
+            url     : url,
+            data    : data
+        });
+    }
 }
 
 export default Record;
\ No newline at end of file
index 2c0e3fb9c726802760215a1d4401afd989f6b517..f0e6e6aa69d306b63ee947cf1590238a0686975e 100644 (file)
@@ -4,6 +4,7 @@ const object = {
 
     name:'好123',
     UnauthorizedCode:401,// unlogin
+    AuthorizedErrorCode:400,// username or pwd mistake
 
 };
 export default object;
\ No newline at end of file
diff --git a/front-end/src/util/machine-record-table/index.css b/front-end/src/util/machine-record-table/index.css
new file mode 100644 (file)
index 0000000..0fe34f8
--- /dev/null
@@ -0,0 +1,43 @@
+.ReactTable .rt-th{
+    background-color: #ffffff;
+}
+
+.ReactTable .-pagination{
+    background-color: #ffffff;
+}
+
+.ReactTable .rt-tr-group:nth-child(2n) {
+    background-color: #ffffff;
+}
+
+.bgc-clear{
+    background-color: #ffffff;
+}
+
+.anonymous {
+    color: #e8e8e8;
+}
+
+.anonymous :hover {
+    color: lightgrey;
+}
+.improved {
+    color: #7cb305;
+}
+
+.quo {
+    color: #40a9ff;
+}
+
+.regressive {
+    color: #fa541c;
+}
+
+.mini-label {
+    font-weight: 100!important;
+    font-size: 0.1em!important;
+    min-width: 1.3em!important;
+    min-height: 0.1em!important;
+    padding: .2em!important;
+    line-height: 0.5em!important;
+}
\ No newline at end of file
diff --git a/front-end/src/util/machine-record-table/index.jsx b/front-end/src/util/machine-record-table/index.jsx
new file mode 100644 (file)
index 0000000..4705b0c
--- /dev/null
@@ -0,0 +1,189 @@
+import React from 'react';
+import {Link}     from 'react-router-dom';
+import {Icon, Table, Label, Message, Button} from 'semantic-ui-react'
+import Pagination from 'util/pagination/index.jsx'
+import './index.css';
+
+function Bubble(props) {
+
+    if (props.num <= 0) {
+        return null;
+    }
+    let className = props.name + 'IconClassName';
+    return (
+        <Label circular size="mini" className={"mini-label " + className}>
+            {props.num}
+        </Label>
+    );
+}
+
+//todo
+// function TrendCell(trend) {
+//     const isNull = !list;
+//     const isEmpty = !isNull && !list.length;
+//     let improvedIconClassName = trend.improved > 0 ? 'improved' : 'anonymous'
+//     let quoIconClassName = trend.quo > 0 ? 'quo' : 'anonymous'
+//     let regressiveIconClassName = trend.regressive > 0 ? 'regressive' : 'anonymous'
+//     if (!trend.is_first) {
+//         return (
+//             <Table.Cell  textAlign='center'>
+//                 first report
+//             </Table.Cell>
+//         );
+//     } else {
+//         return (
+//             <div>
+//                 <Table.Cell textAlign='center'>
+//                     <Icon className={"bgc-clear " + improvedIconClassName} name='smile outline' size='large'/>
+//                     <Bubble num={trend.improved} name="improved"/>
+//                 </Table.Cell>
+//                 <Table.Cell textAlign='center'>
+//                     <Icon className={"bgc-clear " + quoIconClassName} name='meh outline' size='large'/>
+//                     <Bubble num={trend.quo} name="quo"/>
+//                 </Table.Cell>
+//                 <Table.Cell textAlign='center'>
+//                     <Icon className={"bgc-clear " + regressiveIconClassName} name='frown outline'
+//                           size='large'/>
+//                     <Bubble num={trend.regressive} name="regressive"/>
+//                 </Table.Cell>
+//             </div>
+//         );
+//     }
+//
+// }
+
+// general basic table
+class MachineRecordTable extends React.Component {
+    constructor(props) {
+        super(props);
+        this.state = {
+            isFirstLoading: true,
+            total: this.props.total,
+            currentPage: 1,
+        }
+    }
+
+
+    // onPageNumChange(current) {
+    //     this.setState({
+    //         currentPage: current
+    //     }, () => {
+    //         this.props.loadfunc(current);
+    //     });
+    //     console.log('current:' + this.state.currentPage)
+    // }
+
+    render() {
+        // let branch = record.pg_info.pg_branch;
+        let _list = this.props.list.records || []
+        let style = {
+            display: 'show'
+        };
+        let listBody = _list.map((record, index) => {
+            let machine = record.machine_info[0];
+            let system = machine.os_name + ' ' + machine.os_version + ' ' + machine.comp_name + ' ' + machine.comp_version;
+            let alias = machine.alias;
+
+
+            let trend = record.trend
+            let improvedIconClassName = trend.improved > 0 ? 'improved' : 'anonymous'
+            let quoIconClassName = trend.quo > 0 ? 'quo' : 'anonymous'
+            let regressiveIconClassName = trend.regressive > 0 ? 'regressive' : 'anonymous'
+            return (
+
+                <Table.Row key={index}>
+                    {/*alias*/}
+                    <Table.Cell><a href="#">{alias}</a></Table.Cell>
+
+                    {/*system*/}
+                    <Table.Cell><a href="#">{system}</a></Table.Cell>
+
+                    {/*branch*/}
+                    {/*<Table.Cell>{branch}</Table.Cell>*/}
+
+                    {/*trending-data*/}
+
+                    <Table.Cell textAlign='center'>
+                        <Icon className={"bgc-clear " + improvedIconClassName} name='smile outline' size='large'/>
+                        <Bubble num={trend.improved} name="improved"/>
+                    </Table.Cell>
+                    <Table.Cell textAlign='center'>
+                        <Icon className={"bgc-clear " + quoIconClassName} name='meh outline' size='large'/>
+                        <Bubble num={trend.quo} name="quo"/>
+                    </Table.Cell>
+                    <Table.Cell textAlign='center'>
+                        <Icon className={"bgc-clear " + regressiveIconClassName} name='frown outline'
+                              size='large'/>
+                        <Bubble num={trend.regressive} name="regressive"/>
+                    </Table.Cell>
+
+
+                    <Table.Cell textAlign='center'>
+                        <Link color='linkedin' to={'detailInfo/' + record.uuid}>
+                            <Icon name='linkify'/> Link
+                        </Link>
+                    </Table.Cell>
+
+
+                    {/*date*/}
+                    <Table.Cell>{record.add_time}</Table.Cell>
+                </Table.Row>
+            );
+        });
+
+        return (
+            <Table celled structured compact textAlign='center'>
+                <Table.Header>
+                    {/*<Table.Row>*/}
+                    {/*<Table.HeaderCell rowSpan='9'>Branch: 10_STABLE</Table.HeaderCell>*/}
+                    {/*</Table.Row>*/}
+                    <Table.Row>
+                        <Table.HeaderCell rowSpan='2'>Alias</Table.HeaderCell>
+                        <Table.HeaderCell rowSpan='2'>System</Table.HeaderCell>
+                        {/*<Table.HeaderCell rowSpan='2'>Branch</Table.HeaderCell>*/}
+                        <Table.HeaderCell colSpan='3'>Trending</Table.HeaderCell>
+                        <Table.HeaderCell rowSpan='2'>Detail</Table.HeaderCell>
+                        <Table.HeaderCell rowSpan='2'>Date</Table.HeaderCell>
+                    </Table.Row>
+                    <Table.Row>
+                        <Table.HeaderCell>improvement</Table.HeaderCell>
+                        <Table.HeaderCell>status quo</Table.HeaderCell>
+                        <Table.HeaderCell>regression</Table.HeaderCell>
+                    </Table.Row>
+
+                </Table.Header>
+
+                <Table.Body>
+                    {listBody}
+                </Table.Body>
+                <Table.Footer>
+                    <Table.Row>
+                        <Table.HeaderCell colSpan='10'>
+                            {/*<Menu size='small' floated='right' pagination>*/}
+                            {/*<Menu.Item as='a' icon>*/}
+                            {/*<Icon name='chevron left'/>*/}
+                            {/*</Menu.Item>*/}
+                            {/*<Menu.Item as='a'>1</Menu.Item>*/}
+                            {/*<Menu.Item as='a'>2</Menu.Item>*/}
+                            {/*<Menu.Item as='a'>3</Menu.Item>*/}
+                            {/*<Menu.Item as='a'>4</Menu.Item>*/}
+                            {/*<Menu.Item as='a' icon>*/}
+                            {/*<Icon name='chevron right'/>*/}
+                            {/*</Menu.Item>*/}
+                            {/*</Menu>*/}
+                            {/*<Pagination style={style} onChange={(current) => this.onPageNumChange(current)} pageSize={2}*/}
+                                        {/*current={this.state.currentPage} total={this.props.total}/>*/}
+
+                        </Table.HeaderCell>
+
+                    </Table.Row>
+                </Table.Footer>
+            </Table>
+        );
+
+    }
+
+
+}
+
+export default MachineRecordTable;
\ No newline at end of file
index 0fe34f8c4987b396f2ff662cd0d9f2057fc28f67..af59a47ca880583e43d8c9dc1f60a6107375146f 100644 (file)
@@ -40,4 +40,9 @@
     min-height: 0.1em!important;
     padding: .2em!important;
     line-height: 0.5em!important;
+}
+
+.link-div{
+    display: flex;
+    flex-direction: column;
 }
\ No newline at end of file
index 34cc229167d2cef91b0098bab57efd7509e31cbf..a5154bc69d2f0ef5f1eb08a7637753f6e5c20fe4 100644 (file)
@@ -54,9 +54,14 @@ class MachineTable extends React.Component {
             // let improvedIconClassName = trend.improved > 0 ? 'improved' : 'anonymous'
             // let quoIconClassName = trend.quo > 0 ? 'quo' : 'anonymous'
             // let regressiveIconClassName = trend.regressive > 0 ? 'regressive' : 'anonymous'
+            let color = 'positive';
+            if(machine.state == 'pending'){
+                color = 'warning';
+            }else if(machine.state == 'prohibited'){
+                color = 'negative';
+            }
             return (
-
-                <Table.Row key={index}>
+                <Table.Row key={index} className={color}>
                     {/*alias*/}
                     <Table.Cell><a href="#">{machine.alias}</a></Table.Cell>
 
@@ -64,18 +69,22 @@ class MachineTable extends React.Component {
                     <Table.Cell><a href="#">{system}</a></Table.Cell>
 
                     {/*State*/}
-                    <Table.Cell>{machine.state}</Table.Cell>
+                    <Table.Cell>
+                        {machine.state}
+                    </Table.Cell>
 
                     {/*lastest-records*/}
                     <Table.Cell textAlign='center'>
                         {/*<Icon className={"bgc-clear " + improvedIconClassName} name='smile outline' size='large'/>*/}
                         {/*<Bubble num={trend.improved} name="improved"/>*/}
-                        <LastestLink list={machine.lastest}/>
+                        <div className="link-div">
+                            <LastestLink list={machine.lastest}/>
+                        </div>
                     </Table.Cell>
 
                     {/*machine history*/}
                     <Table.Cell textAlign='center'>
-                        <Link color='linkedin' to={'machineInfo/' + '###'}>
+                        <Link color='linkedin' to={'machineInfo/' + machine.machine_sn}>
                             <Icon name='linkify'/> Link
                         </Link>
                     </Table.Cell>
@@ -116,7 +125,7 @@ class MachineTable extends React.Component {
                     <Table.Row>
                         <Table.HeaderCell colSpan='10'>
 
-                            <Pagination style={style} onChange={(current) => this.onPageNumChange(current)} pageSize={2}
+                            <Pagination style={style} onChange={(current) => this.onPageNumChange(current)} pageSize={15}
                                         current={this.state.currentPage} total={this.props.total}/>
                         </Table.HeaderCell>
 
index 4c69ef98998ccd7e60d1fb6ddfd79c59c33b8025..6a93479989b0b6ef5b3a28c6e9f2afb6c199d9bb 100644 (file)
@@ -32,9 +32,10 @@ class PGUtil {
                     console.dir(err.status)
                     // nologin force to login
                     if (PGConstant.UnauthorizedCode === err.status) {
+                        this.removeStorage('userInfo');
                         this.doLogin();
                     } else {
-                        typeof reject === 'function' && reject(err.statusText);
+                        typeof reject === 'function' && reject(err.status);
                     }
 
                 }
@@ -44,7 +45,8 @@ class PGUtil {
 
     // redirect to login
     doLogin() {
-        window.location.href = '/login?redirect=' + encodeURIComponent(window.location.pathname);
+        this.props.history.push('/login')
+        // window.location.href = '/login?redirect=' + encodeURIComponent(window.location.pathname);
         // window.location.href = '/login';
     }
 
index b50071dca53cf64484ae6abefe9086396e9fd2bc..556db499624900968205484ba4dddcd3b4040cb3 100644 (file)
@@ -7,6 +7,7 @@ from users.serializer import UserMachineSerializer
 from users.models import UserMachine
 from django.db.models import Count
 
+
 class TestBranchSerializer(serializers.ModelSerializer):
     '''
     use TestBranchSerializer
@@ -16,6 +17,7 @@ class TestBranchSerializer(serializers.ModelSerializer):
         model = TestBranch
         fields = ('branch_name',)
 
+
 class TestCategorySerializer(serializers.ModelSerializer):
     '''
     use TestCategorySerializer
@@ -45,6 +47,7 @@ class HardwareInfoDetailSerializer(serializers.ModelSerializer):
         model = LinuxInfo
         fields = ('cpuinfo', 'meminfo')
 
+
 class LinuxInfoDetailSerializer(serializers.ModelSerializer):
     '''
     use LinuxInfoDetailSerializer
@@ -54,6 +57,7 @@ class LinuxInfoDetailSerializer(serializers.ModelSerializer):
         model = LinuxInfo
         fields = ('mounts', 'sysctl')
 
+
 class LinuxInfoSerializer(serializers.ModelSerializer):
     '''
     use LinuxInfoSerializer
@@ -71,7 +75,8 @@ class MetaInfoDetailSerializer(serializers.ModelSerializer):
 
     class Meta:
         model = MetaInfo
-        fields = ('uname', )
+        fields = ('uname',)
+
 
 class MetaInfoSerializer(serializers.ModelSerializer):
     '''
@@ -88,13 +93,16 @@ class TestResultSerializer(serializers.ModelSerializer):
     use TestResultSerializer
     '''
     mode = serializers.SerializerMethodField()
+
     class Meta:
         model = TestResult
         fields = "__all__"
+
     def get_mode(self, obj):
         new_dict = {v: k for k, v in DB_ENUM["mode"].items()}
         return new_dict[obj.mode]
 
+
 class CreateTestRecordSerializer(serializers.ModelSerializer):
     '''
     create ModelSerializer
@@ -143,7 +151,7 @@ class TestRecordListSerializer(serializers.ModelSerializer):
     # client_max_num = serializers.SerializerMethodField()
     class Meta:
         model = TestRecord
-        fields = ('uuid', 'add_time', 'machine_info', 'pg_info', 'branch','trend', 'linux_info', 'meta_info')
+        fields = ('uuid', 'add_time', 'machine_info', 'pg_info', 'branch', 'trend', 'linux_info', 'meta_info')
 
     def get_branch(self, obj):
         branch = TestBranch.objects.filter(id=obj.branch.id).first()
@@ -191,6 +199,7 @@ class TestRecordListSerializer(serializers.ModelSerializer):
 
 class TestDataSetDetailSerializer(serializers.ModelSerializer):
     results = serializers.SerializerMethodField()
+
     class Meta:
         model = TestDataSet
         fields = "__all__"
@@ -220,7 +229,8 @@ class TestRecordDetailSerializer(serializers.ModelSerializer):
     class Meta:
         model = TestRecord
         fields = (
-            'branch', 'date', 'uuid', 'pg_info', 'linux_info', 'hardware_info', 'meta_info', 'dataset_info', 'test_desc', 'meta_time', 'test_machine')
+            'branch', 'date', 'uuid', 'pg_info', 'linux_info', 'hardware_info', 'meta_info', 'dataset_info',
+            'test_desc', 'meta_time', 'test_machine')
 
     def get_branch(self, obj):
         branch = TestBranch.objects.filter(id=obj.branch_id).first()
@@ -287,6 +297,7 @@ class TestRecordDetailSerializer(serializers.ModelSerializer):
     #     rw_info_serializer = TestResultSerializer(all_data, many=True, context={'request': self.context['request']})
     #     return rw_info_serializer.data
 
+
 class MachineHistoryRecordSerializer(serializers.ModelSerializer):
     '''
     use MachineHistoryRecordSerializer
@@ -299,13 +310,23 @@ class MachineHistoryRecordSerializer(serializers.ModelSerializer):
         fields = ('machine_info', 'reports')
 
     def get_reports(self, obj):
-        target_records = TestRecord.objects.filter(test_machine_id=obj.id)
-        serializer = TestRecordListSerializer(target_records,many=True)
+        target_records = TestRecord.objects.filter(test_machine_id=obj.id).values_list(
+            'branch').annotate(Count('id'))
+        # print(target_records) # <QuerySet [(2, 2), (1, 3)]>
+        ret = []
+        for branch_item in target_records:
+            item = {}
+            item['branch'] = branch_item[0]
 
-        return serializer.data
+            records = TestRecord.objects.filter(test_machine_id=obj.id,branch_id=branch_item[0])
+
+            serializer = TestRecordListSerializer(records, many=True)
+            item['records'] = serializer.data
+            ret.append(item)
+        return ret
 
     def get_machine_info(self, obj):
         target_machine = UserMachine.objects.filter(id=obj.id).first()
         serializer = UserMachineSerializer(target_machine)
 
-        return serializer.data
\ No newline at end of file
+        return serializer.data
index 10ce25fbc939168759204aca20e251afb4732d17..ce701459d2b9a95ae8763a81b2162c507f1bff6b 100644 (file)
@@ -52,7 +52,7 @@ class TestRecordDetailViewSet(mixins.RetrieveModelMixin, viewsets.GenericViewSet
     serializer_class = TestRecordDetailSerializer
     # pagination_class = StandardResultsSetPagination
 
-class MachineHistoryRecordViewSet(mixins.RetrieveModelMixin, viewsets.GenericViewSet):
+class MachineHistoryRecordViewSet( mixins.RetrieveModelMixin, viewsets.GenericViewSet):
     """
     detail test records
     """
index 9361c179c04c0e93af405e4eb18fbff4fce55593..770b083428bc745c063aec3553ffc2004b110c85 100644 (file)
@@ -41,7 +41,7 @@ class UserMachineManageSerializer(serializers.ModelSerializer):
     state = serializers.SerializerMethodField()
     class Meta:
         model = UserMachine
-        fields = ('alias', 'os_name', 'os_version', 'comp_name', 'comp_version', 'reports', 'state', 'lastest', 'state', 'add_time')
+        fields = ('alias', 'machine_sn','os_name', 'os_version', 'comp_name', 'comp_version', 'reports', 'state', 'lastest', 'state', 'add_time')
 
     def get_state(self, obj):
         state_code = obj.state
index f6b5989e0d252786ee25254494433018a34708d0..7e4ff2023147e4c0f124ec3757065eec6dee3bf8 100644 (file)
@@ -36,7 +36,7 @@ from user_operation.views import UserMachineListViewSet, UserPortalInfoViewSet
 router = DefaultRouter()
 router.register(r'records', TestRecordListViewSet, base_name="records")
 router.register(r'detail', TestRecordDetailViewSet, base_name="detail")
-router.register(r'machine', MachineHistoryRecordViewSet, base_name="machine")
+router.register(r'machine-records', MachineHistoryRecordViewSet, base_name="machine-records")
 
 
 # user's machine manage list