From 7cc3ac1a115e27a8f1891668bdabad05046f5131 Mon Sep 17 00:00:00 2001 From: nixocio Date: Tue, 6 Jul 2021 16:57:17 -0400 Subject: [PATCH] Identify sliced jobs on Job List and Job Details Identify sliced jobs on Job List and Job details - for workflow jobs. closes: https://github.com/ansible/awx/issues/2479 closes: https://github.com/ansible/awx/issues/10593 --- .../src/components/JobList/JobListItem.jsx | 16 +++ .../components/JobList/JobListItem.test.jsx | 8 ++ .../src/screens/Job/JobDetail/JobDetail.jsx | 4 + .../screens/Job/JobDetail/JobDetail.test.jsx | 112 ++++++++++++++++++ 4 files changed, 140 insertions(+) diff --git a/awx/ui_next/src/components/JobList/JobListItem.jsx b/awx/ui_next/src/components/JobList/JobListItem.jsx index 85d2ade5bd..f816ba1543 100644 --- a/awx/ui_next/src/components/JobList/JobListItem.jsx +++ b/awx/ui_next/src/components/JobList/JobListItem.jsx @@ -50,6 +50,12 @@ function JobListItem({ workflow_job_template, } = job.summary_fields; + const { + job_slice_number: jobSliceNumber, + job_slice_count: jobSliceCount, + is_sliced_job: isSlicedJob, + } = job; + return ( <> @@ -244,6 +250,16 @@ function JobListItem({ value={job.job_explanation} /> )} + {typeof jobSliceNumber === 'number' && + typeof jobSliceCount === 'number' && ( + + )} + {job.type === 'workflow_job' && isSlicedJob && ( + + )} diff --git a/awx/ui_next/src/components/JobList/JobListItem.test.jsx b/awx/ui_next/src/components/JobList/JobListItem.test.jsx index 70f89fdb63..42dfd404fe 100644 --- a/awx/ui_next/src/components/JobList/JobListItem.test.jsx +++ b/awx/ui_next/src/components/JobList/JobListItem.test.jsx @@ -22,6 +22,8 @@ const mockJob = { started: '2019-08-08T19:24:18.329589Z', finished: '2019-08-08T19:24:50.119995Z', status: 'successful', + job_slice_number: 1, + job_slice_count: 3, }; describe('', () => { @@ -41,8 +43,14 @@ describe('', () => { ); }); + function assertDetail(label, value) { + expect(wrapper.find(`Detail[label="${label}"] dt`).text()).toBe(label); + expect(wrapper.find(`Detail[label="${label}"] dd`).text()).toBe(value); + } + test('initially renders successfully', () => { expect(wrapper.find('JobListItem').length).toBe(1); + assertDetail('Job Slice', '1/3'); }); test('launch button shown to users with launch capabilities', () => { diff --git a/awx/ui_next/src/screens/Job/JobDetail/JobDetail.jsx b/awx/ui_next/src/screens/Job/JobDetail/JobDetail.jsx index 6bb79b52f7..e7fab462ab 100644 --- a/awx/ui_next/src/screens/Job/JobDetail/JobDetail.jsx +++ b/awx/ui_next/src/screens/Job/JobDetail/JobDetail.jsx @@ -258,6 +258,10 @@ function JobDetail({ job }) { value={`${job.job_slice_number}/${job.job_slice_count}`} /> )} + {job.type === 'workflow_job' && job.is_sliced_job && ( + + )} + {credential && ( ', () => { mockJobData.summary_fields.execution_environment.name ); + assertDetail('Job Slice', '0/1'); + const credentialChip = wrapper.find( `Detail[label="Credentials"] CredentialChip` ); @@ -355,4 +357,114 @@ describe('', () => { wrapper.find('Button[aria-label="Cancel Demo Job Template"]') ).toHaveLength(1); }); + + test('should render workflow job details', () => { + const workFlowJob = { + id: 15, + type: 'workflow_job', + url: '/api/v2/workflow_jobs/15/', + related: { + created_by: '/api/v2/users/1/', + modified_by: '/api/v2/users/1/', + unified_job_template: '/api/v2/job_templates/9/', + job_template: '/api/v2/job_templates/9/', + workflow_nodes: '/api/v2/workflow_jobs/15/workflow_nodes/', + labels: '/api/v2/workflow_jobs/15/labels/', + activity_stream: '/api/v2/workflow_jobs/15/activity_stream/', + relaunch: '/api/v2/workflow_jobs/15/relaunch/', + cancel: '/api/v2/workflow_jobs/15/cancel/', + }, + summary_fields: { + organization: { + id: 1, + name: 'Default', + description: '', + }, + inventory: { + id: 1, + name: 'Demo Inventory', + description: '', + has_active_failures: false, + total_hosts: 4, + hosts_with_active_failures: 0, + total_groups: 0, + has_inventory_sources: false, + total_inventory_sources: 0, + inventory_sources_with_failures: 0, + organization_id: 1, + kind: '', + }, + job_template: { + id: 9, + name: 'Sliced Job Template', + description: '', + }, + unified_job_template: { + id: 9, + name: 'Sliced Job Template', + description: '', + unified_job_type: 'job', + }, + created_by: { + id: 1, + username: 'admin', + first_name: '', + last_name: '', + }, + modified_by: { + id: 1, + username: 'admin', + first_name: '', + last_name: '', + }, + user_capabilities: { + delete: true, + start: true, + }, + labels: { + count: 0, + results: [], + }, + }, + created: '2021-07-06T19:40:17.654030Z', + modified: '2021-07-06T19:40:17.964699Z', + name: 'Sliced Job Template', + description: '', + unified_job_template: 9, + launch_type: 'manual', + status: 'successful', + failed: false, + started: '2021-07-06T19:40:17.962019Z', + finished: '2021-07-06T19:40:42.238563Z', + canceled_on: null, + elapsed: 24.277, + job_explanation: '', + launched_by: { + id: 1, + name: 'admin', + type: 'user', + url: '/api/v2/users/1/', + }, + work_unit_id: null, + workflow_job_template: null, + extra_vars: '{}', + allow_simultaneous: false, + job_template: 9, + is_sliced_job: true, + inventory: 1, + limit: '', + scm_branch: '', + webhook_service: '', + webhook_credential: null, + webhook_guid: '', + }; + wrapper = mountWithContexts(); + assertDetail('Status', ' successful Successful'); + assertDetail('Started', '7/6/2021, 7:40:17 PM'); + assertDetail('Finished', '7/6/2021, 7:40:42 PM'); + assertDetail('Job Template', 'Sliced Job Template'); + assertDetail('Job Type', 'Workflow Job'); + assertDetail('Inventory', 'Demo Inventory'); + assertDetail('Job Slice Parent', 'True'); + }); });