fix: replace the header with openedx header
Description: Replace the header with openedx header van-1914
This commit is contained in:
committed by
Mubbshar Anwar
parent
68a46ac023
commit
7ef5d5b034
85
package-lock.json
generated
85
package-lock.json
generated
@@ -11,6 +11,7 @@
|
||||
"dependencies": {
|
||||
"@edx/brand": "npm:@openedx/brand-openedx@^1.2.2",
|
||||
"@edx/browserslist-config": "^1.1.0",
|
||||
"@edx/frontend-component-header": "^5.3.1",
|
||||
"@edx/frontend-enterprise-hotjar": "3.0.0",
|
||||
"@edx/frontend-platform": "8.1.1",
|
||||
"@edx/openedx-atlas": "^0.6.0",
|
||||
@@ -2242,9 +2243,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@edx/frontend-component-footer": {
|
||||
"version": "14.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@edx/frontend-component-footer/-/frontend-component-footer-14.0.0.tgz",
|
||||
"integrity": "sha512-3Riz6ippBnPz1oq6gZgFBx27bJkNL+rwwKrv0uCuHV/5MscS1aYeKx1ZAMuUsxkKcGX6uhyU6PwM6agvnhKfNQ==",
|
||||
"version": "13.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@edx/frontend-component-footer/-/frontend-component-footer-13.1.0.tgz",
|
||||
"integrity": "sha512-Rtv8dfQmL75El8kF8dG9nYF1Cqj2AbWPLVLE4b0XTvipfx2RMeDKpgAO5XLAzTt0h+5fmiMCGhVEv3Y70Xu5pQ==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@fortawesome/fontawesome-svg-core": "6.5.2",
|
||||
@@ -2326,6 +2327,82 @@
|
||||
"react": ">=16.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@edx/frontend-component-header": {
|
||||
"version": "5.3.4",
|
||||
"resolved": "https://registry.npmjs.org/@edx/frontend-component-header/-/frontend-component-header-5.3.4.tgz",
|
||||
"integrity": "sha512-niuaXu0+qWPHud9Bs1pqmNXvZc9jpf8WS270/2YEH5owokd+BiDwQ6MWkvS9qbuQIVGPGTSZFFTttUKmQO5O0A==",
|
||||
"dependencies": {
|
||||
"@fortawesome/fontawesome-svg-core": "6.6.0",
|
||||
"@fortawesome/free-brands-svg-icons": "6.6.0",
|
||||
"@fortawesome/free-regular-svg-icons": "6.6.0",
|
||||
"@fortawesome/free-solid-svg-icons": "6.6.0",
|
||||
"@fortawesome/react-fontawesome": "^0.2.0",
|
||||
"axios-mock-adapter": "1.22.0",
|
||||
"babel-polyfill": "6.26.0",
|
||||
"jest-environment-jsdom": "^29.7.0",
|
||||
"react-responsive": "8.2.0",
|
||||
"react-transition-group": "4.4.5"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@edx/frontend-platform": "^7.0.0 || ^8.0.0",
|
||||
"@openedx/paragon": ">= 21.5.7 < 23.0.0",
|
||||
"prop-types": "^15.5.10",
|
||||
"react": "^16.9.0 || ^17.0.0",
|
||||
"react-dom": "^16.9.0 || ^17.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@edx/frontend-component-header/node_modules/@fortawesome/fontawesome-common-types": {
|
||||
"version": "6.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.6.0.tgz",
|
||||
"integrity": "sha512-xyX0X9mc0kyz9plIyryrRbl7ngsA9jz77mCZJsUkLl+ZKs0KWObgaEBoSgQiYWAsSmjz/yjl0F++Got0Mdp4Rw==",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/@edx/frontend-component-header/node_modules/@fortawesome/fontawesome-svg-core": {
|
||||
"version": "6.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.6.0.tgz",
|
||||
"integrity": "sha512-KHwPkCk6oRT4HADE7smhfsKudt9N/9lm6EJ5BVg0tD1yPA5hht837fB87F8pn15D8JfTqQOjhKTktwmLMiD7Kg==",
|
||||
"dependencies": {
|
||||
"@fortawesome/fontawesome-common-types": "6.6.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/@edx/frontend-component-header/node_modules/@fortawesome/free-brands-svg-icons": {
|
||||
"version": "6.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@fortawesome/free-brands-svg-icons/-/free-brands-svg-icons-6.6.0.tgz",
|
||||
"integrity": "sha512-1MPD8lMNW/earme4OQi1IFHtmHUwAKgghXlNwWi9GO7QkTfD+IIaYpIai4m2YJEzqfEji3jFHX1DZI5pbY/biQ==",
|
||||
"dependencies": {
|
||||
"@fortawesome/fontawesome-common-types": "6.6.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/@edx/frontend-component-header/node_modules/@fortawesome/free-regular-svg-icons": {
|
||||
"version": "6.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@fortawesome/free-regular-svg-icons/-/free-regular-svg-icons-6.6.0.tgz",
|
||||
"integrity": "sha512-Yv9hDzL4aI73BEwSEh20clrY8q/uLxawaQ98lekBx6t9dQKDHcDzzV1p2YtBGTtolYtNqcWdniOnhzB+JPnQEQ==",
|
||||
"dependencies": {
|
||||
"@fortawesome/fontawesome-common-types": "6.6.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/@edx/frontend-component-header/node_modules/@fortawesome/free-solid-svg-icons": {
|
||||
"version": "6.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.6.0.tgz",
|
||||
"integrity": "sha512-IYv/2skhEDFc2WGUcqvFJkeK39Q+HyPf5GHUrT/l2pKbtgEIv1al1TKd6qStR5OIwQdN1GZP54ci3y4mroJWjA==",
|
||||
"dependencies": {
|
||||
"@fortawesome/fontawesome-common-types": "6.6.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/@edx/frontend-enterprise-hotjar": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@edx/frontend-enterprise-hotjar/-/frontend-enterprise-hotjar-3.0.0.tgz",
|
||||
@@ -7005,7 +7082,6 @@
|
||||
"version": "1.22.0",
|
||||
"resolved": "https://registry.npmjs.org/axios-mock-adapter/-/axios-mock-adapter-1.22.0.tgz",
|
||||
"integrity": "sha512-dmI0KbkyAhntUR05YY96qg2H6gg0XMl2+qTW0xmYg6Up+BFBAJYRLROMXRdDEL06/Wqwa0TJThAYvFtSFdRCZw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"fast-deep-equal": "^3.1.3",
|
||||
"is-buffer": "^2.0.5"
|
||||
@@ -13315,7 +13391,6 @@
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz",
|
||||
"integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
"dependencies": {
|
||||
"@edx/brand": "npm:@openedx/brand-openedx@^1.2.2",
|
||||
"@edx/browserslist-config": "^1.1.0",
|
||||
"@edx/frontend-component-header": "^5.3.1",
|
||||
"@edx/frontend-enterprise-hotjar": "3.0.0",
|
||||
"@edx/frontend-platform": "8.1.1",
|
||||
"@edx/openedx-atlas": "^0.6.0",
|
||||
|
||||
@@ -9,6 +9,7 @@ $fa-font-path: "~font-awesome/fonts";
|
||||
|
||||
$input-focus-box-shadow: $input-box-shadow; // hack to get upgrade to paragon 4.0.0 to work
|
||||
|
||||
@import "~@edx/frontend-component-header/dist/index";
|
||||
@import "~@edx/frontend-component-footer/dist/_footer";
|
||||
|
||||
.text-ellipsis {
|
||||
|
||||
@@ -1,104 +0,0 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import { getConfig } from '@edx/frontend-platform';
|
||||
import { useIntl } from '@edx/frontend-platform/i18n';
|
||||
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 { findCoursesNavDropdownClicked } from '../hooks';
|
||||
import messages from '../messages';
|
||||
|
||||
export const CollapseMenuBody = ({ isOpen }) => {
|
||||
const { formatMessage } = useIntl();
|
||||
const { authenticatedUser } = React.useContext(AppContext);
|
||||
|
||||
const dashboard = reduxHooks.useEnterpriseDashboardData();
|
||||
const { courseSearchUrl } = reduxHooks.usePlatformSettingsData();
|
||||
|
||||
const exploreCoursesClick = findCoursesNavDropdownClicked(
|
||||
urls.baseAppUrl(courseSearchUrl),
|
||||
);
|
||||
|
||||
if (!isOpen) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="d-flex flex-column shadow-sm nav-small-menu">
|
||||
<Button as="a" href="/" variant="inverse-primary">
|
||||
{formatMessage(messages.course)}
|
||||
</Button>
|
||||
<Button as="a" href={urls.programsUrl()} variant="inverse-primary">
|
||||
{formatMessage(messages.program)}
|
||||
</Button>
|
||||
<Button
|
||||
as="a"
|
||||
href={urls.baseAppUrl(courseSearchUrl)}
|
||||
variant="inverse-primary"
|
||||
onClick={exploreCoursesClick}
|
||||
>
|
||||
{formatMessage(messages.discoverNew)}
|
||||
</Button>
|
||||
<Button as="a" href={getConfig().SUPPORT_URL} variant="inverse-primary">
|
||||
{formatMessage(messages.help)}
|
||||
</Button>
|
||||
{authenticatedUser && (
|
||||
<>
|
||||
{!!dashboard && (
|
||||
<Button as="a" href={dashboard.url} variant="inverse-primary">
|
||||
{formatMessage(messages.dashboard)}
|
||||
</Button>
|
||||
)}
|
||||
{!dashboard && getConfig().CAREER_LINK_URL && (
|
||||
<Button href={`${getConfig().CAREER_LINK_URL}`}>
|
||||
{formatMessage(messages.career)}
|
||||
<Badge className="px-2 mx-2" variant="warning">
|
||||
{formatMessage(messages.newAlert)}
|
||||
</Badge>
|
||||
</Button>
|
||||
)}
|
||||
<Button
|
||||
as="a"
|
||||
href={`${getConfig().LMS_BASE_URL}/u/${authenticatedUser.username}`}
|
||||
variant="inverse-primary"
|
||||
>
|
||||
{formatMessage(messages.profile)}
|
||||
</Button>
|
||||
<Button
|
||||
as="a"
|
||||
href={`${getConfig().LMS_BASE_URL}/account/settings`}
|
||||
variant="inverse-primary"
|
||||
>
|
||||
{formatMessage(messages.account)}
|
||||
</Button>
|
||||
{getConfig().ORDER_HISTORY_URL && (
|
||||
<Button
|
||||
as="a"
|
||||
variant="inverse-primary"
|
||||
href={getConfig().ORDER_HISTORY_URL}
|
||||
>
|
||||
{formatMessage(messages.orderHistory)}
|
||||
</Button>
|
||||
)}
|
||||
<Button
|
||||
as="a"
|
||||
href={getConfig().LOGOUT_URL}
|
||||
variant="inverse-primary"
|
||||
>
|
||||
{formatMessage(messages.signOut)}
|
||||
</Button>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
CollapseMenuBody.propTypes = {
|
||||
isOpen: PropTypes.bool.isRequired,
|
||||
};
|
||||
|
||||
export default CollapseMenuBody;
|
||||
@@ -1,48 +0,0 @@
|
||||
import { shallow } from '@edx/react-unit-test-utils';
|
||||
import { AppContext } from '@edx/frontend-platform/react';
|
||||
|
||||
import CollapseMenuBody from './CollapseMenuBody';
|
||||
|
||||
jest.mock('@edx/frontend-platform/react', () => ({
|
||||
AppContext: {
|
||||
authenticatedUser: {
|
||||
username: 'username',
|
||||
},
|
||||
},
|
||||
}));
|
||||
|
||||
jest.mock('hooks', () => ({
|
||||
reduxHooks: {
|
||||
useEnterpriseDashboardData: () => ({
|
||||
url: 'url',
|
||||
}),
|
||||
usePlatformSettingsData: () => ({
|
||||
courseSearchUrl: '/courseSearchUrl',
|
||||
}),
|
||||
},
|
||||
}));
|
||||
|
||||
jest.mock('../hooks', () => ({
|
||||
findCoursesNavDropdownClicked: (url) => jest.fn().mockName(`findCoursesNavDropdownClicked("${url}")`),
|
||||
}));
|
||||
|
||||
describe('CollapseMenuBody', () => {
|
||||
test('render', () => {
|
||||
const wrapper = shallow(<CollapseMenuBody isOpen />);
|
||||
expect(wrapper.snapshot).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('render empty if not open', () => {
|
||||
const wrapper = shallow(<CollapseMenuBody isOpen={false} />);
|
||||
expect(wrapper.snapshot).toMatchSnapshot();
|
||||
expect(wrapper.isEmptyRender()).toBe(true);
|
||||
});
|
||||
|
||||
test('render unauthenticated', () => {
|
||||
const { authenticatedUser } = AppContext;
|
||||
AppContext.authenticatedUser = null;
|
||||
const wrapper = shallow(<CollapseMenuBody isOpen />);
|
||||
expect(wrapper.snapshot).toMatchSnapshot();
|
||||
AppContext.authenticatedUser = authenticatedUser;
|
||||
});
|
||||
});
|
||||
@@ -1,105 +0,0 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`CollapseMenuBody render 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/dashboard/programs"
|
||||
variant="inverse-primary"
|
||||
>
|
||||
Programs
|
||||
</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>
|
||||
`;
|
||||
|
||||
exports[`CollapseMenuBody render empty if not open 1`] = `null`;
|
||||
|
||||
exports[`CollapseMenuBody render unauthenticated 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/dashboard/programs"
|
||||
variant="inverse-primary"
|
||||
>
|
||||
Programs
|
||||
</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>
|
||||
</div>
|
||||
`;
|
||||
@@ -1,48 +0,0 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`CollapsedHeader render nothing if not collapsed 1`] = `false`;
|
||||
|
||||
exports[`CollapsedHeader renders 1`] = `
|
||||
<Fragment>
|
||||
<header
|
||||
className="d-flex shadow-sm align-items-center learner-variant-header"
|
||||
>
|
||||
<IconButton
|
||||
alt="Close"
|
||||
className="p-4"
|
||||
iconAs="Icon"
|
||||
invertColors={true}
|
||||
isActive={true}
|
||||
onClick={[MockFunction toggleIsOpen]}
|
||||
variant="primary"
|
||||
/>
|
||||
<mockConstructor />
|
||||
</header>
|
||||
<mockConstructor
|
||||
isOpen={false}
|
||||
/>
|
||||
</Fragment>
|
||||
`;
|
||||
|
||||
exports[`CollapsedHeader renders with isOpen true 1`] = `
|
||||
<Fragment>
|
||||
<header
|
||||
className="d-flex shadow-sm align-items-center learner-variant-header"
|
||||
>
|
||||
<IconButton
|
||||
alt="Menu"
|
||||
className="p-4"
|
||||
iconAs="Icon"
|
||||
invertColors={true}
|
||||
isActive={true}
|
||||
onClick={[MockFunction toggleIsOpen]}
|
||||
src={[MockFunction icons.Close]}
|
||||
variant="primary"
|
||||
/>
|
||||
<mockConstructor />
|
||||
</header>
|
||||
<mockConstructor
|
||||
isOpen={true}
|
||||
/>
|
||||
</Fragment>
|
||||
`;
|
||||
@@ -1,47 +0,0 @@
|
||||
import React from 'react';
|
||||
|
||||
import { useIntl } from '@edx/frontend-platform/i18n';
|
||||
import { MenuIcon, Close } from '@openedx/paragon/icons';
|
||||
import { IconButton, Icon } from '@openedx/paragon';
|
||||
|
||||
import { useLearnerDashboardHeaderData, useIsCollapsed } from '../hooks';
|
||||
|
||||
import CollapseMenuBody from './CollapseMenuBody';
|
||||
import BrandLogo from '../BrandLogo';
|
||||
|
||||
import messages from '../messages';
|
||||
|
||||
export const CollapsedHeader = () => {
|
||||
const { formatMessage } = useIntl();
|
||||
const isCollapsed = useIsCollapsed();
|
||||
const { isOpen, toggleIsOpen } = useLearnerDashboardHeaderData();
|
||||
|
||||
return (
|
||||
isCollapsed && (
|
||||
<>
|
||||
<header className="d-flex shadow-sm align-items-center learner-variant-header">
|
||||
<IconButton
|
||||
invertColors
|
||||
isActive
|
||||
src={isOpen ? Close : MenuIcon}
|
||||
iconAs={Icon}
|
||||
alt={
|
||||
isOpen
|
||||
? formatMessage(messages.collapseMenuOpenAltText)
|
||||
: formatMessage(messages.collapseMenuClosedAltText)
|
||||
}
|
||||
onClick={toggleIsOpen}
|
||||
variant="primary"
|
||||
className="p-4"
|
||||
/>
|
||||
<BrandLogo />
|
||||
</header>
|
||||
<CollapseMenuBody isOpen={isOpen} />
|
||||
</>
|
||||
)
|
||||
);
|
||||
};
|
||||
|
||||
CollapsedHeader.propTypes = {};
|
||||
|
||||
export default CollapsedHeader;
|
||||
@@ -1,38 +0,0 @@
|
||||
import { shallow } from '@edx/react-unit-test-utils';
|
||||
|
||||
import CollapsedHeader from '.';
|
||||
|
||||
import { useLearnerDashboardHeaderData, useIsCollapsed } from '../hooks';
|
||||
|
||||
jest.mock('../BrandLogo', () => jest.fn(() => 'BrandLogo'));
|
||||
jest.mock('./CollapseMenuBody', () => jest.fn(() => 'CollapseMenuBody'));
|
||||
|
||||
jest.mock('../hooks', () => ({
|
||||
useIsCollapsed: jest.fn(() => true),
|
||||
useLearnerDashboardHeaderData: jest.fn(() => ({
|
||||
isOpen: false,
|
||||
toggleIsOpen: jest.fn().mockName('toggleIsOpen'),
|
||||
})),
|
||||
}));
|
||||
|
||||
describe('CollapsedHeader', () => {
|
||||
it('renders', () => {
|
||||
const wrapper = shallow(<CollapsedHeader />);
|
||||
expect(wrapper.snapshot).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('render nothing if not collapsed', () => {
|
||||
useIsCollapsed.mockReturnValueOnce(false);
|
||||
const wrapper = shallow(<CollapsedHeader />);
|
||||
expect(wrapper.snapshot).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('renders with isOpen true', () => {
|
||||
useLearnerDashboardHeaderData.mockReturnValueOnce({
|
||||
isOpen: true,
|
||||
toggleIsOpen: jest.fn().mockName('toggleIsOpen'),
|
||||
});
|
||||
const wrapper = shallow(<CollapsedHeader />);
|
||||
expect(wrapper.snapshot).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
@@ -1,78 +0,0 @@
|
||||
import React from 'react';
|
||||
|
||||
import { getConfig } from '@edx/frontend-platform';
|
||||
import { useIntl } from '@edx/frontend-platform/i18n';
|
||||
import { AppContext } from '@edx/frontend-platform/react';
|
||||
import { AvatarButton, Dropdown, Badge } from '@openedx/paragon';
|
||||
|
||||
import { reduxHooks } from 'hooks';
|
||||
|
||||
import messages from '../messages';
|
||||
|
||||
export const AuthenticatedUserDropdown = () => {
|
||||
const { formatMessage } = useIntl();
|
||||
const { authenticatedUser } = React.useContext(AppContext);
|
||||
const dashboard = reduxHooks.useEnterpriseDashboardData();
|
||||
|
||||
return (
|
||||
authenticatedUser && (
|
||||
<Dropdown className="user-dropdown pr4">
|
||||
<Dropdown.Toggle
|
||||
as={AvatarButton}
|
||||
src={authenticatedUser.profileImage}
|
||||
id="user"
|
||||
variant="light"
|
||||
className="p-4"
|
||||
>
|
||||
<span data-hj-suppress className="d-md-inline">
|
||||
{authenticatedUser.username}
|
||||
</span>
|
||||
</Dropdown.Toggle>
|
||||
<Dropdown.Menu className="dropdown-menu-right">
|
||||
{ getConfig().ENABLE_EDX_PERSONAL_DASHBOARD && (
|
||||
<>
|
||||
<Dropdown.Header>{formatMessage(messages.dashboardSwitch)}</Dropdown.Header>
|
||||
<Dropdown.Item as="a" href="/edx-dashboard" className="active">
|
||||
{formatMessage(messages.dashboardPersonal)}
|
||||
</Dropdown.Item>
|
||||
{!!dashboard && (
|
||||
<Dropdown.Item as="a" href={dashboard.url} key={dashboard.label}>
|
||||
{dashboard.label} {formatMessage(messages.dashboard)}
|
||||
</Dropdown.Item>
|
||||
)}
|
||||
<Dropdown.Divider />
|
||||
</>
|
||||
)}
|
||||
|
||||
{!dashboard && getConfig().CAREER_LINK_URL && (
|
||||
<Dropdown.Item href={`${getConfig().CAREER_LINK_URL}`}>
|
||||
{formatMessage(messages.career)}
|
||||
<Badge className="px-2 mx-2" variant="warning">
|
||||
{formatMessage(messages.newAlert)}
|
||||
</Badge>
|
||||
</Dropdown.Item>
|
||||
)}
|
||||
<Dropdown.Item href={`${getConfig().ACCOUNT_PROFILE_URL}/u/${authenticatedUser.username}`}>
|
||||
{formatMessage(messages.profile)}
|
||||
</Dropdown.Item>
|
||||
<Dropdown.Item href={getConfig().ACCOUNT_SETTINGS_URL}>
|
||||
{formatMessage(messages.account)}
|
||||
</Dropdown.Item>
|
||||
{getConfig().ORDER_HISTORY_URL && (
|
||||
<Dropdown.Item href={getConfig().ORDER_HISTORY_URL}>
|
||||
{formatMessage(messages.orderHistory)}
|
||||
</Dropdown.Item>
|
||||
)}
|
||||
<Dropdown.Divider />
|
||||
<Dropdown.Item href={getConfig().LOGOUT_URL}>
|
||||
{formatMessage(messages.signOut)}
|
||||
</Dropdown.Item>
|
||||
</Dropdown.Menu>
|
||||
</Dropdown>
|
||||
)
|
||||
);
|
||||
};
|
||||
|
||||
AuthenticatedUserDropdown.propTypes = {};
|
||||
|
||||
export default AuthenticatedUserDropdown;
|
||||
@@ -1,81 +0,0 @@
|
||||
import { shallow } from '@edx/react-unit-test-utils';
|
||||
|
||||
import { reduxHooks } from 'hooks';
|
||||
import { getConfig } from '@edx/frontend-platform';
|
||||
import { AppContext } from '@edx/frontend-platform/react';
|
||||
import { AuthenticatedUserDropdown } from './AuthenticatedUserDropdown';
|
||||
import { useIsCollapsed } from '../hooks';
|
||||
|
||||
jest.mock('@edx/frontend-platform', () => ({
|
||||
getConfig: jest.fn(),
|
||||
}));
|
||||
|
||||
jest.mock('@edx/frontend-platform/react', () => ({
|
||||
AppContext: {
|
||||
authenticatedUser: {
|
||||
profileImage: 'profileImage',
|
||||
username: 'username',
|
||||
},
|
||||
},
|
||||
}));
|
||||
const COURSE_SEARCH_URL = 'test-course-search-url';
|
||||
|
||||
jest.mock('hooks', () => ({
|
||||
reduxHooks: {
|
||||
useEnterpriseDashboardData: jest.fn(),
|
||||
usePlatformSettingsData: jest.fn(() => ({
|
||||
courseSearchUrl: COURSE_SEARCH_URL,
|
||||
})),
|
||||
},
|
||||
}));
|
||||
jest.mock('../hooks', () => ({
|
||||
useIsCollapsed: jest.fn(),
|
||||
findCoursesNavDropdownClicked: (href) => jest.fn().mockName(`findCoursesNavDropdownClicked('${href}')`),
|
||||
}));
|
||||
|
||||
jest.mock('data/services/lms/urls', () => ({
|
||||
baseAppUrl: (url) => (url),
|
||||
programsUrl: 'http://localhost:18000/dashboard/programs',
|
||||
}));
|
||||
|
||||
const config = {
|
||||
ACCOUNT_PROFILE_URL: 'http://account-profile-url.test',
|
||||
ACCOUNT_SETTINGS_URL: 'http://account-settings-url.test',
|
||||
LOGOUT_URL: 'http://logout-url.test',
|
||||
ORDER_HISTORY_URL: 'http://order-history-url.test',
|
||||
SUPPORT_URL: 'http://localhost:18000/support',
|
||||
CAREER_LINK_URL: 'http://localhost:18000/career',
|
||||
LMS_BASE_URL: 'http:/localhost:18000',
|
||||
ENABLE_EDX_PERSONAL_DASHBOARD: true,
|
||||
};
|
||||
getConfig.mockReturnValue(config);
|
||||
|
||||
describe('AuthenticatedUserDropdown', () => {
|
||||
const defaultDashboardData = {
|
||||
label: 'label',
|
||||
url: 'url',
|
||||
};
|
||||
|
||||
describe('snapshots', () => {
|
||||
test('no auth render empty', () => {
|
||||
const { authenticatedUser } = AppContext;
|
||||
AppContext.authenticatedUser = null;
|
||||
const wrapper = shallow(<AuthenticatedUserDropdown />);
|
||||
expect(wrapper.snapshot).toMatchSnapshot();
|
||||
expect(wrapper.isEmptyRender()).toBe(true);
|
||||
AppContext.authenticatedUser = authenticatedUser;
|
||||
});
|
||||
test('with enterprise dashboard', () => {
|
||||
reduxHooks.useEnterpriseDashboardData.mockReturnValueOnce(defaultDashboardData);
|
||||
useIsCollapsed.mockReturnValueOnce(true);
|
||||
const wrapper = shallow(<AuthenticatedUserDropdown />);
|
||||
expect(wrapper.snapshot).toMatchSnapshot();
|
||||
});
|
||||
test('without enterprise dashboard and expanded', () => {
|
||||
reduxHooks.useEnterpriseDashboardData.mockReturnValueOnce(null);
|
||||
useIsCollapsed.mockReturnValueOnce(false);
|
||||
const wrapper = shallow(<AuthenticatedUserDropdown />);
|
||||
expect(wrapper.snapshot).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,139 +0,0 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`AuthenticatedUserDropdown snapshots no auth render empty 1`] = `null`;
|
||||
|
||||
exports[`AuthenticatedUserDropdown snapshots with enterprise dashboard 1`] = `
|
||||
<Dropdown
|
||||
className="user-dropdown pr4"
|
||||
>
|
||||
<Dropdown.Toggle
|
||||
className="p-4"
|
||||
id="user"
|
||||
src="profileImage"
|
||||
variant="light"
|
||||
>
|
||||
<span
|
||||
className="d-md-inline"
|
||||
data-hj-suppress={true}
|
||||
>
|
||||
username
|
||||
</span>
|
||||
</Dropdown.Toggle>
|
||||
<Dropdown.Menu
|
||||
className="dropdown-menu-right"
|
||||
>
|
||||
<Fragment>
|
||||
<Dropdown.Header>
|
||||
SWITCH DASHBOARD
|
||||
</Dropdown.Header>
|
||||
<Dropdown.Item
|
||||
as="a"
|
||||
className="active"
|
||||
href="/edx-dashboard"
|
||||
>
|
||||
Personal
|
||||
</Dropdown.Item>
|
||||
<Dropdown.Item
|
||||
as="a"
|
||||
href="url"
|
||||
key="label"
|
||||
>
|
||||
label
|
||||
|
||||
Dashboard
|
||||
</Dropdown.Item>
|
||||
<Dropdown.Divider />
|
||||
</Fragment>
|
||||
<Dropdown.Item
|
||||
href="http://account-profile-url.test/u/username"
|
||||
>
|
||||
Profile
|
||||
</Dropdown.Item>
|
||||
<Dropdown.Item
|
||||
href="http://account-settings-url.test"
|
||||
>
|
||||
Account
|
||||
</Dropdown.Item>
|
||||
<Dropdown.Item
|
||||
href="http://order-history-url.test"
|
||||
>
|
||||
Order History
|
||||
</Dropdown.Item>
|
||||
<Dropdown.Divider />
|
||||
<Dropdown.Item
|
||||
href="http://logout-url.test"
|
||||
>
|
||||
Sign Out
|
||||
</Dropdown.Item>
|
||||
</Dropdown.Menu>
|
||||
</Dropdown>
|
||||
`;
|
||||
|
||||
exports[`AuthenticatedUserDropdown snapshots without enterprise dashboard and expanded 1`] = `
|
||||
<Dropdown
|
||||
className="user-dropdown pr4"
|
||||
>
|
||||
<Dropdown.Toggle
|
||||
className="p-4"
|
||||
id="user"
|
||||
src="profileImage"
|
||||
variant="light"
|
||||
>
|
||||
<span
|
||||
className="d-md-inline"
|
||||
data-hj-suppress={true}
|
||||
>
|
||||
username
|
||||
</span>
|
||||
</Dropdown.Toggle>
|
||||
<Dropdown.Menu
|
||||
className="dropdown-menu-right"
|
||||
>
|
||||
<Fragment>
|
||||
<Dropdown.Header>
|
||||
SWITCH DASHBOARD
|
||||
</Dropdown.Header>
|
||||
<Dropdown.Item
|
||||
as="a"
|
||||
className="active"
|
||||
href="/edx-dashboard"
|
||||
>
|
||||
Personal
|
||||
</Dropdown.Item>
|
||||
<Dropdown.Divider />
|
||||
</Fragment>
|
||||
<Dropdown.Item
|
||||
href="http://localhost:18000/career"
|
||||
>
|
||||
Career
|
||||
<Badge
|
||||
className="px-2 mx-2"
|
||||
variant="warning"
|
||||
>
|
||||
New
|
||||
</Badge>
|
||||
</Dropdown.Item>
|
||||
<Dropdown.Item
|
||||
href="http://account-profile-url.test/u/username"
|
||||
>
|
||||
Profile
|
||||
</Dropdown.Item>
|
||||
<Dropdown.Item
|
||||
href="http://account-settings-url.test"
|
||||
>
|
||||
Account
|
||||
</Dropdown.Item>
|
||||
<Dropdown.Item
|
||||
href="http://order-history-url.test"
|
||||
>
|
||||
Order History
|
||||
</Dropdown.Item>
|
||||
<Dropdown.Divider />
|
||||
<Dropdown.Item
|
||||
href="http://logout-url.test"
|
||||
>
|
||||
Sign Out
|
||||
</Dropdown.Item>
|
||||
</Dropdown.Menu>
|
||||
</Dropdown>
|
||||
`;
|
||||
@@ -1,52 +0,0 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`ExpandedHeader render 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="programsUrl"
|
||||
variant="inverse-primary"
|
||||
>
|
||||
Programs
|
||||
</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>
|
||||
`;
|
||||
|
||||
exports[`ExpandedHeader render empty if collapsed 1`] = `null`;
|
||||
@@ -1,76 +0,0 @@
|
||||
import React from 'react';
|
||||
|
||||
import { getConfig } from '@edx/frontend-platform';
|
||||
import { useIntl } from '@edx/frontend-platform/i18n';
|
||||
import { Button } from '@openedx/paragon';
|
||||
|
||||
import urls from 'data/services/lms/urls';
|
||||
import { reduxHooks } from 'hooks';
|
||||
|
||||
import AuthenticatedUserDropdown from './AuthenticatedUserDropdown';
|
||||
import { useIsCollapsed, findCoursesNavClicked } from '../hooks';
|
||||
import messages from '../messages';
|
||||
import BrandLogo from '../BrandLogo';
|
||||
|
||||
export const ExpandedHeader = () => {
|
||||
const { formatMessage } = useIntl();
|
||||
const { courseSearchUrl } = reduxHooks.usePlatformSettingsData();
|
||||
const isCollapsed = useIsCollapsed();
|
||||
|
||||
const exploreCoursesClick = findCoursesNavClicked(
|
||||
urls.baseAppUrl(courseSearchUrl),
|
||||
);
|
||||
|
||||
if (isCollapsed) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<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"
|
||||
href="/"
|
||||
variant="inverse-primary"
|
||||
className="p-4 course-link"
|
||||
>
|
||||
{formatMessage(messages.course)}
|
||||
</Button>
|
||||
<Button
|
||||
as="a"
|
||||
href={urls.programsUrl()}
|
||||
variant="inverse-primary"
|
||||
className="p-4"
|
||||
>
|
||||
{formatMessage(messages.program)}
|
||||
</Button>
|
||||
<Button
|
||||
as="a"
|
||||
href={urls.baseAppUrl(courseSearchUrl)}
|
||||
variant="inverse-primary"
|
||||
className="p-4"
|
||||
onClick={exploreCoursesClick}
|
||||
>
|
||||
{formatMessage(messages.discoverNew)}
|
||||
</Button>
|
||||
<span className="flex-grow-1" />
|
||||
<Button
|
||||
as="a"
|
||||
href={getConfig().SUPPORT_URL}
|
||||
variant="inverse-primary"
|
||||
className="p-4"
|
||||
>
|
||||
{formatMessage(messages.help)}
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<AuthenticatedUserDropdown />
|
||||
</header>
|
||||
);
|
||||
};
|
||||
|
||||
ExpandedHeader.propTypes = {};
|
||||
|
||||
export default ExpandedHeader;
|
||||
@@ -1,41 +0,0 @@
|
||||
import { shallow } from '@edx/react-unit-test-utils';
|
||||
|
||||
import ExpandedHeader from '.';
|
||||
|
||||
import { useIsCollapsed } from '../hooks';
|
||||
|
||||
jest.mock('data/services/lms/urls', () => ({
|
||||
programsUrl: () => 'programsUrl',
|
||||
baseAppUrl: url => (`http://localhost:18000${url}`),
|
||||
}));
|
||||
|
||||
jest.mock('hooks', () => ({
|
||||
reduxHooks: {
|
||||
usePlatformSettingsData: () => ({
|
||||
courseSearchUrl: '/courseSearchUrl',
|
||||
}),
|
||||
},
|
||||
}));
|
||||
|
||||
jest.mock('../hooks', () => ({
|
||||
useIsCollapsed: jest.fn(),
|
||||
findCoursesNavClicked: (url) => jest.fn().mockName(`findCoursesNavClicked("${url}")`),
|
||||
}));
|
||||
|
||||
jest.mock('./AuthenticatedUserDropdown', () => 'AuthenticatedUserDropdown');
|
||||
jest.mock('../BrandLogo', () => 'BrandLogo');
|
||||
|
||||
describe('ExpandedHeader', () => {
|
||||
test('render', () => {
|
||||
useIsCollapsed.mockReturnValueOnce(false);
|
||||
const wrapper = shallow(<ExpandedHeader />);
|
||||
expect(wrapper.snapshot).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('render empty if collapsed', () => {
|
||||
useIsCollapsed.mockReturnValueOnce(true);
|
||||
const wrapper = shallow(<ExpandedHeader />);
|
||||
expect(wrapper.snapshot).toMatchSnapshot();
|
||||
expect(wrapper.isEmptyRender()).toBe(true);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,75 @@
|
||||
import { getConfig } from '@edx/frontend-platform';
|
||||
|
||||
import urls from 'data/services/lms/urls';
|
||||
|
||||
import messages from './messages';
|
||||
|
||||
const getLearnerHeaderMenu = (
|
||||
formatMessage,
|
||||
courseSearchUrl,
|
||||
authenticatedUser,
|
||||
exploreCoursesClick,
|
||||
) => ({
|
||||
mainMenu: [
|
||||
{
|
||||
type: 'item',
|
||||
href: '/',
|
||||
content: formatMessage(messages.course),
|
||||
isActive: true,
|
||||
},
|
||||
{
|
||||
type: 'item',
|
||||
href: `${urls.programsUrl()}`,
|
||||
content: formatMessage(messages.program),
|
||||
},
|
||||
{
|
||||
type: 'item',
|
||||
href: `${urls.baseAppUrl(courseSearchUrl)}`,
|
||||
content: formatMessage(messages.discoverNew),
|
||||
onClick: (e) => {
|
||||
exploreCoursesClick(e);
|
||||
},
|
||||
},
|
||||
],
|
||||
secondaryMenu: [
|
||||
{
|
||||
type: 'item',
|
||||
href: `${getConfig().SUPPORT_URL}`,
|
||||
content: formatMessage(messages.help),
|
||||
},
|
||||
],
|
||||
userMenu: [
|
||||
{
|
||||
heading: '',
|
||||
items: [
|
||||
{
|
||||
type: 'item',
|
||||
href: `${getConfig().ACCOUNT_PROFILE_URL}/u/${authenticatedUser?.username}`,
|
||||
content: formatMessage(messages.profile),
|
||||
},
|
||||
{
|
||||
type: 'item',
|
||||
href: `${getConfig().ACCOUNT_SETTINGS_URL}`,
|
||||
content: formatMessage(messages.account),
|
||||
},
|
||||
...(getConfig().ORDER_HISTORY_URL ? [{
|
||||
type: 'item',
|
||||
href: getConfig().ORDER_HISTORY_URL,
|
||||
content: formatMessage(messages.orderHistory),
|
||||
}] : []),
|
||||
],
|
||||
},
|
||||
{
|
||||
heading: '',
|
||||
items: [
|
||||
{
|
||||
type: 'item',
|
||||
href: `${getConfig().LOGOUT_URL}`,
|
||||
content: formatMessage(messages.signOut),
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
export default getLearnerHeaderMenu;
|
||||
@@ -3,8 +3,72 @@
|
||||
exports[`LearnerDashboardHeader render 1`] = `
|
||||
<Fragment>
|
||||
<ConfirmEmailBanner />
|
||||
<CollapsedHeader />
|
||||
<ExpandedHeader />
|
||||
<Header
|
||||
mainMenuItems={
|
||||
[
|
||||
{
|
||||
"content": "Courses",
|
||||
"href": "/",
|
||||
"isActive": true,
|
||||
"type": "item",
|
||||
},
|
||||
{
|
||||
"content": "Programs",
|
||||
"href": "http://localhost:18000/dashboard/programs",
|
||||
"type": "item",
|
||||
},
|
||||
{
|
||||
"content": "Discover New",
|
||||
"href": "http://localhost:18000/course-search-url",
|
||||
"onClick": [Function],
|
||||
"type": "item",
|
||||
},
|
||||
]
|
||||
}
|
||||
secondaryMenuItems={
|
||||
[
|
||||
{
|
||||
"content": "Help",
|
||||
"href": "http://localhost:18000/support",
|
||||
"type": "item",
|
||||
},
|
||||
]
|
||||
}
|
||||
userMenuItems={
|
||||
[
|
||||
{
|
||||
"heading": "",
|
||||
"items": [
|
||||
{
|
||||
"content": "Profile",
|
||||
"href": "http://account-profile-url.test/u/undefined",
|
||||
"type": "item",
|
||||
},
|
||||
{
|
||||
"content": "Account",
|
||||
"href": "http://account-settings-url.test",
|
||||
"type": "item",
|
||||
},
|
||||
{
|
||||
"content": "Order History",
|
||||
"href": "test-url",
|
||||
"type": "item",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
"heading": "",
|
||||
"items": [
|
||||
{
|
||||
"content": "Sign Out",
|
||||
"href": "http://localhost:18000/logout",
|
||||
"type": "item",
|
||||
},
|
||||
],
|
||||
},
|
||||
]
|
||||
}
|
||||
/>
|
||||
<MasqueradeBar />
|
||||
</Fragment>
|
||||
`;
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
import React from 'react';
|
||||
import { useWindowSize, breakpoints } from '@openedx/paragon';
|
||||
import { useIntl } from '@edx/frontend-platform/i18n';
|
||||
import track from 'tracking';
|
||||
import { StrictDict } from 'utils';
|
||||
import { linkNames } from 'tracking/constants';
|
||||
|
||||
import getLearnerHeaderMenu from './LearnerDashboardMenu';
|
||||
|
||||
import * as module from './hooks';
|
||||
|
||||
export const state = StrictDict({
|
||||
@@ -24,6 +27,13 @@ export const findCoursesNavDropdownClicked = (href) => track.findCourses.findCou
|
||||
linkName: linkNames.learnerHomeNavDropdownExplore,
|
||||
});
|
||||
|
||||
export const useLearnerDashboardHeaderMenu = ({
|
||||
courseSearchUrl, authenticatedUser, exploreCoursesClick,
|
||||
}) => {
|
||||
const { formatMessage } = useIntl();
|
||||
return getLearnerHeaderMenu(formatMessage, courseSearchUrl, authenticatedUser, exploreCoursesClick);
|
||||
};
|
||||
|
||||
export const useLearnerDashboardHeaderData = () => {
|
||||
const [isOpen, setIsOpen] = module.state.isOpen(false);
|
||||
const toggleIsOpen = () => setIsOpen(!isOpen);
|
||||
@@ -39,4 +49,5 @@ export default {
|
||||
findCoursesNavClicked,
|
||||
findCoursesNavDropdownClicked,
|
||||
useLearnerDashboardHeaderData,
|
||||
useLearnerDashboardHeaderMenu,
|
||||
};
|
||||
|
||||
@@ -13,6 +13,7 @@ const {
|
||||
findCoursesNavClicked,
|
||||
findCoursesNavDropdownClicked,
|
||||
useLearnerDashboardHeaderData,
|
||||
useLearnerDashboardHeaderMenu,
|
||||
} = hooks;
|
||||
|
||||
jest.mock('tracking', () => ({
|
||||
@@ -48,6 +49,17 @@ describe('LearnerDashboardHeader hooks', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('getLearnerDashboardHeaderMenu', () => {
|
||||
test('calls header menu data hook', () => {
|
||||
const courseSearchUrl = '/courses';
|
||||
const authenticatedUser = {
|
||||
username: 'test',
|
||||
};
|
||||
const learnerHomeHeaderMenu = useLearnerDashboardHeaderMenu({ courseSearchUrl, authenticatedUser });
|
||||
expect(learnerHomeHeaderMenu.mainMenu.length).toBe(3);
|
||||
});
|
||||
});
|
||||
|
||||
describe('findCoursesNavDropdownClicked', () => {
|
||||
test('calls tracking with dropdown link name', () => {
|
||||
findCoursesNavDropdownClicked(url);
|
||||
|
||||
@@ -1,21 +1,43 @@
|
||||
import React from 'react';
|
||||
|
||||
import MasqueradeBar from 'containers/MasqueradeBar';
|
||||
import { AppContext } from '@edx/frontend-platform/react';
|
||||
import Header from '@edx/frontend-component-header';
|
||||
import { reduxHooks } from 'hooks';
|
||||
import urls from 'data/services/lms/urls';
|
||||
|
||||
import ConfirmEmailBanner from './ConfirmEmailBanner';
|
||||
|
||||
import CollapsedHeader from './CollapsedHeader';
|
||||
import ExpandedHeader from './ExpandedHeader';
|
||||
import { useLearnerDashboardHeaderMenu, findCoursesNavClicked } from './hooks';
|
||||
|
||||
import './index.scss';
|
||||
|
||||
export const LearnerDashboardHeader = () => (
|
||||
<>
|
||||
<ConfirmEmailBanner />
|
||||
<CollapsedHeader />
|
||||
<ExpandedHeader />
|
||||
<MasqueradeBar />
|
||||
</>
|
||||
);
|
||||
export const LearnerDashboardHeader = () => {
|
||||
const { authenticatedUser } = React.useContext(AppContext);
|
||||
const { courseSearchUrl } = reduxHooks.usePlatformSettingsData();
|
||||
|
||||
const exploreCoursesClick = () => {
|
||||
findCoursesNavClicked(urls.baseAppUrl(courseSearchUrl));
|
||||
};
|
||||
|
||||
const learnerHomeHeaderMenu = useLearnerDashboardHeaderMenu({
|
||||
courseSearchUrl,
|
||||
authenticatedUser,
|
||||
exploreCoursesClick,
|
||||
});
|
||||
|
||||
return (
|
||||
<>
|
||||
<ConfirmEmailBanner />
|
||||
<Header
|
||||
mainMenuItems={learnerHomeHeaderMenu.mainMenu}
|
||||
secondaryMenuItems={learnerHomeHeaderMenu.secondaryMenu}
|
||||
userMenuItems={learnerHomeHeaderMenu.userMenu}
|
||||
/>
|
||||
<MasqueradeBar />
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
LearnerDashboardHeader.propTypes = {};
|
||||
|
||||
|
||||
@@ -1,18 +1,35 @@
|
||||
import { mergeConfig } from '@edx/frontend-platform';
|
||||
import { shallow } from '@edx/react-unit-test-utils';
|
||||
import LearnerDashboardHeader from '.';
|
||||
import Header from '@edx/frontend-component-header';
|
||||
|
||||
import urls from 'data/services/lms/urls';
|
||||
import LearnerDashboardHeader from '.';
|
||||
import { findCoursesNavClicked } from './hooks';
|
||||
|
||||
jest.mock('hooks', () => ({
|
||||
reduxHooks: {
|
||||
usePlatformSettingsData: jest.fn(() => ({
|
||||
courseSearchUrl: '/course-search-url',
|
||||
})),
|
||||
},
|
||||
}));
|
||||
jest.mock('./hooks', () => ({
|
||||
...jest.requireActual('./hooks'),
|
||||
findCoursesNavClicked: jest.fn(),
|
||||
}));
|
||||
jest.mock('containers/MasqueradeBar', () => 'MasqueradeBar');
|
||||
jest.mock('./CollapsedHeader', () => 'CollapsedHeader');
|
||||
jest.mock('./ConfirmEmailBanner', () => 'ConfirmEmailBanner');
|
||||
jest.mock('./ExpandedHeader', () => 'ExpandedHeader');
|
||||
jest.mock('@edx/frontend-component-header', () => 'Header');
|
||||
|
||||
describe('LearnerDashboardHeader', () => {
|
||||
test('render', () => {
|
||||
mergeConfig({ ORDER_HISTORY_URL: 'test-url' });
|
||||
const wrapper = shallow(<LearnerDashboardHeader />);
|
||||
expect(wrapper.snapshot).toMatchSnapshot();
|
||||
expect(wrapper.instance.findByType('ConfirmEmailBanner')).toHaveLength(1);
|
||||
expect(wrapper.instance.findByType('MasqueradeBar')).toHaveLength(1);
|
||||
expect(wrapper.instance.findByType('CollapsedHeader')).toHaveLength(1);
|
||||
expect(wrapper.instance.findByType('ExpandedHeader')).toHaveLength(1);
|
||||
expect(wrapper.instance.findByType(Header)).toHaveLength(1);
|
||||
wrapper.instance.findByType(Header)[0].props.mainMenuItems[2].onClick();
|
||||
expect(findCoursesNavClicked).toHaveBeenCalledWith(urls.baseAppUrl('/course-search-url'));
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user