zuul/web/src/containers/autohold/AutoholdTable.jsx

225 lines
5.5 KiB
JavaScript

// Copyright 2020 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 from 'react'
import PropTypes from 'prop-types'
import { connect } from 'react-redux'
import {
EmptyState,
EmptyStateBody,
EmptyStateIcon,
Spinner,
Title,
} from '@patternfly/react-core'
import {
OutlinedQuestionCircleIcon,
HashtagIcon,
BuildIcon,
CodeBranchIcon,
CubeIcon,
OutlinedClockIcon,
LockIcon,
TrashIcon,
FingerprintIcon,
} from '@patternfly/react-icons'
import {
Table,
TableHeader,
TableBody,
TableVariant,
} from '@patternfly/react-table'
import { Link } from 'react-router-dom'
import * as moment from 'moment'
import { autohold_delete } from '../../api'
import { addNotification } from '../../actions/notifications'
import { addAutoholdError } from '../../actions/adminActions'
import { fetchAutoholds } from '../../actions/autoholds'
import { IconProperty } from '../../Misc'
function AutoholdTable(props) {
const { autoholds, fetching, tenant, user, dispatch } = props
const columns = [
{
title: <IconProperty icon={<FingerprintIcon />} value="ID" />,
dataLabel: 'Request ID',
},
{
title: <IconProperty icon={<CubeIcon />} value="Project" />,
dataLabel: 'Project',
},
{
title: <IconProperty icon={<BuildIcon />} value="Job" />,
dataLabel: 'Job',
},
{
title: <IconProperty icon={<CodeBranchIcon />} value="Ref Filter" />,
dataLabel: 'Ref Filter',
},
{
title: <IconProperty icon={<HashtagIcon />} value="Triggers" />,
dataLabel: 'Triggers',
},
{
title: <IconProperty icon={<OutlinedQuestionCircleIcon />} value="Reason" />,
dataLabel: 'Reason',
},
{
title: <IconProperty icon={<OutlinedClockIcon />} value="Hold for" />,
dataLabel: 'Hold for',
},
{
title: '',
dataLabel: 'Delete',
}
]
function handleAutoholdDelete(requestId) {
autohold_delete(tenant.apiPrefix, requestId, user.token)
.then(() => {
dispatch(addNotification(
{
text: 'Autohold request deleted successfully.',
type: 'success',
status: '',
url: '',
}))
dispatch(fetchAutoholds(tenant))
})
.catch(error => {
dispatch(addAutoholdError(error))
})
}
function renderAutoholdDeleteButton(requestId) {
return (
<TrashIcon
title="Delete Autohold request"
style={{
cursor: 'pointer',
color: 'var(--pf-global--danger-color--100)',
}}
onClick={(event) => {
event.preventDefault()
handleAutoholdDelete(requestId)
}} />
)
}
function createAutoholdRow(autohold) {
const count = autohold.current_count + '/' + autohold.max_count
const node_expiration = (autohold.node_expiration === 0) ? 'Indefinitely' : moment.duration(autohold.node_expiration, 'seconds').humanize()
const delete_button = (user.isAdmin && user.scope.indexOf(tenant.name) !== -1) ? renderAutoholdDeleteButton(autohold.id) : ''
return {
cells: [
{
title: (
<Link to={`${tenant.linkPrefix}/autohold/${autohold.id}`}>{autohold.id}</Link>
),
},
{
title: autohold.project,
},
{
title: autohold.job,
},
{
title: autohold.ref_filter,
},
{
title: count
},
{
title: autohold.reason,
},
{
title: node_expiration,
},
{
title: delete_button
},
]
}
}
function createFetchingRow() {
const rows = [
{
heightAuto: true,
cells: [
{
props: { colSpan: 8 },
title: (
<center>
<Spinner size="xl" />
</center>
),
},
],
},
]
return rows
}
let rows = []
if (fetching) {
rows = createFetchingRow()
columns[0].dataLabel = ''
} else {
rows = autoholds.map((autohold) => createAutoholdRow(autohold))
}
return (
<>
<Table
aria-label="Autohold Requests Table"
variant={TableVariant.compact}
cells={columns}
rows={rows}
className="zuul-table"
>
<TableHeader />
<TableBody />
</Table>
{/* Show an empty state in case we don't have any autoholds but are also not
fetching */}
{!fetching && autoholds.length === 0 && (
<EmptyState>
<EmptyStateIcon icon={LockIcon} />
<Title headingLevel="h1">No autohold requests found</Title>
<EmptyStateBody>
Nothing to display.
</EmptyStateBody>
</EmptyState>
)}
</>
)
}
AutoholdTable.propTypes = {
autoholds: PropTypes.array.isRequired,
fetching: PropTypes.bool.isRequired,
tenant: PropTypes.object,
user: PropTypes.object,
dispatch: PropTypes.func,
}
export default connect((state) => ({
tenant: state.tenant,
user: state.user,
}))(AutoholdTable)