From 4372e977f070edac164c5d66b1a095b18402fe32 Mon Sep 17 00:00:00 2001 From: Keith Grant Date: Tue, 25 Jun 2019 15:31:14 -0700 Subject: [PATCH 01/12] build basic job details --- awx/ui_next/src/api/models/Jobs.js | 5 + .../src/components/DetailList/Detail.jsx | 2 +- awx/ui_next/src/screens/Job/Job.jsx | 26 ++- .../src/screens/Job/JobDetail/JobDetail.jsx | 150 +++++++++++++++--- .../src/screens/Job/JobList/JobListItem.jsx | 2 +- awx/ui_next/src/screens/Job/Jobs.jsx | 2 +- 6 files changed, 158 insertions(+), 29 deletions(-) diff --git a/awx/ui_next/src/api/models/Jobs.js b/awx/ui_next/src/api/models/Jobs.js index 295ee815e8..1c3375691c 100644 --- a/awx/ui_next/src/api/models/Jobs.js +++ b/awx/ui_next/src/api/models/Jobs.js @@ -5,6 +5,11 @@ class Jobs extends Base { super(http); this.baseUrl = '/api/v2/jobs/'; } + + readDetail (id, type) { + // TODO: adjust url based on type + return this.http.get(`${this.baseUrl}${id}/`); + } } export default Jobs; diff --git a/awx/ui_next/src/components/DetailList/Detail.jsx b/awx/ui_next/src/components/DetailList/Detail.jsx index ea65fdc288..761fd6aa94 100644 --- a/awx/ui_next/src/components/DetailList/Detail.jsx +++ b/awx/ui_next/src/components/DetailList/Detail.jsx @@ -26,7 +26,7 @@ const DetailValue = styled(({ fullWidth, ...props }) => ( `; const Detail = ({ label, value, fullWidth }) => { - if (!value) return null; + if (!value && typeof value !== 'number') { return null; } return ( diff --git a/awx/ui_next/src/screens/Job/Job.jsx b/awx/ui_next/src/screens/Job/Job.jsx index 67b33f6fc5..b936edb0fa 100644 --- a/awx/ui_next/src/screens/Job/Job.jsx +++ b/awx/ui_next/src/screens/Job/Job.jsx @@ -49,7 +49,7 @@ class Job extends Component { this.setState({ contentError: null, hasContentLoading: true }); try { - const { data } = await JobsAPI.readDetail(id); + const { data } = await JobsAPI.readDetail(id, match.params.type); setBreadcrumb(data); this.setState({ job: data }); } catch (err) { @@ -106,17 +106,31 @@ class Job extends Component { {cardHeader} - + {job && ( } + path="/jobs/:type/:id/details" + render={() => ( + + )} /> )} {job && ( } + path="/jobs/:type/:id/output" + render={() => ( + + )} /> )} diff --git a/awx/ui_next/src/screens/Job/JobDetail/JobDetail.jsx b/awx/ui_next/src/screens/Job/JobDetail/JobDetail.jsx index a4b1ea8651..93f5a825e6 100644 --- a/awx/ui_next/src/screens/Job/JobDetail/JobDetail.jsx +++ b/awx/ui_next/src/screens/Job/JobDetail/JobDetail.jsx @@ -1,35 +1,145 @@ -import React, { Component } from 'react'; +import React, { Component, useState, useEffect } from 'react'; import { Link, withRouter } from 'react-router-dom'; import { withI18n } from '@lingui/react'; import { t } from '@lingui/macro'; import { CardBody, Button } from '@patternfly/react-core'; 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` display: flex; justify-content: flex-end; `; -class JobDetail extends Component { - render() { - const { job, i18n } = this.props; - return ( - - {job.name} +const VERBOSITY = { + 0: '0 (Normal)', + 1: '1 (Verbose)', + 2: '2 (More Verbose)', + 3: '3 (Debug)', + 4: '4 (Connection Debug)', +}; - - - - - ); - } +function JobDetail ({ job, i18n }) { + const [instanceGroups, setInstanceGroups] = useState(null); + console.log(job); + const { + job_template: jobTemplate, + project, + inventory, + instance_group: instanceGroup, + } = job.summary_fields; + + return ( + + + {/* TODO: add status icon? */} + + + + + {jobTemplate.name} + + )} + /> + + + {inventory.name} + + )} + /> + {/* TODO: show project status icon */} + + {project.name} + + )} + /> + + + + + + + + {instanceGroup.name} + + )} + /> + + {(instanceGroups && instanceGroups.length > 0) && ( + + {instanceGroups.map(ig => ( + {ig.name} + ))} + + )} + /> + )} + + + + + + ); } export default withI18n()(withRouter(JobDetail)); diff --git a/awx/ui_next/src/screens/Job/JobList/JobListItem.jsx b/awx/ui_next/src/screens/Job/JobList/JobListItem.jsx index 4d2fe70f53..805d4e1506 100644 --- a/awx/ui_next/src/screens/Job/JobList/JobListItem.jsx +++ b/awx/ui_next/src/screens/Job/JobList/JobListItem.jsx @@ -32,7 +32,7 @@ class JobListItem extends Component { - + {job.name} diff --git a/awx/ui_next/src/screens/Job/Jobs.jsx b/awx/ui_next/src/screens/Job/Jobs.jsx index fc4311b2bb..a71bfeef71 100644 --- a/awx/ui_next/src/screens/Job/Jobs.jsx +++ b/awx/ui_next/src/screens/Job/Jobs.jsx @@ -58,7 +58,7 @@ class Jobs extends Component { )} /> ( Date: Wed, 26 Jun 2019 15:27:39 -0700 Subject: [PATCH 02/12] add variables & artifacts to job detail --- .../src/components/CodeMirrorInput/index.js | 1 + .../src/screens/Job/JobDetail/JobDetail.jsx | 46 +++++++-- .../CodeMirrorInput/VariablesInput.jsx | 99 +++++++++++++++++++ 3 files changed, 137 insertions(+), 9 deletions(-) create mode 100644 src/components/CodeMirrorInput/VariablesInput.jsx diff --git a/awx/ui_next/src/components/CodeMirrorInput/index.js b/awx/ui_next/src/components/CodeMirrorInput/index.js index 932883224b..48940bbb37 100644 --- a/awx/ui_next/src/components/CodeMirrorInput/index.js +++ b/awx/ui_next/src/components/CodeMirrorInput/index.js @@ -1,4 +1,5 @@ import CodeMirrorInput from './CodeMirrorInput'; export default CodeMirrorInput; +export { default as VariablesInput } from './VariablesInput'; export { default as VariablesField } from './VariablesField'; diff --git a/awx/ui_next/src/screens/Job/JobDetail/JobDetail.jsx b/awx/ui_next/src/screens/Job/JobDetail/JobDetail.jsx index 93f5a825e6..57e03638ed 100644 --- a/awx/ui_next/src/screens/Job/JobDetail/JobDetail.jsx +++ b/awx/ui_next/src/screens/Job/JobDetail/JobDetail.jsx @@ -1,4 +1,4 @@ -import React, { Component, useState, useEffect } from 'react'; +import React from 'react'; import { Link, withRouter } from 'react-router-dom'; import { withI18n } from '@lingui/react'; import { t } from '@lingui/macro'; @@ -6,8 +6,7 @@ import { CardBody, Button } from '@patternfly/react-core'; 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 { VariablesInput } from '@components/CodeMirrorInput'; import { toTitleCase } from '@util/strings'; const ActionButtonWrapper = styled.div` @@ -24,13 +23,13 @@ const VERBOSITY = { }; function JobDetail ({ job, i18n }) { - const [instanceGroups, setInstanceGroups] = useState(null); - console.log(job); const { job_template: jobTemplate, project, inventory, instance_group: instanceGroup, + credentials, + labels, } = job.summary_fields; return ( @@ -114,20 +113,49 @@ function JobDetail ({ job, i18n }) { label={i18n._(t`Job Slice`)} value={`${job.job_slice_number}/${job.job_slice_count}`} /> - {(instanceGroups && instanceGroups.length > 0) && ( + {(credentials && credentials.length > 0) && ( - {instanceGroups.map(ig => ( - {ig.name} + {credentials.map(c => ( + {c.name} + ))} + + )} + /> + )} + {(labels && labels.count > 0) && ( + + {labels.results.map(l => ( + {l.name} ))} )} /> )} + +