Add enterprise portal links to user dropdown menu and dashboard alerts. (#21833)
This commit is contained in:
committed by
Douglas Hall
parent
e05f244bba
commit
6e2887f851
11
lms/static/js/apiClient/.eslintrc.js
Normal file
11
lms/static/js/apiClient/.eslintrc.js
Normal file
@@ -0,0 +1,11 @@
|
||||
module.exports = {
|
||||
extends: 'eslint-config-edx',
|
||||
root: true,
|
||||
settings: {
|
||||
'import/resolver': {
|
||||
webpack: {
|
||||
config: 'webpack.dev.config.js',
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
16
lms/static/js/apiClient/index.js
Normal file
16
lms/static/js/apiClient/index.js
Normal file
@@ -0,0 +1,16 @@
|
||||
import { getAuthenticatedAPIClient } from '@edx/frontend-auth';
|
||||
import { NewRelicLoggingService } from '@edx/frontend-logging';
|
||||
|
||||
const apiClient = getAuthenticatedAPIClient({
|
||||
appBaseUrl: process.env.LMS_ROOT_URL,
|
||||
authBaseUrl: process.env.LMS_ROOT_URL,
|
||||
loginUrl: `${process.env.LMS_ROOT_URL}/login`,
|
||||
logoutUrl: `${process.env.LMS_ROOT_URL}/logout`,
|
||||
csrfTokenApiPath: '/csrf/api/v1/token',
|
||||
refreshAccessTokenEndpoint: `${process.env.LMS_ROOT_URL}/login_refresh`,
|
||||
accessTokenCookieName: process.env.JWT_AUTH_COOKIE_HEADER_PAYLOAD,
|
||||
userInfoCookieName: process.env.EDXMKTG_USER_INFO_COOKIE_NAME,
|
||||
loggingService: NewRelicLoggingService,
|
||||
});
|
||||
|
||||
export default apiClient;
|
||||
11
lms/static/js/custom_user_menu_links/.eslintrc.js
Normal file
11
lms/static/js/custom_user_menu_links/.eslintrc.js
Normal file
@@ -0,0 +1,11 @@
|
||||
module.exports = {
|
||||
extends: 'eslint-config-edx',
|
||||
root: true,
|
||||
settings: {
|
||||
'import/resolver': {
|
||||
webpack: {
|
||||
config: 'webpack.dev.config.js',
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
20
lms/static/js/custom_user_menu_links/CustomUserMenuLinks.js
Normal file
20
lms/static/js/custom_user_menu_links/CustomUserMenuLinks.js
Normal file
@@ -0,0 +1,20 @@
|
||||
import { getLearnerPortalLinks } from '@edx/frontend-enterprise';
|
||||
|
||||
import apiClient from '../apiClient';
|
||||
|
||||
function CustomUserMenuLinks() {
|
||||
// Inject enterprise learner portal links
|
||||
getLearnerPortalLinks(apiClient).then((learnerPortalLinks) => {
|
||||
const $dashboardLink = $('#user-menu .dashboard');
|
||||
const classNames = 'mobile-nav-item dropdown-item dropdown-nav-item';
|
||||
for (let i = 0; i < learnerPortalLinks.length; i += 1) {
|
||||
const link = learnerPortalLinks[i];
|
||||
|
||||
$dashboardLink.after( // xss-lint: disable=javascript-jquery-insertion
|
||||
`<div class="${classNames}"><a href="${link.url}" role="menuitem">${link.title} Dashboard</a></div>`,
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export { CustomUserMenuLinks }; // eslint-disable-line import/prefer-default-export
|
||||
@@ -0,0 +1,78 @@
|
||||
import React, { Component } from 'react';
|
||||
import { getLearnerPortalLinks } from '@edx/frontend-enterprise';
|
||||
import { StatusAlert } from '@edx/paragon';
|
||||
|
||||
import apiClient from '../apiClient';
|
||||
|
||||
const LOCAL_STORAGE_KEY = 'has-viewed-enterprise-learner-portal-banner';
|
||||
|
||||
function getAlertHtml(learnerPortalLinks) {
|
||||
let html = '';
|
||||
for (let i = 0; i < learnerPortalLinks.length; i += 1) {
|
||||
const link = learnerPortalLinks[i];
|
||||
html += `<div>
|
||||
${link.title} has a dedicated page where you can see all of your sponsored courses.
|
||||
Go to <a href="${link.url}">your learner portal</a>.
|
||||
</div>`;
|
||||
}
|
||||
return html;
|
||||
}
|
||||
|
||||
function setViewedBanner() {
|
||||
window.localStorage.setItem(LOCAL_STORAGE_KEY, true);
|
||||
}
|
||||
|
||||
function hasViewedBanner() {
|
||||
window.localStorage.getItem(LOCAL_STORAGE_KEY);
|
||||
}
|
||||
|
||||
class EnterpriseLearnerPortalBanner extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.onClose = this.onClose.bind(this);
|
||||
|
||||
this.state = {
|
||||
open: false,
|
||||
alertHtml: '',
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
if (!hasViewedBanner()) {
|
||||
getLearnerPortalLinks(apiClient).then((learnerPortalLinks) => {
|
||||
this.setState({
|
||||
open: true,
|
||||
alertHtml: getAlertHtml(learnerPortalLinks),
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
onClose() {
|
||||
this.setState({ open: false });
|
||||
setViewedBanner();
|
||||
}
|
||||
|
||||
render() {
|
||||
const { alertHtml, open } = this.state;
|
||||
|
||||
if (open) {
|
||||
return (
|
||||
<div className="edx-enterprise-learner-portal-banner-wrapper">
|
||||
<StatusAlert
|
||||
className={['edx-enterprise-learner-portal-banner']}
|
||||
open={open}
|
||||
// eslint-disable-next-line react/no-danger
|
||||
dialog={(<span dangerouslySetInnerHTML={{ __html: alertHtml }} />)}
|
||||
onClose={this.onClose}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
export { EnterpriseLearnerPortalBanner }; // eslint-disable-line import/prefer-default-export
|
||||
@@ -73,6 +73,7 @@
|
||||
@import 'features/_unsupported-browser-alert';
|
||||
@import 'features/content-type-gating';
|
||||
@import 'features/course-duration-limits';
|
||||
@import 'features/enterprise-learner-portal-banner';
|
||||
|
||||
// search
|
||||
@import 'search/search';
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
@import 'features/course-sock';
|
||||
@import 'features/course-upgrade-message';
|
||||
@import 'features/content-type-gating';
|
||||
@import 'features/enterprise-learner-portal-banner';
|
||||
|
||||
|
||||
// Responsive Design
|
||||
|
||||
@@ -25,6 +25,7 @@ $static-path: '../..';
|
||||
@import 'features/course-sock';
|
||||
@import 'features/course-upgrade-message';
|
||||
@import 'features/course-duration-limits';
|
||||
@import 'features/enterprise-learner-portal-banner';
|
||||
|
||||
|
||||
// Individual Pages
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
$enterprise-learner-portal-banner-background-color: #d9edf7 !default;
|
||||
$enterprise-learner-portal-banner-text-color: #4e4e4e !default;
|
||||
$enterprise-learner-portal-banner-cta-base: #0075b4 !default;
|
||||
$enterprise-learner-portal-banner-cta-hover: #075683 !default;
|
||||
|
||||
.edx-enterprise-learner-portal-banner-wrapper {
|
||||
background: $enterprise-learner-portal-banner-background-color;
|
||||
box-sizing: border-box;
|
||||
|
||||
/** Base Styles - start **/
|
||||
text-align: left;
|
||||
line-height: 1.5;
|
||||
font: {
|
||||
family: 'Open Sans', "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
size: 1rem;
|
||||
weight: 400;
|
||||
}
|
||||
|
||||
.alert {
|
||||
position: relative;
|
||||
padding: 0.75rem 1.25rem;
|
||||
}
|
||||
|
||||
.alert-dismissible {
|
||||
.close {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
padding: 0.75rem 1.25rem;
|
||||
background: transparent;
|
||||
border: 0;
|
||||
text-shadow: 0 1px 0 #fff;
|
||||
opacity: 0.5;
|
||||
float: right;
|
||||
line-height: 1;
|
||||
font: {
|
||||
size: 1.5rem;
|
||||
weight: 700;
|
||||
}
|
||||
}
|
||||
|
||||
.btn {
|
||||
display: inline-block;
|
||||
text-align: center;
|
||||
white-space: nowrap;
|
||||
vertical-align: middle;
|
||||
box-shadow: none;
|
||||
}
|
||||
}
|
||||
/** Base Styles - end **/
|
||||
|
||||
|
||||
.edx-enterprise-learner-portal-banner {
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
max-width: 1200px;
|
||||
min-width: 0;
|
||||
margin: 0 auto;
|
||||
background: inherit;
|
||||
border: none;
|
||||
|
||||
.policy-link {
|
||||
color: $enterprise-learner-portal-banner-cta-base;
|
||||
text-decoration: underline;
|
||||
|
||||
&:focus,
|
||||
&:hover {
|
||||
color: $enterprise-learner-portal-banner-cta-hover;
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
|
||||
.alert-dialog {
|
||||
margin-right: 30px;
|
||||
color: $enterprise-learner-portal-banner-text-color;
|
||||
}
|
||||
|
||||
.btn.close {
|
||||
color: $enterprise-learner-portal-banner-cta-base;
|
||||
|
||||
&:focus,
|
||||
&:hover {
|
||||
color: $enterprise-learner-portal-banner-cta-hover;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
## mako
|
||||
<%page expression_filter="h"/>
|
||||
<%namespace name='static' file='static_content.html'/>
|
||||
<%namespace name='static' file='../static_content.html'/>
|
||||
|
||||
<%!
|
||||
from django.conf import settings
|
||||
@@ -22,6 +22,12 @@ resume_block = retrieve_last_sitewide_block_completed(self.real_user)
|
||||
displayname = get_enterprise_learner_generic_name(request) or username
|
||||
%>
|
||||
|
||||
<%static:webpack entry="CustomUserMenuLinks">
|
||||
$(document).ready(function() {
|
||||
CustomUserMenuLinks();
|
||||
});
|
||||
</%static:webpack>
|
||||
|
||||
<div class="nav-item hidden-mobile">
|
||||
<a href="${reverse('dashboard')}" class="menu-title">
|
||||
<img class="user-image-frame" src="${profile_image_url}" alt="">
|
||||
@@ -37,7 +43,7 @@ displayname = get_enterprise_learner_generic_name(request) or username
|
||||
% if resume_block:
|
||||
<div class="mobile-nav-item dropdown-item dropdown-nav-item"><a href="${resume_block}" role="menuitem">${_("Resume your last course")}</a></div>
|
||||
% endif
|
||||
<div class="mobile-nav-item dropdown-item dropdown-nav-item"><a href="${reverse('dashboard')}" role="menuitem">${_("Dashboard")}</a></div>
|
||||
<div class="mobile-nav-item dropdown-item dropdown-nav-item dashboard"><a href="${reverse('dashboard')}" role="menuitem">${_("Dashboard")}</a></div>
|
||||
<div class="mobile-nav-item dropdown-item dropdown-nav-item"><a href="${reverse('learner_profile', kwargs={'username': username})}" role="menuitem">${_("Profile")}</a></div>
|
||||
<div class="mobile-nav-item dropdown-item dropdown-nav-item"><a href="${reverse('account_settings')}" role="menuitem">${_("Account")}</a></div>
|
||||
% if should_redirect_to_order_history_microfrontend():
|
||||
|
||||
Reference in New Issue
Block a user