From ba2941bd7a893d3c3079f75d2f035c1b83e7ec26 Mon Sep 17 00:00:00 2001 From: Haitao Yue Date: Sat, 18 Mar 2017 22:37:29 +0800 Subject: [PATCH] Add hosts table view Add hosts api; Add hosts table view for react theme; Change-Id: I07efe8a5ac052ddc750249224efdd5c00c72e436 Signed-off-by: Haitao Yue --- src/resources/host_api.py | 10 +++ .../react/static/js/components/hosts/list.jsx | 84 +++++++++++++++++++ .../static/js/components/hosts/list.less | 11 +++ src/themes/react/static/js/models/host.js | 35 ++++++-- src/themes/react/static/js/routes/hosts.js | 26 ++++-- src/themes/react/static/js/services/hosts.js | 12 +++ src/themes/react/static/js/utils/config.js | 4 +- src/themes/react/static/webpack.config.js | 5 ++ src/themes/react/templates/index.html | 3 + 9 files changed, 178 insertions(+), 12 deletions(-) create mode 100644 src/themes/react/static/js/components/hosts/list.jsx create mode 100644 src/themes/react/static/js/components/hosts/list.less create mode 100644 src/themes/react/static/js/services/hosts.js diff --git a/src/resources/host_api.py b/src/resources/host_api.py index 6045c71e6..08e6a4c0a 100644 --- a/src/resources/host_api.py +++ b/src/resources/host_api.py @@ -22,6 +22,16 @@ url_prefix='/{}'.format("api")) +@bp_host_api.route('/hosts', methods=['GET']) +def hosts_list(): + logger.info("/hosts_list method=" + r.method) + request_debug(r, logger) + col_filter = dict((key, r.args.get(key)) for key in r.args) + items = list(host_handler.list(filter_data=col_filter)) + + return make_ok_response(data=items) + + @bp_host_api.route('/host/', methods=['GET']) def host_query(host_id): request_debug(r, logger) diff --git a/src/themes/react/static/js/components/hosts/list.jsx b/src/themes/react/static/js/components/hosts/list.jsx new file mode 100644 index 000000000..f2af5d9f5 --- /dev/null +++ b/src/themes/react/static/js/components/hosts/list.jsx @@ -0,0 +1,84 @@ +/** + * Created by yuehaitao on 2017/2/7. + */ +import React, { PropTypes } from 'react' +import { Badge, Tag, Button, Table, Popconfirm, Pagination } from 'antd' +import styles from './list.less' + +function list({loadingList, dataSource, onDeleteItem, onSelectItem, onSelectTagItem}) { + const columns = [ + { + title: 'Name', + dataIndex: 'name', + key: 'name', + render: (text, record) => ( + onSelectItem(record.id)}>{text} + ) + }, + { + title: 'Status', + dataIndex: 'status', + key: 'status', + render: (text) => ( + {text == "active" ? : } + ) + }, + { + title: 'Create Time', + dataIndex: 'create_ts', + key: 'create_ts' + }, + { + title: 'Log Level', + dataIndex: 'log_level', + key: 'log_level' + }, + { + title: 'Type', + dataIndex: 'type', + key: 'type' + }, + { + title: 'Log Type', + dataIndex: 'log_type', + key: 'log_type' + }, + { + title: 'Operation', + key: 'operation', + width: 100, + render: (text, record) => ( +

+ onDeleteItem(record.id, record.name)}> + Delete + +

+ ) + } + ] + + return ( +
+ record.id} + /> + + ) +} + +list.propTypes = { + loadingList: PropTypes.any, + dataSource: PropTypes.array, + pagination: PropTypes.any, + onPageChange: PropTypes.func, + onDeleteItem: PropTypes.func, + onSelectItem: PropTypes.func, + onSelectTagItem: PropTypes.func +} + +export default list \ No newline at end of file diff --git a/src/themes/react/static/js/components/hosts/list.less b/src/themes/react/static/js/components/hosts/list.less new file mode 100644 index 000000000..e432b921a --- /dev/null +++ b/src/themes/react/static/js/components/hosts/list.less @@ -0,0 +1,11 @@ +.avatar{ + line-height: 1; + img{ + border-radius: 50%; + } +} +.table{ + td{ + height: 38px; + } +} \ No newline at end of file diff --git a/src/themes/react/static/js/models/host.js b/src/themes/react/static/js/models/host.js index e6bac13d8..3a3cc3bf7 100644 --- a/src/themes/react/static/js/models/host.js +++ b/src/themes/react/static/js/models/host.js @@ -1,27 +1,52 @@ /** * Created by yuehaitao on 2017/1/18. */ +import {getHosts} from '../services/hosts' +import {message} from 'antd' + export default { namespace: 'host', state: { + loadingHosts: false, hosts: [] }, subscriptions: { setup({dispatch, history}) { history.listen(location => { if (location.pathname == '/hosts') { - dispatch({type: 'queryHostList'}) + dispatch({type: 'getHosts'}) } }) } }, effects: { - *queryHostList({ - payload - }, {call, put}) { - console.log("query host list") + *getHosts({payload}, {call, put}) { + yield put({type: 'showLoadingHosts'}) + try { + const data = yield call(getHosts) + if (data && data.status == "OK") { + yield put({type: 'getHostsSuccess', payload: { + hosts: data.data + }}) + } else { + message.error("get hosts list failed") + yield put({type: 'hideLoadingHosts'}) + } + } catch (e) { + message.error("get hosts list failed") + yield put({type: 'hideLoadingHosts'}) + } } }, reducers: { + showLoadingHosts(state) { + return {...state, loadingHosts: true} + }, + hideLoadingHosts(state) { + return {...state, loadingHosts: false} + }, + getHostsSuccess(state, action) { + return {...state, ...action.payload, loadingHosts: false} + } } } diff --git a/src/themes/react/static/js/routes/hosts.js b/src/themes/react/static/js/routes/hosts.js index 63b582112..2baca99d4 100644 --- a/src/themes/react/static/js/routes/hosts.js +++ b/src/themes/react/static/js/routes/hosts.js @@ -1,9 +1,23 @@ import React from 'react' +import HostsList from '../components/hosts/list' +import { connect } from 'dva' -const Hosts = () =>
-
-

Hosts

-
-
+class Hosts extends React.Component { + constructor(props) { + super(props) + } + render() { + const {host: {loadingHosts, hosts}} = this.props; + const hostsListProps = { + dataSource: hosts, + loadingList: loadingHosts + } + return ( +
+ +
+ ) + } +} -export default Hosts +export default connect(({host}) => ({host}))(Hosts) diff --git a/src/themes/react/static/js/services/hosts.js b/src/themes/react/static/js/services/hosts.js new file mode 100644 index 000000000..ab9f39ecf --- /dev/null +++ b/src/themes/react/static/js/services/hosts.js @@ -0,0 +1,12 @@ +/** + * Created by yuehaitao on 2017/1/18. + */ +import { request } from '../utils' +import { config } from '../utils' + +export async function getHosts(params) { + return request(config.urls.hosts, { + method: 'get', + data: params + }) +} diff --git a/src/themes/react/static/js/utils/config.js b/src/themes/react/static/js/utils/config.js index 21fcb5be9..153617ce7 100644 --- a/src/themes/react/static/js/utils/config.js +++ b/src/themes/react/static/js/utils/config.js @@ -1,9 +1,11 @@ +const apiBase = '/api' module.exports = { name: 'Cello Dashboard', prefix: 'cello', footerText: 'Cello Dashboard', logoText: 'Cello', urls: { - queryStat: '/api/stat' + queryStat: apiBase + '/stat', + hosts: apiBase + '/hosts' } } diff --git a/src/themes/react/static/webpack.config.js b/src/themes/react/static/webpack.config.js index 5b3521c57..bb1f452f8 100644 --- a/src/themes/react/static/webpack.config.js +++ b/src/themes/react/static/webpack.config.js @@ -44,6 +44,11 @@ module.exports = function (webpackConfig, env) { loader.test = /\.css$/ } }) + webpackConfig.externals = { + 'react': 'React', + 'react-dom': 'ReactDOM', + 'echarts': true + } return webpackConfig } diff --git a/src/themes/react/templates/index.html b/src/themes/react/templates/index.html index 575af2422..1625b763a 100644 --- a/src/themes/react/templates/index.html +++ b/src/themes/react/templates/index.html @@ -20,6 +20,9 @@
+ + +