diff --git a/awx/ui/src/api/models/Users.js b/awx/ui/src/api/models/Users.js
index c9d47826e2..22f8f24d32 100644
--- a/awx/ui/src/api/models/Users.js
+++ b/awx/ui/src/api/models/Users.js
@@ -29,6 +29,12 @@ class Users extends Base {
});
}
+ readOrganizationOptions(userId, params) {
+ return this.http.options(`${this.baseUrl}${userId}/organizations/`, {
+ params,
+ });
+ }
+
readRoles(userId, params) {
return this.http.get(`${this.baseUrl}${userId}/roles/`, {
params,
diff --git a/awx/ui/src/components/PaginatedTable/HeaderRow.js b/awx/ui/src/components/PaginatedTable/HeaderRow.js
index 213d6e6cae..0c60db070a 100644
--- a/awx/ui/src/components/PaginatedTable/HeaderRow.js
+++ b/awx/ui/src/components/PaginatedTable/HeaderRow.js
@@ -68,7 +68,6 @@ export function HeaderCell({
columnIndex,
idPrefix,
className,
- alignRight,
children,
}) {
const sort = sortKey
@@ -83,7 +82,7 @@ export function HeaderCell({
id={sortKey ? `${idPrefix}-${sortKey}` : null}
className={className}
sort={sort}
- css={alignRight ? 'text-align: right' : null}
+ css={children === 'Actions' ? 'text-align: right' : null}
>
{children}
diff --git a/awx/ui/src/screens/Credential/CredentialList/CredentialList.js b/awx/ui/src/screens/Credential/CredentialList/CredentialList.js
index 928a725cce..ab8fa76004 100644
--- a/awx/ui/src/screens/Credential/CredentialList/CredentialList.js
+++ b/awx/ui/src/screens/Credential/CredentialList/CredentialList.js
@@ -144,7 +144,7 @@ function CredentialList() {
{t`Name`}
{t`Type`}
- {t`Actions`}
+ {t`Actions`}
}
renderRow={(item, index) => (
diff --git a/awx/ui/src/screens/Host/HostList/HostList.js b/awx/ui/src/screens/Host/HostList/HostList.js
index 8e24d847d8..46083c6400 100644
--- a/awx/ui/src/screens/Host/HostList/HostList.js
+++ b/awx/ui/src/screens/Host/HostList/HostList.js
@@ -68,7 +68,7 @@ function HostList() {
actions: results[1].data.actions,
relatedSearchableKeys: (
results[1]?.data?.related_search_fields || []
- ).map((val) => val.slice(0, -8)),
+ ).map((val) => (val.endsWith('search') ? val.slice(0, -8) : val)),
searchableKeys: getSearchableKeys(results[1].data.actions?.GET),
};
}, [location]),
diff --git a/awx/ui/src/screens/Host/HostList/HostList.test.js b/awx/ui/src/screens/Host/HostList/HostList.test.js
index 7fdc65c0a9..b6f0d00571 100644
--- a/awx/ui/src/screens/Host/HostList/HostList.test.js
+++ b/awx/ui/src/screens/Host/HostList/HostList.test.js
@@ -95,6 +95,7 @@ describe('', () => {
GET: {},
POST: {},
},
+ related_search_fields: ['first_key__search', 'ansible_facts'],
},
});
});
@@ -121,6 +122,10 @@ describe('', () => {
});
await waitForLoaded(wrapper);
+ expect(
+ wrapper.find('PaginatedTable').props().toolbarRelatedSearchableKeys
+ ).toStrictEqual(['first_key', 'ansible_facts']);
+
expect(HostsAPI.read).toHaveBeenCalled();
expect(wrapper.find('HostListItem')).toHaveLength(3);
});
diff --git a/awx/ui/src/screens/Inventory/InventoryHosts/InventoryHostList.js b/awx/ui/src/screens/Inventory/InventoryHosts/InventoryHostList.js
index a04a196fd5..41d2a69c25 100644
--- a/awx/ui/src/screens/Inventory/InventoryHosts/InventoryHostList.js
+++ b/awx/ui/src/screens/Inventory/InventoryHosts/InventoryHostList.js
@@ -59,7 +59,7 @@ function InventoryHostList() {
actions: hostOptions.data.actions,
relatedSearchableKeys: (
hostOptions?.data?.related_search_fields || []
- ).map((val) => val.slice(0, -8)),
+ ).map((val) => (val.endsWith('search') ? val.slice(0, -8) : val)),
searchableKeys: getSearchableKeys(hostOptions.data.actions?.GET),
};
}, [id, search]),
diff --git a/awx/ui/src/screens/Inventory/InventoryHosts/InventoryHostList.test.js b/awx/ui/src/screens/Inventory/InventoryHosts/InventoryHostList.test.js
index 937b99e0d3..e5851bd5c3 100644
--- a/awx/ui/src/screens/Inventory/InventoryHosts/InventoryHostList.test.js
+++ b/awx/ui/src/screens/Inventory/InventoryHosts/InventoryHostList.test.js
@@ -91,6 +91,7 @@ describe('', () => {
GET: {},
POST: {},
},
+ related_search_fields: ['first_key__search', 'ansible_facts'],
},
});
@@ -123,6 +124,9 @@ describe('', () => {
test('should fetch hosts from api and render them in the list', async () => {
expect(InventoriesAPI.readHosts).toHaveBeenCalled();
expect(wrapper.find('InventoryHostItem').length).toBe(3);
+ expect(
+ wrapper.find('PaginatedTable').props().toolbarRelatedSearchableKeys
+ ).toStrictEqual(['first_key', 'ansible_facts']);
});
test('should render Run Commands button', async () => {
diff --git a/awx/ui/src/screens/Inventory/InventorySources/InventorySourceList.js b/awx/ui/src/screens/Inventory/InventorySources/InventorySourceList.js
index 8ae59c8b24..52f24c678b 100644
--- a/awx/ui/src/screens/Inventory/InventorySources/InventorySourceList.js
+++ b/awx/ui/src/screens/Inventory/InventorySources/InventorySourceList.js
@@ -36,7 +36,14 @@ function InventorySourceList() {
const {
isLoading,
error: fetchError,
- result: { result, sourceCount, sourceChoices, sourceChoicesOptions },
+ result: {
+ result,
+ sourceCount,
+ sourceChoices,
+ sourceChoicesOptions,
+ searchableKeys,
+ relatedSearchableKeys,
+ },
request: fetchSources,
} = useRequest(
useCallback(async () => {
@@ -50,12 +57,20 @@ function InventorySourceList() {
sourceCount: results[0].data.count,
sourceChoices: results[1].data.actions.GET.source.choices,
sourceChoicesOptions: results[1].data.actions,
+ searchableKeys: Object.keys(results[1].data.actions?.GET || {}).filter(
+ (key) => results[1].data.actions?.GET[key].filterable
+ ),
+ relatedSearchableKeys: (
+ results[1]?.data?.related_search_fields || []
+ ).map((val) => val.slice(0, -8)),
};
}, [id, search]),
{
result: [],
sourceCount: 0,
sourceChoices: [],
+ searchableKeys: [],
+ relatedSearchableKeys: [],
}
);
@@ -149,6 +164,8 @@ function InventorySourceList() {
<>
{
const actions = options?.data?.actions?.GET || {};
const searchableKeys = getSearchableKeys(actions);
- const relatedSearchableKeys = options?.data?.related_search_fields || [];
+
+ const relatedSearchableKeys = (
+ options?.data?.related_search_fields || []
+ ).map((val) => val.slice(0, -8));
return { searchableKeys, relatedSearchableKeys };
};
diff --git a/awx/ui/src/screens/User/UserOrganizations/UserOrganizationList.js b/awx/ui/src/screens/User/UserOrganizations/UserOrganizationList.js
index ca79f24026..a4b19840ce 100644
--- a/awx/ui/src/screens/User/UserOrganizations/UserOrganizationList.js
+++ b/awx/ui/src/screens/User/UserOrganizations/UserOrganizationList.js
@@ -23,17 +23,29 @@ function UserOrganizationList() {
const { id: userId } = useParams();
const {
- result: { organizations, count },
+ result: { organizations, count, searchableKeys, relatedSearchableKeys },
error: contentError,
isLoading,
request: fetchOrgs,
} = useRequest(
useCallback(async () => {
const params = parseQueryString(QS_CONFIG, location.search);
- const {
- data: { results, count: orgCount },
- } = await UsersAPI.readOrganizations(userId, params);
+ const [
+ {
+ data: { results, count: orgCount },
+ },
+ actions,
+ ] = await Promise.all([
+ UsersAPI.readOrganizations(userId, params),
+ UsersAPI.readOrganizationOptions(),
+ ]);
return {
+ searchableKeys: Object.keys(actions.data.actions?.GET || {}).filter(
+ (key) => actions.data.actions?.GET[key].filterable
+ ),
+ relatedSearchableKeys: (actions?.data?.related_search_fields || []).map(
+ (val) => val.slice(0, -8)
+ ),
organizations: results,
count: orgCount,
};
@@ -41,6 +53,8 @@ function UserOrganizationList() {
{
organizations: [],
count: 0,
+ searchableKeys: [],
+ relatedSearchableKeys: [],
}
);
@@ -52,6 +66,8 @@ function UserOrganizationList() {
', () => {
count: 1,
},
});
+ UsersAPI.readOrganizationOptions.mockResolvedValue({
+ data: { actions: { GET: {} } },
+ });
await act(async () => {
wrapper = mountWithContexts(
', () => {
page_size: 20,
type: 'organization',
});
+ expect(UsersAPI.readOrganizationOptions).toBeCalled();
});
});