mirror of
https://github.com/ZwareBear/awx.git
synced 2026-04-12 11:01:48 -05:00
173 lines
4.7 KiB
JavaScript
173 lines
4.7 KiB
JavaScript
import React from 'react';
|
|
import styled from 'styled-components';
|
|
import { withI18n } from '@lingui/react';
|
|
import { t } from '@lingui/macro';
|
|
import { shape, func } from 'prop-types';
|
|
import {
|
|
DownloadIcon,
|
|
RocketIcon,
|
|
TrashAltIcon,
|
|
} from '@patternfly/react-icons';
|
|
import { Badge as PFBadge, Button, Tooltip } from '@patternfly/react-core';
|
|
import VerticalSeparator from '@components/VerticalSeparator';
|
|
import DeleteButton from '@components/DeleteButton';
|
|
import LaunchButton from '@components/LaunchButton';
|
|
|
|
const BadgeGroup = styled.div`
|
|
margin-left: 20px;
|
|
height: 18px;
|
|
display: inline-flex;
|
|
`;
|
|
|
|
const Badge = styled(PFBadge)`
|
|
align-items: center;
|
|
display: flex;
|
|
justify-content: center;
|
|
margin-left: 10px;
|
|
${props =>
|
|
props.color
|
|
? `
|
|
background-color: ${props.color}
|
|
color: white;
|
|
`
|
|
: null}
|
|
`;
|
|
|
|
const Wrapper = styled.div`
|
|
align-items: center;
|
|
display: flex;
|
|
flex-flow: row wrap;
|
|
font-size: 14px;
|
|
`;
|
|
|
|
function toHHMMSS(s) {
|
|
function pad(n) {
|
|
return `00${n}`.slice(-2);
|
|
}
|
|
|
|
const secs = s % 60;
|
|
s = (s - secs) / 60;
|
|
const mins = s % 60;
|
|
const hrs = (s - mins) / 60;
|
|
|
|
return `${pad(hrs)}:${pad(mins)}:${pad(secs)}`;
|
|
}
|
|
|
|
const OUTPUT_NO_COUNT_JOB_TYPES = [
|
|
'ad_hoc_command',
|
|
'system_job',
|
|
'inventory_update',
|
|
];
|
|
|
|
const OutputToolbar = ({ i18n, job, onDelete }) => {
|
|
const hideCounts = OUTPUT_NO_COUNT_JOB_TYPES.includes(job.type);
|
|
|
|
const playCount = job?.playbook_counts?.play_count;
|
|
const taskCount = job?.playbook_counts?.task_count;
|
|
const darkCount = job?.host_status_counts?.dark;
|
|
const failureCount = job?.host_status_counts?.failures;
|
|
const totalHostCount = Object.keys(job?.host_status_counts).reduce(
|
|
(sum, key) => sum + job?.host_status_counts[key],
|
|
0
|
|
);
|
|
|
|
return (
|
|
<Wrapper>
|
|
{!hideCounts && (
|
|
<>
|
|
{playCount > 0 && (
|
|
<BadgeGroup aria-label={i18n._(t`Play Count`)}>
|
|
<div>{i18n._(t`Plays`)}</div>
|
|
<Badge isRead>{playCount}</Badge>
|
|
</BadgeGroup>
|
|
)}
|
|
{taskCount > 0 && (
|
|
<BadgeGroup aria-label={i18n._(t`Task Count`)}>
|
|
<div>{i18n._(t`Tasks`)}</div>
|
|
<Badge isRead>{taskCount}</Badge>
|
|
</BadgeGroup>
|
|
)}
|
|
{totalHostCount > 0 && (
|
|
<BadgeGroup aria-label={i18n._(t`Host Count`)}>
|
|
<div>{i18n._(t`Hosts`)}</div>
|
|
<Badge isRead>{totalHostCount}</Badge>
|
|
</BadgeGroup>
|
|
)}
|
|
{darkCount > 0 && (
|
|
<BadgeGroup aria-label={i18n._(t`Unreachable Host Count`)}>
|
|
<div>{i18n._(t`Unreachable`)}</div>
|
|
<Tooltip content={i18n._(t`Unreachable Hosts`)}>
|
|
<Badge color="#470000" isRead>
|
|
{darkCount}
|
|
</Badge>
|
|
</Tooltip>
|
|
</BadgeGroup>
|
|
)}
|
|
{failureCount > 0 && (
|
|
<BadgeGroup aria-label={i18n._(t`Failed Host Count`)}>
|
|
<div>{i18n._(t`Failed`)}</div>
|
|
<Tooltip content={i18n._(t`Failed Hosts`)}>
|
|
<Badge color="#C9190B" isRead>
|
|
{failureCount}
|
|
</Badge>
|
|
</Tooltip>
|
|
</BadgeGroup>
|
|
)}
|
|
</>
|
|
)}
|
|
|
|
<BadgeGroup aria-label={i18n._(t`Elapsed Time`)}>
|
|
<div>{i18n._(t`Elapsed`)}</div>
|
|
<Tooltip content={i18n._(t`Elapsed time that the job ran`)}>
|
|
<Badge isRead>{toHHMMSS(job.elapsed)}</Badge>
|
|
</Tooltip>
|
|
</BadgeGroup>
|
|
|
|
<VerticalSeparator />
|
|
|
|
{job.type !== 'system_job' &&
|
|
job.summary_fields.user_capabilities?.start && (
|
|
<Tooltip content={i18n._(t`Relaunch Job`)}>
|
|
<LaunchButton resource={job} aria-label={i18n._(t`Relaunch`)}>
|
|
{({ handleRelaunch }) => (
|
|
<Button variant="plain" onClick={handleRelaunch}>
|
|
<RocketIcon />
|
|
</Button>
|
|
)}
|
|
</LaunchButton>
|
|
</Tooltip>
|
|
)}
|
|
|
|
{job.related?.stdout && (
|
|
<Tooltip content={i18n._(t`Download Output`)}>
|
|
<a href={`${job.related.stdout}?format=txt_download`}>
|
|
<Button variant="plain">
|
|
<DownloadIcon />
|
|
</Button>
|
|
</a>
|
|
</Tooltip>
|
|
)}
|
|
|
|
{job.summary_fields.user_capabilities.delete && (
|
|
<Tooltip content={i18n._(t`Delete Job`)}>
|
|
<DeleteButton
|
|
name={job.name}
|
|
modalTitle={i18n._(t`Delete Job`)}
|
|
onConfirm={onDelete}
|
|
variant="plain"
|
|
>
|
|
<TrashAltIcon />
|
|
</DeleteButton>
|
|
</Tooltip>
|
|
)}
|
|
</Wrapper>
|
|
);
|
|
};
|
|
|
|
OutputToolbar.propTypes = {
|
|
job: shape({}).isRequired,
|
|
onDelete: func.isRequired,
|
|
};
|
|
|
|
export default withI18n()(OutputToolbar);
|