mirror of
https://github.com/ansible/awx.git
synced 2026-01-16 04:10:44 -03:30
use unified jobs api to redirect to canonical url from /jobs/:id
This commit is contained in:
parent
2f9be4796a
commit
0d7500d349
@ -15,6 +15,7 @@ import RoutedTabs from '@components/RoutedTabs';
|
||||
|
||||
import JobDetail from './JobDetail';
|
||||
import JobOutput from './JobOutput';
|
||||
import { JOB_TYPE_URL_SEGMENTS } from './constants';
|
||||
|
||||
class Job extends Component {
|
||||
constructor(props) {
|
||||
@ -59,9 +60,13 @@ class Job extends Component {
|
||||
}
|
||||
|
||||
render() {
|
||||
const { history, match, i18n } = this.props;
|
||||
const { history, match, i18n, lookup } = this.props;
|
||||
|
||||
const { job, contentError, hasContentLoading, isInitialized } = this.state;
|
||||
let jobType;
|
||||
if (job) {
|
||||
jobType = JOB_TYPE_URL_SEGMENTS[job.type];
|
||||
}
|
||||
|
||||
const tabsArray = [
|
||||
{ name: i18n._(t`Details`), link: `${match.url}/details`, id: 0 },
|
||||
@ -100,6 +105,19 @@ class Job extends Component {
|
||||
);
|
||||
}
|
||||
|
||||
if (lookup && job) {
|
||||
return (
|
||||
<Switch>
|
||||
<Redirect from="jobs/:id" to={`/jobs/${jobType}/:id/details`} />
|
||||
<Redirect
|
||||
from="jobs/:id/details"
|
||||
to={`/jobs/${jobType}/:id/details`}
|
||||
/>
|
||||
<Redirect from="jobs/:id/output" to={`/jobs/${jobType}/:id/output`} />
|
||||
</Switch>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<PageSection>
|
||||
<Card>
|
||||
|
||||
@ -9,7 +9,7 @@ import {
|
||||
import DataListCell from '@components/DataListCell';
|
||||
import VerticalSeparator from '@components/VerticalSeparator';
|
||||
import { toTitleCase } from '@util/strings';
|
||||
import { JOB_TYPE_URLS } from '../constants';
|
||||
import { JOB_TYPE_URL_SEGMENTS } from '../constants';
|
||||
|
||||
class JobListItem extends Component {
|
||||
render() {
|
||||
@ -32,7 +32,9 @@ class JobListItem extends Component {
|
||||
<DataListCell key="divider">
|
||||
<VerticalSeparator />
|
||||
<span>
|
||||
<Link to={`/jobs/${JOB_TYPE_URLS[job.type]}/${job.id}`}>
|
||||
<Link
|
||||
to={`/jobs/${JOB_TYPE_URL_SEGMENTS[job.type]}/${job.id}`}
|
||||
>
|
||||
<b>{job.name}</b>
|
||||
</Link>
|
||||
</span>
|
||||
|
||||
52
awx/ui_next/src/screens/Job/JobTypeRedirect.jsx
Normal file
52
awx/ui_next/src/screens/Job/JobTypeRedirect.jsx
Normal file
@ -0,0 +1,52 @@
|
||||
import React, { Component } from 'react';
|
||||
import { Redirect } from 'react-router-dom';
|
||||
import { UnifiedJobsAPI } from '@api';
|
||||
import { JOB_TYPE_URL_SEGMENTS } from './constants';
|
||||
|
||||
class JobTypeRedirect extends Component {
|
||||
static defaultProps = {
|
||||
view: 'details',
|
||||
};
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
hasError: false,
|
||||
job: null,
|
||||
};
|
||||
this.loadJob = this.loadJob.bind(this);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.loadJob();
|
||||
}
|
||||
|
||||
async loadJob() {
|
||||
const { id } = this.props;
|
||||
try {
|
||||
const { data } = await UnifiedJobsAPI.read({ id });
|
||||
this.setState({
|
||||
job: data.results[0],
|
||||
});
|
||||
} catch (err) {
|
||||
this.setState({ hasError: true });
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const { path, view } = this.props;
|
||||
const { hasError, job } = this.state;
|
||||
|
||||
if (hasError) {
|
||||
return <div>Error</div>;
|
||||
}
|
||||
if (!job) {
|
||||
return <div>Loading...</div>;
|
||||
}
|
||||
const type = JOB_TYPE_URL_SEGMENTS[job.type];
|
||||
return <Redirect from={path} to={`/jobs/${type}/${job.id}/${view}`} />;
|
||||
}
|
||||
}
|
||||
|
||||
export default JobTypeRedirect;
|
||||
@ -4,8 +4,9 @@ import { withI18n } from '@lingui/react';
|
||||
import { t } from '@lingui/macro';
|
||||
import Breadcrumbs from '@components/Breadcrumbs/Breadcrumbs';
|
||||
import Job from './Job';
|
||||
import JobTypeRedirect from './JobTypeRedirect';
|
||||
import JobList from './JobList/JobList';
|
||||
import { JOB_TYPE_URLS } from './constants';
|
||||
import { JOB_TYPE_URL_SEGMENTS } from './constants';
|
||||
|
||||
class Jobs extends Component {
|
||||
constructor(props) {
|
||||
@ -27,7 +28,7 @@ class Jobs extends Component {
|
||||
return;
|
||||
}
|
||||
|
||||
const type = JOB_TYPE_URLS[job.type];
|
||||
const type = JOB_TYPE_URL_SEGMENTS[job.type];
|
||||
const breadcrumbConfig = {
|
||||
'/jobs': i18n._(t`Jobs`),
|
||||
[`/jobs/${type}/${job.id}`]: `${job.name}`,
|
||||
@ -57,6 +58,18 @@ class Jobs extends Component {
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
<Route
|
||||
path={`${match.path}/:id/details`}
|
||||
render={({ match: m }) => (
|
||||
<JobTypeRedirect id={m.params.id} path={m.path} view="details" />
|
||||
)}
|
||||
/>
|
||||
<Route
|
||||
path={`${match.path}/:id/output`}
|
||||
render={({ match: m }) => (
|
||||
<JobTypeRedirect id={m.params.id} path={m.path} view="output" />
|
||||
)}
|
||||
/>
|
||||
<Route
|
||||
path={`${match.path}/:type/:id`}
|
||||
render={() => (
|
||||
@ -67,6 +80,12 @@ class Jobs extends Component {
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
<Route
|
||||
path={`${match.path}/:id`}
|
||||
render={({ match: m }) => (
|
||||
<JobTypeRedirect id={m.params.id} path={m.path} />
|
||||
)}
|
||||
/>
|
||||
</Switch>
|
||||
</Fragment>
|
||||
);
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/* eslint-disable-next-line import/prefer-default-export */
|
||||
export const JOB_TYPE_URLS = {
|
||||
export const JOB_TYPE_URL_SEGMENTS = {
|
||||
job: 'playbook',
|
||||
project_update: 'project',
|
||||
system_job: 'system',
|
||||
|
||||
@ -377,9 +377,9 @@ exports[`<OrganizationAccessItem /> initially renders succesfully 1`] = `
|
||||
"componentStyle": ComponentStyle {
|
||||
"componentId": "DetailList-sc-12g7m4-0",
|
||||
"isStatic": false,
|
||||
"lastClassName": "hndBXy",
|
||||
"lastClassName": "gmERnX",
|
||||
"rules": Array [
|
||||
"display:grid;grid-gap:20px;",
|
||||
"display:grid;grid-gap:20px;align-items:baseline;",
|
||||
[Function],
|
||||
],
|
||||
},
|
||||
@ -397,15 +397,15 @@ exports[`<OrganizationAccessItem /> initially renders succesfully 1`] = `
|
||||
stacked={true}
|
||||
>
|
||||
<DetailList
|
||||
className="DetailList-sc-12g7m4-0 hndBXy"
|
||||
className="DetailList-sc-12g7m4-0 gmERnX"
|
||||
stacked={true}
|
||||
>
|
||||
<TextList
|
||||
className="DetailList-sc-12g7m4-0 hndBXy"
|
||||
className="DetailList-sc-12g7m4-0 gmERnX"
|
||||
component="dl"
|
||||
>
|
||||
<dl
|
||||
className="DetailList-sc-12g7m4-0 hndBXy"
|
||||
className="DetailList-sc-12g7m4-0 gmERnX"
|
||||
data-pf-content={true}
|
||||
>
|
||||
<Detail
|
||||
@ -545,9 +545,9 @@ exports[`<OrganizationAccessItem /> initially renders succesfully 1`] = `
|
||||
"componentStyle": ComponentStyle {
|
||||
"componentId": "DetailList-sc-12g7m4-0",
|
||||
"isStatic": false,
|
||||
"lastClassName": "hndBXy",
|
||||
"lastClassName": "gmERnX",
|
||||
"rules": Array [
|
||||
"display:grid;grid-gap:20px;",
|
||||
"display:grid;grid-gap:20px;align-items:baseline;",
|
||||
[Function],
|
||||
],
|
||||
},
|
||||
@ -565,15 +565,15 @@ exports[`<OrganizationAccessItem /> initially renders succesfully 1`] = `
|
||||
stacked={true}
|
||||
>
|
||||
<DetailList
|
||||
className="DetailList-sc-12g7m4-0 hndBXy"
|
||||
className="DetailList-sc-12g7m4-0 gmERnX"
|
||||
stacked={true}
|
||||
>
|
||||
<TextList
|
||||
className="DetailList-sc-12g7m4-0 hndBXy"
|
||||
className="DetailList-sc-12g7m4-0 gmERnX"
|
||||
component="dl"
|
||||
>
|
||||
<dl
|
||||
className="DetailList-sc-12g7m4-0 hndBXy"
|
||||
className="DetailList-sc-12g7m4-0 gmERnX"
|
||||
data-pf-content={true}
|
||||
>
|
||||
<Detail
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user