Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { AppContext } from '@edx/frontend-platform/react';
import { Button, Badge } from '@openedx/paragon';

import urls from 'data/services/lms/urls';
import { reduxHooks } from 'hooks';
import { reduxHooks, apiHooks } from 'hooks';

import { findCoursesNavDropdownClicked } from '../hooks';
import messages from '../messages';
Expand All @@ -16,6 +16,8 @@ export const CollapseMenuBody = ({ isOpen }) => {
const { formatMessage } = useIntl();
const { authenticatedUser } = React.useContext(AppContext);

const { enabled: programsEnabled } = apiHooks.useProgramsConfig();

const dashboard = reduxHooks.useEnterpriseDashboardData();
const { courseSearchUrl } = reduxHooks.usePlatformSettingsData();

Expand All @@ -32,9 +34,11 @@ export const CollapseMenuBody = ({ isOpen }) => {
<Button as="a" href="/" variant="inverse-primary">
{formatMessage(messages.course)}
</Button>
<Button as="a" href={urls.programsUrl()} variant="inverse-primary">
{formatMessage(messages.program)}
</Button>
{programsEnabled && (
<Button as="a" href={urls.programsUrl()} variant="inverse-primary">
{formatMessage(messages.program)}
</Button>
)}
<Button
as="a"
href={urls.baseAppUrl(courseSearchUrl)}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { shallow } from '@edx/react-unit-test-utils';
import { AppContext } from '@edx/frontend-platform/react';

import { apiHooks } from 'hooks';
import CollapseMenuBody from './CollapseMenuBody';

jest.mock('@edx/frontend-platform/react', () => ({
Expand All @@ -20,6 +21,11 @@ jest.mock('hooks', () => ({
courseSearchUrl: '/courseSearchUrl',
}),
},
apiHooks: {
useProgramsConfig: () => ({
enabled: true,
}),
},
}));

jest.mock('../hooks', () => ({
Expand All @@ -45,4 +51,10 @@ describe('CollapseMenuBody', () => {
expect(wrapper.snapshot).toMatchSnapshot();
AppContext.authenticatedUser = authenticatedUser;
});

test('render with disabled programs', () => {
apiHooks.useProgramsConfig = () => ({ enabled: false });
const wrapper = shallow(<CollapseMenuBody isOpen />);
expect(wrapper.snapshot).toMatchSnapshot();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -103,3 +103,62 @@ exports[`CollapseMenuBody render unauthenticated 1`] = `
</Button>
</div>
`;

exports[`CollapseMenuBody render with disabled programs 1`] = `
<div
className="d-flex flex-column shadow-sm nav-small-menu"
>
<Button
as="a"
href="/"
variant="inverse-primary"
>
Courses
</Button>
<Button
as="a"
href="http://localhost:18000/courseSearchUrl"
onClick={[MockFunction findCoursesNavDropdownClicked("http://localhost:18000/courseSearchUrl")]}
variant="inverse-primary"
>
Discover New
</Button>
<Button
as="a"
href="http://localhost:18000/support"
variant="inverse-primary"
>
Help
</Button>
<Fragment>
<Button
as="a"
href="url"
variant="inverse-primary"
>
Dashboard
</Button>
<Button
as="a"
href="http://localhost:18000/u/username"
variant="inverse-primary"
>
Profile
</Button>
<Button
as="a"
href="http://localhost:18000/account/settings"
variant="inverse-primary"
>
Account
</Button>
<Button
as="a"
href="http://localhost:18000/logout"
variant="inverse-primary"
>
Sign Out
</Button>
</Fragment>
</div>
`;
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,44 @@ exports[`ExpandedHeader render 1`] = `
`;

exports[`ExpandedHeader render empty if collapsed 1`] = `null`;

exports[`ExpandedHeader render with disabled programs 1`] = `
<header
className="d-flex shadow-sm align-items-center learner-variant-header pl-4"
>
<div
className="flex-grow-1 d-flex align-items-center"
>
<BrandLogo />
<Button
as="a"
className="p-4 course-link"
href="/"
variant="inverse-primary"
>
Courses
</Button>
<Button
as="a"
className="p-4"
href="http://localhost:18000/courseSearchUrl"
onClick={[MockFunction findCoursesNavClicked("http://localhost:18000/courseSearchUrl")]}
variant="inverse-primary"
>
Discover New
</Button>
<span
className="flex-grow-1"
/>
<Button
as="a"
className="p-4"
href="http://localhost:18000/support"
variant="inverse-primary"
>
Help
</Button>
</div>
<AuthenticatedUserDropdown />
</header>
`;
22 changes: 13 additions & 9 deletions src/containers/LearnerDashboardHeader/ExpandedHeader/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { useIntl } from '@edx/frontend-platform/i18n';
import { Button } from '@openedx/paragon';

import urls from 'data/services/lms/urls';
import { reduxHooks } from 'hooks';
import { reduxHooks, apiHooks } from 'hooks';

import AuthenticatedUserDropdown from './AuthenticatedUserDropdown';
import { useIsCollapsed, findCoursesNavClicked } from '../hooks';
Expand All @@ -17,6 +17,8 @@ export const ExpandedHeader = () => {
const { courseSearchUrl } = reduxHooks.usePlatformSettingsData();
const isCollapsed = useIsCollapsed();

const { enabled: programsEnabled } = apiHooks.useProgramsConfig();

const exploreCoursesClick = findCoursesNavClicked(
urls.baseAppUrl(courseSearchUrl),
);
Expand All @@ -38,14 +40,16 @@ export const ExpandedHeader = () => {
>
{formatMessage(messages.course)}
</Button>
<Button
as="a"
href={urls.programsUrl()}
variant="inverse-primary"
className="p-4"
>
{formatMessage(messages.program)}
</Button>
{programsEnabled && (
<Button
as="a"
href={urls.programsUrl()}
variant="inverse-primary"
className="p-4"
>
{formatMessage(messages.program)}
</Button>
)}
<Button
as="a"
href={urls.baseAppUrl(courseSearchUrl)}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { shallow } from '@edx/react-unit-test-utils';

import { apiHooks } from 'hooks';
import ExpandedHeader from '.';

import { useIsCollapsed } from '../hooks';
Expand All @@ -15,6 +16,11 @@ jest.mock('hooks', () => ({
courseSearchUrl: '/courseSearchUrl',
}),
},
apiHooks: {
useProgramsConfig: () => ({
enabled: true,
}),
},
}));

jest.mock('../hooks', () => ({
Expand All @@ -38,4 +44,10 @@ describe('ExpandedHeader', () => {
expect(wrapper.snapshot).toMatchSnapshot();
expect(wrapper.isEmptyRender()).toBe(true);
});

test('render with disabled programs', () => {
apiHooks.useProgramsConfig = () => ({ enabled: false });
const wrapper = shallow(<ExpandedHeader />);
expect(wrapper.snapshot).toMatchSnapshot();
});
});
3 changes: 3 additions & 0 deletions src/data/services/lms/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ export const initializeList = ({ user } = {}) => get(
stringifyUrl(urls.getInitApiUrl(), { [apiKeys.user]: user }),
);

export const getProgramsConfig = () => get(urls.programsConfigUrl());

export const updateEntitlementEnrollment = ({ uuid, courseId }) => post(
urls.entitlementEnrollment(uuid),
{ [apiKeys.courseRunId]: courseId },
Expand Down Expand Up @@ -75,6 +77,7 @@ export default {
initializeList,
unenrollFromCourse,
updateEmailSettings,
getProgramsConfig,
updateEntitlementEnrollment,
deleteEntitlementEnrollment,
logEvent,
Expand Down
2 changes: 2 additions & 0 deletions src/data/services/lms/urls.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export const baseAppUrl = (url) => updateUrl(getBaseUrl(), url);
export const learningMfeUrl = (url) => updateUrl(getConfig().LEARNING_BASE_URL, url);

// static view url
const programsConfigUrl = () => baseAppUrl('/config/programs');
const programsUrl = () => baseAppUrl('/dashboard/programs');

export const creditPurchaseUrl = (courseId) => `${getEcommerceUrl()}/credit/checkout/${courseId}/`;
Expand All @@ -38,5 +39,6 @@ export default StrictDict({
getInitApiUrl,
learningMfeUrl,
programsUrl,
programsConfigUrl,
updateEmailSettings,
});
20 changes: 20 additions & 0 deletions src/hooks/api.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React from 'react';

import { AppContext } from '@edx/frontend-platform/react';
import { logError } from '@edx/frontend-platform/logging';

import { RequestKeys } from 'data/constants/requests';
import { post } from 'data/services/lms/utils';
Expand Down Expand Up @@ -31,6 +32,25 @@ export const useInitializeApp = () => {
});
};

export const useProgramsConfig = () => {
const [config, setConfig] = React.useState({});

const fetchProgramsConfig = React.useCallback(async () => {
try {
const { data } = await api.getProgramsConfig();
setConfig(data);
} catch (error) {
logError(`Error accessing programs configuration: ${error.message}`);
}
}, []);

React.useEffect(() => {
fetchProgramsConfig();
}, [fetchProgramsConfig]);

return config;
};

export const useNewEntitlementEnrollment = (cardId) => {
const { uuid } = reduxHooks.useCardEntitlementData(cardId);
const onSuccess = module.useInitializeApp();
Expand Down
Loading