summaryrefslogtreecommitdiff
path: root/web/src/pages/Builds.jsx
diff options
context:
space:
mode:
authorTristan Cacqueray <tdecacqu@redhat.com>2018-08-14 05:13:15 +0000
committerTristan Cacqueray <tdecacqu@redhat.com>2018-09-27 02:14:46 +0000
commit1082faae958bffa719ab333c3f5ae9776a8b26d7 (patch)
tree73b58bd8462d6d446f5c8caabb6a5f30695765f4 /web/src/pages/Builds.jsx
parenta74dc74ea1975388dc9f38cafe2cfb68de53811f (diff)
downloadzuul-1082faae958bffa719ab333c3f5ae9776a8b26d7.tar.gz
web: rewrite interface in react
This change rewrites the web interface using React: http://lists.zuul-ci.org/pipermail/zuul-discuss/2018-August/000528.html Depends-On: https://review.openstack.org/591964 Change-Id: Ic6c33102ac3da69ebd0b8e9c6c8b431d51f3cfd4 Co-Authored-By: Monty Taylor <mordred@inaugust.com> Co-Authored-By: James E. Blair <jeblair@redhat.com>
Diffstat (limited to 'web/src/pages/Builds.jsx')
-rw-r--r--web/src/pages/Builds.jsx159
1 files changed, 159 insertions, 0 deletions
diff --git a/web/src/pages/Builds.jsx b/web/src/pages/Builds.jsx
new file mode 100644
index 000000000..8f902ee83
--- /dev/null
+++ b/web/src/pages/Builds.jsx
@@ -0,0 +1,159 @@
+// 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 { fetchBuilds } from '../api'
+import TableFilters from '../containers/TableFilters'
+
+
+class BuildsPage extends TableFilters {
+ static propTypes = {
+ tenant: PropTypes.object
+ }
+
+ constructor () {
+ super()
+
+ this.prepareTableHeaders()
+ this.state = {
+ builds: null,
+ currentFilterType: this.filterTypes[0],
+ activeFilters: [],
+ currentValue: ''
+ }
+ }
+
+ updateData = (filters) => {
+ let queryString = ''
+ if (filters) {
+ filters.forEach(item => queryString += '&' + item.key + '=' + item.value)
+ }
+ this.setState({builds: null})
+ fetchBuilds(this.props.tenant.apiPrefix, queryString).then(response => {
+ this.setState({builds: response.data})
+ })
+ }
+
+ componentDidMount () {
+ document.title = 'Zuul Build'
+ if (this.props.tenant.name) {
+ this.updateData(this.getFilterFromUrl())
+ }
+ }
+
+ componentDidUpdate (prevProps) {
+ if (this.props.tenant.name !== prevProps.tenant.name) {
+ this.updateData(this.getFilterFromUrl())
+ }
+ }
+
+ prepareTableHeaders() {
+ const headerFormat = value => <Table.Heading>{value}</Table.Heading>
+ const cellFormat = (value) => (
+ <Table.Cell>{value}</Table.Cell>)
+ const linkCellFormat = (value) => (
+ <Table.Cell>
+ <a href={value} target='_blank' rel='noopener noreferrer'>link</a>
+ </Table.Cell>
+ )
+ this.columns = []
+ this.filterTypes = []
+ const myColumns = [
+ 'job',
+ 'project',
+ 'branch',
+ 'pipeline',
+ 'change',
+ 'duration',
+ 'log',
+ 'start time',
+ 'result']
+ myColumns.forEach(column => {
+ let prop = column
+ let formatter = cellFormat
+ // Adapt column name and property name
+ if (column === 'job') {
+ prop = 'job_name'
+ } else if (column === 'start time') {
+ prop = 'start_time'
+ } else if (column === 'change') {
+ prop = 'ref_url'
+ formatter = linkCellFormat
+ } else if (column === 'log') {
+ prop = 'log_url'
+ formatter = linkCellFormat
+ }
+ const label = column.charAt(0).toUpperCase() + column.slice(1)
+ this.columns.push({
+ header: {label: label, formatters: [headerFormat]},
+ property: prop,
+ cell: {formatters: [formatter]}
+ })
+ if (prop !== 'start_time' && prop !== 'ref_url' && prop !== 'duration'
+ && prop !== 'log_url' && prop !== 'uuid') {
+ this.filterTypes.push({
+ id: prop,
+ title: label,
+ placeholder: 'Filter by ' + label,
+ filterType: 'text',
+ })
+ }
+ })
+ // Add build filter at the end
+ this.filterTypes.push({
+ id: 'uuid',
+ title: 'Build',
+ palceholder: 'Filter by Build UUID',
+ fileterType: 'text',
+ })
+ }
+
+ renderTable (builds) {
+ return (
+ <Table.PfProvider
+ striped
+ bordered
+ columns={this.columns}
+ >
+ <Table.Header/>
+ <Table.Body
+ rows={builds}
+ rowKey='uuid'
+ onRow={(row) => {
+ switch (row.result) {
+ case 'SUCCESS':
+ return { className: 'success' }
+ default:
+ return { className: 'warning' }
+ }
+ }} />
+ </Table.PfProvider>)
+ }
+
+ render() {
+ const { builds } = this.state
+ return (
+ <React.Fragment>
+ {this.renderFilter()}
+ {builds ? this.renderTable(builds) : <p>Loading...</p>}
+ </React.Fragment>
+ )
+ }
+}
+
+export default connect(state => ({tenant: state.tenant}))(BuildsPage)