diff --git a/awx/ui/src/components/DetailList/Detail.js b/awx/ui/src/components/DetailList/Detail.js
index 6837e23ea1..8f56f4ad40 100644
--- a/awx/ui/src/components/DetailList/Detail.js
+++ b/awx/ui/src/components/DetailList/Detail.js
@@ -41,6 +41,7 @@ const Detail = ({
className,
dataCy,
alwaysVisible,
+ isEmpty,
helpText,
isEncrypted,
isNotConfigured,
@@ -49,6 +50,10 @@ const Detail = ({
return null;
}
+ if (isEmpty && !alwaysVisible) {
+ return null;
+ }
+
const labelCy = dataCy ? `${dataCy}-label` : null;
const valueCy = dataCy ? `${dataCy}-value` : null;
diff --git a/awx/ui/src/components/JobList/JobListItem.js b/awx/ui/src/components/JobList/JobListItem.js
index 364b4279c0..fdded4f857 100644
--- a/awx/ui/src/components/JobList/JobListItem.js
+++ b/awx/ui/src/components/JobList/JobListItem.js
@@ -163,16 +163,16 @@ function JobListItem({
- {job.type === 'inventory_update' &&
- inventorySourceLabels.length > 0 && (
-
- string === job.source ? label : null
- )}
- />
- )}
+ {job.type === 'inventory_update' && (
+
+ string === job.source ? label : null
+ )}
+ isEmpty={inventorySourceLabels?.length === 0}
+ />
+ )}
{job.launch_type === 'scheduled' &&
(schedule ? (
@@ -254,7 +254,7 @@ function JobListItem({
dataCy={`execution-environment-detail-${job.id}`}
/>
)}
- {credentials && credentials.length > 0 && (
+ {credentials && (
}
+ isEmpty={credentials.length === 0}
/>
)}
{labels && labels.count > 0 && (
diff --git a/awx/ui/src/components/JobList/JobListItem.test.js b/awx/ui/src/components/JobList/JobListItem.test.js
index 4b8348a846..e3d7930763 100644
--- a/awx/ui/src/components/JobList/JobListItem.test.js
+++ b/awx/ui/src/components/JobList/JobListItem.test.js
@@ -203,6 +203,49 @@ describe('', () => {
wrapper.find('Detail[label="Execution Environment"] dd').text()
).toBe('Missing resource');
});
+
+ test('should not load Source', () => {
+ wrapper = mountWithContexts(
+
+ );
+ const source_detail = wrapper.find(`Detail[label="Source"]`).at(0);
+ expect(source_detail.prop('isEmpty')).toEqual(true);
+ });
+
+ test('should not load Credentials', () => {
+ wrapper = mountWithContexts(
+
+ );
+ const credentials_detail = wrapper
+ .find(`Detail[label="Credentials"]`)
+ .at(0);
+ expect(credentials_detail.prop('isEmpty')).toEqual(true);
+ });
});
describe('', () => {
diff --git a/awx/ui/src/components/PromptDetail/PromptInventorySourceDetail.js b/awx/ui/src/components/PromptDetail/PromptInventorySourceDetail.js
index 7c3443895e..750270efe0 100644
--- a/awx/ui/src/components/PromptDetail/PromptInventorySourceDetail.js
+++ b/awx/ui/src/components/PromptDetail/PromptInventorySourceDetail.js
@@ -113,15 +113,14 @@ function PromptInventorySourceDetail({ resource }) {
label={t`Cache Timeout`}
value={`${update_cache_timeout} ${t`Seconds`}`}
/>
- {summary_fields?.credentials?.length > 0 && (
- (
-
- ))}
- />
- )}
+ (
+
+ ))}
+ isEmpty={summary_fields?.credentials?.length === 0}
+ />
{source_regions && (
{
);
assertDetail(wrapper, 'Organization', 'Deleted');
});
+
+ test('should not load Credentials', () => {
+ wrapper = mountWithContexts(
+
+ );
+ const credentials_detail = wrapper.find(`Detail[label="Credential"]`).at(0);
+ expect(credentials_detail.prop('isEmpty')).toEqual(true);
+ });
});
diff --git a/awx/ui/src/components/PromptDetail/PromptJobTemplateDetail.js b/awx/ui/src/components/PromptDetail/PromptJobTemplateDetail.js
index 1803426876..6e690337e1 100644
--- a/awx/ui/src/components/PromptDetail/PromptJobTemplateDetail.js
+++ b/awx/ui/src/components/PromptDetail/PromptJobTemplateDetail.js
@@ -26,7 +26,7 @@ function PromptJobTemplateDetail({ resource }) {
extra_vars,
forks,
host_config_key,
- instance_groups,
+ instance_groups = [],
job_slice_count,
job_tags,
job_type,
@@ -94,9 +94,11 @@ function PromptJobTemplateDetail({ resource }) {
return (
<>
- {summary_fields.recent_jobs?.length > 0 && (
- } label={t`Activity`} />
- )}
+ }
+ isEmpty={summary_fields.recent_jobs?.length === 0}
+ />
{summary_fields?.organization ? (
)}
{optionsList && }
- {summary_fields?.credentials?.length > 0 && (
+ {summary_fields?.credentials && (
}
+ isEmpty={summary_fields?.credentials?.length === 0}
/>
)}
- {summary_fields?.labels?.results?.length > 0 && (
+ {summary_fields?.labels?.results && (
}
+ isEmpty={summary_fields?.labels?.results?.length === 0}
/>
)}
- {instance_groups?.length > 0 && (
-
- {instance_groups.map((ig) => (
-
- {ig.name}
-
- ))}
-
- }
- />
- )}
- {job_tags?.length > 0 && (
+
+ {instance_groups?.map((ig) => (
+
+ {ig.name}
+
+ ))}
+
+ }
+ isEmpty={instance_groups?.length === 0}
+ />
+ {job_tags && (
}
+ isEmpty={job_tags?.length === 0}
/>
)}
- {skip_tags?.length > 0 && (
+ {skip_tags && (
}
+ isEmpty={skip_tags?.length === 0}
/>
)}
{extra_vars && (
diff --git a/awx/ui/src/components/PromptDetail/PromptJobTemplateDetail.test.js b/awx/ui/src/components/PromptDetail/PromptJobTemplateDetail.test.js
index 8ebd1e004d..b0a782c1ec 100644
--- a/awx/ui/src/components/PromptDetail/PromptJobTemplateDetail.test.js
+++ b/awx/ui/src/components/PromptDetail/PromptJobTemplateDetail.test.js
@@ -125,4 +125,92 @@ describe('PromptJobTemplateDetail', () => {
assertDetail(wrapper, 'Organization', 'Deleted');
assertDetail(wrapper, 'Project', 'Deleted');
});
+
+ test('should not load Activity', () => {
+ wrapper = mountWithContexts(
+
+ );
+ const activity_detail = wrapper.find(`Detail[label="Activity"]`).at(0);
+ expect(activity_detail.prop('isEmpty')).toEqual(true);
+ });
+
+ test('should not load Credentials', () => {
+ wrapper = mountWithContexts(
+
+ );
+ const credentials_detail = wrapper
+ .find(`Detail[label="Credentials"]`)
+ .at(0);
+ expect(credentials_detail.prop('isEmpty')).toEqual(true);
+ });
+
+ test('should not load Labels', () => {
+ wrapper = mountWithContexts(
+
+ );
+ const labels_detail = wrapper.find(`Detail[label="Labels"]`).at(0);
+ expect(labels_detail.prop('isEmpty')).toEqual(true);
+ });
+
+ test('should not load Instance Groups', () => {
+ wrapper = mountWithContexts(
+
+ );
+ const instance_groups_detail = wrapper
+ .find(`Detail[label="Instance Groups"]`)
+ .at(0);
+ expect(instance_groups_detail.prop('isEmpty')).toEqual(true);
+ });
+
+ test('should not load Job Tags', () => {
+ wrapper = mountWithContexts(
+
+ );
+ expect(wrapper.find('Detail[label="Job Tags"]').length).toBe(0);
+ });
+
+ test('should not load Skip Tags', () => {
+ wrapper = mountWithContexts(
+
+ );
+ expect(wrapper.find('Detail[label="Skip Tags"]').length).toBe(0);
+ });
});
diff --git a/awx/ui/src/components/PromptDetail/PromptWFJobTemplateDetail.js b/awx/ui/src/components/PromptDetail/PromptWFJobTemplateDetail.js
index 70fe71d854..8b26fa1486 100644
--- a/awx/ui/src/components/PromptDetail/PromptWFJobTemplateDetail.js
+++ b/awx/ui/src/components/PromptDetail/PromptWFJobTemplateDetail.js
@@ -57,9 +57,11 @@ function PromptWFJobTemplateDetail({ resource }) {
return (
<>
- {summary_fields?.recent_jobs?.length > 0 && (
- } label={t`Activity`} />
- )}
+ }
+ isEmpty={summary_fields?.recent_jobs?.length === 0}
+ />
{summary_fields?.organization && (
)}
- {summary_fields?.labels?.results?.length > 0 && (
+ {summary_fields?.labels?.results && (
}
+ isEmpty={summary_fields?.labels?.results?.length === 0}
/>
)}
{extra_vars && (
diff --git a/awx/ui/src/components/PromptDetail/PromptWFJobTemplateDetail.test.js b/awx/ui/src/components/PromptDetail/PromptWFJobTemplateDetail.test.js
index 42550869cd..56eee8d368 100644
--- a/awx/ui/src/components/PromptDetail/PromptWFJobTemplateDetail.test.js
+++ b/awx/ui/src/components/PromptDetail/PromptWFJobTemplateDetail.test.js
@@ -62,4 +62,36 @@ describe('PromptWFJobTemplateDetail', () => {
'---\nmock: data'
);
});
+
+ test('should not load Activity', () => {
+ wrapper = mountWithContexts(
+
+ );
+ const activity_detail = wrapper.find(`Detail[label="Activity"]`).at(0);
+ expect(activity_detail.prop('isEmpty')).toEqual(true);
+ });
+
+ test('should not load Labels', () => {
+ wrapper = mountWithContexts(
+
+ );
+ const labels_detail = wrapper.find(`Detail[label="Labels"]`).at(0);
+ expect(labels_detail.prop('isEmpty')).toEqual(true);
+ });
});
diff --git a/awx/ui/src/components/ResourceAccessList/ResourceAccessListItem.js b/awx/ui/src/components/ResourceAccessList/ResourceAccessListItem.js
index ccf692dd4c..916fbc17c4 100644
--- a/awx/ui/src/components/ResourceAccessList/ResourceAccessListItem.js
+++ b/awx/ui/src/components/ResourceAccessList/ResourceAccessListItem.js
@@ -68,34 +68,32 @@ function ResourceAccessListItem({ accessRecord, onRoleDelete }) {
| {accessRecord.last_name} |
- {userRoles.length > 0 && (
-
- {userRoles.map(renderChip)}
-
- }
- />
- )}
- {teamRoles.length > 0 && (
-
- {teamRoles.map(renderChip)}
-
- }
- />
- )}
+
+ {userRoles.map(renderChip)}
+
+ }
+ isEmpty={userRoles.length === 0}
+ />
+
+ {teamRoles.map(renderChip)}
+
+ }
+ isEmpty={teamRoles.length === 0}
+ />
|
diff --git a/awx/ui/src/components/ResourceAccessList/ResourceAccessListItem.test.js b/awx/ui/src/components/ResourceAccessList/ResourceAccessListItem.test.js
index 2c168f0aa5..a3a6efe035 100644
--- a/awx/ui/src/components/ResourceAccessList/ResourceAccessListItem.test.js
+++ b/awx/ui/src/components/ResourceAccessList/ResourceAccessListItem.test.js
@@ -53,5 +53,41 @@ describe('', () => {
expect(wrapper.find('Td[dataLabel="First name"]').text()).toBe('jane');
expect(wrapper.find('Td[dataLabel="Last name"]').text()).toBe('brown');
+
+ const user_roles_detail = wrapper.find(`Detail[label="User Roles"]`).at(0);
+ expect(user_roles_detail.prop('isEmpty')).toEqual(true);
+ });
+
+ test('should not load team roles', async () => {
+ let wrapper;
+
+ await act(async () => {
+ wrapper = mountWithContexts(
+
+ );
+ });
+ const team_roles_detail = wrapper.find(`Detail[label="Team Roles"]`).at(0);
+ expect(team_roles_detail.prop('isEmpty')).toEqual(true);
});
});
diff --git a/awx/ui/src/components/TemplateList/TemplateListItem.js b/awx/ui/src/components/TemplateList/TemplateListItem.js
index 27dad710bb..349f455379 100644
--- a/awx/ui/src/components/TemplateList/TemplateListItem.js
+++ b/awx/ui/src/components/TemplateList/TemplateListItem.js
@@ -272,11 +272,12 @@ function TemplateListItem({
value={template.description}
dataCy={`template-${template.id}-description`}
/>
- {summaryFields.recent_jobs && summaryFields.recent_jobs.length ? (
+ {summaryFields.recent_jobs ? (
}
dataCy={`template-${template.id}-activity`}
+ isEmpty={summaryFields.recent_jobs.length === 0}
/>
) : null}
{summaryFields.inventory ? (
@@ -316,7 +317,7 @@ function TemplateListItem({
value={formatDateString(template.modified)}
dataCy={`template-${template.id}-last-modified`}
/>
- {summaryFields.credentials && summaryFields.credentials.length ? (
+ {summaryFields.credentials ? (
}
dataCy={`template-${template.id}-credentials`}
+ isEmpty={summaryFields.credentials.length === 0}
/>
) : null}
- {summaryFields.labels && summaryFields.labels.results.length > 0 && (
+ {summaryFields.labels && (
}
dataCy={`template-${template.id}-labels`}
+ isEmpty={summaryFields.labels.results.length === 0}
/>
)}
diff --git a/awx/ui/src/components/TemplateList/TemplateListItem.test.js b/awx/ui/src/components/TemplateList/TemplateListItem.test.js
index 9edbff49de..612f3868ff 100644
--- a/awx/ui/src/components/TemplateList/TemplateListItem.test.js
+++ b/awx/ui/src/components/TemplateList/TemplateListItem.test.js
@@ -465,4 +465,68 @@ describe('', () => {
).toEqual(true);
expect(wrapper.find(`Detail[label="Activity"] Sparkline`)).toHaveLength(1);
});
+
+ test('should not load Activity', async () => {
+ const wrapper = mountWithContexts(
+
+ );
+ const activity_detail = wrapper.find(`Detail[label="Activity"]`).at(0);
+ expect(activity_detail.prop('isEmpty')).toEqual(true);
+ });
+
+ test('should not load Credentials', async () => {
+ const wrapper = mountWithContexts(
+
+ );
+ const credentials_detail = wrapper
+ .find(`Detail[label="Credentials"]`)
+ .at(0);
+ expect(credentials_detail.prop('isEmpty')).toEqual(true);
+ });
+
+ test('should not load Labels', async () => {
+ const wrapper = mountWithContexts(
+
+ );
+ const labels_detail = wrapper.find(`Detail[label="Labels"]`).at(0);
+ expect(labels_detail.prop('isEmpty')).toEqual(true);
+ });
});
diff --git a/awx/ui/src/screens/Credential/CredentialDetail/CredentialDetail.js b/awx/ui/src/screens/Credential/CredentialDetail/CredentialDetail.js
index 25c83ad143..a5ec427ad8 100644
--- a/awx/ui/src/screens/Credential/CredentialDetail/CredentialDetail.js
+++ b/awx/ui/src/screens/Credential/CredentialDetail/CredentialDetail.js
@@ -264,20 +264,19 @@ function CredentialDetail({ credential }) {
date={modified}
user={modified_by}
/>
- {enabledBooleanFields.length > 0 && (
-
- {enabledBooleanFields.map(({ id, label }) => (
-
- {label}
-
- ))}
-
- }
- />
- )}
+
+ {enabledBooleanFields.map(({ id, label }) => (
+
+ {label}
+
+ ))}
+
+ }
+ isEmpty={enabledBooleanFields.length === 0}
+ />
{Object.keys(inputSources).length > 0 && (
diff --git a/awx/ui/src/screens/Credential/CredentialDetail/CredentialDetail.test.js b/awx/ui/src/screens/Credential/CredentialDetail/CredentialDetail.test.js
index c900dece85..911e2e7056 100644
--- a/awx/ui/src/screens/Credential/CredentialDetail/CredentialDetail.test.js
+++ b/awx/ui/src/screens/Credential/CredentialDetail/CredentialDetail.test.js
@@ -149,4 +149,23 @@ describe('', () => {
wrapper.find('ModalBoxCloseButton').invoke('onClose')();
});
});
+
+ test('should not load enabled options', async () => {
+ await act(async () => {
+ wrapper = mountWithContexts(
+
+ );
+ });
+ const enabled_options_detail = wrapper
+ .find(`Detail[label="Enabled Options"]`)
+ .at(0);
+ expect(enabled_options_detail.prop('isEmpty')).toEqual(true);
+ });
});
diff --git a/awx/ui/src/screens/Host/HostDetail/HostDetail.js b/awx/ui/src/screens/Host/HostDetail/HostDetail.js
index 02556819ad..61bdbdd8ee 100644
--- a/awx/ui/src/screens/Host/HostDetail/HostDetail.js
+++ b/awx/ui/src/screens/Host/HostDetail/HostDetail.js
@@ -67,9 +67,11 @@ function HostDetail({ host }) {
- {recentJobs?.length > 0 && (
- } />
- )}
+ }
+ isEmpty={recentJobs?.length === 0}
+ />
', () => {
expect(wrapper.find(`Detail[label="Activity"] Sparkline`)).toHaveLength(
0
);
+ const activity_detail = wrapper.find(`Detail[label="Activity"]`).at(0);
+ expect(activity_detail.prop('isEmpty')).toEqual(true);
});
test('should hide edit button for users without edit permission', async () => {
diff --git a/awx/ui/src/screens/Inventory/InventoryDetail/InventoryDetail.js b/awx/ui/src/screens/Inventory/InventoryDetail/InventoryDetail.js
index 42cda6e630..d69b9a6419 100644
--- a/awx/ui/src/screens/Inventory/InventoryDetail/InventoryDetail.js
+++ b/awx/ui/src/screens/Inventory/InventoryDetail/InventoryDetail.js
@@ -79,17 +79,17 @@ function InventoryDetail({ inventory }) {
}
/>
- {instanceGroups && instanceGroups.length > 0 && (
+ {instanceGroups && (
- {instanceGroups.map((ig) => (
+ {instanceGroups?.map((ig) => (
}
+ isEmpty={instanceGroups.length === 0}
+ />
+ )}
+ {inventory.summary_fields.labels && (
+
+ {inventory.summary_fields.labels?.results?.map((l) => (
+
+ {l.name}
+
+ ))}
+
+ }
+ isEmpty={inventory.summary_fields.labels?.results?.length === 0}
/>
)}
- {inventory.summary_fields.labels &&
- inventory.summary_fields.labels?.results?.length > 0 && (
-
- {inventory.summary_fields.labels.results.map((l) => (
-
- {l.name}
-
- ))}
-
- }
- />
- )}
', () => {
expect(InventoriesAPI.readInstanceGroups).toHaveBeenCalledWith(
mockInventory.id
);
- expect(wrapper.find(`Detail[label="Instance Groups"]`)).toHaveLength(0);
+ const instance_groups_detail = wrapper
+ .find(`Detail[label="Instance Groups"]`)
+ .at(0);
+ expect(instance_groups_detail.prop('isEmpty')).toEqual(true);
});
});
diff --git a/awx/ui/src/screens/Inventory/InventoryHostDetail/InventoryHostDetail.js b/awx/ui/src/screens/Inventory/InventoryHostDetail/InventoryHostDetail.js
index 777cb42be9..d7bfa590a2 100644
--- a/awx/ui/src/screens/Inventory/InventoryHostDetail/InventoryHostDetail.js
+++ b/awx/ui/src/screens/Inventory/InventoryHostDetail/InventoryHostDetail.js
@@ -72,12 +72,11 @@ function InventoryHostDetail({ host }) {
- {recentPlaybookJobs?.length > 0 && (
- }
- />
- )}
+ }
+ isEmpty={recentPlaybookJobs?.length === 0}
+ />
', () => {
expect(wrapper.find(`Detail[label="Activity"] Sparkline`)).toHaveLength(
0
);
+ const activity_detail = wrapper.find(`Detail[label="Activity"]`).at(0);
+ expect(activity_detail.prop('isEmpty')).toEqual(true);
});
test('should hide edit button for users without edit permission', async () => {
diff --git a/awx/ui/src/screens/Inventory/InventorySourceDetail/InventorySourceDetail.js b/awx/ui/src/screens/Inventory/InventorySourceDetail/InventorySourceDetail.js
index db5a8008f3..4106b891fd 100644
--- a/awx/ui/src/screens/Inventory/InventorySourceDetail/InventorySourceDetail.js
+++ b/awx/ui/src/screens/Inventory/InventorySourceDetail/InventorySourceDetail.js
@@ -268,15 +268,14 @@ function InventorySourceDetail({ inventorySource }) {
helpText={helpText.enabledValue}
value={enabled_value}
/>
- {credentials?.length > 0 && (
- (
-
- ))}
- />
- )}
+ (
+
+ ))}
+ isEmpty={credentials?.length === 0}
+ />
{optionsList && (
)}
diff --git a/awx/ui/src/screens/Inventory/InventorySourceDetail/InventorySourceDetail.test.js b/awx/ui/src/screens/Inventory/InventorySourceDetail/InventorySourceDetail.test.js
index 1bf4518861..b3ed34a5a2 100644
--- a/awx/ui/src/screens/Inventory/InventorySourceDetail/InventorySourceDetail.test.js
+++ b/awx/ui/src/screens/Inventory/InventorySourceDetail/InventorySourceDetail.test.js
@@ -237,4 +237,21 @@ describe('InventorySourceDetail', () => {
(el) => el.length === 0
);
});
+
+ test('should not load Credentials', async () => {
+ await act(async () => {
+ wrapper = mountWithContexts(
+
+ );
+ });
+ const credentials_detail = wrapper.find(`Detail[label="Credential"]`).at(0);
+ expect(credentials_detail.prop('isEmpty')).toEqual(true);
+ });
});
diff --git a/awx/ui/src/screens/Inventory/SmartInventoryDetail/SmartInventoryDetail.js b/awx/ui/src/screens/Inventory/SmartInventoryDetail/SmartInventoryDetail.js
index 6518f97411..e91e22b116 100644
--- a/awx/ui/src/screens/Inventory/SmartInventoryDetail/SmartInventoryDetail.js
+++ b/awx/ui/src/screens/Inventory/SmartInventoryDetail/SmartInventoryDetail.js
@@ -96,12 +96,11 @@ function SmartInventoryDetail({ inventory }) {
- {recentJobs.length > 0 && (
- }
- />
- )}
+ }
+ isEmpty={recentJobs.length === 0}
+ />
{host_filter}}
/>
- {instanceGroups.length > 0 && (
-
- {instanceGroups.map((ig) => (
-
- {ig.name}
-
- ))}
-
- }
- />
- )}
+
+ {instanceGroups.map((ig) => (
+
+ {ig.name}
+
+ ))}
+
+ }
+ isEmpty={instanceGroups.length === 0}
+ />
', () => {
(el) => el.length === 0
);
});
+
+ test('should not load Activity', async () => {
+ await act(async () => {
+ wrapper = mountWithContexts(
+
+ );
+ });
+ const activity_detail = wrapper.find(`Detail[label="Activity"]`).at(0);
+ expect(activity_detail.prop('isEmpty')).toEqual(true);
+ });
+
+ test('should not load Instance Groups', async () => {
+ InventoriesAPI.readInstanceGroups.mockResolvedValue({
+ data: {
+ results: [],
+ },
+ });
+
+ let wrapper;
+ await act(async () => {
+ wrapper = mountWithContexts(
+
+ );
+ });
+ wrapper.update();
+ const instance_groups_detail = wrapper
+ .find(`Detail[label="Instance groups"]`)
+ .at(0);
+ expect(instance_groups_detail.prop('isEmpty')).toEqual(true);
+ });
});
describe('User has read-only permissions', () => {
diff --git a/awx/ui/src/screens/Inventory/SmartInventoryHostDetail/SmartInventoryHostDetail.js b/awx/ui/src/screens/Inventory/SmartInventoryHostDetail/SmartInventoryHostDetail.js
index e792f29c46..27af396135 100644
--- a/awx/ui/src/screens/Inventory/SmartInventoryHostDetail/SmartInventoryHostDetail.js
+++ b/awx/ui/src/screens/Inventory/SmartInventoryHostDetail/SmartInventoryHostDetail.js
@@ -28,12 +28,11 @@ function SmartInventoryHostDetail({ host }) {
- {recentPlaybookJobs?.length > 0 && (
- }
- />
- )}
+ }
+ isEmpty={recentPlaybookJobs?.length === 0}
+ />
', () => {
expect(wrapper.find('Detail[label="Activity"] Sparkline')).toHaveLength(1);
expect(wrapper.find('VariablesDetail')).toHaveLength(1);
});
+
+ test('should not load Activity', () => {
+ wrapper = mountWithContexts(
+
+ );
+ const activity_detail = wrapper.find(`Detail[label="Activity"]`).at(0);
+ expect(activity_detail.prop('isEmpty')).toEqual(true);
+ });
});
diff --git a/awx/ui/src/screens/Job/JobDetail/JobDetail.js b/awx/ui/src/screens/Job/JobDetail/JobDetail.js
index 262cec8d95..0202a7bcd3 100644
--- a/awx/ui/src/screens/Job/JobDetail/JobDetail.js
+++ b/awx/ui/src/screens/Job/JobDetail/JobDetail.js
@@ -268,15 +268,14 @@ function JobDetail({ job, inventorySourceLabels }) {
}
/>
- {inventorySourceLabels.length > 0 && (
-
- string === job.source ? label : null
- )}
- />
- )}
+
+ string === job.source ? label : null
+ )}
+ isEmpty={inventorySourceLabels.length === 0}
+ />
>
)}
{inventory_source && inventory_source.source === 'scm' && (
@@ -406,7 +405,7 @@ function JobDetail({ job, inventorySourceLabels }) {
}
/>
)}
- {credentials && credentials.length > 0 && (
+ {credentials && (
}
+ isEmpty={credentials.length === 0}
/>
)}
{labels && labels.count > 0 && (
@@ -451,7 +451,7 @@ function JobDetail({ job, inventorySourceLabels }) {
}
/>
)}
- {job.job_tags && job.job_tags.length > 0 && (
+ {job.job_tags && (
}
+ isEmpty={job.job_tags.length === 0}
/>
)}
- {job.skip_tags && job.skip_tags.length > 0 && (
+ {job.skip_tags && (
}
+ isEmpty={job.skip_tags.length === 0}
/>
)}
', () => {
assertDetail('Inventory', 'Demo Inventory');
assertDetail('Job Slice Parent', 'True');
});
+
+ test('should not load Source', () => {
+ wrapper = mountWithContexts(
+
+ );
+ const source_detail = wrapper.find(`Detail[label="Source"]`).at(0);
+ expect(source_detail.prop('isEmpty')).toEqual(true);
+ });
+
+ test('should not load Credentials', () => {
+ wrapper = mountWithContexts(
+
+ );
+ const credentials_detail = wrapper
+ .find(`Detail[label="Credentials"]`)
+ .at(0);
+ expect(credentials_detail.prop('isEmpty')).toEqual(true);
+ });
+
+ test('should not load Job Tags', () => {
+ wrapper = mountWithContexts(
+
+ );
+ expect(wrapper.find('Detail[label="Job Tags"]').length).toBe(0);
+ });
+
+ test('should not load Skip Tags', () => {
+ wrapper = mountWithContexts(
+
+ );
+ expect(wrapper.find('Detail[label="Skip Tags"]').length).toBe(0);
+ });
});
diff --git a/awx/ui/src/screens/Organization/OrganizationDetail/OrganizationDetail.js b/awx/ui/src/screens/Organization/OrganizationDetail/OrganizationDetail.js
index 4dfbc4247e..99d4955f3d 100644
--- a/awx/ui/src/screens/Organization/OrganizationDetail/OrganizationDetail.js
+++ b/awx/ui/src/screens/Organization/OrganizationDetail/OrganizationDetail.js
@@ -30,7 +30,7 @@ function OrganizationDetail({ organization }) {
created,
modified,
summary_fields,
- galaxy_credentials,
+ galaxy_credentials = [],
} = organization;
const [contentError, setContentError] = useState(null);
const [hasContentLoading, setHasContentLoading] = useState(true);
@@ -121,7 +121,7 @@ function OrganizationDetail({ organization }) {
date={modified}
user={summary_fields.modified_by}
/>
- {instanceGroups && instanceGroups.length > 0 && (
+ {instanceGroups && (
}
+ isEmpty={instanceGroups.length === 0}
/>
)}
- {galaxy_credentials && galaxy_credentials.length > 0 && (
-
- {galaxy_credentials.map((credential) => (
-
+ {galaxy_credentials?.map((credential) => (
+
+
-
-
- ))}
-
- }
- />
- )}
+ isReadOnly
+ ouiaId={`galaxy-credential-${credential.id}-chip`}
+ />
+
+ ))}
+
+ }
+ isEmpty={galaxy_credentials?.length === 0}
+ />
{summary_fields.user_capabilities.edit && (
diff --git a/awx/ui/src/screens/Organization/OrganizationDetail/OrganizationDetail.test.js b/awx/ui/src/screens/Organization/OrganizationDetail/OrganizationDetail.test.js
index 3953cfeb5f..5141a198f8 100644
--- a/awx/ui/src/screens/Organization/OrganizationDetail/OrganizationDetail.test.js
+++ b/awx/ui/src/screens/Organization/OrganizationDetail/OrganizationDetail.test.js
@@ -216,4 +216,44 @@ describe('', () => {
(el) => el.length === 0
);
});
+
+ test('should not load instance groups', async () => {
+ OrganizationsAPI.readInstanceGroups.mockResolvedValue({
+ data: {
+ results: [],
+ },
+ });
+
+ let wrapper;
+ await act(async () => {
+ wrapper = mountWithContexts(
+
+ );
+ });
+ wrapper.update();
+ const instance_groups_detail = wrapper
+ .find(`Detail[label="Instance Groups"]`)
+ .at(0);
+ expect(instance_groups_detail.prop('isEmpty')).toEqual(true);
+ });
+
+ test('should not load galaxy credentials', async () => {
+ OrganizationsAPI.readInstanceGroups.mockResolvedValue({ data: {} });
+ let wrapper;
+ await act(async () => {
+ wrapper = mountWithContexts(
+
+ );
+ });
+ wrapper.update();
+ const galaxy_credentials_detail = wrapper
+ .find(`Detail[label="Galaxy Credentials"]`)
+ .at(0);
+ expect(galaxy_credentials_detail.prop('isEmpty')).toEqual(true);
+ });
});
diff --git a/awx/ui/src/screens/Template/JobTemplateDetail/JobTemplateDetail.js b/awx/ui/src/screens/Template/JobTemplateDetail/JobTemplateDetail.js
index 3a4869d0f3..c99348c33c 100644
--- a/awx/ui/src/screens/Template/JobTemplateDetail/JobTemplateDetail.js
+++ b/awx/ui/src/screens/Template/JobTemplateDetail/JobTemplateDetail.js
@@ -354,7 +354,7 @@ function JobTemplateDetail({ template }) {
helpText={helpText.enabledOptions}
/>
)}
- {summary_fields.credentials && summary_fields.credentials.length > 0 && (
+ {summary_fields.credentials && (
}
+ isEmpty={summary_fields.credentials.length === 0}
/>
)}
- {summary_fields.labels && summary_fields.labels.results.length > 0 && (
+ {summary_fields.labels && (
}
+ isEmpty={summary_fields.labels.results.length === 0}
/>
)}
- {instanceGroups.length > 0 && (
-
- {instanceGroups.map((ig) => (
-
-
- {ig.name}
-
-
- ))}
-
- }
- />
- )}
- {job_tags && job_tags.length > 0 && (
+
+ {instanceGroups.map((ig) => (
+
+
+ {ig.name}
+
+
+ ))}
+
+ }
+ isEmpty={instanceGroups.length === 0}
+ />
+ {job_tags && (
}
+ isEmpty={job_tags.length === 0}
/>
)}
- {skip_tags && skip_tags.length > 0 && (
+ {skip_tags && (
}
+ isEmpty={skip_tags.length === 0}
/>
)}
', () => {
wrapper.find(`Detail[label="Execution Environment"] dd`).text()
).toBe('Default EE');
});
+
+ test('should not load credentials', async () => {
+ await act(async () => {
+ wrapper = mountWithContexts(
+
+ );
+ });
+ const credentials_detail = wrapper
+ .find(`Detail[label="Credentials"]`)
+ .at(0);
+ expect(credentials_detail.prop('isEmpty')).toEqual(true);
+ });
+
+ test('should not load labels', async () => {
+ await act(async () => {
+ wrapper = mountWithContexts(
+
+ );
+ });
+ const labels_detail = wrapper.find(`Detail[label="Labels"]`).at(0);
+ expect(labels_detail.prop('isEmpty')).toEqual(true);
+ });
+
+ test('should not load instance groups', async () => {
+ JobTemplatesAPI.readInstanceGroups.mockResolvedValue({
+ data: {
+ results: [],
+ },
+ });
+
+ let wrapper;
+ await act(async () => {
+ wrapper = mountWithContexts(
+
+ );
+ });
+ wrapper.update();
+ const instance_groups_detail = wrapper
+ .find(`Detail[label="Instance Groups"]`)
+ .at(0);
+ expect(instance_groups_detail.prop('isEmpty')).toEqual(true);
+ });
+
+ test('should not load job tags', async () => {
+ await act(async () => {
+ wrapper = mountWithContexts(
+
+ );
+ });
+ expect(wrapper.find('Detail[label="Job Tags"]').length).toBe(0);
+ });
+
+ test('should not load skip tags', async () => {
+ await act(async () => {
+ wrapper = mountWithContexts(
+
+ );
+ });
+ expect(wrapper.find('Detail[label="Skip Tags"]').length).toBe(0);
+ });
});
diff --git a/awx/ui/src/screens/Template/WorkflowJobTemplateDetail/WorkflowJobTemplateDetail.js b/awx/ui/src/screens/Template/WorkflowJobTemplateDetail/WorkflowJobTemplateDetail.js
index 511f3cae4d..a3316b527c 100644
--- a/awx/ui/src/screens/Template/WorkflowJobTemplateDetail/WorkflowJobTemplateDetail.js
+++ b/awx/ui/src/screens/Template/WorkflowJobTemplateDetail/WorkflowJobTemplateDetail.js
@@ -110,12 +110,11 @@ function WorkflowJobTemplateDetail({ template }) {
- {summary_fields.recent_jobs?.length > 0 && (
- }
- label={t`Activity`}
- />
- )}
+ }
+ label={t`Activity`}
+ isEmpty={summary_fields.recent_jobs?.length === 0}
+ />
{summary_fields.organization && (
)}
- {summary_fields.labels?.results?.length > 0 && (
-
- {summary_fields.labels.results.map((l) => (
-
- {l.name}
-
- ))}
-
- }
- />
- )}
+
+ {summary_fields.labels.results.map((l) => (
+
+ {l.name}
+
+ ))}
+
+ }
+ isEmpty={!summary_fields.labels?.results?.length}
+ />
', () => {
expect(inventory.prop('to')).toEqual('/inventories/inventory/1/details');
expect(organization.prop('to')).toEqual('/organizations/1/details');
});
+
+ test('should not load Activity', async () => {
+ await act(async () => {
+ wrapper = mountWithContexts(
+ {}}
+ />
+ );
+ });
+ const activity_detail = wrapper.find(`Detail[label="Activity"]`).at(0);
+ expect(activity_detail.prop('isEmpty')).toEqual(true);
+ });
+
+ test('should not load Labels', async () => {
+ await act(async () => {
+ wrapper = mountWithContexts(
+ {}}
+ />
+ );
+ });
+ const labels_detail = wrapper.find(`Detail[label="Labels"]`).at(0);
+ expect(labels_detail.prop('isEmpty')).toEqual(true);
+ });
});
diff --git a/awx/ui/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/NodeModals/NodeTypeStep/JobTemplatesList.js b/awx/ui/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/NodeModals/NodeTypeStep/JobTemplatesList.js
index eccd397cd9..2d206a39f9 100644
--- a/awx/ui/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/NodeModals/NodeTypeStep/JobTemplatesList.js
+++ b/awx/ui/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/NodeModals/NodeTypeStep/JobTemplatesList.js
@@ -44,30 +44,28 @@ function TemplatePopoverContent({ template }) {
value={template?.playbook}
dataCy={`template-${template.id}-playbook`}
/>
- {template.summary_fields?.credentials &&
- template.summary_fields.credentials.length ? (
-
- {template.summary_fields.credentials.map((c) => (
-
- ))}
-
- }
- />
- ) : null}
+
+ {template.summary_fields?.credentials?.map((c) => (
+
+ ))}
+
+ }
+ isEmpty={template.summary_fields?.credentials?.length === 0}
+ />
);
}
diff --git a/awx/ui/src/screens/WorkflowApproval/WorkflowApprovalDetail/WorkflowApprovalDetail.js b/awx/ui/src/screens/WorkflowApproval/WorkflowApprovalDetail/WorkflowApprovalDetail.js
index ee8957c70a..e8eadad293 100644
--- a/awx/ui/src/screens/WorkflowApproval/WorkflowApprovalDetail/WorkflowApprovalDetail.js
+++ b/awx/ui/src/screens/WorkflowApproval/WorkflowApprovalDetail/WorkflowApprovalDetail.js
@@ -309,25 +309,24 @@ function WorkflowApprovalDetail({ workflowApproval }) {
dataCy="wa-detail-inventory"
/>
) : null}
- {workflowJob?.summary_fields?.labels?.results?.length > 0 && (
-
- {workflowJob.summary_fields.labels.results.map((label) => (
-
- {label.name}
-
- ))}
-
- }
- />
- )}
+
+ {workflowJob.summary_fields.labels.results.map((label) => (
+
+ {label.name}
+
+ ))}
+
+ }
+ isEmpty={!workflowJob?.summary_fields?.labels?.results?.length}
+ />
{workflowJob?.extra_vars ? (
', () => {
expect(wrapper.find('DeleteButton').length).toBe(1);
});
+ test('should not load Labels', async () => {
+ WorkflowJobTemplatesAPI.readDetail.mockResolvedValue({
+ data: workflowJobTemplate,
+ });
+ WorkflowJobsAPI.readDetail.mockResolvedValue({
+ data: {
+ ...workflowApproval,
+ summary_fields: {
+ ...workflowApproval.summary_fields,
+ labels: {
+ results: [],
+ },
+ },
+ },
+ });
+
+ let wrapper;
+ await act(async () => {
+ wrapper = mountWithContexts(
+
+ );
+ });
+ waitForElement(wrapper, 'WorkflowApprovalDetail', (el) => el.length > 0);
+ const labels_detail = wrapper.find(`Detail[label="Labels"]`).at(0);
+ expect(labels_detail.prop('isEmpty')).toEqual(true);
+ });
+
test('Error dialog shown for failed approval', async () => {
WorkflowApprovalsAPI.approve.mockImplementationOnce(() =>
Promise.reject(new Error())
|