Skip to content

Commit ba2941b

Browse files
committed
Add hosts table view
Add hosts api; Add hosts table view for react theme; Change-Id: I07efe8a5ac052ddc750249224efdd5c00c72e436 Signed-off-by: Haitao Yue <hightall@me.com>
1 parent 143912f commit ba2941b

File tree

9 files changed

+178
-12
lines changed

9 files changed

+178
-12
lines changed

src/resources/host_api.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,16 @@
2222
url_prefix='/{}'.format("api"))
2323

2424

25+
@bp_host_api.route('/hosts', methods=['GET'])
26+
def hosts_list():
27+
logger.info("/hosts_list method=" + r.method)
28+
request_debug(r, logger)
29+
col_filter = dict((key, r.args.get(key)) for key in r.args)
30+
items = list(host_handler.list(filter_data=col_filter))
31+
32+
return make_ok_response(data=items)
33+
34+
2535
@bp_host_api.route('/host/<host_id>', methods=['GET'])
2636
def host_query(host_id):
2737
request_debug(r, logger)
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
/**
2+
* Created by yuehaitao on 2017/2/7.
3+
*/
4+
import React, { PropTypes } from 'react'
5+
import { Badge, Tag, Button, Table, Popconfirm, Pagination } from 'antd'
6+
import styles from './list.less'
7+
8+
function list({loadingList, dataSource, onDeleteItem, onSelectItem, onSelectTagItem}) {
9+
const columns = [
10+
{
11+
title: 'Name',
12+
dataIndex: 'name',
13+
key: 'name',
14+
render: (text, record) => (
15+
<a onClick={() => onSelectItem(record.id)}>{text}</a>
16+
)
17+
},
18+
{
19+
title: 'Status',
20+
dataIndex: 'status',
21+
key: 'status',
22+
render: (text) => (
23+
<span>{text == "active" ? <Badge status="success" text={text}/> : <Badge status="warning" text={text} />}</span>
24+
)
25+
},
26+
{
27+
title: 'Create Time',
28+
dataIndex: 'create_ts',
29+
key: 'create_ts'
30+
},
31+
{
32+
title: 'Log Level',
33+
dataIndex: 'log_level',
34+
key: 'log_level'
35+
},
36+
{
37+
title: 'Type',
38+
dataIndex: 'type',
39+
key: 'type'
40+
},
41+
{
42+
title: 'Log Type',
43+
dataIndex: 'log_type',
44+
key: 'log_type'
45+
},
46+
{
47+
title: 'Operation',
48+
key: 'operation',
49+
width: 100,
50+
render: (text, record) => (
51+
<p>
52+
<Popconfirm title="Confirm to Delete?" onConfirm={() => onDeleteItem(record.id, record.name)}>
53+
<a style={{color: "red"}}>Delete</a>
54+
</Popconfirm>
55+
</p>
56+
)
57+
}
58+
]
59+
60+
return (
61+
<div>
62+
<Table
63+
className={styles.table}
64+
columns={columns}
65+
dataSource={dataSource}
66+
loading={loadingList}
67+
size="small"
68+
rowKey={record => record.id}
69+
/>
70+
</div>
71+
)
72+
}
73+
74+
list.propTypes = {
75+
loadingList: PropTypes.any,
76+
dataSource: PropTypes.array,
77+
pagination: PropTypes.any,
78+
onPageChange: PropTypes.func,
79+
onDeleteItem: PropTypes.func,
80+
onSelectItem: PropTypes.func,
81+
onSelectTagItem: PropTypes.func
82+
}
83+
84+
export default list
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
.avatar{
2+
line-height: 1;
3+
img{
4+
border-radius: 50%;
5+
}
6+
}
7+
.table{
8+
td{
9+
height: 38px;
10+
}
11+
}
Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,52 @@
11
/**
22
* Created by yuehaitao on 2017/1/18.
33
*/
4+
import {getHosts} from '../services/hosts'
5+
import {message} from 'antd'
6+
47
export default {
58
namespace: 'host',
69
state: {
10+
loadingHosts: false,
711
hosts: []
812
},
913
subscriptions: {
1014
setup({dispatch, history}) {
1115
history.listen(location => {
1216
if (location.pathname == '/hosts') {
13-
dispatch({type: 'queryHostList'})
17+
dispatch({type: 'getHosts'})
1418
}
1519
})
1620
}
1721
},
1822
effects: {
19-
*queryHostList({
20-
payload
21-
}, {call, put}) {
22-
console.log("query host list")
23+
*getHosts({payload}, {call, put}) {
24+
yield put({type: 'showLoadingHosts'})
25+
try {
26+
const data = yield call(getHosts)
27+
if (data && data.status == "OK") {
28+
yield put({type: 'getHostsSuccess', payload: {
29+
hosts: data.data
30+
}})
31+
} else {
32+
message.error("get hosts list failed")
33+
yield put({type: 'hideLoadingHosts'})
34+
}
35+
} catch (e) {
36+
message.error("get hosts list failed")
37+
yield put({type: 'hideLoadingHosts'})
38+
}
2339
}
2440
},
2541
reducers: {
42+
showLoadingHosts(state) {
43+
return {...state, loadingHosts: true}
44+
},
45+
hideLoadingHosts(state) {
46+
return {...state, loadingHosts: false}
47+
},
48+
getHostsSuccess(state, action) {
49+
return {...state, ...action.payload, loadingHosts: false}
50+
}
2651
}
2752
}
Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,23 @@
11
import React from 'react'
2+
import HostsList from '../components/hosts/list'
3+
import { connect } from 'dva'
24

3-
const Hosts = () => <div className='content-inner'>
4-
<div>
5-
<h1>Hosts</h1>
6-
</div>
7-
</div>
5+
class Hosts extends React.Component {
6+
constructor(props) {
7+
super(props)
8+
}
9+
render() {
10+
const {host: {loadingHosts, hosts}} = this.props;
11+
const hostsListProps = {
12+
dataSource: hosts,
13+
loadingList: loadingHosts
14+
}
15+
return (
16+
<div className="content-inner">
17+
<HostsList {...hostsListProps} />
18+
</div>
19+
)
20+
}
21+
}
822

9-
export default Hosts
23+
export default connect(({host}) => ({host}))(Hosts)
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/**
2+
* Created by yuehaitao on 2017/1/18.
3+
*/
4+
import { request } from '../utils'
5+
import { config } from '../utils'
6+
7+
export async function getHosts(params) {
8+
return request(config.urls.hosts, {
9+
method: 'get',
10+
data: params
11+
})
12+
}
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1+
const apiBase = '/api'
12
module.exports = {
23
name: 'Cello Dashboard',
34
prefix: 'cello',
45
footerText: 'Cello Dashboard',
56
logoText: 'Cello',
67
urls: {
7-
queryStat: '/api/stat'
8+
queryStat: apiBase + '/stat',
9+
hosts: apiBase + '/hosts'
810
}
911
}

src/themes/react/static/webpack.config.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,11 @@ module.exports = function (webpackConfig, env) {
4444
loader.test = /\.css$/
4545
}
4646
})
47+
webpackConfig.externals = {
48+
'react': 'React',
49+
'react-dom': 'ReactDOM',
50+
'echarts': true
51+
}
4752

4853
return webpackConfig
4954
}

src/themes/react/templates/index.html

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@
2020
<body>
2121

2222
<div id="root"></div>
23+
<script src="//cdn.bootcss.com/react/15.4.2/react.min.js"></script>
24+
<script src="//cdn.bootcss.com/react/15.4.2/react-dom.min.js"></script>
25+
<script src="//cdn.bootcss.com/echarts/3.4.0/echarts.min.js"></script>
2326
<script src="{{ url_for('static', filename='js/dist/index.js') }}"> </script>
2427

2528
</body>

0 commit comments

Comments
 (0)