mirror of
https://github.com/ansible/awx.git
synced 2026-05-13 20:37:39 -02:30
build basic job details
This commit is contained in:
@@ -5,6 +5,11 @@ class Jobs extends Base {
|
|||||||
super(http);
|
super(http);
|
||||||
this.baseUrl = '/api/v2/jobs/';
|
this.baseUrl = '/api/v2/jobs/';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
readDetail (id, type) {
|
||||||
|
// TODO: adjust url based on type
|
||||||
|
return this.http.get(`${this.baseUrl}${id}/`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Jobs;
|
export default Jobs;
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ const DetailValue = styled(({ fullWidth, ...props }) => (
|
|||||||
`;
|
`;
|
||||||
|
|
||||||
const Detail = ({ label, value, fullWidth }) => {
|
const Detail = ({ label, value, fullWidth }) => {
|
||||||
if (!value) return null;
|
if (!value && typeof value !== 'number') { return null; }
|
||||||
return (
|
return (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
<DetailName component={TextListItemVariants.dt} fullWidth={fullWidth}>
|
<DetailName component={TextListItemVariants.dt} fullWidth={fullWidth}>
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ class Job extends Component {
|
|||||||
|
|
||||||
this.setState({ contentError: null, hasContentLoading: true });
|
this.setState({ contentError: null, hasContentLoading: true });
|
||||||
try {
|
try {
|
||||||
const { data } = await JobsAPI.readDetail(id);
|
const { data } = await JobsAPI.readDetail(id, match.params.type);
|
||||||
setBreadcrumb(data);
|
setBreadcrumb(data);
|
||||||
this.setState({ job: data });
|
this.setState({ job: data });
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@@ -106,17 +106,31 @@ class Job extends Component {
|
|||||||
<Card>
|
<Card>
|
||||||
{cardHeader}
|
{cardHeader}
|
||||||
<Switch>
|
<Switch>
|
||||||
<Redirect from="/jobs/:id" to="/jobs/:id/details" exact />
|
<Redirect
|
||||||
|
from="/jobs/:type/:id"
|
||||||
|
to="/jobs/:type/:id/details"
|
||||||
|
exact
|
||||||
|
/>
|
||||||
{job && (
|
{job && (
|
||||||
<Route
|
<Route
|
||||||
path="/jobs/:id/details"
|
path="/jobs/:type/:id/details"
|
||||||
render={() => <JobDetail match={match} job={job} />}
|
render={() => (
|
||||||
|
<JobDetail
|
||||||
|
match={match}
|
||||||
|
job={job}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{job && (
|
{job && (
|
||||||
<Route
|
<Route
|
||||||
path="/jobs/:id/output"
|
path="/jobs/:type/:id/output"
|
||||||
render={() => <JobOutput match={match} job={job} />}
|
render={() => (
|
||||||
|
<JobOutput
|
||||||
|
match={match}
|
||||||
|
job={job}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</Switch>
|
</Switch>
|
||||||
|
|||||||
@@ -1,35 +1,145 @@
|
|||||||
import React, { Component } from 'react';
|
import React, { Component, useState, useEffect } from 'react';
|
||||||
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';
|
||||||
import { CardBody, Button } from '@patternfly/react-core';
|
import { CardBody, Button } from '@patternfly/react-core';
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
|
import { DetailList, Detail } from '@components/DetailList';
|
||||||
|
import { ChipGroup, Chip } from '@components/Chip';
|
||||||
|
import ContentError from '@components/ContentError';
|
||||||
|
import ContentLoading from '@components/ContentLoading';
|
||||||
|
import { toTitleCase } from '@util/strings';
|
||||||
|
|
||||||
const ActionButtonWrapper = styled.div`
|
const ActionButtonWrapper = styled.div`
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
`;
|
`;
|
||||||
class JobDetail extends Component {
|
|
||||||
render() {
|
|
||||||
const { job, i18n } = this.props;
|
|
||||||
|
|
||||||
return (
|
const VERBOSITY = {
|
||||||
<CardBody>
|
0: '0 (Normal)',
|
||||||
<b>{job.name}</b>
|
1: '1 (Verbose)',
|
||||||
|
2: '2 (More Verbose)',
|
||||||
|
3: '3 (Debug)',
|
||||||
|
4: '4 (Connection Debug)',
|
||||||
|
};
|
||||||
|
|
||||||
<ActionButtonWrapper>
|
function JobDetail ({ job, i18n }) {
|
||||||
<Button
|
const [instanceGroups, setInstanceGroups] = useState(null);
|
||||||
variant="secondary"
|
console.log(job);
|
||||||
aria-label="close"
|
const {
|
||||||
component={Link}
|
job_template: jobTemplate,
|
||||||
to="/jobs"
|
project,
|
||||||
>
|
inventory,
|
||||||
{i18n._(t`Close`)}
|
instance_group: instanceGroup,
|
||||||
</Button>
|
} = job.summary_fields;
|
||||||
</ActionButtonWrapper>
|
|
||||||
</CardBody>
|
return (
|
||||||
);
|
<CardBody>
|
||||||
}
|
<DetailList>
|
||||||
|
{/* TODO: add status icon? */}
|
||||||
|
<Detail
|
||||||
|
label={i18n._(t`Status`)}
|
||||||
|
value={toTitleCase(job.status)}
|
||||||
|
/>
|
||||||
|
<Detail
|
||||||
|
label={i18n._(t`Started`)}
|
||||||
|
value={job.started}
|
||||||
|
/>
|
||||||
|
<Detail
|
||||||
|
label={i18n._(t`Finished`)}
|
||||||
|
value={job.finished}
|
||||||
|
/>
|
||||||
|
<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>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
{/* TODO: show project status icon */}
|
||||||
|
<Detail
|
||||||
|
label={i18n._(t`Project`)}
|
||||||
|
value={(
|
||||||
|
<Link to={`/projects/${project.id}`}>
|
||||||
|
{project.name}
|
||||||
|
</Link>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<Detail
|
||||||
|
label={i18n._(t`Revision`)}
|
||||||
|
value={job.scm_revision}
|
||||||
|
/>
|
||||||
|
<Detail
|
||||||
|
label={i18n._(t`Playbook`)}
|
||||||
|
value={null}
|
||||||
|
/>
|
||||||
|
<Detail
|
||||||
|
label={i18n._(t`Limit`)}
|
||||||
|
value={job.limit}
|
||||||
|
/>
|
||||||
|
<Detail
|
||||||
|
label={i18n._(t`Verbosity`)}
|
||||||
|
value={VERBOSITY[job.verbosity]}
|
||||||
|
/>
|
||||||
|
<Detail
|
||||||
|
label={i18n._(t`Environment`)}
|
||||||
|
value={null}
|
||||||
|
/>
|
||||||
|
<Detail
|
||||||
|
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}`}
|
||||||
|
/>
|
||||||
|
{(instanceGroups && instanceGroups.length > 0) && (
|
||||||
|
<Detail
|
||||||
|
fullWidth
|
||||||
|
label={i18n._(t`Instance Groups`)}
|
||||||
|
value={(
|
||||||
|
<ChipGroup showOverflowAfter={5}>
|
||||||
|
{instanceGroups.map(ig => (
|
||||||
|
<Chip key={ig.id} isReadOnly>{ig.name}</Chip>
|
||||||
|
))}
|
||||||
|
</ChipGroup>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</DetailList>
|
||||||
|
<ActionButtonWrapper>
|
||||||
|
<Button
|
||||||
|
variant="secondary"
|
||||||
|
aria-label="close"
|
||||||
|
component={Link}
|
||||||
|
to="/jobs"
|
||||||
|
>
|
||||||
|
{i18n._(t`Close`)}
|
||||||
|
</Button>
|
||||||
|
</ActionButtonWrapper>
|
||||||
|
</CardBody>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default withI18n()(withRouter(JobDetail));
|
export default withI18n()(withRouter(JobDetail));
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ class JobListItem extends Component {
|
|||||||
<DataListCell key="divider">
|
<DataListCell key="divider">
|
||||||
<VerticalSeparator />
|
<VerticalSeparator />
|
||||||
<span>
|
<span>
|
||||||
<Link to={`/jobs/${job.id}`}>
|
<Link to={`/jobs/${job.type}/${job.id}`}>
|
||||||
<b>{job.name}</b>
|
<b>{job.name}</b>
|
||||||
</Link>
|
</Link>
|
||||||
</span>
|
</span>
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ class Jobs extends Component {
|
|||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
<Route
|
<Route
|
||||||
path={`${match.path}/:id`}
|
path={`${match.path}/:type/:id`}
|
||||||
render={() => (
|
render={() => (
|
||||||
<Job
|
<Job
|
||||||
history={history}
|
history={history}
|
||||||
|
|||||||
Reference in New Issue
Block a user