update newly useRequested lists to get advanced searchableKeys

This commit is contained in:
John Mitchell 2020-08-13 15:30:00 -04:00 committed by John Mitchell
parent a659b9d994
commit aee2a81b27
26 changed files with 367 additions and 42 deletions

View File

@ -6,6 +6,7 @@ class Credentials extends Base {
this.baseUrl = '/api/v2/credentials/';
this.readAccessList = this.readAccessList.bind(this);
this.readAccessOptions = this.readAccessOptions.bind(this);
this.readInputSources = this.readInputSources.bind(this);
}
@ -15,6 +16,10 @@ class Credentials extends Base {
});
}
readAccessOptions(id) {
return this.http.options(`${this.baseUrl}${id}/access_list/`);
}
readInputSources(id, params) {
return this.http.get(`${this.baseUrl}${id}/input_sources/`, {
params,

View File

@ -7,6 +7,7 @@ class Inventories extends InstanceGroupsMixin(Base) {
this.baseUrl = '/api/v2/inventories/';
this.readAccessList = this.readAccessList.bind(this);
this.readAccessOptions = this.readAccessOptions.bind(this);
this.readHosts = this.readHosts.bind(this);
this.readHostDetail = this.readHostDetail.bind(this);
this.readGroups = this.readGroups.bind(this);
@ -20,6 +21,10 @@ class Inventories extends InstanceGroupsMixin(Base) {
});
}
readAccessOptions(id) {
return this.http.options(`${this.baseUrl}${id}/access_list/`);
}
createHost(id, data) {
return this.http.post(`${this.baseUrl}${id}/hosts/`, data);
}

View File

@ -16,6 +16,7 @@ class JobTemplates extends SchedulesMixin(
this.disassociateLabel = this.disassociateLabel.bind(this);
this.readCredentials = this.readCredentials.bind(this);
this.readAccessList = this.readAccessList.bind(this);
this.readAccessOptions = this.readAccessOptions.bind(this);
this.readWebhookKey = this.readWebhookKey.bind(this);
}
@ -66,6 +67,10 @@ class JobTemplates extends SchedulesMixin(
});
}
readAccessOptions(id) {
return this.http.options(`${this.baseUrl}${id}/access_list/`);
}
readScheduleList(id, params) {
return this.http.get(`${this.baseUrl}${id}/schedules/`, {
params,

View File

@ -12,10 +12,18 @@ class Organizations extends InstanceGroupsMixin(NotificationsMixin(Base)) {
return this.http.get(`${this.baseUrl}${id}/access_list/`, { params });
}
readAccessOptions(id) {
return this.http.options(`${this.baseUrl}${id}/access_list/`);
}
readTeams(id, params) {
return this.http.get(`${this.baseUrl}${id}/teams/`, { params });
}
readTeamsOptions(id) {
return this.http.options(`${this.baseUrl}${id}/teams/`);
}
createUser(id, data) {
return this.http.post(`${this.baseUrl}${id}/users/`, data);
}

View File

@ -11,6 +11,7 @@ class Projects extends SchedulesMixin(
this.baseUrl = '/api/v2/projects/';
this.readAccessList = this.readAccessList.bind(this);
this.readAccessOptions = this.readAccessOptions.bind(this);
this.readInventories = this.readInventories.bind(this);
this.readPlaybooks = this.readPlaybooks.bind(this);
this.readSync = this.readSync.bind(this);
@ -21,6 +22,10 @@ class Projects extends SchedulesMixin(
return this.http.get(`${this.baseUrl}${id}/access_list/`, { params });
}
readAccessOptions(id) {
return this.http.options(`${this.baseUrl}${id}/access_list/`);
}
readInventories(id) {
return this.http.get(`${this.baseUrl}${id}/inventories/`);
}

View File

@ -35,6 +35,10 @@ class Teams extends Base {
});
}
readAccessOptions(id) {
return this.http.options(`${this.baseUrl}${id}/access_list/`);
}
readUsersAccessOptions(teamId) {
return this.http.options(`${this.baseUrl}${teamId}/users/`);
}

View File

@ -54,6 +54,10 @@ class WorkflowJobTemplates extends SchedulesMixin(NotificationsMixin(Base)) {
});
}
readAccessOptions(id) {
return this.http.options(`${this.baseUrl}${id}/access_list/`);
}
readSurvey(id) {
return this.http.get(`${this.baseUrl}${id}/survey_spec/`);
}

View File

