From b2328d17a438d0f454bfb0323143dcc7f84424be Mon Sep 17 00:00:00 2001 From: Jake McDermott Date: Tue, 1 Dec 2020 12:34:28 -0500 Subject: [PATCH 1/3] Render result tracebacks as stdout --- .../src/screens/Job/JobOutput/JobOutput.jsx | 29 ++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/awx/ui_next/src/screens/Job/JobOutput/JobOutput.jsx b/awx/ui_next/src/screens/Job/JobOutput/JobOutput.jsx index 88e32be49f..ed3a988ab1 100644 --- a/awx/ui_next/src/screens/Job/JobOutput/JobOutput.jsx +++ b/awx/ui_next/src/screens/Job/JobOutput/JobOutput.jsx @@ -225,7 +225,7 @@ class JobOutput extends Component { this.state = { contentError: null, deletionError: null, - hasContentLoading: true, + hasContentLoading: !props?.job?.result_traceback, results: {}, currentlyLoading: [], remoteRowCount: 0, @@ -241,6 +241,7 @@ class JobOutput extends Component { this._isMounted = false; this.loadJobEvents = this.loadJobEvents.bind(this); + this.loadTracebackEvents = this.loadTracebackEvents.bind(this); this.handleDeleteJob = this.handleDeleteJob.bind(this); this.rowRenderer = this.rowRenderer.bind(this); this.handleHostEventClick = this.handleHostEventClick.bind(this); @@ -261,6 +262,8 @@ class JobOutput extends Component { this._isMounted = true; this.loadJobEvents(); + if (job.result_traceback) return; + connectJobSocket(job, data => { if (data.counter && data.counter > this.jobSocketCounter) { this.jobSocketCounter = data.counter; @@ -308,8 +311,32 @@ class JobOutput extends Component { } } + loadTracebackEvents() { + // When a job has traceback results, render it as a job event + // with the traceback as the stdout text + const { job } = this.props; + const remoteRowCount = 1; + const results = [ + { + counter: -1, + created: null, + event: null, + type: null, + stdout: job?.result_traceback || '', + start_line: 0, + }, + ]; + this._isMounted && this.setState({ results, remoteRowCount }); + } + async loadJobEvents() { const { job, type } = this.props; + if (job.result_traceback) { + // Jobs with tracebacks don't have actual job events to show, + // so just render the traceback as stdout + this.loadTracebackEvents(); + return; + } const loadRange = range(1, 50); this._isMounted && From 7a6cbe2685a9fe4ee043646064583a8382c8c40f Mon Sep 17 00:00:00 2001 From: Jake McDermott Date: Tue, 1 Dec 2020 12:57:25 -0500 Subject: [PATCH 2/3] Display status explanation message when available --- awx/ui_next/src/screens/Job/JobDetail/JobDetail.jsx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/awx/ui_next/src/screens/Job/JobDetail/JobDetail.jsx b/awx/ui_next/src/screens/Job/JobDetail/JobDetail.jsx index 9e79d4de1b..9ee8e2a94e 100644 --- a/awx/ui_next/src/screens/Job/JobDetail/JobDetail.jsx +++ b/awx/ui_next/src/screens/Job/JobDetail/JobDetail.jsx @@ -133,13 +133,15 @@ function JobDetail({ job, i18n }) { return ( - {/* TODO: hookup status to websockets */} {job.status && } - {toTitleCase(job.status)} + {job.job_explanation + ? job.job_explanation + : toTitleCase(job.status)} } /> From e7719e3fdc5fbbaaf2a94957e1691cd77907d8c0 Mon Sep 17 00:00:00 2001 From: Jake McDermott Date: Sun, 31 Jan 2021 22:15:16 -0500 Subject: [PATCH 3/3] Splice result_traceback into first row stdout --- .../src/screens/Job/JobOutput/JobOutput.jsx | 51 +++++++++---------- 1 file changed, 24 insertions(+), 27 deletions(-) diff --git a/awx/ui_next/src/screens/Job/JobOutput/JobOutput.jsx b/awx/ui_next/src/screens/Job/JobOutput/JobOutput.jsx index ed3a988ab1..7d7519d3f6 100644 --- a/awx/ui_next/src/screens/Job/JobOutput/JobOutput.jsx +++ b/awx/ui_next/src/screens/Job/JobOutput/JobOutput.jsx @@ -225,7 +225,7 @@ class JobOutput extends Component { this.state = { contentError: null, deletionError: null, - hasContentLoading: !props?.job?.result_traceback, + hasContentLoading: true, results: {}, currentlyLoading: [], remoteRowCount: 0, @@ -241,7 +241,6 @@ class JobOutput extends Component { this._isMounted = false; this.loadJobEvents = this.loadJobEvents.bind(this); - this.loadTracebackEvents = this.loadTracebackEvents.bind(this); this.handleDeleteJob = this.handleDeleteJob.bind(this); this.rowRenderer = this.rowRenderer.bind(this); this.handleHostEventClick = this.handleHostEventClick.bind(this); @@ -311,32 +310,8 @@ class JobOutput extends Component { } } - loadTracebackEvents() { - // When a job has traceback results, render it as a job event - // with the traceback as the stdout text - const { job } = this.props; - const remoteRowCount = 1; - const results = [ - { - counter: -1, - created: null, - event: null, - type: null, - stdout: job?.result_traceback || '', - start_line: 0, - }, - ]; - this._isMounted && this.setState({ results, remoteRowCount }); - } - async loadJobEvents() { const { job, type } = this.props; - if (job.result_traceback) { - // Jobs with tracebacks don't have actual job events to show, - // so just render the traceback as stdout - this.loadTracebackEvents(); - return; - } const loadRange = range(1, 50); this._isMounted && @@ -353,10 +328,32 @@ class JobOutput extends Component { }); this._isMounted && this.setState(({ results }) => { + let countOffset = 1; + if (job?.result_traceback) { + const tracebackEvent = { + counter: -1, + created: null, + event: null, + type: null, + stdout: job?.result_traceback, + start_line: 0, + }; + const firstIndex = newResults.findIndex( + jobEvent => jobEvent.counter === 1 + ); + if (firstIndex) { + const stdoutLines = newResults[firstIndex].stdout.split('\r\n'); + stdoutLines[0] = tracebackEvent.stdout; + newResults[firstIndex].stdout = stdoutLines.join('\r\n'); + } else { + countOffset += 1; + newResults.unshift(tracebackEvent); + } + } newResults.forEach(jobEvent => { results[jobEvent.counter] = jobEvent; }); - return { results, remoteRowCount: count + 1 }; + return { results, remoteRowCount: count + countOffset }; }); } catch (err) { this.setState({ contentError: err });