Add host status bar

This commit is contained in:
Marliana Lara 2020-02-05 19:57:55 -05:00
parent fd027f87a9
commit 4be7cf66ec
No known key found for this signature in database
GPG Key ID: 38C73B40DFA809EE
4 changed files with 145 additions and 3 deletions

View File

@ -1,3 +1,4 @@
import React, { Component } from 'react';
import styled from 'styled-components';
import {
AutoSizer,
@ -7,16 +8,15 @@ import {
List,
} from 'react-virtualized';
import React, { Component } from 'react';
import { CardBody } from '@components/Card';
import { JobsAPI } from '@api';
import ContentError from '@components/ContentError';
import ContentLoading from '@components/ContentLoading';
import JobEvent from './JobEvent';
import JobEventSkeleton from './JobEventSkeleton';
import PageControls from './PageControls';
import HostEventModal from './HostEventModal';
import { HostStatusBar } from './shared';
import { JobsAPI } from '@api';
const OutputHeader = styled.div`
font-weight: var(--pf-global--FontWeight--bold);
@ -306,6 +306,7 @@ class JobOutput extends Component {
/>
)}
<OutputHeader>{job.name}</OutputHeader>
<HostStatusBar counts={job.host_status_counts} />
<PageControls
onScrollFirst={this.handleScrollFirst}
onScrollLast={this.handleScrollLast}

View File

@ -0,0 +1,88 @@
import React from 'react';
import styled from 'styled-components';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import { Badge, Tooltip } from '@patternfly/react-core';
const BarWrapper = styled.div`
background-color: #d7d7d7;
display: flex;
height: 5px;
margin: 24px 0;
width: 100%;
`;
const BarSegment = styled.div`
background-color: ${props => props.color || 'inherit'};
flex-grow: ${props => props.count || 0};
`;
const TooltipContent = styled.div`
align-items: center;
display: flex;
span.pf-c-badge {
margin-left: 10px;
}
`;
const HostStatusBar = ({ i18n, counts = {} }) => {
const noData = Object.keys(counts).length === 0;
const hostStatus = {
ok: {
color: '#92D400',
label: i18n._(t`OK`),
},
dark: {
color: '#470000',
label: i18n._(t`Unreachable`),
},
failures: {
color: '#C9190B',
label: i18n._(t`Failed`),
},
changed: {
color: '#F0AB00',
label: i18n._(t`Changed`),
},
skipped: {
color: '#73BCF7',
label: i18n._(t`Skipped`),
},
};
const barSegments = Object.keys(hostStatus).map(key => {
const count = counts[key] || 0;
return (
<Tooltip
key={key}
content={
<TooltipContent>
{hostStatus[key].label}
<Badge isRead>{count}</Badge>
</TooltipContent>
}
>
<BarSegment key={key} color={hostStatus[key].color} count={count} />
</Tooltip>
);
});
if (noData) {
return (
<BarWrapper>
<Tooltip
content={i18n._(
t`Host status information for this job is unavailable.`
)}
>
<BarSegment count={1} />
</Tooltip>
</BarWrapper>
);
}
return <BarWrapper>{barSegments}</BarWrapper>;
};
export default withI18n()(HostStatusBar);

View File

@ -0,0 +1,52 @@
import React from 'react';
import { mountWithContexts } from '@testUtils/enzymeHelpers';
import { HostStatusBar } from '.';
describe('<HostStatusBar />', () => {
let wrapper;
const mockCounts = {
ok: 5,
skipped: 1,
};
beforeEach(() => {
wrapper = mountWithContexts(<HostStatusBar counts={mockCounts} />);
});
afterEach(() => {
wrapper.unmount();
});
test('initially renders without crashing', () => {
expect(wrapper.length).toBe(1);
});
test('should render five bar segments', () => {
expect(wrapper.find('HostStatusBar__BarSegment').length).toBe(5);
});
test('tooltips should display host status and count', () => {
const tooltips = wrapper.find('TooltipContent');
const expectedContent = [
{ label: 'OK', count: 5 },
{ label: 'Unreachable', count: 0 },
{ label: 'Failed', count: 0 },
{ label: 'Changed', count: 0 },
{ label: 'Skipped', count: 1 },
];
tooltips.forEach((tooltip, index) => {
expect(tooltip.text()).toEqual(
`${expectedContent[index].label}${expectedContent[index].count}`
);
});
});
test('empty host counts should display tooltip and one bar segment', () => {
wrapper = mountWithContexts(<HostStatusBar />);
expect(wrapper.find('HostStatusBar__BarSegment').length).toBe(1);
expect(wrapper.find('TooltipContent').text()).toEqual(
'Host status information for this job is unavailable.'
);
});
});

View File

@ -2,3 +2,4 @@ export { default as JobEventLine } from './JobEventLine';
export { default as JobEventLineToggle } from './JobEventLineToggle';
export { default as JobEventLineNumber } from './JobEventLineNumber';
export { default as JobEventLineText } from './JobEventLineText';
export { default as HostStatusBar } from './HostStatusBar';