diff options
author | Felix Edel <felix.edel@bmw.de> | 2020-06-24 08:47:54 +0200 |
---|---|---|
committer | Felix Edel <felix.edel@bmw.de> | 2020-07-15 09:06:04 +0200 |
commit | 403a828b86b9c7fe1d2f0a9646fad32b480888f3 (patch) | |
tree | 154229c6e5ae2f372c024b20deafaf538908a75d /web/src/containers/build/Buildset.jsx | |
parent | 18e55acb61eb25c71e365210dba27aa3cceae7a1 (diff) | |
download | zuul-403a828b86b9c7fe1d2f0a9646fad32b480888f3.tar.gz |
PF4: Update buildset result page (new layout and styling)
This updates the buildset result page with Patternfly 4 components and
a new design based on inspirations from other CI systems, Patternfly 4
demos and my own ideas.
I chose the buildset result page because it doesn't contain too much
elements und therefore is a good starting point. If you like the
design, I will continue with that also for other pages like the build
result pages or the various "list" pages like builds and buildsets.
Change-Id: I978ee448ddf6e22e4a6ec8211204f694932eaa4e
Diffstat (limited to 'web/src/containers/build/Buildset.jsx')
-rw-r--r-- | web/src/containers/build/Buildset.jsx | 221 |
1 files changed, 113 insertions, 108 deletions
diff --git a/web/src/containers/build/Buildset.jsx b/web/src/containers/build/Buildset.jsx index 42d4f1e48..f6eb0d587 100644 --- a/web/src/containers/build/Buildset.jsx +++ b/web/src/containers/build/Buildset.jsx @@ -15,117 +15,122 @@ import * as React from 'react' import PropTypes from 'prop-types' import { connect } from 'react-redux' -import { Link } from 'react-router-dom' -import { Panel } from 'react-bootstrap' -import * as moment from 'moment' -import 'moment-duration-format' +import { Flex, FlexItem, List, ListItem, Title } from '@patternfly/react-core' +import { + CodeIcon, + CodeBranchIcon, + OutlinedCommentDotsIcon, + CubeIcon, + FingerprintIcon, + StreamIcon, +} from '@patternfly/react-icons' +import { ExternalLink } from '../../Misc' +import { BuildResultBadge, BuildResultWithIcon, IconProperty } from './Misc' -class Buildset extends React.Component { - static propTypes = { - buildset: PropTypes.object, - tenant: PropTypes.object, - } +function Buildset(props) { + const { buildset, fetchable } = props - render () { - const { buildset } = this.props - const rows = [] - const myColumns = [ - 'change', 'project', 'branch', 'pipeline', 'result', 'message', 'event_id' - ] - const buildRows = [] - const buildColumns = [ - 'job', 'result', 'voting', 'duration' - ] - - myColumns.forEach(column => { - let label = column - let value = buildset[column] - if (column === 'change') { - value = ( - <a href={buildset.ref_url}> - {buildset.change},{buildset.patchset} - </a> - ) - } - if (column === 'event_id') { - label = 'event id' - } - if (value) { - rows.push({key: label, value: value}) - } - }) - - if (buildset.builds) { - buildset.builds.forEach(build => { - const row = [] - buildColumns.forEach(column => { - if (column === 'job') { - row.push(build.job_name) - } else if (column === 'duration') { - row.push(moment.duration(build.duration, 'seconds') - .format('h [hr] m [min] s [sec]')) - } else if (column === 'voting') { - row.push(build.voting ? 'true' : 'false') - } else if (column === 'result') { - row.push(<Link - to={this.props.tenant.linkPrefix + '/build/' + build.uuid}> - {build.result} - </Link>) - } else { - row.push(build[column]) - } - }) - buildRows.push(row) - }) - } - - return ( - <React.Fragment> - <Panel> - <Panel.Heading>Buildset result {buildset.uuid}</Panel.Heading> - <Panel.Body> - <table className="table table-striped table-bordered"> - <tbody> - {rows.map(item => ( - <tr key={item.key}> - <td>{item.key}</td> - <td>{item.value}</td> - </tr> - ))} - </tbody> - </table> - </Panel.Body> - </Panel> - {buildset.builds && - <Panel> - <Panel.Heading>Builds</Panel.Heading> - <Panel.Body> - <table className="table table-striped table-bordered"> - <thead> - <tr> - {buildColumns.map(item => ( - <td key={item}>{item}</td> - ))} - </tr> - </thead> - <tbody> - {buildset.builds.map((item, idx) => ( - <tr key={idx} className={item.result === 'SUCCESS' ? 'success': 'warning'}> - {buildRows[idx].map((item, idx) => ( - <td key={idx}>{item}</td> - ))} - </tr> - ))} - </tbody> - </table> - </Panel.Body> - </Panel> - } - </React.Fragment> - ) - } + return ( + <> + <Title headingLevel="h2"> + <BuildResultWithIcon result={buildset.result} size="md"> + Buildset result + </BuildResultWithIcon> + <BuildResultBadge result={buildset.result} /> + {fetchable} + </Title> + {/* We handle the spacing for the body and the flex items by ourselves + so they go hand in hand. By default, the flex items' spacing only + affects left/right margin, but not top or bottom (which looks + awkward when the items are stacked at certain breakpoints) */} + <Flex className="zuul-build-attributes"> + <Flex flex={{ default: 'flex_1' }}> + <FlexItem> + <List style={{ listStyle: 'none' }}> + {/* TODO (felix): It would be cool if we could differentiate + between the SVC system (Github, Gitlab, Gerrit), so we could + show the respective icon here (GithubIcon, GitlabIcon, + GitIcon - AFAIK the Gerrit icon is not very popular among + icon frameworks like fontawesome */} + {buildset.change && ( + <IconProperty + WrapElement={ListItem} + icon={<CodeIcon />} + value={ + <ExternalLink target={buildset.ref_url}> + <strong>Change </strong> + {buildset.change},{buildset.patchset} + </ExternalLink> + } + /> + )} + {/* TODO (felix): Link to project page in Zuul */} + <IconProperty + WrapElement={ListItem} + icon={<CubeIcon />} + value={ + <> + <strong>Project </strong> {buildset.project} + </> + } + /> + <IconProperty + WrapElement={ListItem} + icon={<CodeBranchIcon />} + value={ + <> + <strong>Branch </strong> {buildset.branch} + </> + } + /> + <IconProperty + WrapElement={ListItem} + icon={<StreamIcon />} + value={ + <> + <strong>Pipeline </strong> {buildset.pipeline} + </> + } + /> + <IconProperty + WrapElement={ListItem} + icon={<FingerprintIcon />} + value={ + <span> + <strong>UUID </strong> {buildset.uuid} <br /> + <strong>Event ID </strong> {buildset.event_id} <br /> + </span> + } + /> + </List> + </FlexItem> + </Flex> + <Flex flex={{ default: 'flex_1' }}> + <FlexItem> + <List style={{ listStyle: 'none' }}> + <IconProperty + WrapElement={ListItem} + icon={<OutlinedCommentDotsIcon />} + value={ + <> + <strong>Message:</strong> + <pre>{buildset.message}</pre> + </> + } + /> + </List> + </FlexItem> + </Flex> + </Flex> + </> + ) } +Buildset.propTypes = { + buildset: PropTypes.object, + tenant: PropTypes.object, + fetchable: PropTypes.node, +} -export default connect(state => ({tenant: state.tenant}))(Buildset) +export default connect((state) => ({ tenant: state.tenant }))(Buildset) |