import MachinelInfo from './page/machineInfo/index.jsx'
import Portal from './page/portal/index.jsx'
+import FarmerApply from './page/farmerApply/index.jsx'
+
// we need to map the `scale` prop we define below
// to the transform style property
function mapStyles(styles) {
<Route exact path="/ppolicy/" component={PPolicy}/>
<Route exact path="/portal/" component={Portal}/>
+ <Route exact path="/farmerApply/" component={FarmerApply}/>
<Route path="/detailInfo/:uuid" component={DetailInfo}/>
<Route path="/machineInfo/:machine_sn" component={MachinelInfo}/>
{/*<Redirect exact from="/order" to="/order/index"/>*/}
/*----------------------------------------------
COMMON STYLES
+ https://www.webthemez.com/demo/insight-free-bootstrap-html5-admin-template/empty.html#
------------------------------------------------*/
body {
font-family: 'Open Sans', sans-serif;
.trend-span .regressive{
color: #cf1322!important;
+}
+
+
+/*catalog*/
+.catalog.ui.vertical.menu {
+ width: 100%;
+}
+.catalog.ui.menu .item{
+ color: inherit;
}
\ No newline at end of file
import React from 'react';
import {Link} from 'react-router-dom';
import './index.css';
-import {Table, Divider, Segment, Icon} from 'semantic-ui-react'
+import {Table, Divider, Segment, Icon, Menu, Input, Dropdown, Sticky} from 'semantic-ui-react'
import PGUtil from 'util/util.jsx'
import FarmerCard from 'component/farmer-card/index.jsx'
import InfoList from 'component/info-list/index.jsx'
});
}
+
render() {
let prev = this.state.recordInfo.prev || 'none';
- let branch = this.state.recordInfo.branch || '';
- let commit = this.state.recordInfo.commit || '';
+ let branch = this.state.recordInfo.branch || '';
+ let commit = this.state.recordInfo.commit || '';
let date = this.state.recordInfo.date || '';
let machine = this.state.recordInfo.test_machine || {};
let dataset = this.state.recordInfo.dataset_info || {};
if (status == -1) {
trend_span = <span>{percentage}</span>;
- } else if (status == 1){
+ } else if (status == 1) {
trend_span = <span className="trend-span improved"><Icon name="angle double up"/>+{percentage}</span>;
- } else if (status == 2){
+ } else if (status == 2) {
trend_span = <span className="trend-span quo"><Icon name="bars"/>+{percentage}</span>;
- } else if (status == 3){
- trend_span = <span className="trend-span regressive"><Icon name="angle double down"/>{percentage}</span>;
+ } else if (status == 3) {
+ trend_span =
+ <span className="trend-span regressive"><Icon name="angle double down"/>{percentage}</span>;
}
return (
<Table.Row>
<Table.HeaderCell colSpan="4">
<div className="client-title-div">
- <div>Client(s) {key}: {metric} {trend_span}</div>
+ <div>Client(s) {key}: {metric} {trend_span}</div>
{/*<div><a href=""> >>prev</a></div>*/}
</div>
{/*<div>*/}
- {/*<span>Improved ()</span>*/}
+ {/*<span>Improved ()</span>*/}
{/*</div>*/}
</Table.HeaderCell>
</Table.Row>
if (status == -1) {
trend_span = <span>{percentage}</span>;
- } else if (status == 1){
+ } else if (status == 1) {
trend_span = <span className="trend-span improved"><Icon name="angle double up"/>+{percentage}</span>;
- } else if (status == 2){
+ } else if (status == 2) {
trend_span = <span className="trend-span quo"><Icon name="bars"/>+{percentage}</span>;
- } else if (status == 3){
- trend_span = <span className="trend-span regressive"><Icon name="angle double down"/>{percentage}</span>;
+ } else if (status == 3) {
+ trend_span =
+ <span className="trend-span regressive"><Icon name="angle double down"/>{percentage}</span>;
}
return (
<Table.Row>
<Table.HeaderCell colSpan="4">
<div className="client-title-div">
- <div>Client(s) {key}: {metric} {trend_span}</div>
+ <div>Client(s) {key}: {metric} {trend_span}</div>
{/*<div><a href=""> >>prev</a></div>*/}
</div>
{/*<div>*/}
});
let prev_link
- if(prev == 'none') {
+ if (prev == 'none') {
prev_link = prev
- }else{
+ } else {
prev_link = (
- <Link target = '_blank' color='linkedin' to={'/detailInfo/' + prev}>
+ <Link target='_blank' color='linkedin' to={'/detailInfo/' + prev}>
{prev.substring(0, 7)}
</Link>
)
}
+
return (
<div className="container-fluid detail-container">
<div className="record-title ">
<div className="record-title-right title-flex">
<div className="record-title-top">
<span>Branch: {branch}</span>
- <span>Commit: <a target="_blank" href={ PGConstant.PG_GITHUB_MIRROR + commit}>{commit.substring(0, 7)}</a></span>
+ <span>Commit: <a target="_blank"
+ href={ PGConstant.PG_GITHUB_MIRROR + commit}>{commit.substring(0, 7)}</a></span>
</div>
<div className="record-title-bottom">
<h2 >NO: {this.state.recordNo}</h2>
<Segment vertical>Farmer Info</Segment>
<FarmerCard machine={machine}></FarmerCard>
{/*//todo add a catalog*/}
- {/*<div className="affix">aaaa</div>*/}
+
</div>
<div className="col-md-9">
<div>
{/*<h2><a href="#linuxInfo">Linux Info</a></h2>*/}
{/*<div className="" data-example-id="">*/}
- {/*<dl>*/}
- {/*<dt><a href="#">Description lists</a></dt>*/}
- {/*<dd>A description list is perfect for defining terms.</dd>*/}
- {/*<dt>Euismod</dt>*/}
- {/*<dd>*/}
- {/*</dd>*/}
- {/*<dd></dd>*/}
- {/*<dt>Malesuada porta</dt>*/}
- {/*<dd>Etiam porta sem malesuada magna mollis euismod.</dd>*/}
- {/*</dl>*/}
+ {/*<dl>*/}
+ {/*<dt><a href="#">Description lists</a></dt>*/}
+ {/*<dd>A description list is perfect for defining terms.</dd>*/}
+ {/*<dt>Euismod</dt>*/}
+ {/*<dd>*/}
+ {/*</dd>*/}
+ {/*<dd></dd>*/}
+ {/*<dt>Malesuada porta</dt>*/}
+ {/*<dd>Etiam porta sem malesuada magna mollis euismod.</dd>*/}
+ {/*</dl>*/}
{/*</div>*/}
import React from 'react';
+import {hashHistory} from 'React-router'
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 {Link} from 'react-router-dom';
import UserInfoCard from 'component/userinfo-card/index.jsx'
import Record from 'service/record-service.jsx'
import PGUtil from 'util/util.jsx'
import User from 'service/user-service.jsx'
+import PGConstant from 'util/constant.jsx'
+
const _user = new User();
const _util = new PGUtil();
super(props);
this.state = {
username: '',
- isLoading: false,
machines:[],
userinfo: {}
}
-
+ this.loadUserMachineManageList = this.loadUserMachineManageList.bind(this);
}
componentDidMount(){
let user = _util.getStorage('userInfo')
+ let _this = this
this.setState({
username: user.username,
+ },()=>{
+ _this.loadUserPortalInfo()
+ _this.loadUserMachineManageList();
});
console.log(user.token)
- this.loadUserPortalInfo()
- this.loadUserMachineManageList();
+
}
loadUserPortalInfo(){
- _user.getUserPortalInfo().then(res => {
+ let username = this.state.username
+ _user.getUserPortalInfo(username).then(res => {
this.setState({
- userinfo: res.results,
+ userinfo: res,
});
}, errMsg => {
- _util.errorTips(errMsg);
+ _util.errorTips('Please make sure no fields are empty.');
});
}
loadUserMachineManageList(page=1){
- _user.getUserMachineManageList().then(res => {
+
+ let listParam = {};
+ listParam.page = page;
+ listParam.machine_owner__username = this.state.username;
+ _user.getUserMachineManageList(listParam).then(res => {
this.setState({
machines: res.results,
total: res.count,
- isLoading: false
});
}, errMsg => {
_util.errorTips(errMsg);
// this.props.history.push('/login')
// hashHistory.push('/login')
window.location.href = '/';
- // _user.logout().then(res => {
- // _util.removeStorage('userInfo');
- // window.location.href = '/login';
- // }, errMsg => {
- // _util.errorTips(errMsg);
- // });
+ }
+
+ onInputChange(e) {
+ let inputValue = e.target.value,
+ inputName = e.target.name;
+ this.setState({
+ [inputName]: inputValue
+ });
+ }
+
+ onInputKeyUp(e) {
+ if (e.keyCode === 13) {
+ this.onSubmit();
+ }
+ }
+
+ onSubmit() {
+ // alert(1)
+ let machineInfo = {
+ os_name: this.state.os_name,
+ os_version: this.state.os_version,
+ comp_name: this.state.comp_name,
+ comp_version: this.state.comp_version,
+ machine_owner:this.state.username
+ }
+ let checkResult = true
+ // check success
+ if (checkResult) {
+ _user.farmerApply(machineInfo).then((res) => {
+ // console.dir(res)
+ alert('add machine success!')
+ hashHistory.push('/portal')
+ // 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);
+ }
+
}
render() {
<div className="col-md-3">
{/*<Segment vertical>Farmer Info</Segment>*/}
- <UserInfoCard info={this.state.userinfo}></UserInfoCard>
+ <UserInfoCard userinfo={this.state.userinfo}></UserInfoCard>
<div className="panel panel-default panel-blue">
<div className="panel-heading">
</h3>
</div>
<div className="list-group">
- <a href="\add-machine" className="list-group-item">
+ <Link target='_blank' to="farmerApply/" className="list-group-item">
<i className="fa fa-globe fa-fw"></i> Add a New Mchine
- </a>
+ </Link>
<a onClick={() => {this.onLogout()}} className="list-group-item">
<i className="fa fa-arrow-left fa-fw"></i> Logout
</a>
<h2 >Welcome Back, {this.state.username}</h2>
</div>
- <MachineTable list={this.state.machines} total={this.state.total} current={this.state.currentPage} loadfunc={this.loadRecordList}/>
+ <div className="panel panel-default">
+ <div className="panel-heading">
+ Apply New Machines
+ </div>
+ <div className="panel-body">
+ <div className="row">
+ {/*<!-- /.col-lg-6 (nested) -->*/}
+ <div className="col-lg-12">
+ {/*<h4>Login Form</h4>*/}
+ <form role="form">
+ <div className="form-group input-group">
+ {/*<label className="control-label" for="inputLogin"> login input</label>*/}
+ <span class="input-group-addon">system name</span>
+ <input type="text" className="form-control" id="inputOSName"
+ placeholder="etc.Debian,Ubuntu"
+ name="os_name"
+ onKeyUp={e => this.onInputKeyUp(e)}
+ onChange={e => this.onInputChange(e)}/>
+ </div>
+ <div className="form-group input-group">
+ <span class="input-group-addon">system version</span>
+ <input type="text" className="form-control" id="inputOSVersion"
+ name="os_version"
+ placeholder="etc.9,14.4" onKeyUp={e => this.onInputKeyUp(e)}
+ onChange={e => this.onInputChange(e)}/>
+ </div>
+ <div className="form-group input-group">
+ <span class="input-group-addon">arch name</span>
+ <input type="text" className="form-control" id="inputCampName"
+ name="comp_name"
+ placeholder="etc.x86" onKeyUp={e => this.onInputKeyUp(e)}
+ onChange={e => this.onInputChange(e)}/>
+ </div>
+ <div className="form-group input-group">
+ <span class="input-group-addon">arch version</span>
+ <input type="text" className="form-control" id="inputCampVersion"
+ name="comp_version"
+ placeholder="etc.64" onKeyUp={e => this.onInputKeyUp(e)}
+ onChange={e => this.onInputChange(e)}/>
+ </div>
+ <button type="button" className="btn btn-primary" onClick={e => {this.onSubmit(e)}}>Submit</button>
+ </form>
+ </div>
+ {/*<!-- /.col-lg-6 (nested) -->*/}
+ </div>
+ {/*<!-- /.row (nested) -->*/}
+ </div>
+ {/*<!-- /.panel-body -->*/}
+ </div>
</div>
</div>
return (
<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 className="record-title-right title-flex">
+ <div className="record-title-top">
+ <span>NO: {this.state.machineNo}</span>
+ {/*<span>Commit: <a target="_blank" href={ PGConstant.PG_GITHUB_MIRROR + commit}>{commit.substring(0, 7)}</a></span>*/}
+ </div>
+ <div className="record-title-bottom">
+ <h2 >Farmer: {this.state.machineInfo.alias}</h2>
+ </div>
</div>
- <h2 >Farmer: {this.state.machineInfo.alias}</h2>
+ {/*<div className="record-title-left title-flex">*/}
+ {/*<span>Date joined: {this.state.machineInfo.add_time}</span>*/}
+ {/*</div>*/}
</div>
<div className="machine-info-divier-div">
import React from 'react';
+import {Link} from 'react-router-dom';
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'
import Record from 'service/record-service.jsx'
</h3>
</div>
<div className="list-group">
- <a href="\add-machine" className="list-group-item">
+ <Link target='_blank' to="farmerApply/" className="list-group-item">
<i className="fa fa-globe fa-fw"></i> Add a New Mchine
- </a>
+ </Link>
+
<a onClick={() => {this.onLogout()}} className="list-group-item">
<i className="fa fa-arrow-left fa-fw"></i> Logout
</a>
const _util = new PGUtil();
class User{
+ farmerApply(farmerInfo){
+ let url = PGConstant.base_url + '/my-machine/';
+ return _util.request({
+ type: 'post',
+ url: url,
+ data: farmerInfo
+ });
+ }
+
login(loginInfo){
let url = PGConstant.base_url + '/login/';
return _util.request({
test_machine = UserMachineSerializer()
hardware_info = serializers.SerializerMethodField()
meta_info = MetaInfoDetailSerializer()
-
dataset_info = serializers.SerializerMethodField()
prev = serializers.SerializerMethodField()
reports = TestRecord.objects.filter(test_machine__machine_sn__in=machine_dict).values_list('branch__branch_name').annotate(Count('id'))
return reports.count()
+class CreateUserMachineSerializer(serializers.ModelSerializer):
+ class Meta:
+ model = UserMachine
+ fields = "__all__"
class UserMachineManageSerializer(serializers.ModelSerializer):
'''
from filters import MachineRecordListFilter, UserMachineListFilter
from test_records.models import TestRecord
from users.models import UserMachine, UserProfile
+from users.serializer import CreateUserProfileSerializer
from serializer import UserMachineManageSerializer, UserPortalInfoSerializer, TestRecordListSerializer, \
- UserMachineSerializer
-
+ UserMachineSerializer, CreateUserMachineSerializer
+from rest_framework.response import Response
+from rest_framework import status
class StandardResultsSetPagination(PageNumberPagination):
page_size = 20
filter_backends = (django_filters.rest_framework.DjangoFilterBackend,)
filter_class = MachineRecordListFilter
-class UserMachineListViewSet(mixins.ListModelMixin, viewsets.GenericViewSet):
+class UserMachineListViewSet(mixins.ListModelMixin, mixins.CreateModelMixin, viewsets.GenericViewSet):
"""
List test records
"""
filter_backends = (django_filters.rest_framework.DjangoFilterBackend,)
filter_class = UserMachineListFilter
- # def perform_create(self, serializer):
- # shop_cart = serializer.save()
- # goods = shop_cart.goods
- # goods.goods_num -= shop_cart.nums
- # goods.save()
-
- # def get_serializer_class(self):
- # if self.action == 'create':
- # return UserMachineSerializer
- # else:
- # return UserMachineManageSerializer
+ def post(self, request, *args, **kwargs):
+ return self.create(request, *args, **kwargs)
+
+ def create(self, request, *args, **kwargs):
+ data = {}
+ data['os_name'] = request.data['os_name']
+ data['os_version'] = request.data['os_version']
+ data['comp_name'] = request.data['comp_name']
+ data['comp_version'] = request.data['comp_version']
+
+ username = request.data['machine_owner']
+ user = UserProfile.objects.filter(username=username).filter().first()
+ user_serializer = CreateUserProfileSerializer(user)
+
+ data['machine_owner'] = user_serializer.data['id']
+
+ serializer = CreateUserMachineSerializer(data=data)
+ serializer.is_valid(raise_exception=True)
+ machine = self.perform_create(serializer)
+
+ headers = self.get_success_headers(serializer.data)
+
+ return Response('success', status=status.HTTP_201_CREATED, headers=headers)
+
+ def perform_create(self, serializer):
+ return serializer.save()
+
class PublicMachineListViewSet(mixins.ListModelMixin, viewsets.GenericViewSet):
"""
# first_name = None
# last_name = None
- # user_name = models.CharField(max_length=64, verbose_name="name")
+ username = models.CharField(max_length=64, unique=True, verbose_name="username")
# user_email = models.EmailField(max_length=256, verbose_name="email")
# add_time = models.DateTimeField(default=datetime.now, verbose_name="user added time")
model = Alias
fields = ('name', )
+class CreateUserProfileSerializer(serializers.ModelSerializer):
+ '''
+ use CreateUserProfileSerializer
+ '''
+ class Meta:
+ model = UserProfile
+ fields = "__all__"
+
class UserMachineSerializer(serializers.ModelSerializer):
'''
use UserMachineSerializer