Merge "Consolidate summary, logs and console on a single build page"

This commit is contained in:
Zuul 2020-07-16 05:34:26 +00:00 committed by Gerrit Code Review
commit eb1531ba47
6 changed files with 40 additions and 173 deletions

View File

@ -134,13 +134,19 @@ class App extends React.Component {
.filter(item =>
(tenant.whiteLabel && !item.globalRoute) || !tenant.whiteLabel)
.forEach((item, index) => {
// We use react-router's render function to be able to pass custom props
// to our route components (pages):
// https://reactrouter.com/web/api/Route/render-func
// https://learnwithparam.com/blog/how-to-pass-props-in-react-router/
allRoutes.push(
<Route
key={index}
path={
item.globalRoute ? item.to :
item.noTenantPrefix ? item.to : tenant.routePrefix + item.to}
component={item.component}
render={routerProps => (
<item.component {...item.props} {...routerProps} />
)}
exact
/>
)

View File

@ -17,16 +17,21 @@ import PropTypes from 'prop-types'
import { connect } from 'react-redux'
import { Link } from 'react-router-dom'
import Summary from './Summary'
import Manifest from './Manifest'
import Console from './Console'
class Build extends React.Component {
static propTypes = {
build: PropTypes.object,
tenant: PropTypes.object,
active: PropTypes.string,
children: PropTypes.object,
hash: PropTypes.array,
}
render () {
const { build, active } = this.props
const { build, active, hash } = this.props
return (
<div>
<h2>Build result {build.uuid}</h2>
@ -50,10 +55,23 @@ class Build extends React.Component {
Console
</Link>
</li>}
</ul>
<div>
{this.props.children}
{/* NOTE (felix): Since I'm already working on a PF4 change for
this file, I don't want to change too much here for now and
just make it compatible to the improved routing solution.
*/}
{active === 'summary' && <Summary build={build} />}
{active === 'logs' && build && build.manifest && (
<Manifest tenant={this.props.tenant} build={build}/>
)}
{active === 'console' && build && build.output && (
<Console
output={build.output}
errorIds={build.errorIds}
displayPath={hash.length>0?hash:undefined}
/>
)}
</div>
</div>
</div>

View File

@ -20,7 +20,6 @@ import { PageSection, PageSectionVariants } from '@patternfly/react-core'
import { fetchBuildIfNeeded } from '../actions/build'
import { Fetchable } from '../containers/Fetching'
import Build from '../containers/build/Build'
import Summary from '../containers/build/Summary'
class BuildPage extends React.Component {
@ -29,6 +28,8 @@ class BuildPage extends React.Component {
remoteData: PropTypes.object,
tenant: PropTypes.object,
dispatch: PropTypes.func,
activeTab: PropTypes.string.isRequired,
location: PropTypes.object,
}
updateData = (force) => {
@ -50,8 +51,9 @@ class BuildPage extends React.Component {
}
render () {
const { remoteData } = this.props
const { remoteData, activeTab, location } = this.props
const build = remoteData.builds[this.props.match.params.buildId]
const hash = location.hash.substring(1).split('/')
return (
<PageSection variant={PageSectionVariants.light}>
<PageSection style={{paddingRight: '5px'}}>
@ -60,10 +62,7 @@ class BuildPage extends React.Component {
fetchCallback={this.updateData}
/>
</PageSection>
{build &&
<Build build={build} active='summary'>
<Summary build={build}/>
</Build>}
{build && <Build build={build} active={activeTab} hash={hash}/>}
</PageSection>
)
}

View File

@ -1,82 +0,0 @@
// 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 { connect } from 'react-redux'
import PropTypes from 'prop-types'
import { PageSection, PageSectionVariants } from '@patternfly/react-core'
import { fetchBuildIfNeeded } from '../actions/build'
import { Fetchable } from '../containers/Fetching'
import Build from '../containers/build/Build'
import Console from '../containers/build/Console'
class BuildConsolePage extends React.Component {
static propTypes = {
match: PropTypes.object.isRequired,
remoteData: PropTypes.object,
tenant: PropTypes.object,
dispatch: PropTypes.func,
location: PropTypes.object,
}
updateData = (force) => {
this.props.dispatch(fetchBuildIfNeeded(
this.props.tenant, this.props.match.params.buildId, null, force))
}
componentDidMount () {
document.title = 'Zuul Build'
if (this.props.tenant.name) {
this.updateData()
}
}
componentDidUpdate (prevProps) {
if (this.props.tenant.name !== prevProps.tenant.name) {
this.updateData()
}
}
render () {
const { remoteData } = this.props
const build = remoteData.builds[this.props.match.params.buildId]
const hash = this.props.location.hash.substring(1).split('/')
return (
<PageSection variant={PageSectionVariants.light}>
<PageSection style={{paddingRight: '5px'}}>
<Fetchable
isFetching={remoteData.isFetching}
fetchCallback={this.updateData}
/>
</PageSection>
{build && build.output &&
<Build build={build} active='console'>
<Console
output={build.output}
errorIds={build.errorIds}
displayPath={hash.length>0?hash:undefined}
/>
</Build>}
</PageSection>
)
}
}
export default connect(state => ({
tenant: state.tenant,
remoteData: state.build,
}))(BuildConsolePage)

View File

@ -1,75 +0,0 @@
// 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 { connect } from 'react-redux'
import PropTypes from 'prop-types'
import { PageSection, PageSectionVariants } from '@patternfly/react-core'
import { fetchBuildIfNeeded } from '../actions/build'
import { Fetchable } from '../containers/Fetching'
import Build from '../containers/build/Build'
import Manifest from '../containers/build/Manifest'
class BuildLogsPage extends React.Component {
static propTypes = {
match: PropTypes.object.isRequired,
remoteData: PropTypes.object,
tenant: PropTypes.object,
dispatch: PropTypes.func,
}
updateData = (force) => {
this.props.dispatch(fetchBuildIfNeeded(
this.props.tenant, this.props.match.params.buildId, null, force))
}
componentDidMount () {
document.title = 'Zuul Build'
if (this.props.tenant.name) {
this.updateData()
}
}
componentDidUpdate (prevProps) {
if (this.props.tenant.name !== prevProps.tenant.name) {
this.updateData()
}
}
render () {
const { remoteData } = this.props
const build = remoteData.builds[this.props.match.params.buildId]
return (
<PageSection variant={PageSectionVariants.light}>
<PageSection style={{paddingRight: '5px'}}>
<Fetchable
isFetching={remoteData.isFetching}
fetchCallback={this.updateData}
/>
</PageSection>
{build && build.manifest &&
<Build build={build} active='logs'>
<Manifest tenant={this.props.tenant} build={build}/>
</Build>}
</PageSection>
)
}
}
export default connect(state => ({
tenant: state.tenant,
remoteData: state.build,
}))(BuildLogsPage)

View File

@ -21,8 +21,6 @@ import JobsPage from './pages/Jobs'
import LabelsPage from './pages/Labels'
import NodesPage from './pages/Nodes'
import BuildPage from './pages/Build'
import BuildLogsPage from './pages/BuildLogs'
import BuildConsolePage from './pages/BuildConsole'
import LogFilePage from './pages/LogFile'
import BuildsPage from './pages/Builds'
import BuildsetPage from './pages/Buildset'
@ -90,15 +88,18 @@ const routes = () => [
},
{
to: '/build/:buildId',
component: BuildPage
component: BuildPage,
props: {'activeTab': 'summary'},
},
{
to: '/build/:buildId/logs',
component: BuildLogsPage
component: BuildPage,
props: {'activeTab': 'logs'},
},
{
to: '/build/:buildId/console',
component: BuildConsolePage
component: BuildPage,
props: {'activeTab': 'console'},
},
{
to: '/build/:buildId/log/:file*',