@ -29,21 +29,32 @@ function OrganizationLookup({
history,
}) {
const {
result: { itemCount, organizations },
result: { itemCount, organizations, relatedSearchableKeys, searchableKeys },
error: contentError,
request: fetchOrganizations,
} = useRequest(
useCallback(async () => {
const params = parseQueryString(QS_CONFIG, history.location.search);
const { data } = await OrganizationsAPI.read(params);
const [response, actionsResponse] = await Promise.all([
OrganizationsAPI.read(params),
OrganizationsAPI.readOptions(),
]);
return {
organizations: data.results,
itemCount: data.count,
organizations: response.data.results,
itemCount: response.data.count,
relatedSearchableKeys: (
actionsResponse?.data?.related_search_fields || []
).map(val => val.slice(0, -8)),
searchableKeys: Object.keys(
actionsResponse.data.actions?.GET || {}
).filter(key => actionsResponse.data.actions?.GET[key].filterable),
};
}, [history.location.search]),
{
organizations: [],
itemCount: 0,
relatedSearchableKeys: [],
searchableKeys: [],
}
);
@ -98,6 +109,8 @@ function OrganizationLookup({
key: 'name',
},
]}
searchableKeys={searchableKeys}
relatedSearchableKeys={relatedSearchableKeys}
readOnly={!canDelete}
selectItem={item => dispatch({ type: 'SELECT_ITEM', item })}
deselectItem={item => dispatch({ type: 'DESELECT_ITEM', item })}

View File

