diff --git a/web/src/api.js b/web/src/api.js index 03dd15b8cf..7354226fbe 100644 --- a/web/src/api.js +++ b/web/src/api.js @@ -143,6 +143,9 @@ function fetchJobs (apiPrefix) { function fetchLabels (apiPrefix) { return Axios.get(apiUrl + apiPrefix + 'labels') } +function fetchNodes (apiPrefix) { + return Axios.get(apiUrl + apiPrefix + 'nodes') +} export { getHomepageUrl, @@ -157,6 +160,7 @@ export { fetchJob, fetchJobs, fetchLabels, + fetchNodes, fetchTenants, fetchInfo } diff --git a/web/src/pages/Nodes.jsx b/web/src/pages/Nodes.jsx new file mode 100644 index 0000000000..6e77341820 --- /dev/null +++ b/web/src/pages/Nodes.jsx @@ -0,0 +1,110 @@ +// Copyright 2018 Red Hat, Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. You may obtain +// a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations +// under the License. + +import * as React from 'react' +import PropTypes from 'prop-types' +import { connect } from 'react-redux' +import { Table } from 'patternfly-react' +import * as moment from 'moment' + +import { fetchNodes } from '../api' + + +class NodesPage extends React.Component { + static propTypes = { + tenant: PropTypes.object + } + + state = { + nodes: null + } + + updateData () { + fetchNodes(this.props.tenant.apiPrefix).then(response => { + this.setState({nodes: response.data}) + }) + } + + componentDidMount () { + document.title = 'Zuul Nodes' + if (this.props.tenant.name) { + this.updateData() + } + } + + componentDidUpdate (prevProps) { + if (this.props.tenant.name !== prevProps.tenant.name) { + this.updateData() + } + } + + render () { + const { nodes } = this.state + if (!nodes) { + return (

Loading...

) + } + + const headerFormat = value => {value} + const cellFormat = value => {value} + const cellPreFormat = value => ( + + {value} + ) + const cellAgeFormat = value => ( + + {moment.unix(value).fromNow()} + ) + + const columns = [] + const myColumns = [ + 'id', 'label', 'connection', 'server', 'provider', 'state', + 'age', 'comment' + ] + myColumns.forEach(column => { + let formatter = cellFormat + let prop = column + if (column === 'label') { + prop = 'type' + } else if (column === 'connection') { + prop = 'connection_type' + } else if (column === 'server') { + prop = 'external_id' + formatter = cellPreFormat + } else if (column === 'age') { + prop = 'state_time' + formatter = cellAgeFormat + } + columns.push({ + header: {label: column, formatters: [headerFormat]}, + property: prop, + cell: {formatters: [formatter]} + }) + }) + return ( + + + + ) + } +} + +export default connect(state => ({tenant: state.tenant}))(NodesPage) diff --git a/web/src/routes.js b/web/src/routes.js index 99653ec0d0..ee93ab44a5 100644 --- a/web/src/routes.js +++ b/web/src/routes.js @@ -19,6 +19,7 @@ import ProjectsPage from './pages/Projects' import JobPage from './pages/Job' import JobsPage from './pages/Jobs' import LabelsPage from './pages/Labels' +import NodesPage from './pages/Nodes' import BuildPage from './pages/Build' import BuildsPage from './pages/Builds' import ConfigErrorsPage from './pages/ConfigErrors' @@ -50,6 +51,11 @@ const routes = () => [ to: '/labels', component: LabelsPage }, + { + title: 'Nodes', + to: '/nodes', + component: NodesPage + }, { title: 'Builds', to: '/builds',