refactor: Migrate Help Urls from Redux store to React Query (#2714)
This commit is contained in:
@@ -1,35 +1,35 @@
|
||||
module.exports = {
|
||||
default: 'https://docs.openedx.org/en/latest/educators/index.html',
|
||||
home: 'https://docs.openedx.org/en/latest/educators/navigation/content_creation_management.html',
|
||||
develop_course: 'https://docs.openedx.org/en/latest/educators/references/course_content_development.html',
|
||||
outline: 'https://docs.openedx.org/en/latest/educators/concepts/open_edx_platform/about_course_outline.html',
|
||||
unit: 'https://docs.openedx.org/en/latest/educators/concepts/open_edx_platform/about_course_units.html',
|
||||
visibility: 'https://docs.openedx.org/en/latest/educators/references/controlling_content_visibility.html',
|
||||
updates: 'https://docs.openedx.org/en/latest/educators/concepts/communication/about_course_updates_handouts.html',
|
||||
pages: 'https://docs.openedx.org/en/latest/educators/how-tos/course_development/manage_custom_page.html',
|
||||
files: 'https://docs.openedx.org/en/latest/educators/how-tos/course_development/manage_course_files.html',
|
||||
textbooks: 'https://docs.openedx.org/en/latest/educators/how-tos/course_development/manage_textbooks.html',
|
||||
schedule: 'https://docs.openedx.org/en/latest/educators/references/course_development/about_page.html',
|
||||
grading: 'https://docs.openedx.org/en/latest/educators/concepts/grading/about_graded_subsections.html',
|
||||
team_course: 'https://docs.openedx.org/en/latest/educators/references/course_development/course_team_roles.html#guide-to-course-team-roles',
|
||||
team_library: 'https://docs.openedx.org/en/latest/educators/how-tos/course_development/library_access.html',
|
||||
advanced: 'https://docs.openedx.org/en/latest/educators/navigation/advanced_features.html',
|
||||
checklist: 'https://docs.openedx.org/en/latest/educators/quickstarts/build_a_course.html#quick-start-build-a-course',
|
||||
import_library: 'https://docs.openedx.org/en/latest/educators/how-tos/course_development/export_import_library.html',
|
||||
import_course: 'https://docs.openedx.org/en/latest/educators/how-tos/releasing-course/import_course.html',
|
||||
export_library: 'https://docs.openedx.org/en/latest/educators/how-tos/course_development/export_import_library.html',
|
||||
export_course: 'https://docs.openedx.org/en/latest/educators/how-tos/releasing-course/export_course.html',
|
||||
welcome: 'https://docs.openedx.org/en/latest/educators/quickstarts/build_a_course.html#quick-start-build-a-course',
|
||||
login: 'https://docs.openedx.org/en/latest/educators/quickstarts/build_a_course.html#quick-start-build-a-course',
|
||||
register: 'https://docs.openedx.org/en/latest/educators/quickstarts/build_a_course.html#quick-start-build-a-course',
|
||||
content_libraries: 'https://docs.openedx.org/en/latest/educators/navigation/content_creation_management.html#work-with-content-libraries',
|
||||
content_groups: 'https://docs.openedx.org/en/latest/educators/navigation/advanced_features.html#manage-course-cohorts',
|
||||
enrollment_tracks: 'https://docs.openedx.org/en/latest/educators/how-tos/advanced_features/create_content_for_specific_enrollment_tracks.html',
|
||||
group_configurations: 'https://docs.openedx.org/en/latest/educators/concepts/advanced_features/about_group_configurations.html',
|
||||
container: 'https://docs.openedx.org/en/latest/educators/references/course_development/parent_child_components.html',
|
||||
video: 'https://docs.openedx.org/en/latest/educators/navigation/content_creation_management.html#manage-video-components',
|
||||
certificates: 'https://docs.openedx.org/en/latest/educators/navigation/creating_course.html#set-up-course-certificates',
|
||||
content_highlights: 'https://docs.openedx.org/en/latest/educators/how-tos/course_development/manage_course_highlight_emails.html#set-course-section-highlights',
|
||||
image_accessibility: 'https://docs.openedx.org/en/latest/educators/references/accessibility/accessibility_best_practices_checklist.html#use-best-practices-for-describing-images',
|
||||
social_sharing: 'https://docs.openedx.org/en/latest/educators/how-tos/course_development/social_sharing.html',
|
||||
checklist: 'https://docs.openedx.org/en/latest/educators/quickstarts/build_a_course.html#quick-start-build-a-course',
|
||||
container: 'https://docs.openedx.org/en/latest/educators/references/course_development/parent_child_components.html',
|
||||
contentGroups: 'https://docs.openedx.org/en/latest/educators/navigation/advanced_features.html#manage-course-cohorts',
|
||||
contentHighlights: 'https://docs.openedx.org/en/latest/educators/how-tos/course_development/manage_course_highlight_emails.html#set-course-section-highlights',
|
||||
contentLibraries: 'https://docs.openedx.org/en/latest/educators/navigation/content_creation_management.html#work-with-content-libraries',
|
||||
default: 'https://docs.openedx.org/en/latest/educators/index.html',
|
||||
developCourse: 'https://docs.openedx.org/en/latest/educators/references/course_content_development.html',
|
||||
enrollmentTracks: 'https://docs.openedx.org/en/latest/educators/how-tos/advanced_features/create_content_for_specific_enrollment_tracks.html',
|
||||
exportCourse: 'https://docs.openedx.org/en/latest/educators/how-tos/releasing-course/export_course.html',
|
||||
exportLibrary: 'https://docs.openedx.org/en/latest/educators/how-tos/course_development/export_import_library.html',
|
||||
files: 'https://docs.openedx.org/en/latest/educators/how-tos/course_development/manage_course_files.html',
|
||||
grading: 'https://docs.openedx.org/en/latest/educators/concepts/grading/about_graded_subsections.html',
|
||||
groupConfigurations: 'https://docs.openedx.org/en/latest/educators/concepts/advanced_features/about_group_configurations.html',
|
||||
home: 'https://docs.openedx.org/en/latest/educators/navigation/content_creation_management.html',
|
||||
imageAccessibility: 'https://docs.openedx.org/en/latest/educators/references/imageAccessibility/image_accessibility.html',
|
||||
importCourse: 'https://docs.openedx.org/en/latest/educators/how-tos/releasing-course/import_course.html',
|
||||
importLibrary: 'https://docs.openedx.org/en/latest/educators/how-tos/course_development/export_import_library.html',
|
||||
login: 'https://docs.openedx.org/en/latest/educators/quickstarts/build_a_course.html#quick-start-build-a-course',
|
||||
outline: 'https://docs.openedx.org/en/latest/educators/concepts/open_edx_platform/about_course_outline.html',
|
||||
pages: 'https://docs.openedx.org/en/latest/educators/how-tos/course_development/manage_custom_page.html',
|
||||
register: 'https://docs.openedx.org/en/latest/educators/quickstarts/build_a_course.html#quick-start-build-a-course',
|
||||
schedule: 'https://docs.openedx.org/en/latest/educators/references/course_development/about_page.html',
|
||||
socialSharing: 'https://docs.openedx.org/en/latest/educators/how-tos/course_development/social_sharing.html',
|
||||
teamCourse: 'https://docs.openedx.org/en/latest/educators/references/course_development/course_team_roles.html#guide-to-course-team-roles',
|
||||
teamLibrary: 'https://docs.openedx.org/en/latest/educators/how-tos/course_development/library_access.html',
|
||||
textbooks: 'https://docs.openedx.org/en/latest/educators/how-tos/course_development/manage_textbooks.html',
|
||||
unit: 'https://docs.openedx.org/en/latest/educators/concepts/open_edx_platform/about_course_units.html',
|
||||
updates: 'https://docs.openedx.org/en/latest/educators/concepts/communication/about_course_updates_handouts.html',
|
||||
video: 'https://docs.openedx.org/en/latest/educators/navigation/content_creation_management.html#manage-video-components',
|
||||
visibility: 'https://docs.openedx.org/en/latest/educators/references/controlling_content_visibility.html',
|
||||
welcome: 'https://docs.openedx.org/en/latest/educators/quickstarts/build_a_course.html#quick-start-build-a-course',
|
||||
};
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
import { camelCaseObject, getConfig } from '@edx/frontend-platform';
|
||||
import { getAuthenticatedHttpClient } from '@edx/frontend-platform/auth';
|
||||
|
||||
export const getHelpUrlsApiUrl = () => `${getConfig().STUDIO_BASE_URL}/api/contentstore/v1/help_urls`;
|
||||
|
||||
export async function getHelpUrls() {
|
||||
const { data } = await getAuthenticatedHttpClient()
|
||||
.get(getHelpUrlsApiUrl());
|
||||
return camelCaseObject(data);
|
||||
}
|
||||
46
src/help-urls/data/api.ts
Normal file
46
src/help-urls/data/api.ts
Normal file
@@ -0,0 +1,46 @@
|
||||
import { camelCaseObject, getConfig } from '@edx/frontend-platform';
|
||||
import { getAuthenticatedHttpClient } from '@edx/frontend-platform/auth';
|
||||
|
||||
export const getHelpUrlsApiUrl = () => `${getConfig().STUDIO_BASE_URL}/api/contentstore/v1/help_urls`;
|
||||
|
||||
export interface HelpUrls {
|
||||
advanced: string;
|
||||
certificates: string;
|
||||
checklist: string;
|
||||
container: string;
|
||||
contentGroups: string;
|
||||
contentHighlights: string;
|
||||
contentLibraries: string;
|
||||
default: string;
|
||||
developCourse: string;
|
||||
enrollmentTracks: string;
|
||||
exportCourse: string;
|
||||
exportLibrary: string;
|
||||
files: string;
|
||||
grading: string;
|
||||
groupConfigurations: string;
|
||||
home: string;
|
||||
imageAccessibility: string;
|
||||
importCourse: string;
|
||||
importLibrary: string;
|
||||
login: string;
|
||||
outline: string;
|
||||
pages: string;
|
||||
register: string;
|
||||
schedule: string;
|
||||
socialSharing: string;
|
||||
teamCourse: string;
|
||||
teamLibrary: string;
|
||||
textbooks: string;
|
||||
unit: string;
|
||||
updates: string;
|
||||
video: string;
|
||||
visibility: string;
|
||||
welcome: string;
|
||||
}
|
||||
|
||||
export async function getHelpUrls(): Promise<HelpUrls> {
|
||||
const { data } = await getAuthenticatedHttpClient()
|
||||
.get(getHelpUrlsApiUrl());
|
||||
return camelCaseObject(data);
|
||||
}
|
||||
13
src/help-urls/data/apiHooks.ts
Normal file
13
src/help-urls/data/apiHooks.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
|
||||
import * as api from './api';
|
||||
|
||||
/**
|
||||
* Hook to fetch all help urls
|
||||
*/
|
||||
export const useAllHelpUrls = () => (
|
||||
useQuery({
|
||||
queryKey: ['helpURLs'],
|
||||
queryFn: api.getHelpUrls,
|
||||
})
|
||||
);
|
||||
@@ -1,13 +0,0 @@
|
||||
export const selectHelpUrlsByNames = (names) => (state) => {
|
||||
const urlsDictionary = {};
|
||||
|
||||
names.forEach(name => {
|
||||
urlsDictionary[name] = state.helpUrls.pages[name] || null;
|
||||
});
|
||||
|
||||
return urlsDictionary;
|
||||
};
|
||||
|
||||
export const getPages = (state) => state.helpUrls.pages;
|
||||
|
||||
export const getLoadingHelpUrlsStatus = (state) => state.helpUrls.loadingHelpUrlsStatus;
|
||||
@@ -1,27 +0,0 @@
|
||||
/* eslint-disable no-param-reassign */
|
||||
import { createSlice } from '@reduxjs/toolkit';
|
||||
|
||||
const initialState = {
|
||||
loadingHelpUrlsStatus: '',
|
||||
pages: {},
|
||||
};
|
||||
|
||||
const slice = createSlice({
|
||||
name: 'helpUrls',
|
||||
initialState,
|
||||
reducers: {
|
||||
updatePages: (state, { payload }) => {
|
||||
state.pages = payload;
|
||||
},
|
||||
updateLoadingHelpUrlsStatus: (state, { payload }) => {
|
||||
state.loadingHelpUrlsStatus = payload.status;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
export const {
|
||||
updatePages,
|
||||
updateLoadingHelpUrlsStatus,
|
||||
} = slice.actions;
|
||||
|
||||
export const { reducer } = slice;
|
||||
@@ -1,23 +0,0 @@
|
||||
import { RequestStatus } from '../../data/constants';
|
||||
|
||||
import { getHelpUrls } from './api';
|
||||
import { updateLoadingHelpUrlsStatus, updatePages } from './slice';
|
||||
|
||||
export function fetchHelpUrls() {
|
||||
return async (dispatch) => {
|
||||
dispatch(updateLoadingHelpUrlsStatus({ status: RequestStatus.IN_PROGRESS }));
|
||||
|
||||
try {
|
||||
const urls = await getHelpUrls();
|
||||
|
||||
dispatch(updatePages(urls));
|
||||
|
||||
dispatch(updateLoadingHelpUrlsStatus({ status: RequestStatus.SUCCESSFUL }));
|
||||
return true;
|
||||
} catch {
|
||||
dispatch(updateLoadingHelpUrlsStatus({ status: RequestStatus.FAILED }));
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
import { useEffect } from 'react';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import { isEmpty } from 'lodash';
|
||||
|
||||
import { fetchHelpUrls } from './data/thunks';
|
||||
import { getPages, selectHelpUrlsByNames } from './data/selectors';
|
||||
|
||||
const useHelpUrls = (tokenNames) => {
|
||||
const dispatch = useDispatch();
|
||||
const helpTokens = useSelector(selectHelpUrlsByNames(tokenNames));
|
||||
const pages = useSelector(getPages);
|
||||
|
||||
useEffect(() => {
|
||||
if (isEmpty(pages)) {
|
||||
dispatch(fetchHelpUrls());
|
||||
}
|
||||
}, []);
|
||||
|
||||
return helpTokens;
|
||||
};
|
||||
|
||||
export { useHelpUrls };
|
||||
22
src/help-urls/hooks.tsx
Normal file
22
src/help-urls/hooks.tsx
Normal file
@@ -0,0 +1,22 @@
|
||||
import { HelpUrls } from './data/api';
|
||||
import { useAllHelpUrls } from './data/apiHooks';
|
||||
|
||||
const useHelpUrls = <T extends string[]>(tokenNames: T & (keyof HelpUrls)[]): {
|
||||
[K in T[number]]?: K extends keyof HelpUrls ? string : null
|
||||
} => {
|
||||
const {
|
||||
data: pages,
|
||||
} = useAllHelpUrls();
|
||||
|
||||
const urlsDictionary = {};
|
||||
|
||||
if (pages) {
|
||||
tokenNames.forEach(name => {
|
||||
urlsDictionary[name] = pages[name] || null;
|
||||
});
|
||||
}
|
||||
|
||||
return urlsDictionary;
|
||||
};
|
||||
|
||||
export { useHelpUrls };
|
||||
@@ -16,7 +16,6 @@ import { reducer as filesReducer } from './files-and-videos/files-page/data/slic
|
||||
import { reducer as courseTeamReducer } from './course-team/data/slice';
|
||||
import { reducer as CourseUpdatesReducer } from './course-updates/data/slice';
|
||||
import { reducer as processingNotificationReducer } from './generic/processing-notification/data/slice';
|
||||
import { reducer as helpUrlsReducer } from './help-urls/data/slice';
|
||||
import { reducer as courseExportReducer } from './export-page/data/slice';
|
||||
import { reducer as courseOptimizerReducer } from './optimizer-page/data/slice';
|
||||
import { reducer as genericReducer } from './generic/data/slice';
|
||||
@@ -50,7 +49,6 @@ export interface DeprecatedReduxState {
|
||||
courseTeam: Record<string, any>;
|
||||
courseUpdates: Record<string, any>;
|
||||
processingNotification: Record<string, any>;
|
||||
helpUrls: Record<string, any>;
|
||||
courseExport: Record<string, any>;
|
||||
courseOptimizer: Record<string, any>;
|
||||
generic: Record<string, any>;
|
||||
@@ -81,7 +79,6 @@ export default function initializeStore(preloadedState: Partial<DeprecatedReduxS
|
||||
courseTeam: courseTeamReducer,
|
||||
courseUpdates: CourseUpdatesReducer,
|
||||
processingNotification: processingNotificationReducer,
|
||||
helpUrls: helpUrlsReducer,
|
||||
courseExport: courseExportReducer,
|
||||
courseOptimizer: courseOptimizerReducer,
|
||||
generic: genericReducer,
|
||||
|
||||
Reference in New Issue
Block a user