diff options
author | Hongyuan Ma | 2018-07-09 14:38:08 +0000 |
---|---|---|
committer | Hongyuan Ma | 2018-07-09 14:38:08 +0000 |
commit | e8d19d9bb977f473783242e9df8e5b520a65a28b (patch) | |
tree | 72c1cb2ca9bc9f799d9f1726beecf4379dd320f4 | |
parent | b4f869cf90f3968d219f362a975612e5c749b169 (diff) |
add MachineRecordTable;
-rw-r--r-- | front-end/src/app.jsx | 5 | ||||
-rw-r--r-- | front-end/src/component/farmer-detail-card/index.jsx | 47 | ||||
-rw-r--r-- | front-end/src/component/nav-top/index.jsx | 22 | ||||
-rw-r--r-- | front-end/src/page/login/index.jsx | 23 | ||||
-rw-r--r-- | front-end/src/page/machineInfo/index.css | 12 | ||||
-rw-r--r-- | front-end/src/page/machineInfo/index.jsx | 60 | ||||
-rw-r--r-- | front-end/src/page/machineInfo/index.scss | 0 | ||||
-rw-r--r-- | front-end/src/page/portal/index.jsx | 6 | ||||
-rw-r--r-- | front-end/src/service/record-service.jsx | 16 | ||||
-rw-r--r-- | front-end/src/util/constant.jsx | 1 | ||||
-rw-r--r-- | front-end/src/util/machine-record-table/index.css | 43 | ||||
-rw-r--r-- | front-end/src/util/machine-record-table/index.jsx | 189 | ||||
-rw-r--r-- | front-end/src/util/machine-table/index.css | 5 | ||||
-rw-r--r-- | front-end/src/util/machine-table/index.jsx | 21 | ||||
-rw-r--r-- | front-end/src/util/util.jsx | 6 | ||||
-rw-r--r-- | web/apps/test_records/serializer.py | 35 | ||||
-rw-r--r-- | web/apps/test_records/views.py | 2 | ||||
-rw-r--r-- | web/apps/user_operation/serializer.py | 2 | ||||
-rw-r--r-- | web/pgperffarm/urls.py | 2 |
19 files changed, 450 insertions, 47 deletions
diff --git a/front-end/src/app.jsx b/front-end/src/app.jsx index 78443b1..6606564 100644 --- a/front-end/src/app.jsx +++ b/front-end/src/app.jsx @@ -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 index 0000000..9e328d5 --- /dev/null +++ b/front-end/src/component/farmer-detail-card/index.jsx @@ -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; + diff --git a/front-end/src/component/nav-top/index.jsx b/front-end/src/component/nav-top/index.jsx index f474075..2fa02a2 100644 --- a/front-end/src/component/nav-top/index.jsx +++ b/front-end/src/component/nav-top/index.jsx @@ -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="/https/git.postgresql.org/login" aria-expanded="false"> + <Link to="/login" aria-expanded="false"> Sign in - </a> + </Link> </li>; } diff --git a/front-end/src/page/login/index.jsx b/front-end/src/page/login/index.jsx index bbf6bb4..317690e 100644 --- a/front-end/src/page/login/index.jsx +++ b/front-end/src/page/login/index.jsx @@ -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 index 0000000..14cbbe9 --- /dev/null +++ b/front-end/src/page/machineInfo/index.css @@ -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 diff --git a/front-end/src/page/machineInfo/index.jsx b/front-end/src/page/machineInfo/index.jsx index 0c9740e..8e54e4c 100644 --- a/front-end/src/page/machineInfo/index.jsx +++ b/front-end/src/page/machineInfo/index.jsx @@ -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 index e69de29..0000000 --- a/front-end/src/page/machineInfo/index.scss +++ /dev/null diff --git a/front-end/src/page/portal/index.jsx b/front-end/src/page/portal/index.jsx index 1406190..9e292c6 100644 --- a/front-end/src/page/portal/index.jsx +++ b/front-end/src/page/portal/index.jsx @@ -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'; diff --git a/front-end/src/service/record-service.jsx b/front-end/src/service/record-service.jsx index c45e766..6e79a21 100644 --- a/front-end/src/service/record-service.jsx +++ b/front-end/src/service/record-service.jsx @@ -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 diff --git a/front-end/src/util/constant.jsx b/front-end/src/util/constant.jsx index 2c0e3fb..f0e6e6a 100644 --- a/front-end/src/util/constant.jsx +++ b/front-end/src/util/constant.jsx @@ -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 index 0000000..0fe34f8 --- /dev/null +++ b/front-end/src/util/machine-record-table/index.css @@ -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 index 0000000..4705b0c --- /dev/null +++ b/front-end/src/util/machine-record-table/index.jsx @@ -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 diff --git a/front-end/src/util/machine-table/index.css b/front-end/src/util/machine-table/index.css index 0fe34f8..af59a47 100644 --- a/front-end/src/util/machine-table/index.css +++ b/front-end/src/util/machine-table/index.css @@ -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 diff --git a/front-end/src/util/machine-table/index.jsx b/front-end/src/util/machine-table/index.jsx index 34cc229..a5154bc 100644 --- a/front-end/src/util/machine-table/index.jsx +++ b/front-end/src/util/machine-table/index.jsx @@ -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> diff --git a/front-end/src/util/util.jsx b/front-end/src/util/util.jsx index 4c69ef9..6a93479 100644 --- a/front-end/src/util/util.jsx +++ b/front-end/src/util/util.jsx @@ -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'; } diff --git a/web/apps/test_records/serializer.py b/web/apps/test_records/serializer.py index b50071d..556db49 100644 --- a/web/apps/test_records/serializer.py +++ b/web/apps/test_records/serializer.py @@ -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 diff --git a/web/apps/test_records/views.py b/web/apps/test_records/views.py index 10ce25f..ce70145 100644 --- a/web/apps/test_records/views.py +++ b/web/apps/test_records/views.py @@ -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 """ diff --git a/web/apps/user_operation/serializer.py b/web/apps/user_operation/serializer.py index 9361c17..770b083 100644 --- a/web/apps/user_operation/serializer.py +++ b/web/apps/user_operation/serializer.py @@ -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 diff --git a/web/pgperffarm/urls.py b/web/pgperffarm/urls.py index f6b5989..7e4ff20 100644 --- a/web/pgperffarm/urls.py +++ b/web/pgperffarm/urls.py @@ -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 |