@ -23,7 +23,7 @@ function NotificationList({ apiModel, canToggleNotifications, id, i18n }) {
const [toggleError, setToggleError] = useState(null);
const {
result: fetchNotificationsResult,
result: fetchNotificationsResults,
result: {
notifications,
itemCount,
@ -31,6 +31,8 @@ function NotificationList({ apiModel, canToggleNotifications, id, i18n }) {
successTemplateIds,
errorTemplateIds,
typeLabels,
relatedSearchableKeys,
searchableKeys,
},
error: contentError,
isLoading,
@ -43,15 +45,13 @@ function NotificationList({ apiModel, canToggleNotifications, id, i18n }) {
{
data: { results: notificationsResults, count: notificationsCount },
},
{
data: { actions },
},
actionsResponse,
] = await Promise.all([
NotificationTemplatesAPI.read(params),
NotificationTemplatesAPI.readOptions(),
]);
const labels = actions.GET.notification_type.choices.reduce(
const labels = actionsResponse.data.actions.GET.notification_type.choices.reduce(
(map, notifType) => ({ ...map, [notifType[0]]: notifType[1] }),
{}
);
@ -78,6 +78,12 @@ function NotificationList({ apiModel, canToggleNotifications, id, i18n }) {
successTemplateIds: successTemplates.results.map(su => su.id),
errorTemplateIds: errorTemplates.results.map(e => e.id),
typeLabels: labels,
relatedSearchableKeys: (
actionsResponse?.data?.related_search_fields || []
).map(val => val.slice(0, -8)),
searchableKeys: Object.keys(
actionsResponse.data.actions?.GET || {}
).filter(key => actionsResponse.data.actions?.GET[key].filterable),
};
}, [apiModel, id, location]),
{
@ -87,6 +93,8 @@ function NotificationList({ apiModel, canToggleNotifications, id, i18n }) {
successTemplateIds: [],
errorTemplateIds: [],
typeLabels: {},
relatedSearchableKeys: [],
searchableKeys: [],
}
);
@ -108,8 +116,8 @@ function NotificationList({ apiModel, canToggleNotifications, id, i18n }) {
status
);
setValue({
...fetchNotificationsResult,
[`${status}TemplateIds`]: fetchNotificationsResult[
...fetchNotificationsResults,
[`${status}TemplateIds`]: fetchNotificationsResults[
`${status}TemplateIds`
].filter(i => i !== notificationId),
});
@ -120,8 +128,8 @@ function NotificationList({ apiModel, canToggleNotifications, id, i18n }) {
status
);
setValue({
...fetchNotificationsResult,
[`${status}TemplateIds`]: fetchNotificationsResult[
...fetchNotificationsResults,
[`${status}TemplateIds`]: fetchNotificationsResults[
`${status}TemplateIds`
].concat(notificationId),
});
@ -179,6 +187,8 @@ function NotificationList({ apiModel, canToggleNotifications, id, i18n }) {
key: 'name',
},
]}
toolbarSearchableKeys={searchableKeys}
toolbarRelatedSearchableKeys={relatedSearchableKeys}
renderItem={notification => (
<NotificationListItem
key={notification.id}

View File

@ -26,22 +26,33 @@ function ResourceAccessList({ i18n, apiModel, resource }) {
const location = useLocation();
const {
result: { accessRecords, itemCount },
result: { accessRecords, itemCount, relatedSearchableKeys, searchableKeys },
error: contentError,
isLoading,
request: fetchAccessRecords,
} = useRequest(
useCallback(async () => {
const params = parseQueryString(QS_CONFIG, location.search);
const response = await apiModel.readAccessList(resource.id, params);
const [response, actionsResponse] = await Promise.all([
apiModel.readAccessList(resource.id, params),
apiModel.readAccessOptions(resource.id),
]);
return {
accessRecords: response.data.results,
itemCount: response.data.count,
relatedSearchableKeys: (
actionsResponse?.data?.related_search_fields || []
).map(val => val.slice(0, -8)),
searchableKeys: Object.keys(
actionsResponse.data.actions?.GET || {}
).filter(key => actionsResponse.data.actions?.GET[key].filterable),
};
}, [apiModel, location, resource.id]),
{
accessRecords: [],
itemCount: 0,
relatedSearchableKeys: [],
searchableKeys: [],
}
);
@ -106,6 +117,8 @@ function ResourceAccessList({ i18n, apiModel, resource }) {
key: 'last_name',
},
]}
toolbarSearchableKeys={searchableKeys}
toolbarRelatedSearchableKeys={relatedSearchableKeys}
renderToolbar={props => (
<DataListToolbar
{...props}

View File

@ -76,6 +76,15 @@ describe('<ResourceAccessList />', () => {
beforeEach(async () => {
OrganizationsAPI.readAccessList.mockResolvedValue({ data });
OrganizationsAPI.readAccessOptions.mockResolvedValue({
data: {
actions: {
GET: {},
POST: {},
},
related_search_fields: [],
},
});
TeamsAPI.disassociateRole.mockResolvedValue({});
UsersAPI.disassociateRole.mockResolvedValue({});
await act(async () => {

View File

@ -47,7 +47,13 @@ function InventoryGroupsList({ i18n }) {
const { id: inventoryId } = useParams();
const {
result: { groups, groupCount, actions },
result: {
groups,
groupCount,
actions,
relatedSearchableKeys,
searchableKeys,
},
error: contentError,
isLoading,
request: fetchGroups,
@ -62,12 +68,20 @@ function InventoryGroupsList({ i18n }) {
groups: response.data.results,
groupCount: response.data.count,
actions: actionsResponse.data.actions,
relatedSearchableKeys: (
actionsResponse?.data?.related_search_fields || []
).map(val => val.slice(0, -8)),
searchableKeys: Object.keys(
actionsResponse.data.actions?.GET || {}
).filter(key => actionsResponse.data.actions?.GET[key].filterable),
};
}, [inventoryId, location]),
{
groups: [],
groupCount: 0,
actions: {},
relatedSearchableKeys: [],
searchableKeys: [],
}
);
@ -168,6 +182,8 @@ function InventoryGroupsList({ i18n }) {
key: 'name',
},
]}
toolbarSearchableKeys={searchableKeys}
toolbarRelatedSearchableKeys={relatedSearchableKeys}
renderItem={item => (
<InventoryGroupItem
key={item.id}

View File

@ -19,22 +19,33 @@ function OrganizationTeamList({ id, i18n }) {
const location = useLocation();
const {
result: { teams, count },
result: { teams, count, relatedSearchableKeys, searchableKeys },
error,
isLoading,
request: fetchTeams,
} = useRequest(
useCallback(async () => {
const params = parseQueryString(QS_CONFIG, location.search);
const results = await OrganizationsAPI.readTeams(id, params);
const [response, actionsResponse] = await Promise.all([
OrganizationsAPI.readTeams(id, params),
OrganizationsAPI.readTeamsOptions(id),
]);
return {
teams: results.data.results,
count: results.data.count,
teams: response.data.results,
count: response.data.count,
relatedSearchableKeys: (
actionsResponse?.data?.related_search_fields || []
).map(val => val.slice(0, -8)),
searchableKeys: Object.keys(
actionsResponse.data.actions?.GET || {}
).filter(key => actionsResponse.data.actions?.GET[key].filterable),
};
}, [id, location]),
{
teams: [],
count: 0,
relatedSearchableKeys: [],
searchableKeys: [],
}
);
@ -71,6 +82,8 @@ function OrganizationTeamList({ id, i18n }) {
key: 'name',
},
]}
toolbarSearchableKeys={searchableKeys}
toolbarRelatedSearchableKeys={relatedSearchableKeys}
renderItem={item => (
<OrganizationTeamListItem
key={item.id}

View File

@ -53,6 +53,15 @@ const listData = {
describe('<OrganizationTeamList />', () => {
beforeEach(() => {
OrganizationsAPI.readTeams.mockResolvedValue(listData);
OrganizationsAPI.readTeamsOptions.mockResolvedValue({
data: {
actions: {
GET: {},
POST: {},
},
related_search_fields: [],
},
});
});
afterEach(() => {

View File

@ -27,7 +27,13 @@ function ProjectJobTemplatesList({ i18n }) {
const location = useLocation();
const {
result: { jobTemplates, itemCount, actions },
result: {
jobTemplates,
itemCount,
actions,
relatedSearchableKeys,
searchableKeys,
},
error: contentError,
isLoading,
request: fetchTemplates,
@ -43,12 +49,20 @@ function ProjectJobTemplatesList({ i18n }) {
jobTemplates: response.data.results,
itemCount: response.data.count,
actions: actionsResponse.data.actions,
relatedSearchableKeys: (
actionsResponse?.data?.related_search_fields || []
).map(val => val.slice(0, -8)),
searchableKeys: Object.keys(
actionsResponse.data.actions?.GET || {}
).filter(key => actionsResponse.data.actions?.GET[key].filterable),
};
}, [location, projectId]),
{
jobTemplates: [],
itemCount: 0,
actions: {},
relatedSearchableKeys: [],
searchableKeys: [],
}
);
@ -142,6 +156,8 @@ function ProjectJobTemplatesList({ i18n }) {
key: 'type',
},
]}
toolbarSearchableKeys={searchableKeys}
toolbarRelatedSearchableKeys={relatedSearchableKeys}
renderToolbar={props => (
<DatalistToolbar
{...props}

View File

@ -40,6 +40,15 @@ describe('NodeModal', () => {
],
},
});
JobTemplatesAPI.readOptions.mockResolvedValue({
data: {
actions: {
GET: {},
POST: {},
},
related_search_fields: [],
},
});
ProjectsAPI.read.mockResolvedValue({
data: {
count: 1,
@ -53,6 +62,15 @@ describe('NodeModal', () => {
],
},
});
ProjectsAPI.readOptions.mockResolvedValue({
data: {
actions: {
GET: {},
POST: {},
},
related_search_fields: [],
},
});
InventorySourcesAPI.read.mockResolvedValue({
data: {
count: 1,
@ -66,6 +84,15 @@ describe('NodeModal', () => {
],
},
});
InventorySourcesAPI.readOptions.mockResolvedValue({
data: {
actions: {
GET: {},
POST: {},
},
related_search_fields: [],
},
});
WorkflowJobTemplatesAPI.read.mockResolvedValue({
data: {
count: 1,
@ -79,6 +106,15 @@ describe('NodeModal', () => {
],
},
});
WorkflowJobTemplatesAPI.readOptions.mockResolvedValue({
data: {
actions: {
GET: {},
POST: {},
},
related_search_fields: [],
},
});
});
afterAll(() => {
jest.clearAllMocks();

View File

@ -20,22 +20,33 @@ function InventorySourcesList({ i18n, nodeResource, onUpdateNodeResource }) {
const location = useLocation();
const {
result: { inventorySources, count },
result: { inventorySources, count, relatedSearchableKeys, searchableKeys },
error,
isLoading,
request: fetchInventorySources,
} = useRequest(
useCallback(async () => {
const params = parseQueryString(QS_CONFIG, location.search);
const results = await InventorySourcesAPI.read(params);
const [response, actionsResponse] = await Promise.all([
InventorySourcesAPI.read(params),
InventorySourcesAPI.readOptions(),
]);
return {
inventorySources: results.data.results,
count: results.data.count,
inventorySources: response.data.results,
count: response.data.count,
relatedSearchableKeys: (
actionsResponse?.data?.related_search_fields || []
).map(val => val.slice(0, -8)),
searchableKeys: Object.keys(
actionsResponse.data.actions?.GET || {}
).filter(key => actionsResponse.data.actions?.GET[key].filterable),
};
}, [location]),
{
inventorySources: [],
count: 0,
relatedSearchableKeys: [],
searchableKeys: [],
}
);
@ -94,6 +105,8 @@ function InventorySourcesList({ i18n, nodeResource, onUpdateNodeResource }) {
key: 'name',
},
]}
toolbarSearchableKeys={searchableKeys}
toolbarRelatedSearchableKeys={relatedSearchableKeys}
/>
);
}

View File

@ -38,6 +38,15 @@ describe('InventorySourcesList', () => {
],
},
});
InventorySourcesAPI.readOptions.mockResolvedValue({
data: {
actions: {
GET: {},
POST: {},
},
related_search_fields: [],
},
});
await act(async () => {
wrapper = mountWithContexts(
<InventorySourcesList

View File

@ -20,24 +20,35 @@ function JobTemplatesList({ i18n, nodeResource, onUpdateNodeResource }) {
const location = useLocation();
const {
result: { jobTemplates, count },
result: { jobTemplates, count, relatedSearchableKeys, searchableKeys },
error,
isLoading,
request: fetchJobTemplates,
} = useRequest(
useCallback(async () => {
const params = parseQueryString(QS_CONFIG, location.search);
const results = await JobTemplatesAPI.read(params, {
role_level: 'execute_role',
});
const [response, actionsResponse] = await Promise.all([
JobTemplatesAPI.read(params, {
role_level: 'execute_role',
}),
JobTemplatesAPI.readOptions(),
]);
return {
jobTemplates: results.data.results,
count: results.data.count,
jobTemplates: response.data.results,
count: response.data.count,
relatedSearchableKeys: (
actionsResponse?.data?.related_search_fields || []
).map(val => val.slice(0, -8)),
searchableKeys: Object.keys(
actionsResponse.data.actions?.GET || {}
).filter(key => actionsResponse.data.actions?.GET[key].filterable),
};
}, [location]),
{
jobTemplates: [],
count: 0,
relatedSearchableKeys: [],
searchableKeys: [],
}
);
@ -92,6 +103,8 @@ function JobTemplatesList({ i18n, nodeResource, onUpdateNodeResource }) {
key: 'name',
},
]}
toolbarSearchableKeys={searchableKeys}
toolbarRelatedSearchableKeys={relatedSearchableKeys}
/>
);
}

View File

@ -38,6 +38,15 @@ describe('JobTemplatesList', () => {
],
},
});
JobTemplatesAPI.readOptions.mockResolvedValue({
data: {
actions: {
GET: {},
POST: {},
},
related_search_fields: [],
},
});
await act(async () => {
wrapper = mountWithContexts(
<JobTemplatesList
@ -67,6 +76,15 @@ describe('JobTemplatesList', () => {
});
test('Error shown when read() request errors', async () => {
JobTemplatesAPI.read.mockRejectedValue(new Error());
JobTemplatesAPI.readOptions.mockResolvedValue({
data: {
actions: {
GET: {},
POST: {},
},
related_search_fields: [],
},
});
await act(async () => {
wrapper = mountWithContexts(
<JobTemplatesList

View File

@ -35,6 +35,15 @@ describe('NodeTypeStep', () => {
],
},
});
JobTemplatesAPI.readOptions.mockResolvedValue({
data: {
actions: {
GET: {},
POST: {},
},
related_search_fields: [],
},
});
ProjectsAPI.read.mockResolvedValue({
data: {
count: 1,
@ -48,6 +57,15 @@ describe('NodeTypeStep', () => {
],
},
});
ProjectsAPI.readOptions.mockResolvedValue({
data: {
actions: {
GET: {},
POST: {},
},
related_search_fields: [],
},
});
InventorySourcesAPI.read.mockResolvedValue({
data: {
count: 1,
@ -61,6 +79,15 @@ describe('NodeTypeStep', () => {
],
},
});
InventorySourcesAPI.readOptions.mockResolvedValue({
data: {
actions: {
GET: {},
POST: {},
},
related_search_fields: [],
},
});
WorkflowJobTemplatesAPI.read.mockResolvedValue({
data: {
count: 1,
@ -74,6 +101,15 @@ describe('NodeTypeStep', () => {
],
},
});
WorkflowJobTemplatesAPI.readOptions.mockResolvedValue({
data: {
actions: {
GET: {},
POST: {},
},
related_search_fields: [],
},
});
});
afterAll(() => {
jest.clearAllMocks();

View File

@ -20,22 +20,33 @@ function ProjectsList({ i18n, nodeResource, onUpdateNodeResource }) {
const location = useLocation();
const {
result: { projects, count },
result: { projects, count, relatedSearchableKeys, searchableKeys },
error,
isLoading,
request: fetchProjects,
} = useRequest(
useCallback(async () => {
const params = parseQueryString(QS_CONFIG, location.search);
const results = await ProjectsAPI.read(params);
const [response, actionsResponse] = await Promise.all([
ProjectsAPI.read(params),
ProjectsAPI.readOptions(),
]);
return {
projects: results.data.results,
count: results.data.count,
projects: response.data.results,
count: response.data.count,
relatedSearchableKeys: (
actionsResponse?.data?.related_search_fields || []
).map(val => val.slice(0, -8)),
searchableKeys: Object.keys(
actionsResponse.data.actions?.GET || {}
).filter(key => actionsResponse.data.actions?.GET[key].filterable),
};
}, [location]),
{
projects: [],
count: 0,
relatedSearchableKeys: [],
searchableKeys: [],
}
);
@ -101,6 +112,8 @@ function ProjectsList({ i18n, nodeResource, onUpdateNodeResource }) {
key: 'name',
},
]}
toolbarSearchableKeys={searchableKeys}
toolbarRelatedSearchableKeys={relatedSearchableKeys}
/>
);
}

View File

@ -38,6 +38,15 @@ describe('ProjectsList', () => {
],
},
});
ProjectsAPI.readOptions.mockResolvedValue({
data: {
actions: {
GET: {},
POST: {},
},
related_search_fields: [],
},
});
await act(async () => {
wrapper = mountWithContexts(
<ProjectsList

View File

@ -24,24 +24,40 @@ function WorkflowJobTemplatesList({
const location = useLocation();
const {
result: { workflowJobTemplates, count },
result: {
workflowJobTemplates,
count,
relatedSearchableKeys,
searchableKeys,
},
error,
isLoading,
request: fetchWorkflowJobTemplates,
} = useRequest(
useCallback(async () => {
const params = parseQueryString(QS_CONFIG, location.search);
const results = await WorkflowJobTemplatesAPI.read(params, {
role_level: 'execute_role',
});
const [response, actionsResponse] = await Promise.all([
WorkflowJobTemplatesAPI.read(params, {
role_level: 'execute_role',
}),
WorkflowJobTemplatesAPI.readOptions(),
]);
return {
workflowJobTemplates: results.data.results,
count: results.data.count,
workflowJobTemplates: response.data.results,
count: response.data.count,
relatedSearchableKeys: (
actionsResponse?.data?.related_search_fields || []
).map(val => val.slice(0, -8)),
searchableKeys: Object.keys(
actionsResponse.data.actions?.GET || {}
).filter(key => actionsResponse.data.actions?.GET[key].filterable),
};
}, [location]),
{
workflowJobTemplates: [],
count: 0,
relatedSearchableKeys: [],
searchableKeys: [],
}
);
@ -100,6 +116,8 @@ function WorkflowJobTemplatesList({
key: 'name',
},
]}
toolbarSearchableKeys={searchableKeys}
toolbarRelatedSearchableKeys={relatedSearchableKeys}
/>
);
}

View File

@ -38,6 +38,15 @@ describe('WorkflowJobTemplatesList', () => {
],
},
});
WorkflowJobTemplatesAPI.readOptions.mockResolvedValue({
data: {
actions: {
GET: {},
POST: {},
},
related_search_fields: [],
},
});
await act(async () => {
wrapper = mountWithContexts(
<WorkflowJobTemplatesList

View File

@ -27,7 +27,13 @@ function UserList({ i18n }) {
const match = useRouteMatch();
const {
result: { users, itemCount, actions },
result: {
users,
itemCount,
actions,
relatedSearchableKeys,
searchableKeys,
},
error: contentError,
isLoading,
request: fetchUsers,
@ -42,12 +48,20 @@ function UserList({ i18n }) {
users: response.data.results,
itemCount: response.data.count,
actions: actionsResponse.data.actions,
relatedSearchableKeys: (
actionsResponse?.data?.related_search_fields || []
).map(val => val.slice(0, -8)),
searchableKeys: Object.keys(
actionsResponse.data.actions?.GET || {}
).filter(key => actionsResponse.data.actions?.GET[key].filterable),
};
}, [location]),
{
users: [],
itemCount: 0,
actions: {},
relatedSearchableKeys: [],
searchableKeys: [],
}
);
@ -124,6 +138,8 @@ function UserList({ i18n }) {
key: 'last_name',
},
]}
toolbarSearchableKeys={searchableKeys}
toolbarRelatedSearchableKeys={relatedSearchableKeys}
renderToolbar={props => (
<DataListToolbar
{...props}