diff --git a/plugins/communications-app/ScheduleSection/index.jsx b/plugins/communications-app/ScheduleSection/index.jsx
index 05f87883..588b25ae 100644
--- a/plugins/communications-app/ScheduleSection/index.jsx
+++ b/plugins/communications-app/ScheduleSection/index.jsx
@@ -89,6 +89,7 @@ const ScheduleSection = ({ openTaskAlert }) => {
complete: ,
completeSchedule: ,
error: ,
+ loadingTeams: ,
}), []);
const statefulButtonLabels = useMemo(() => ({
@@ -99,12 +100,14 @@ const ScheduleSection = ({ openTaskAlert }) => {
complete: intl.formatMessage(messages.ScheduleSectionSubmitButtonComplete),
completeSchedule: intl.formatMessage(messages.ScheduleSectionSubmitButtonCompleteSchedule),
error: intl.formatMessage(messages.ScheduleSectionSubmitButtonError),
+ loadingTeams: intl.formatMessage(messages.ScheduleSectionSubmitButtonLoadingTeams),
}), [intl]);
const statefulButtonDisableStates = useMemo(() => [
'pending',
'complete',
'completeSchedule',
+ 'loadingTeams',
], []);
return (
diff --git a/plugins/communications-app/ScheduleSection/messages.js b/plugins/communications-app/ScheduleSection/messages.js
index e795715d..c3f8ff07 100644
--- a/plugins/communications-app/ScheduleSection/messages.js
+++ b/plugins/communications-app/ScheduleSection/messages.js
@@ -48,6 +48,10 @@ const messages = defineMessages({
id: 'schedule.section.submit.button.schedule.complete',
defaultMessage: 'Scheduling Done',
},
+ ScheduleSectionSubmitButtonLoadingTeams: {
+ id: 'schedule.section.submit.button.loading.teams',
+ defaultMessage: 'Loading teams',
+ },
});
export default messages;
diff --git a/plugins/communications-app/TeamEmails/api.js b/plugins/communications-app/TeamEmails/api.js
index b4dafbd0..625abf3d 100644
--- a/plugins/communications-app/TeamEmails/api.js
+++ b/plugins/communications-app/TeamEmails/api.js
@@ -1,10 +1,10 @@
import { getConfig } from '@edx/frontend-platform';
import { getAuthenticatedHttpClient } from '@edx/frontend-platform/auth';
-export async function getTeamsList(courseId, page = 1, pageSize = 100) {
+export async function getTopicsList(courseId, page = 1, pageSize = 100) {
const endpointUrl = `${
getConfig().LMS_BASE_URL
- }/platform-plugin-teams/${courseId}/api/topics/?page=${page}&pageSize=${pageSize}`;
+ }/platform-plugin-teams/${courseId}/api/topics/?page=${page}&page_size=${pageSize}`;
try {
const response = await getAuthenticatedHttpClient().get(endpointUrl);
return response;
diff --git a/plugins/communications-app/TeamEmails/api.test.js b/plugins/communications-app/TeamEmails/api.test.js
index b326508c..477784bc 100644
--- a/plugins/communications-app/TeamEmails/api.test.js
+++ b/plugins/communications-app/TeamEmails/api.test.js
@@ -1,7 +1,7 @@
import { getAuthenticatedHttpClient } from '@edx/frontend-platform/auth';
import { getConfig } from '@edx/frontend-platform';
-import { getTeamsList } from './api';
+import { getTopicsList } from './api';
jest.mock('@edx/frontend-platform/auth', () => ({
getAuthenticatedHttpClient: jest.fn(),
@@ -10,7 +10,7 @@ jest.mock('@edx/frontend-platform', () => ({
getConfig: jest.fn(),
}));
-describe('getTeamsList function', () => {
+describe('getTopicsList function', () => {
const mockCourseId = 'course123';
const mockResponseData = { data: 'someData' };
const mockConfig = { LMS_BASE_URL: 'http://localhost' };
@@ -23,11 +23,11 @@ describe('getTeamsList function', () => {
});
test('successfully fetches teams list with default parameters', async () => {
- const response = await getTeamsList(mockCourseId);
+ const response = await getTopicsList(mockCourseId);
expect(response).toEqual(mockResponseData);
expect(getAuthenticatedHttpClient().get).toHaveBeenCalledWith(
- `http://localhost/platform-plugin-teams/${mockCourseId}/api/topics/?page=1&pageSize=100`,
+ `http://localhost/platform-plugin-teams/${mockCourseId}/api/topics/?page=1&page_size=100`,
);
});
@@ -35,11 +35,11 @@ describe('getTeamsList function', () => {
const customPage = 2;
const customPageSize = 50;
- const response = await getTeamsList(mockCourseId, customPage, customPageSize);
+ const response = await getTopicsList(mockCourseId, customPage, customPageSize);
expect(response).toEqual(mockResponseData);
expect(getAuthenticatedHttpClient().get).toHaveBeenCalledWith(
- `http://localhost/platform-plugin-teams/${mockCourseId}/api/topics/?page=${customPage}&pageSize=${customPageSize}`,
+ `http://localhost/platform-plugin-teams/${mockCourseId}/api/topics/?page=${customPage}&page_size=${customPageSize}`,
);
});
@@ -47,6 +47,6 @@ describe('getTeamsList function', () => {
const errorMessage = 'Network error';
getAuthenticatedHttpClient().get.mockRejectedValue(new Error(errorMessage));
- await expect(getTeamsList(mockCourseId)).rejects.toThrow(errorMessage);
+ await expect(getTopicsList(mockCourseId)).rejects.toThrow(errorMessage);
});
});
diff --git a/plugins/communications-app/TeamEmails/index.jsx b/plugins/communications-app/TeamEmails/index.jsx
index acc22158..53abbfbc 100644
--- a/plugins/communications-app/TeamEmails/index.jsx
+++ b/plugins/communications-app/TeamEmails/index.jsx
@@ -9,7 +9,7 @@ import { actionCreators as formActions } from '@communications-app/src/component
import ListTeams from './ListTeams';
import messages from './messages';
-import { getTeamsList } from './api';
+import { getTopicsList } from './api';
import { getTeamsFromTopics, convertSnakeCaseToCamelCase } from './utils';
const TeamEmails = ({ courseId }) => {
@@ -24,25 +24,44 @@ const TeamEmails = ({ courseId }) => {
} = formData;
const [teams, setTeams] = useState([]);
const [checkedTeams, setCheckedTeams] = useState([]);
+ const [loadingTeams, setLoadingTeams] = useState(false);
const previousFormStatusRef = useRef(null);
- useEffect(() => {
- const getTeamsFromApi = async () => {
- try {
- const responseTeams = await getTeamsList(courseId);
- const { results } = responseTeams.data;
- const camelCaseResult = convertSnakeCaseToCamelCase(results);
- const formatResult = getTeamsFromTopics(camelCaseResult);
- setTeams(formatResult);
- } catch (error) {
- console.error('there was an error while getting teams', error.messages);
+ const fetchTeams = async (page = 1) => {
+ try {
+ setLoadingTeams(true);
+ const responseTopics = await getTopicsList(courseId, page);
+ const { results, next } = responseTopics.data;
+
+ const camelCaseResult = convertSnakeCaseToCamelCase(results);
+ const formatResult = getTeamsFromTopics(camelCaseResult);
+
+ setTeams((prevTeams) => [...prevTeams, ...formatResult]);
+
+ if (next) {
+ fetchTeams(page + 1);
+ } else {
+ dispatch(formActions.updateForm({ formStatus: 'default' }));
}
- };
+ } catch (error) {
+ console.error('There was an error while getting teams:', error.message);
+ } finally {
+ setLoadingTeams(false);
+ }
+ };
- getTeamsFromApi();
+ useEffect(() => {
+ fetchTeams();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [courseId]);
+ useEffect(() => {
+ if (loadingTeams) {
+ dispatch(formActions.updateForm({ formStatus: 'loadingTeams' }));
+ }
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, [formStatus, loadingTeams]);
+
useEffect(() => {
if (teams.length) {
dispatch(formActions.updateForm({ teamsListFullData: teams }));
diff --git a/plugins/communications-app/TeamEmails/index.test.jsx b/plugins/communications-app/TeamEmails/index.test.jsx
index dcf1b2e9..c1256f50 100644
--- a/plugins/communications-app/TeamEmails/index.test.jsx
+++ b/plugins/communications-app/TeamEmails/index.test.jsx
@@ -148,7 +148,7 @@ describe('TeamEmails Component', () => {
beforeEach(() => {
jest.clearAllMocks();
- api.getTeamsList.mockResolvedValue({ data: mockData });
+ api.getTopicsList.mockResolvedValue({ data: mockData });
useSelector.mockImplementation((selectorFn) => selectorFn({
form: {
teamsList: [],
@@ -169,7 +169,7 @@ describe('TeamEmails Component', () => {
);
test('renders the component without errors', async () => {
- api.getTeamsList.mockResolvedValue({ data: mockData });
+ api.getTopicsList.mockResolvedValue({ data: mockData });
render(
@@ -189,7 +189,7 @@ describe('TeamEmails Component', () => {
});
test('renders null when teams are empty', async () => {
- api.getTeamsList.mockResolvedValue({ data: { results: [] } });
+ api.getTopicsList.mockResolvedValue({ data: { results: [] } });
render(
@@ -205,7 +205,7 @@ describe('TeamEmails Component', () => {
test('handles checkbox change', async () => {
const mockDispatch = jest.fn();
useDispatch.mockReturnValue(mockDispatch);
- api.getTeamsList.mockResolvedValue({ data: mockData });
+ api.getTopicsList.mockResolvedValue({ data: mockData });
render(
@@ -220,9 +220,9 @@ describe('TeamEmails Component', () => {
});
});
- test('handles error when api.getTeamsList fails', async () => {
+ test('handles error when api.getTopicsList fails', async () => {
const mockedError = new Error('API Failed');
- api.getTeamsList.mockRejectedValue(mockedError);
+ api.getTopicsList.mockRejectedValue(mockedError);
const consoleSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
@@ -233,7 +233,7 @@ describe('TeamEmails Component', () => {
);
await waitFor(() => {
- expect(consoleSpy).toHaveBeenCalledWith('there was an error while getting teams', mockedError.messages);
+ expect(consoleSpy).toHaveBeenCalledWith('There was an error while getting teams:', mockedError.message);
});
consoleSpy.mockRestore();