Browse Source

Merge "web: add buildsets page"

tags/3.6.0
Zuul 2 months ago
parent
commit
e9900ca1d4
4 changed files with 168 additions and 1 deletions
  1. 8
    0
      web/src/api.js
  2. 150
    0
      web/src/pages/Buildsets.jsx
  3. 4
    1
      web/src/pages/Tenants.jsx
  4. 6
    0
      web/src/routes.js

+ 8
- 0
web/src/api.js View File

@@ -128,6 +128,13 @@ function fetchBuilds (apiPrefix, queryString) {
128 128
   }
129 129
   return Axios.get(apiUrl + apiPrefix + path)
130 130
 }
131
+function fetchBuildsets (apiPrefix, queryString) {
132
+  let path = 'buildsets'
133
+  if (queryString) {
134
+    path += '?' + queryString.slice(1)
135
+  }
136
+  return Axios.get(apiUrl + apiPrefix + path)
137
+}
131 138
 function fetchProject (apiPrefix, projectName) {
132 139
   return Axios.get(apiUrl + apiPrefix + 'project/' + projectName)
133 140
 }
@@ -155,6 +162,7 @@ export {
155 162
   fetchStatus,
156 163
   fetchBuild,
157 164
   fetchBuilds,
165
+  fetchBuildsets,
158 166
   fetchProject,
159 167
   fetchProjects,
160 168
   fetchJob,

+ 150
- 0
web/src/pages/Buildsets.jsx View File

@@ -0,0 +1,150 @@
1
+// Copyright 2019 Red Hat, Inc
2
+//
3
+// Licensed under the Apache License, Version 2.0 (the "License"); you may
4
+// not use this file except in compliance with the License. You may obtain
5
+// a copy of the License at
6
+//
7
+//      http://www.apache.org/licenses/LICENSE-2.0
8
+//
9
+// Unless required by applicable law or agreed to in writing, software
10
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12
+// License for the specific language governing permissions and limitations
13
+// under the License.
14
+
15
+import * as React from 'react'
16
+import PropTypes from 'prop-types'
17
+import { connect } from 'react-redux'
18
+import { Table } from 'patternfly-react'
19
+
20
+import { fetchBuildsets } from '../api'
21
+import TableFilters from '../containers/TableFilters'
22
+
23
+
24
+class BuildsetsPage extends TableFilters {
25
+  static propTypes = {
26
+    tenant: PropTypes.object
27
+  }
28
+
29
+  constructor () {
30
+    super()
31
+
32
+    this.prepareTableHeaders()
33
+    this.state = {
34
+      buildsets: null,
35
+      currentFilterType: this.filterTypes[0],
36
+      activeFilters: [],
37
+      currentValue: ''
38
+    }
39
+  }
40
+
41
+  updateData = (filters) => {
42
+    let queryString = ''
43
+    if (filters) {
44
+      filters.forEach(item => queryString += '&' + item.key + '=' + item.value)
45
+    }
46
+    this.setState({buildsets: null})
47
+    fetchBuildsets(this.props.tenant.apiPrefix, queryString).then(response => {
48
+      this.setState({buildsets: response.data})
49
+    })
50
+  }
51
+
52
+  componentDidMount () {
53
+    document.title = 'Zuul Buildsets'
54
+    if (this.props.tenant.name) {
55
+      this.updateData(this.getFilterFromUrl())
56
+    }
57
+  }
58
+
59
+  componentDidUpdate (prevProps) {
60
+    if (this.props.tenant.name !== prevProps.tenant.name) {
61
+      this.updateData(this.getFilterFromUrl())
62
+    }
63
+  }
64
+
65
+  prepareTableHeaders() {
66
+    const headerFormat = value => <Table.Heading>{value}</Table.Heading>
67
+    const cellFormat = (value) => <Table.Cell>{value}</Table.Cell>
68
+    const linkChangeFormat = (value, rowdata) => (
69
+      <Table.Cell>
70
+        <a href={rowdata.rowData.ref_url}>
71
+          {value ?
72
+           rowdata.rowData.change + ',' + rowdata.rowData.patchset :
73
+           rowdata.rowData.newrev ?
74
+             rowdata.rowData.newrev.substr(0, 7) :
75
+           rowdata.rowData.branch}
76
+        </a>
77
+      </Table.Cell>
78
+    )
79
+    this.columns = []
80
+    this.filterTypes = []
81
+    const myColumns = [
82
+      'project',
83
+      'branch',
84
+      'pipeline',
85
+      'change',
86
+      'result']
87
+    myColumns.forEach(column => {
88
+      let prop = column
89
+      let formatter = cellFormat
90
+      if (column === 'change') {
91
+        formatter = linkChangeFormat
92
+      }
93
+      const label = column.charAt(0).toUpperCase() + column.slice(1)
94
+      this.columns.push({
95
+        header: {label: label, formatters: [headerFormat]},
96
+        property: prop,
97
+        cell: {formatters: [formatter]}
98
+      })
99
+      if (column !== 'builds') {
100
+        this.filterTypes.push({
101
+          id: prop,
102
+          title: label,
103
+          placeholder: 'Filter by ' + label,
104
+          filterType: 'text',
105
+        })
106
+      }
107
+    })
108
+    // Add buildset filter at the end
109
+    this.filterTypes.push({
110
+      id: 'uuid',
111
+      title: 'Buildset',
112
+      palceholder: 'Filter by Buildset UUID',
113
+      fileterType: 'text',
114
+    })
115
+  }
116
+
117
+  renderTable (buildsets) {
118
+    return (
119
+      <Table.PfProvider
120
+        striped
121
+        bordered
122
+        columns={this.columns}
123
+      >
124
+        <Table.Header/>
125
+        <Table.Body
126
+          rows={buildsets}
127
+          rowKey='uuid'
128
+          onRow={(row) => {
129
+            switch (row.result) {
130
+              case 'SUCCESS':
131
+                return { className: 'success' }
132
+              default:
133
+                return { className: 'warning' }
134
+            }
135
+          }} />
136
+      </Table.PfProvider>)
137
+  }
138
+
139
+  render() {
140
+    const { buildsets } = this.state
141
+    return (
142
+      <React.Fragment>
143
+        {this.renderFilter()}
144
+        {buildsets ? this.renderTable(buildsets) : <p>Loading...</p>}
145
+      </React.Fragment>
146
+    )
147
+  }
148
+}
149
+
150
+export default connect(state => ({tenant: state.tenant}))(BuildsetsPage)

+ 4
- 1
web/src/pages/Tenants.jsx View File

@@ -48,7 +48,8 @@ class TenantsPage extends Refreshable {
48 48
       <Table.Cell>{value}</Table.Cell>)
49 49
     const columns = []
50 50
     const myColumns = [
51
-      'name', 'status', 'projects', 'jobs', 'builds', 'projects count', 'queue']
51
+      'name', 'status', 'projects', 'jobs', 'builds', 'buildsets',
52
+      'projects count', 'queue']
52 53
     myColumns.forEach(column => {
53 54
       let prop = column
54 55
       if (column === 'projects count') {
@@ -72,6 +73,8 @@ class TenantsPage extends Refreshable {
72 73
         <Link to={'/t/' + tenant.name + '/jobs'}>Jobs</Link>)
73 74
       tenant.builds = (
74 75
         <Link to={'/t/' + tenant.name + '/builds'}>Builds</Link>)
76
+      tenant.buildsets = (
77
+        <Link to={'/t/' + tenant.name + '/buildsets'}>Buildsets</Link>)
75 78
     })
76 79
     return (
77 80
       <React.Fragment>

+ 6
- 0
web/src/routes.js View File

@@ -22,6 +22,7 @@ import LabelsPage from './pages/Labels'
22 22
 import NodesPage from './pages/Nodes'
23 23
 import BuildPage from './pages/Build'
24 24
 import BuildsPage from './pages/Builds'
25
+import BuildsetsPage from './pages/Buildsets'
25 26
 import ConfigErrorsPage from './pages/ConfigErrors'
26 27
 import TenantsPage from './pages/Tenants'
27 28
 import StreamPage from './pages/Stream'
@@ -61,6 +62,11 @@ const routes = () => [
61 62
     to: '/builds',
62 63
     component: BuildsPage
63 64
   },
65
+  {
66
+    title: 'Buildsets',
67
+    to: '/buildsets',
68
+    component: BuildsetsPage
69
+  },
64 70
   {
65 71
     to: '/status/change/:changeId',
66 72
     component: ChangeStatusPage

Loading…
Cancel
Save