diff --git a/awx/ui_next/src/components/StatusIcon/StatusIcon.jsx b/awx/ui_next/src/components/StatusIcon/StatusIcon.jsx index c468d2f2ddf8..c386a270e9af 100644 --- a/awx/ui_next/src/components/StatusIcon/StatusIcon.jsx +++ b/awx/ui_next/src/components/StatusIcon/StatusIcon.jsx @@ -93,7 +93,7 @@ SkippedBottom.displayName = 'SkippedBottom'; const StatusIcon = ({ status, ...props }) => { return ( -
{i18n._(t`Click to view job details`)}
)} > diff --git a/awx/ui_next/src/components/Workflow/WorkflowNodeHelp.test.jsx b/awx/ui_next/src/components/Workflow/WorkflowNodeHelp.test.jsx index 183119f5e3c1..9ac9afbacd6b 100644 --- a/awx/ui_next/src/components/Workflow/WorkflowNodeHelp.test.jsx +++ b/awx/ui_next/src/components/Workflow/WorkflowNodeHelp.test.jsx @@ -9,11 +9,15 @@ describe('WorkflowNodeHelp', () => { }); test('renders the expected content for a completed job template job', () => { const node = { - job: { - name: 'Foo Job Template', - elapsed: 9000, - status: 'successful', - type: 'job', + originalNodeObject: { + summary_fields: { + job: { + name: 'Foo Job Template', + elapsed: 9000, + status: 'successful', + type: 'job', + }, + }, }, unifiedJobTemplate: { name: 'Foo Job Template', diff --git a/awx/ui_next/src/components/Workflow/workflowReducer.js b/awx/ui_next/src/components/Workflow/workflowReducer.js index 1fe635c47e0c..36171811e48b 100644 --- a/awx/ui_next/src/components/Workflow/workflowReducer.js +++ b/awx/ui_next/src/components/Workflow/workflowReducer.js @@ -64,6 +64,8 @@ export default function visualizerReducer(state, action) { return { ...state, linkToDelete: action.value }; case 'SET_LINK_TO_EDIT': return { ...state, linkToEdit: action.value }; + case 'SET_NODES': + return { ...state, nodes: action.value }; case 'SET_NODE_POSITIONS': return { ...state, nodePositions: action.value }; case 'SET_NODE_TO_DELETE': @@ -363,9 +365,6 @@ function generateNodes(workflowNodes, i18n) { originalNodeObject: node, }; - if (node.summary_fields.job) { - nodeObj.job = node.summary_fields.job; - } if (node.summary_fields.unified_job_template) { nodeObj.unifiedJobTemplate = node.summary_fields.unified_job_template; } diff --git a/awx/ui_next/src/screens/Inventory/InventoryList/useWsInventories.js b/awx/ui_next/src/screens/Inventory/InventoryList/useWsInventories.js index eea15f9a2c28..60fae9e90e4b 100644 --- a/awx/ui_next/src/screens/Inventory/InventoryList/useWsInventories.js +++ b/awx/ui_next/src/screens/Inventory/InventoryList/useWsInventories.js @@ -2,7 +2,7 @@ import { useState, useEffect } from 'react'; import useWebsocket from '../../../util/useWebsocket'; import useThrottle from '../../../util/useThrottle'; -export default function useWsProjects( +export default function useWsInventories( initialInventories, fetchInventoriesById ) { diff --git a/awx/ui_next/src/screens/Inventory/InventorySources/useWsInventorySources.js b/awx/ui_next/src/screens/Inventory/InventorySources/useWsInventorySources.js index 49a9b4f38742..5ea9a5222f23 100644 --- a/awx/ui_next/src/screens/Inventory/InventorySources/useWsInventorySources.js +++ b/awx/ui_next/src/screens/Inventory/InventorySources/useWsInventorySources.js @@ -1,7 +1,7 @@ import { useState, useEffect } from 'react'; import useWebsocket from '../../../util/useWebsocket'; -export default function useWsJobs(initialSources) { +export default function useWsInventorySources(initialSources) { const [sources, setSources] = useState(initialSources); const lastMessage = useWebsocket({ jobs: ['status_changed'], diff --git a/awx/ui_next/src/screens/Job/Job.jsx b/awx/ui_next/src/screens/Job/Job.jsx index 9530c4eeb374..e5692ad261b9 100644 --- a/awx/ui_next/src/screens/Job/Job.jsx +++ b/awx/ui_next/src/screens/Job/Job.jsx @@ -1,5 +1,13 @@ -import React, { Component } from 'react'; -import { Route, withRouter, Switch, Redirect, Link } from 'react-router-dom'; +import React, { useEffect, useCallback } from 'react'; +import { + Route, + withRouter, + Switch, + Redirect, + Link, + useParams, + useRouteMatch, +} from 'react-router-dom'; import { withI18n } from '@lingui/react'; import { t } from '@lingui/macro'; import { CaretLeftIcon } from '@patternfly/react-icons'; @@ -7,157 +15,116 @@ import { Card, PageSection } from '@patternfly/react-core'; import { JobsAPI } from '../../api'; import ContentError from '../../components/ContentError'; import RoutedTabs from '../../components/RoutedTabs'; +import useRequest from '../../util/useRequest'; import JobDetail from './JobDetail'; import JobOutput from './JobOutput'; import { WorkflowOutput } from './WorkflowOutput'; +import useWsJob from './useWsJob'; import { JOB_TYPE_URL_SEGMENTS } from '../../constants'; -class Job extends Component { - constructor(props) { - super(props); +function Job({ i18n, lookup, setBreadcrumb }) { + const { id, type } = useParams(); + const match = useRouteMatch(); - this.state = { - job: null, - contentError: null, - hasContentLoading: true, - isInitialized: false, - }; - - this.loadJob = this.loadJob.bind(this); - } - - async componentDidMount() { - await this.loadJob(); - this.setState({ isInitialized: true }); - } - - async componentDidUpdate(prevProps) { - const { location } = this.props; - if (location !== prevProps.location) { - await this.loadJob(); - } - } - - async loadJob() { - const { match, setBreadcrumb } = this.props; - const id = parseInt(match.params.id, 10); - - this.setState({ contentError: null, hasContentLoading: true }); - try { - const { data } = await JobsAPI.readDetail(id, match.params.type); + const { isLoading, error, request: fetchJob, result } = useRequest( + useCallback(async () => { + const { data } = await JobsAPI.readDetail(id, type); setBreadcrumb(data); - this.setState({ job: data }); - } catch (err) { - this.setState({ contentError: err }); - } finally { - this.setState({ hasContentLoading: false }); - } - } - - render() { - const { 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: ( - <> -{node.job.name}
+ {job.status &&{job.name || node.unifiedJobTemplate.name}