diff --git a/src/components/Admin/Admin.test.jsx b/src/components/Admin/Admin.test.jsx
index c0a1105c74..0cd7685cf4 100644
--- a/src/components/Admin/Admin.test.jsx
+++ b/src/components/Admin/Admin.test.jsx
@@ -54,6 +54,10 @@ const store = mockStore({
loading: null,
insights: null,
},
+ enterpriseBudgets: {
+ loading: null,
+ budgets: null,
+ },
});
const AdminWrapper = props => (
@@ -78,8 +82,14 @@ const AdminWrapper = props => (
pathname: '/',
}}
{...props}
+ budgets={[{
+ subsidy_access_policy_uuid: '8d6503dd-e40d-42b8-442b-37dd4c5450e3',
+ subsidy_access_policy_display_name: 'Everything',
+ }]}
fetchDashboardInsights={() => {}}
clearDashboardInsights={() => {}}
+ fetchEnterpriseBudgets={() => {}}
+ clearEnterpriseBudgets={() => {}}
/>
@@ -97,6 +107,7 @@ describe('', () => {
lastUpdatedDate: '2018-07-31T23:14:35Z',
numberOfUsers: 3,
insights: null,
+ budgets: [],
};
describe('renders correctly', () => {
@@ -370,6 +381,26 @@ describe('', () => {
expect(tree).toMatchSnapshot();
});
});
+
+ describe('with enterprise budgets data', () => {
+ it('renders budgets correctly', () => {
+ const budgetUUID = '8d6503dd-e40d-42b8-442b-37dd4c5450e3';
+ const budgets = [{
+ subsidy_access_policy_uuid: budgetUUID,
+ subsidy_access_policy_display_name: 'Everything',
+ }];
+ const tree = renderer
+ .create((
+
+ ))
+ .toJSON();
+
+ expect(tree).toMatchSnapshot();
+ });
+ });
});
describe('handle changes to enterpriseId prop', () => {
diff --git a/src/components/Admin/AdminSearchForm.jsx b/src/components/Admin/AdminSearchForm.jsx
index a2624cef84..e93626f166 100644
--- a/src/components/Admin/AdminSearchForm.jsx
+++ b/src/components/Admin/AdminSearchForm.jsx
@@ -1,6 +1,7 @@
/* eslint-disable camelcase */
import React from 'react';
import PropTypes from 'prop-types';
+import classNames from 'classnames';
import { Form } from '@openedx/paragon';
import { Info } from '@openedx/paragon/icons';
@@ -14,17 +15,22 @@ import { withLocation, withNavigate } from '../../hoc';
class AdminSearchForm extends React.Component {
componentDidUpdate(prevProps) {
- const { searchParams: { searchQuery, searchCourseQuery, searchDateQuery } } = this.props;
+ const {
+ searchParams: {
+ searchQuery, searchCourseQuery, searchDateQuery, searchBudgetQuery,
+ },
+ } = this.props;
const {
searchParams: {
searchQuery: prevSearchQuery,
searchCourseQuery: prevSearchCourseQuery,
searchDateQuery: prevSearchDateQuery,
+ searchBudgetQuery: prevSearchBudgetQuery,
},
} = prevProps;
if (searchQuery !== prevSearchQuery || searchCourseQuery !== prevSearchCourseQuery
- || searchDateQuery !== prevSearchDateQuery) {
+ || searchDateQuery !== prevSearchDateQuery || searchBudgetQuery !== prevSearchBudgetQuery) {
this.handleSearch();
}
}
@@ -45,14 +51,27 @@ class AdminSearchForm extends React.Component {
updateUrl(navigate, location.pathname, updateParams);
}
+ onBudgetSelect(event) {
+ const { navigate, location } = this.props;
+ const updateParams = {
+ budget_uuid: event.target.value,
+ page: 1,
+ };
+ updateUrl(navigate, location.pathname, updateParams);
+ }
+
render() {
const {
intl,
tableData,
- searchParams: { searchCourseQuery, searchDateQuery, searchQuery },
+ budgets,
+ searchParams: {
+ searchCourseQuery, searchDateQuery, searchQuery, searchBudgetQuery,
+ },
} = this.props;
const courseTitles = Array.from(new Set(tableData.map(en => en.course_title).sort()));
const courseDates = Array.from(new Set(tableData.map(en => en.course_start_date).sort().reverse()));
+ const columnWidth = budgets?.length ? 'col-md-3' : 'col-md-6';
return (
@@ -151,7 +170,7 @@ class AdminSearchForm extends React.Component {
-
+
+ {budgets?.length && (
+
+
+
+
+
+ this.onBudgetSelect(e)}
+ >
+
+ {budgets.map(budget => (
+
+ ))}
+
+
+
+ )}
@@ -193,8 +247,10 @@ AdminSearchForm.propTypes = {
searchQuery: PropTypes.string,
searchCourseQuery: PropTypes.string,
searchDateQuery: PropTypes.string,
+ searchBudgetQuery: PropTypes.string,
}).isRequired,
tableData: PropTypes.arrayOf(PropTypes.shape({})),
+ budgets: PropTypes.arrayOf(PropTypes.shape({})),
navigate: PropTypes.func,
location: PropTypes.shape({
pathname: PropTypes.string,
diff --git a/src/components/Admin/AdminSearchForm.test.jsx b/src/components/Admin/AdminSearchForm.test.jsx
index 7a0d944ebf..dada76b682 100644
--- a/src/components/Admin/AdminSearchForm.test.jsx
+++ b/src/components/Admin/AdminSearchForm.test.jsx
@@ -5,6 +5,7 @@ import { IntlProvider } from '@edx/frontend-platform/i18n';
import AdminSearchForm from './AdminSearchForm';
import SearchBar from '../SearchBar';
+import { updateUrl } from '../../utils';
jest.mock('react-router-dom', () => ({
...jest.requireActual('react-router-dom'),
@@ -12,6 +13,10 @@ jest.mock('react-router-dom', () => ({
useNavigate: jest.fn(),
}));
+jest.mock('../../utils', () => ({
+ updateUrl: jest.fn(),
+}));
+
const DEFAULT_PROPS = {
searchEnrollmentsList: () => {},
searchParams: {},
@@ -48,4 +53,32 @@ describe('', () => {
expect(spy).toHaveBeenCalledTimes(1);
});
});
+
+ it('select the correct budget', () => {
+ const budgetUUID = '8d6503dd-e40d-42b8-442b-37dd4c5450e3';
+ const budgets = [{
+ subsidy_access_policy_uuid: budgetUUID,
+ subsidy_access_policy_display_name: 'Everything',
+ }];
+ const props = {
+ ...DEFAULT_PROPS,
+ budgets,
+ location: { pathname: '/admin/learners' },
+ };
+ const wrapper = mount(
+ ,
+ );
+ const selectElement = wrapper.find('.budgets-dropdown select');
+
+ selectElement.simulate('change', { target: { value: budgetUUID } });
+ expect(updateUrl).toHaveBeenCalled();
+ expect(updateUrl).toHaveBeenCalledWith(
+ undefined,
+ '/admin/learners',
+ {
+ budget_uuid: budgetUUID,
+ page: 1,
+ },
+ );
+ });
});
diff --git a/src/components/Admin/__snapshots__/Admin.test.jsx.snap b/src/components/Admin/__snapshots__/Admin.test.jsx.snap
index 234d842110..5b2458ef53 100644
--- a/src/components/Admin/__snapshots__/Admin.test.jsx.snap
+++ b/src/components/Admin/__snapshots__/Admin.test.jsx.snap
@@ -1665,7 +1665,7 @@ exports[` renders correctly with dashboard analytics data renders # cou
>
@@ -1674,7 +1674,7 @@ exports[` renders correctly with dashboard analytics data renders # cou
>
renders correctly with dashboard analytics data renders # cou
>