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'; 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 { class Jobs extends Base {
constructor(http) { constructor(http) {
super(http); super(http);
@@ -7,8 +16,7 @@ class Jobs extends Base {
} }
readDetail (id, type) { readDetail (id, type) {
// TODO: adjust url based on type return this.http.get(`/api/v2${BASE_URLS[type]}${id}/`);
return this.http.get(`${this.baseUrl}${id}/`);
} }
} }

View File

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

View File

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

View File

@@ -11,6 +11,15 @@ import DataListCell from '@components/DataListCell';
import VerticalSeparator from '@components/VerticalSeparator'; import VerticalSeparator from '@components/VerticalSeparator';
import { toTitleCase } from '@util/strings'; 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 { class JobListItem extends Component {
render() { render() {
const { job, isSelected, onSelect } = this.props; const { job, isSelected, onSelect } = this.props;
@@ -27,19 +36,18 @@ class JobListItem extends Component {
onChange={onSelect} onChange={onSelect}
aria-labelledby={`check-action-${job.id}`} aria-labelledby={`check-action-${job.id}`}
/> />
<DataListItemCells <DataListItemCells dataListCells={[
dataListCells={[ <DataListCell key="divider">
<DataListCell key="divider"> <VerticalSeparator />
<VerticalSeparator /> <span>
<span> <Link to={`/jobs/${JOB_TYPE_URLS[job.type]}/${job.id}`}>
<Link to={`/jobs/${job.type}/${job.id}`}> <b>{job.name}</b>
<b>{job.name}</b> </Link>
</Link> </span>
</span> </DataListCell>,
</DataListCell>, <DataListCell key="type">{toTitleCase(job.type)}</DataListCell>,
<DataListCell key="type">{toTitleCase(job.type)}</DataListCell>, <DataListCell key="finished">{job.finished}</DataListCell>,
<DataListCell key="finished">{job.finished}</DataListCell>, ]}
]}
/> />
</DataListItemRow> </DataListItemRow>
</DataListItem> </DataListItem>