diff --git a/src/components/ReportingConfig/index.jsx b/src/components/ReportingConfig/index.jsx
index 5108504f0f..b9db86955d 100644
--- a/src/components/ReportingConfig/index.jsx
+++ b/src/components/ReportingConfig/index.jsx
@@ -1,6 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
-import { Collapsible, Icon } from '@openedx/paragon';
+import { Collapsible, Icon, Pagination } from '@openedx/paragon';
import { Check, Close } from '@openedx/paragon/icons';
import { camelCaseObject } from '@edx/frontend-platform';
import { FormattedMessage, injectIntl, intlShape } from '@edx/frontend-platform/i18n';
@@ -12,6 +12,7 @@ import LoadingMessage from '../LoadingMessage';
import ErrorPage from '../ErrorPage';
const STATUS_FULFILLED = 'fulfilled';
+const DEFAULT_PAGE_SIZE = 10;
class ReportingConfig extends React.Component {
// eslint-disable-next-line react/state-in-constructor
@@ -33,7 +34,15 @@ class ReportingConfig extends React.Component {
LMSApiService.fetchReportingConfigTypes(this.props.enterpriseId),
])
.then((responses) => {
+ let totalPages = responses[0].status === STATUS_FULFILLED ? responses[0].value.data.num_pages : 1;
+ if (!totalPages) {
+ totalPages = 1;
+ }
+
this.setState({
+ totalPages,
+ currentPage: 1,
+ totalRecords: responses[0].status === STATUS_FULFILLED ? responses[0].value.data.count : 0,
reportingConfigs: responses[0].status === STATUS_FULFILLED ? responses[0].value.data.results : undefined,
availableCatalogs: responses[1].status === STATUS_FULFILLED ? responses[1].value.data.results : undefined,
reportingConfigTypes: responses[2].status === STATUS_FULFILLED ? responses[2].value.data : undefined,
@@ -55,13 +64,15 @@ class ReportingConfig extends React.Component {
// snake_case the data before sending it to the backend
const transformedData = snakeCaseFormData(formData);
try {
- const response = await LMSApiService.postNewReportingConfig(transformedData);
- this.setState(prevState => ({
- reportingConfigs: [
- ...prevState.reportingConfigs,
- response.data,
- ],
- }));
+ await LMSApiService.postNewReportingConfig(transformedData);
+
+ const lastPageHaveSpace = this.state.totalRecords % this.state.totalPages > 0;
+
+ if (lastPageHaveSpace || this.state.reportingConfigs.length < DEFAULT_PAGE_SIZE) {
+ this.handlePageSelect(this.state.totalPages);
+ } else {
+ this.handlePageSelect(this.state.totalPages + 1);
+ }
this.newConfigFormRef.current.close();
return undefined;
} catch (error) {
@@ -72,18 +83,17 @@ class ReportingConfig extends React.Component {
deleteConfig = async (uuid) => {
try {
await LMSApiService.deleteReportingConfig(uuid);
- const deletedIndex = this.state.reportingConfigs
- .findIndex(config => config.uuid === uuid);
-
- this.setState((state) => {
- // Copy the existing, needs to be updated, list of reporting configs
- const newReportingConfig = [...state.reportingConfigs];
- // Splice out the one that's being deleted
- newReportingConfig.splice(deletedIndex, 1);
- return {
- reportingConfigs: newReportingConfig,
- };
- });
+
+ const isLastPage = this.state.currentPage === this.state.totalPages;
+ const hasOneRecord = this.state.reportingConfigs.length === 1;
+ const isOnlyRecordOnLastPage = hasOneRecord && isLastPage;
+
+ if (isOnlyRecordOnLastPage && this.state.currentPage > 1) {
+ this.handlePageSelect(this.state.totalPages - 1);
+ } else {
+ this.handlePageSelect(this.state.currentPage);
+ }
+
return undefined;
} catch (error) {
return error;
@@ -111,6 +121,32 @@ class ReportingConfig extends React.Component {
}
};
+ /**
+ * Handles page select event and fetches the data for the selected page
+ * @param {number} page - The page number to fetch data for
+ */
+ handlePageSelect = async (page) => {
+ this.setState({
+ loading: true,
+ });
+
+ try {
+ const response = await LMSApiService.fetchReportingConfigs(this.props.enterpriseId, page);
+ this.setState({
+ totalPages: response.data.num_pages || 1,
+ totalRecords: response.data.count,
+ currentPage: page,
+ reportingConfigs: response.data.results,
+ loading: false,
+ });
+ } catch (error) {
+ this.setState({
+ loading: false,
+ error,
+ });
+ }
+ };
+
render() {
const {
reportingConfigs,
@@ -118,6 +154,8 @@ class ReportingConfig extends React.Component {
error,
availableCatalogs,
reportingConfigTypes,
+ currentPage,
+ totalPages,
} = this.state;
const { intl } = this.props;
if (loading) {
@@ -200,6 +238,17 @@ class ReportingConfig extends React.Component {
))}
+
+ {reportingConfigs && reportingConfigs.length > 0 && (
+
+ )}
+
', () => {
const afterClickingDeleteButton = wrapper.find('button[data-testid="deleteConfigButton"]');
expect(afterClickingDeleteButton.exists()).toBe(false);
});
+ it('should not render Pagination when reportingConfigs is empty', async () => {
+ LmsApiService.fetchReportingConfigs.mockResolvedValue({
+ data: {
+ results: [],
+ count: 0,
+ num_pages: 0,
+ },
+ });
+
+ let wrapper;
+ await act(async () => {
+ wrapper = mount(
+
+
+ ,
+ );
+ });
+
+ wrapper.update();
+
+ // Check that Pagination component is not rendered when no configs
+ const paginationComponent = wrapper.find(Pagination);
+ expect(paginationComponent.exists()).toBe(false);
+ });
+ it('should render Pagination when reportingConfigs has items', async () => {
+ let wrapper;
+
+ LmsApiService.fetchReportingConfigs.mockResolvedValue({
+ data: {
+ results: [{
+ enterpriseCustomerId: 'test-customer-uuid',
+ active: true,
+ delivery_method: 'email',
+ uuid: 'test-config-uuid',
+ }],
+ count: 1,
+ num_pages: 1,
+ },
+ });
+
+ await act(async () => {
+ wrapper = mount(
+
+
+ ,
+ );
+ });
+
+ wrapper.update();
+
+ // Check that Pagination component is rendered when configs exist
+ const paginationComponent = wrapper.find(Pagination);
+ expect(paginationComponent.exists()).toBe(true);
+ });
});
diff --git a/src/data/services/LmsApiService.js b/src/data/services/LmsApiService.js
index 7fd5fc65e7..9e5b2f99b9 100644
--- a/src/data/services/LmsApiService.js
+++ b/src/data/services/LmsApiService.js
@@ -119,8 +119,13 @@ class LmsApiService {
return LmsApiService.apiClient().post(requestCodesUrl, postParams);
}
- static fetchReportingConfigs(uuid) {
- return LmsApiService.apiClient().get(`${LmsApiService.reportingConfigUrl}?enterprise_customer=${uuid}`);
+ static fetchReportingConfigs(uuid, pageNumber) {
+ let url = `${LmsApiService.reportingConfigUrl}?enterprise_customer=${uuid}`;
+ if (pageNumber) {
+ url += `&page=${pageNumber}`;
+ }
+
+ return LmsApiService.apiClient().get(url);
}
static fetchReportingConfigTypes(uuid) {