job details: handle different job types

This commit is contained in:
Keith Grant 2019-07-02 14:54:45 -07:00
parent da780c9d7c
commit eee1601528
4 changed files with 103 additions and 78 deletions

View File

@ -1,5 +1,14 @@
import Base from '../Base';
const BASE_URLS = {
playbook: '/jobs/',
project: '/project_updates/',
system: '/system_jobs/',
inventory: '/inventory_updates/',
command: '/ad_hoc_commands/',
workflow: '/workflow_jobs/',
};
class Jobs extends Base {
constructor(http) {
super(http);
@ -7,8 +16,7 @@ class Jobs extends Base {
}
readDetail (id, type) {
// TODO: adjust url based on type
return this.http.get(`${this.baseUrl}${id}/`);
return this.http.get(`/api/v2${BASE_URLS[type]}${id}/`);
}
}

View File

@ -8,7 +8,6 @@ import {
CardHeader as PFCardHeader,
PageSection,
} from '@patternfly/react-core';
import { JobsAPI } from '@api';
import ContentError from '@components/ContentError';
import CardCloseButton from '@components/CardCloseButton';
@ -111,28 +110,18 @@ class Job extends Component {
to="/jobs/:type/:id/details"
exact
/>
{job && (
{job && [
<Route
key="details"
path="/jobs/:type/:id/details"
render={() => (
<JobDetail
match={match}
job={job}
/>
)}
/>
)}
{job && (
render={() => <JobDetail type={match.params.type} job={job} />}
/>,
<Route
key="output"
path="/jobs/:type/:id/output"
render={() => (
<JobOutput
match={match}
job={job}
/>
)}
/>
)}
render={() => <JobOutput type={match.params.type} job={job} />}
/>,
]}
</Switch>
</Card>
</PageSection>

View File

@ -1,4 +1,5 @@
import React from 'react';
import { shape } from 'prop-types';
import { Link, withRouter } from 'react-router-dom';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
@ -48,35 +49,41 @@ function JobDetail ({ job, i18n }) {
label={i18n._(t`Finished`)}
value={job.finished}
/>
<Detail
label={i18n._(t`Template`)}
value={(
<Link to={`/templates/job_template/${jobTemplate.id}`}>
{jobTemplate.name}
</Link>
)}
/>
{jobTemplate && (
<Detail
label={i18n._(t`Template`)}
value={(
<Link to={`/templates/job_template/${jobTemplate.id}`}>
{jobTemplate.name}
</Link>
)}
/>
)}
<Detail
label={i18n._(t`Job Type`)}
value={toTitleCase(job.job_type)}
/>
<Detail
label={i18n._(t`Inventory`)}
value={(
<Link to={`/inventory/${inventory.id}`}>
{inventory.name}
</Link>
)}
/>
{inventory && (
<Detail
label={i18n._(t`Inventory`)}
value={(
<Link to={`/inventory/${inventory.id}`}>
{inventory.name}
</Link>
)}
/>
)}
{/* TODO: show project status icon */}
<Detail
label={i18n._(t`Project`)}
value={(
<Link to={`/projects/${project.id}`}>
{project.name}
</Link>
)}
/>
{project && (
<Detail
label={i18n._(t`Project`)}
value={(
<Link to={`/projects/${project.id}`}>
{project.name}
</Link>
)}
/>
)}
<Detail
label={i18n._(t`Revision`)}
value={job.scm_revision}
@ -101,18 +108,26 @@ function JobDetail ({ job, i18n }) {
label={i18n._(t`Execution Node`)}
value={job.exucution_node}
/>
<Detail
label={i18n._(t`Instance Group`)}
value={(
<Link to={`/instance_groups/${instanceGroup.id}`}>
{instanceGroup.name}
</Link>
)}
/>
<Detail
label={i18n._(t`Job Slice`)}
value={`${job.job_slice_number}/${job.job_slice_count}`}
/>
{instanceGroup && (
<Detail
label={i18n._(t`Instance Group`)}
value={(
<Link to={`/instance_groups/${instanceGroup.id}`}>
{instanceGroup.name}
</Link>
)}
/>
)}
{
typeof job.job_slice_number === 'number'
&& typeof job.job_slice_count === 'number'
&& (
<Detail
label={i18n._(t`Job Slice`)}
value={`${job.job_slice_number}/${job.job_slice_count}`}
/>
)
}
{(credentials && credentials.length > 0) && (
<Detail
fullWidth
@ -140,14 +155,16 @@ function JobDetail ({ job, i18n }) {
/>
)}
</DetailList>
<VariablesInput
css="margin: 20px 0"
id="job-variables"
readOnly
value={job.extra_vars}
rows={4}
label={i18n._(t`Variables`)}
/>
{job.extra_vars && (
<VariablesInput
css="margin: 20px 0"
id="job-variables"
readOnly
value={job.extra_vars}
rows={4}
label={i18n._(t`Variables`)}
/>
)}
<VariablesInput
css="margin: 20px 0"
id="job-artifacts"
@ -169,5 +186,8 @@ function JobDetail ({ job, i18n }) {
</CardBody>
);
}
JobDetail.propTypes = {
job: shape({}).isRequired,
};
export default withI18n()(withRouter(JobDetail));

View File

@ -11,6 +11,15 @@ import DataListCell from '@components/DataListCell';
import VerticalSeparator from '@components/VerticalSeparator';
import { toTitleCase } from '@util/strings';
const JOB_TYPE_URLS = {
job: 'playbook',
project_update: 'project',
system_job: 'system',
inventory_update: 'inventory',
ad_hoc_command: 'command',
workflow_job: 'workflow',
};
class JobListItem extends Component {
render() {
const { job, isSelected, onSelect } = this.props;
@ -27,19 +36,18 @@ class JobListItem extends Component {
onChange={onSelect}
aria-labelledby={`check-action-${job.id}`}
/>
<DataListItemCells
dataListCells={[
<DataListCell key="divider">
<VerticalSeparator />
<span>
<Link to={`/jobs/${job.type}/${job.id}`}>
<b>{job.name}</b>
</Link>
</span>
</DataListCell>,
<DataListCell key="type">{toTitleCase(job.type)}</DataListCell>,
<DataListCell key="finished">{job.finished}</DataListCell>,
]}
<DataListItemCells dataListCells={[
<DataListCell key="divider">
<VerticalSeparator />
<span>
<Link to={`/jobs/${JOB_TYPE_URLS[job.type]}/${job.id}`}>
<b>{job.name}</b>
</Link>
</span>
</DataListCell>,
<DataListCell key="type">{toTitleCase(job.type)}</DataListCell>,
<DataListCell key="finished">{job.finished}</DataListCell>,
]}
/>
</DataListItemRow>
</DataListItem>