// 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 React, { useState } from 'react' import PropTypes from 'prop-types' import { connect } from 'react-redux' import { Link } from 'react-router-dom' import { Flex, FlexItem, List, ListItem, Title } from '@patternfly/react-core' import { BookIcon, BuildIcon, CodeBranchIcon, CodeIcon, CubeIcon, FileCodeIcon, FingerprintIcon, HistoryIcon, OutlinedCalendarAltIcon, OutlinedClockIcon, StreamIcon, ThumbtackIcon, LockIcon, } from '@patternfly/react-icons' import * as moment from 'moment' import 'moment-duration-format' import { BuildResultBadge, BuildResultWithIcon } from './Misc' import { buildExternalLink, ExternalLink, IconProperty } from '../../Misc' import AutoholdModal from '../autohold/autoholdModal' function Build({ build, tenant, timezone, user }) { const [showAutoholdModal, setShowAutoholdModal] = useState(false) const change = build.change ? build.change : '' const ref = build.change ? '' : build.ref const project = build.project const job_name = build.job_name const build_link = buildExternalLink(build) function renderAutoholdButton() { const value = ( { event.preventDefault() setShowAutoholdModal(true) }} > Autohold future build failure(s) ) return ( } value={value} /> ) } return ( <> <BuildResultWithIcon result={build.result} colored={build.voting} size="md" > {build.job_name} {!build.voting && ' (non-voting)'} </BuildResultWithIcon> <BuildResultBadge result={build.result} /> {build.held && <ThumbtackIcon title="This build triggered an autohold" style={{ marginLeft: 'var(--pf-global--spacer--sm)', }} />} {/* 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) */} {build_link && ( } value={build_link} /> )} {/* TODO (felix): Link to project page in Zuul */} } value={ <> Project {build.project} } /> } value={ build.branch ? ( <> Branch {build.branch} ) : ( <> Ref {build.ref} ) } /> } value={ <> Pipeline {build.pipeline} } /> } value={ UUID {build.uuid}
Event ID {build.event_id}
} />
} value={ Started at {moment .utc(build.start_time) .tz(timezone) .format('YYYY-MM-DD HH:mm:ss')}
Completed at {moment .utc(build.end_time) .tz(timezone) .format('YYYY-MM-DD HH:mm:ss')}
} /> } value={ <> Took {moment .duration(build.duration, 'seconds') .format('h [hr] m [min] s [sec]')} } />
} value={ View job documentation } /> } value={ View buildset result } /> )} } value={ build.log_url ? ( View log ) : ( No log available ) } /> {(user.isAdmin && user.scope.indexOf(tenant.name) !== -1) && renderAutoholdButton()}
{} ) } Build.propTypes = { build: PropTypes.object, tenant: PropTypes.object, hash: PropTypes.array, timezone: PropTypes.string, user: PropTypes.object, } export default connect((state) => ({ tenant: state.tenant, timezone: state.timezone, user: state.user, }))(Build)