From 4b8a06801c1594b7fe8e94d54c077d7a09a4fc2d Mon Sep 17 00:00:00 2001 From: Marliana Lara Date: Tue, 24 Sep 2019 15:14:17 -0400 Subject: [PATCH] Add missing job detail fields and status icons --- .../src/components/DetailList/DetailList.jsx | 2 +- .../src/screens/Job/JobDetail/JobDetail.jsx | 88 ++++++++++++++++--- 2 files changed, 78 insertions(+), 12 deletions(-) diff --git a/awx/ui_next/src/components/DetailList/DetailList.jsx b/awx/ui_next/src/components/DetailList/DetailList.jsx index 11d55474b3..f47cfa89bb 100644 --- a/awx/ui_next/src/components/DetailList/DetailList.jsx +++ b/awx/ui_next/src/components/DetailList/DetailList.jsx @@ -11,7 +11,7 @@ const DetailList = ({ children, stacked, ...props }) => ( export default styled(DetailList)` display: grid; grid-gap: 20px; - align-items: baseline; + align-items: flex-start; ${props => props.stacked ? ` diff --git a/awx/ui_next/src/screens/Job/JobDetail/JobDetail.jsx b/awx/ui_next/src/screens/Job/JobDetail/JobDetail.jsx index 2705f1803c..5c217b8bc8 100644 --- a/awx/ui_next/src/screens/Job/JobDetail/JobDetail.jsx +++ b/awx/ui_next/src/screens/Job/JobDetail/JobDetail.jsx @@ -10,6 +10,7 @@ import { DetailList, Detail } from '@components/DetailList'; import { ChipGroup, Chip, CredentialChip } from '@components/Chip'; import { VariablesInput as _VariablesInput } from '@components/CodeMirrorInput'; import ErrorDetail from '@components/ErrorDetail'; +import { StatusIcon } from '@components/Sparkline'; import { toTitleCase } from '@util/strings'; import { Job } from '../../../types'; import { @@ -37,6 +38,14 @@ const VariablesInput = styled(_VariablesInput)` } `; +const StatusDetailValue = styled.div` + align-items: center; + display: inline-flex; + > div { + margin-right: 10px; + } +`; + const VERBOSITY = { 0: '0 (Normal)', 1: '1 (Verbose)', @@ -45,18 +54,50 @@ const VERBOSITY = { 4: '4 (Connection Debug)', }; +const getLaunchedByDetails = ({ summary_fields = {}, related = {} }) => { + const { + created_by: createdBy, + job_template: jobTemplate, + schedule, + } = summary_fields; + const { schedule: relatedSchedule } = related; + + if (!createdBy && !schedule) { + return null; + } + + let link; + let value; + + if (createdBy) { + link = `/users/${createdBy.id}`; + value = createdBy.username; + } else if (relatedSchedule && jobTemplate) { + link = `/templates/job_template/${jobTemplate.id}/schedules/${schedule.id}`; + value = schedule.name; + } else { + link = null; + value = schedule.name; + } + + return { link, value }; +}; + function JobDetail({ job, i18n, history }) { const { - job_template: jobTemplate, - project, - inventory, - instance_group: instanceGroup, credentials, + instance_group: instanceGroup, + inventory, + job_template: jobTemplate, labels, + project, } = job.summary_fields; const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false); const [errorMsg, setErrorMsg] = useState(); + const { value: launchedByValue, link: launchedByLink } = + getLaunchedByDetails(job) || {}; + const deleteJob = async () => { try { switch (job.type) { @@ -84,11 +125,20 @@ function JobDetail({ job, i18n, history }) { setIsDeleteModalOpen(false); } }; + return ( - {/* TODO: add status icon? */} - + {/* TODO: hookup status to websockets */} + + {job.status && } + {toTitleCase(job.status)} + + } + /> {jobTemplate && ( @@ -102,6 +152,18 @@ function JobDetail({ job, i18n, history }) { /> )} + + {launchedByLink ? ( + {launchedByValue} + ) : ( + launchedByValue + )} + + } + /> {inventory && ( )} - {/* TODO: show project status icon */} {project && ( {project.name}} + value={ + + {project.status && } + {project.name} + + } /> )} - + - - + + {instanceGroup && (