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():
|
||||
|
||||
174
package-lock.json
generated
174
package-lock.json
generated
@@ -66,6 +66,59 @@
|
||||
"resolved": "https://registry.npmjs.org/@edx/edx-proctoring/-/edx-proctoring-1.5.0.tgz",
|
||||
"integrity": "sha512-RiNjAgh8ZMX0D5gfN2R09a0RBs/R/Blfs/DiqhLmvCSvyCoeMDGANrDDQXv1w5blxxSJbz8a2awSZkwpv6gWNQ=="
|
||||
},
|
||||
"@edx/frontend-auth": {
|
||||
"version": "6.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@edx/frontend-auth/-/frontend-auth-6.0.2.tgz",
|
||||
"integrity": "sha512-37qMrdzwe02PzLQMF4q2ov7POGM3laWtouHK8BiLL7Q2DhFBxe0IULWAZiEJGvSVBEpMDFfcG+J1s33NiIpUfA==",
|
||||
"requires": {
|
||||
"@edx/frontend-logging": "2.1.0",
|
||||
"axios": "0.18.1",
|
||||
"camelcase-keys": "5.2.0",
|
||||
"jwt-decode": "2.2.0",
|
||||
"pubsub-js": "1.7.0",
|
||||
"snakecase-keys": "2.1.0",
|
||||
"universal-cookie": "3.1.0",
|
||||
"url-parse": "1.4.7"
|
||||
},
|
||||
"dependencies": {
|
||||
"@edx/frontend-logging": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@edx/frontend-logging/-/frontend-logging-2.1.0.tgz",
|
||||
"integrity": "sha512-IN0Bgh0/1Ax3TMPfZztqzdJchW4B5Px9PT4V9uu6TMj2Cj8el1CV3jrSA4Idg8C3CAkFZ/EHjmaFVCxgJ9aXVA=="
|
||||
},
|
||||
"camelcase": {
|
||||
"version": "5.3.1",
|
||||
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
|
||||
"integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg=="
|
||||
},
|
||||
"camelcase-keys": {
|
||||
"version": "5.2.0",
|
||||
"resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-5.2.0.tgz",
|
||||
"integrity": "sha512-mSM/OQKD1HS5Ll2AXxeaHSdqCGC/QQ8IrgTbKYA/rxnC36thBKysfIr9+OVBWuW17jyZF4swHkjtglawgBmVFg==",
|
||||
"requires": {
|
||||
"camelcase": "5.3.1",
|
||||
"map-obj": "3.1.0",
|
||||
"quick-lru": "1.1.0"
|
||||
}
|
||||
},
|
||||
"map-obj": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/map-obj/-/map-obj-3.1.0.tgz",
|
||||
"integrity": "sha512-Xg1iyYz/+iIW6YoMldux47H/e5QZyDSB41Kb0ev+YYHh3FJnyyzY0vTk/WbVeWcCvdXd70cOriUBmhP8alUFBA=="
|
||||
},
|
||||
"universal-cookie": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/universal-cookie/-/universal-cookie-3.1.0.tgz",
|
||||
"integrity": "sha512-sP6WuFgqIUro7ikgI2ndrsw9Ro+YvVBe5O9cQfWnjTicpLaSMUEUUDjQF8m8utzWF2ONl7tRkcZd7v4n6NnzjQ==",
|
||||
"requires": {
|
||||
"@types/cookie": "0.3.3",
|
||||
"@types/object-assign": "4.0.30",
|
||||
"cookie": "0.3.1",
|
||||
"object-assign": "4.1.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"@edx/frontend-component-cookie-policy-banner": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@edx/frontend-component-cookie-policy-banner/-/frontend-component-cookie-policy-banner-1.0.0.tgz",
|
||||
@@ -137,6 +190,16 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"@edx/frontend-enterprise": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@edx/frontend-enterprise/-/frontend-enterprise-1.0.2.tgz",
|
||||
"integrity": "sha512-Xv5R8qpAmg4qr2B4EJpCJrBbgNISPoQbGjK31cS9wWz8u28lhAmsgltKaRKqTD92DPi+uGam3feJ2QhAwLqJqQ=="
|
||||
},
|
||||
"@edx/frontend-logging": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@edx/frontend-logging/-/frontend-logging-3.0.1.tgz",
|
||||
"integrity": "sha512-kRDsPbTUxNfZdnC4KN5HratS/7bkCYv/gyvUnBcuPbiONXwSuriNIVAKCepldvhg1DTwLqQMXh+Qw6vo2r048A=="
|
||||
},
|
||||
"@edx/mockprock": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@edx/mockprock/-/mockprock-1.0.2.tgz",
|
||||
@@ -272,12 +335,22 @@
|
||||
"resolved": "https://registry.npmjs.org/@sambego/storybook-styles/-/storybook-styles-1.0.0.tgz",
|
||||
"integrity": "sha512-n0SqZwDewUDRaStEcoNMiYy9qovaLVStsh4Gb2dc2LLiG3IIK0UXdeR1N7puVuRihJq/192uOyGPCjZ/NAteuA=="
|
||||
},
|
||||
"@types/cookie": {
|
||||
"version": "0.3.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.3.3.tgz",
|
||||
"integrity": "sha512-LKVP3cgXBT9RYj+t+9FDKwS5tdI+rPBXaNSkma7hvqy35lc7mAokC2zsqWJH0LaqIt3B962nuYI77hsJoT1gow=="
|
||||
},
|
||||
"@types/node": {
|
||||
"version": "10.5.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-10.5.2.tgz",
|
||||
"integrity": "sha512-m9zXmifkZsMHZBOyxZWilMwmTlpC8x5Ty360JKTiXvlXZfBWYpsg9ZZvP/Ye+iZUh+Q+MxDLjItVTWIsfwz+8Q==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/object-assign": {
|
||||
"version": "4.0.30",
|
||||
"resolved": "https://registry.npmjs.org/@types/object-assign/-/object-assign-4.0.30.tgz",
|
||||
"integrity": "sha1-iUk3HVqZ9Dge4PHfCpt6GH4H5lI="
|
||||
},
|
||||
"abab": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/abab/-/abab-1.0.4.tgz",
|
||||
@@ -905,6 +978,22 @@
|
||||
"resolved": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz",
|
||||
"integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4="
|
||||
},
|
||||
"axios": {
|
||||
"version": "0.18.1",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-0.18.1.tgz",
|
||||
"integrity": "sha512-0BfJq4NSfQXd+SkFdrvFbG7addhYSBA2mQwISr46pD6E5iqkWg02RAs8vyTT/j0RTnoYmeXauBuSv1qKwR179g==",
|
||||
"requires": {
|
||||
"follow-redirects": "1.5.10",
|
||||
"is-buffer": "2.0.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"is-buffer": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz",
|
||||
"integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"axobject-query": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-0.1.0.tgz",
|
||||
@@ -5203,6 +5292,24 @@
|
||||
"resolved": "https://registry.npmjs.org/flatten/-/flatten-1.0.2.tgz",
|
||||
"integrity": "sha1-2uRqnXj74lKSJYzB54CkHZXAN4I="
|
||||
},
|
||||
"follow-redirects": {
|
||||
"version": "1.5.10",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz",
|
||||
"integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==",
|
||||
"requires": {
|
||||
"debug": "3.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"debug": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
|
||||
"integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
|
||||
"requires": {
|
||||
"ms": "2.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"font-awesome": {
|
||||
"version": "4.7.0",
|
||||
"resolved": "https://registry.npmjs.org/font-awesome/-/font-awesome-4.7.0.tgz",
|
||||
@@ -7837,6 +7944,11 @@
|
||||
"integrity": "sha1-OGchPo3Xm/Ho8jAMDPwe+xgsDfE=",
|
||||
"dev": true
|
||||
},
|
||||
"jwt-decode": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-2.2.0.tgz",
|
||||
"integrity": "sha1-fYa9VmefWM5qhHBKZX3TkruoGnk="
|
||||
},
|
||||
"karma": {
|
||||
"version": "0.13.22",
|
||||
"resolved": "https://registry.npmjs.org/karma/-/karma-0.13.22.tgz",
|
||||
@@ -10491,6 +10603,11 @@
|
||||
"randombytes": "2.0.6"
|
||||
}
|
||||
},
|
||||
"pubsub-js": {
|
||||
"version": "1.7.0",
|
||||
"resolved": "https://registry.npmjs.org/pubsub-js/-/pubsub-js-1.7.0.tgz",
|
||||
"integrity": "sha512-Pb68P9qFZxnvDipHMuj9oT1FoIgBcXJ9C9eWdHCLZAnulaUoJ3+Y87RhGMYilWpun6DMWVmvK70T4RP4drZMSA=="
|
||||
},
|
||||
"punycode": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
|
||||
@@ -10525,11 +10642,15 @@
|
||||
"resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz",
|
||||
"integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM="
|
||||
},
|
||||
"querystringify": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.1.1.tgz",
|
||||
"integrity": "sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA=="
|
||||
},
|
||||
"quick-lru": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-1.1.0.tgz",
|
||||
"integrity": "sha1-Q2CxfGETatOAeDl/8RQW4Ybc+7g=",
|
||||
"dev": true
|
||||
"integrity": "sha1-Q2CxfGETatOAeDl/8RQW4Ybc+7g="
|
||||
},
|
||||
"raf": {
|
||||
"version": "3.4.0",
|
||||
@@ -11295,8 +11416,7 @@
|
||||
"requires-port": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
|
||||
"integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=",
|
||||
"dev": true
|
||||
"integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8="
|
||||
},
|
||||
"reselect": {
|
||||
"version": "3.0.1",
|
||||
@@ -12185,6 +12305,22 @@
|
||||
"resolved": "https://registry.npmjs.org/slick-carousel/-/slick-carousel-1.8.1.tgz",
|
||||
"integrity": "sha512-XB9Ftrf2EEKfzoQXt3Nitrt/IPbT+f1fgqBdoxO3W/+JYvtEOW6EgxnWfr9GH6nmULv7Y2tPmEX3koxThVmebA=="
|
||||
},
|
||||
"snakecase-keys": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/snakecase-keys/-/snakecase-keys-2.1.0.tgz",
|
||||
"integrity": "sha512-oQSiCIgNCwixBf8Kxgv0SPo67zQSutIEymAk/dkgcdZEOMPvGMGPua/WwYGPG4LLHArGGews3CB3zEEfqlMk2g==",
|
||||
"requires": {
|
||||
"map-obj": "3.0.0",
|
||||
"to-snake-case": "1.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"map-obj": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/map-obj/-/map-obj-3.0.0.tgz",
|
||||
"integrity": "sha512-Ot+2wruG8WqTbJngDxz0Ifm03y2pO4iL+brq/l+yEkGjUza03BnMQqX2XT//Jls8MOOl2VTHviAoLX+/nq/HXw=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"snapdragon": {
|
||||
"version": "0.8.2",
|
||||
"resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz",
|
||||
@@ -13893,6 +14029,11 @@
|
||||
"resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz",
|
||||
"integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc="
|
||||
},
|
||||
"to-no-case": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/to-no-case/-/to-no-case-1.0.2.tgz",
|
||||
"integrity": "sha1-xyKQcWTvaxeBMsjmmTAhLRtKoWo="
|
||||
},
|
||||
"to-object-path": {
|
||||
"version": "0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz",
|
||||
@@ -13935,6 +14076,22 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"to-snake-case": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/to-snake-case/-/to-snake-case-1.0.0.tgz",
|
||||
"integrity": "sha1-znRpE4l5RgGah+Yu366upMYIq4w=",
|
||||
"requires": {
|
||||
"to-space-case": "1.0.0"
|
||||
}
|
||||
},
|
||||
"to-space-case": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/to-space-case/-/to-space-case-1.0.0.tgz",
|
||||
"integrity": "sha1-sFLar7Gysp3HcM6gFj5ewOvJ/Bc=",
|
||||
"requires": {
|
||||
"to-no-case": "1.0.2"
|
||||
}
|
||||
},
|
||||
"toggle-selection": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz",
|
||||
@@ -14356,6 +14513,15 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"url-parse": {
|
||||
"version": "1.4.7",
|
||||
"resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.7.tgz",
|
||||
"integrity": "sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg==",
|
||||
"requires": {
|
||||
"querystringify": "2.1.1",
|
||||
"requires-port": "1.0.0"
|
||||
}
|
||||
},
|
||||
"url-toolkit": {
|
||||
"version": "2.1.4",
|
||||
"resolved": "https://registry.npmjs.org/url-toolkit/-/url-toolkit-2.1.4.tgz",
|
||||
|
||||
@@ -5,6 +5,9 @@
|
||||
"@edx/frontend-component-cookie-policy-banner": "1.0.0",
|
||||
"@edx/edx-bootstrap": "1.0.4",
|
||||
"@edx/edx-proctoring": "^1.5.0",
|
||||
"@edx/frontend-auth": "^6.0.2",
|
||||
"@edx/frontend-enterprise": "^1.0.2",
|
||||
"@edx/frontend-logging": "^3.0.1",
|
||||
"@edx/paragon": "2.6.4",
|
||||
"@edx/studio-frontend": "1.16.17",
|
||||
"babel-core": "6.26.0",
|
||||
|
||||
@@ -767,12 +767,28 @@ def webpack(options):
|
||||
settings = getattr(options, 'settings', Env.DEVSTACK_SETTINGS)
|
||||
static_root_lms = Env.get_django_setting("STATIC_ROOT", "lms", settings=settings)
|
||||
static_root_cms = Env.get_django_setting("STATIC_ROOT", "cms", settings=settings)
|
||||
config_path = Env.get_django_setting("WEBPACK_CONFIG_PATH", "lms", settings=settings)
|
||||
environment = u'NODE_ENV={node_env} STATIC_ROOT_LMS={static_root_lms} STATIC_ROOT_CMS={static_root_cms}'.format(
|
||||
node_env="development" if config_path == 'webpack.dev.config.js' else "production",
|
||||
static_root_lms=static_root_lms,
|
||||
static_root_cms=static_root_cms
|
||||
lms_root_url = Env.get_django_setting("LMS_ROOT_URL", "lms", settings=settings)
|
||||
jwt_auth_cookie_header_payload_name = Env.get_nested_django_setting(
|
||||
"JWT_AUTH",
|
||||
"JWT_AUTH_COOKIE_HEADER_PAYLOAD",
|
||||
"lms",
|
||||
settings=settings,
|
||||
)
|
||||
user_info_cookie_name = Env.get_django_setting("EDXMKTG_USER_INFO_COOKIE_NAME", "lms", settings=settings)
|
||||
config_path = Env.get_django_setting("WEBPACK_CONFIG_PATH", "lms", settings=settings)
|
||||
environment = u"NODE_ENV={node_env} " \
|
||||
u"STATIC_ROOT_LMS={static_root_lms} " \
|
||||
u"STATIC_ROOT_CMS={static_root_cms} " \
|
||||
u"LMS_ROOT_URL={lms_root_url} " \
|
||||
u"JWT_AUTH_COOKIE_HEADER_PAYLOAD={jwt_auth_cookie_header_payload_name} " \
|
||||
u"EDXMKTG_USER_INFO_COOKIE_NAME={user_info_cookie_name}".format(
|
||||
node_env="development" if config_path == 'webpack.dev.config.js' else "production",
|
||||
static_root_lms=static_root_lms,
|
||||
static_root_cms=static_root_cms,
|
||||
lms_root_url=lms_root_url,
|
||||
jwt_auth_cookie_header_payload_name=jwt_auth_cookie_header_payload_name,
|
||||
user_info_cookie_name=user_info_cookie_name,
|
||||
)
|
||||
sh(
|
||||
cmd(
|
||||
u'{environment} $(npm bin)/webpack --config={config_path}'.format(
|
||||
|
||||
@@ -46,10 +46,15 @@ EXPECTED_INDEX_COURSE_COMMAND = (
|
||||
EXPECTED_PRINT_SETTINGS_COMMAND = [
|
||||
u"python manage.py lms --settings={settings} print_setting STATIC_ROOT 2>{log_file}",
|
||||
u"python manage.py cms --settings={settings} print_setting STATIC_ROOT 2>{log_file}",
|
||||
u"python manage.py lms --settings={settings} print_setting LMS_ROOT_URL 2>{log_file}",
|
||||
u"python manage.py lms --settings={settings} print_setting JWT_AUTH 2>{log_file}",
|
||||
u"python manage.py lms --settings={settings} print_setting EDXMKTG_USER_INFO_COOKIE_NAME 2>{log_file}",
|
||||
u"python manage.py lms --settings={settings} print_setting WEBPACK_CONFIG_PATH 2>{log_file}"
|
||||
]
|
||||
EXPECTED_WEBPACK_COMMAND = (
|
||||
u"NODE_ENV={node_env} STATIC_ROOT_LMS={static_root_lms} STATIC_ROOT_CMS={static_root_cms} "
|
||||
u"LMS_ROOT_URL={lms_root_url} JWT_AUTH_COOKIE_HEADER_PAYLOAD={jwt_auth_cookie_header_payload_name} "
|
||||
u"EDXMKTG_USER_INFO_COOKIE_NAME={user_info_cookie_name} "
|
||||
u"$(npm bin)/webpack --config={webpack_config_path}"
|
||||
)
|
||||
|
||||
@@ -252,6 +257,9 @@ class TestPaverServerTasks(PaverTestCase):
|
||||
node_env="production",
|
||||
static_root_lms=None,
|
||||
static_root_cms=None,
|
||||
lms_root_url=None,
|
||||
jwt_auth_cookie_header_payload_name=None,
|
||||
user_info_cookie_name=None,
|
||||
webpack_config_path=None
|
||||
))
|
||||
expected_messages.extend(self.expected_sass_commands(system=system, asset_settings=expected_asset_settings))
|
||||
@@ -298,6 +306,9 @@ class TestPaverServerTasks(PaverTestCase):
|
||||
node_env="production",
|
||||
static_root_lms=None,
|
||||
static_root_cms=None,
|
||||
lms_root_url=None,
|
||||
jwt_auth_cookie_header_payload_name=None,
|
||||
user_info_cookie_name=None,
|
||||
webpack_config_path=None
|
||||
))
|
||||
expected_messages.extend(self.expected_sass_commands(asset_settings=expected_asset_settings))
|
||||
|
||||
@@ -6,6 +6,7 @@ from __future__ import absolute_import, print_function
|
||||
import io
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
from time import sleep
|
||||
|
||||
@@ -268,6 +269,25 @@ class Env(object):
|
||||
print(f.read())
|
||||
sys.exit(1)
|
||||
|
||||
@classmethod
|
||||
def get_nested_django_setting(cls, django_setting, nested_django_setting, system, settings=None):
|
||||
"""
|
||||
Interrogate Django environment for specific nested settings values
|
||||
:param django_setting: the root django setting to get
|
||||
:param nested_django_setting: the nested django setting to get
|
||||
:param system: the django app to use when asking for the setting (lms | cms)
|
||||
:param settings: the settings file to use when asking for the value
|
||||
:return: unicode value of the django setting
|
||||
"""
|
||||
django_setting_value = cls.get_django_setting(django_setting, system, settings)
|
||||
pattern = re.compile(
|
||||
u"[\"']{setting}[\"']: [\"'](?P<setting_value>.*)[\"']".format(setting=nested_django_setting)
|
||||
)
|
||||
match = pattern.search(django_setting_value)
|
||||
if match:
|
||||
return match.group('setting_value')
|
||||
return None
|
||||
|
||||
@classmethod
|
||||
def covered_modules(cls):
|
||||
"""
|
||||
|
||||
@@ -137,6 +137,11 @@ from student.models import CourseEnrollment
|
||||
</div>
|
||||
%endif
|
||||
|
||||
${static.renderReact(
|
||||
component="EnterpriseLearnerPortalBanner",
|
||||
id="enterprise-learner-portal-banner",
|
||||
props={}
|
||||
)}
|
||||
</div>
|
||||
|
||||
<section class="dashboard" id="dashboard-main">
|
||||
|
||||
@@ -91,6 +91,8 @@ module.exports = Merge.smart({
|
||||
StudentAccountDeletion: './lms/static/js/student_account/components/StudentAccountDeletion.jsx',
|
||||
StudentAccountDeletionInitializer: './lms/static/js/student_account/StudentAccountDeletionInitializer.js',
|
||||
ProblemBrowser: './lms/djangoapps/instructor/static/instructor/ProblemBrowser/index.jsx',
|
||||
CustomUserMenuLinks: './lms/static/js/custom_user_menu_links/CustomUserMenuLinks.js',
|
||||
EnterpriseLearnerPortalBanner: './lms/static/js/learner_dashboard/EnterpriseLearnerPortalBanner.jsx',
|
||||
|
||||
// Learner Dashboard
|
||||
EntitlementFactory: './lms/static/js/learner_dashboard/course_entitlement_factory.js',
|
||||
|
||||
@@ -20,7 +20,10 @@ module.exports = _.values(Merge.smart(commonConfig, {
|
||||
debug: true
|
||||
}),
|
||||
new webpack.DefinePlugin({
|
||||
'process.env.NODE_ENV': JSON.stringify('development')
|
||||
'process.env.NODE_ENV': JSON.stringify('development'),
|
||||
'process.env.LMS_ROOT_URL': JSON.stringify('https://localhost:18000'),
|
||||
'process.env.JWT_AUTH_COOKIE_HEADER_PAYLOAD': JSON.stringify('edx-jwt-cookie-header-payload'),
|
||||
'process.env.EDXMKTG_USER_INFO_COOKIE_NAME': JSON.stringify('edx-user-info')
|
||||
})
|
||||
],
|
||||
module: {
|
||||
|
||||
@@ -17,7 +17,10 @@ var optimizedConfig = Merge.smart(commonConfig, {
|
||||
devtool: false,
|
||||
plugins: [
|
||||
new webpack.DefinePlugin({
|
||||
'process.env.NODE_ENV': JSON.stringify('production')
|
||||
'process.env.NODE_ENV': JSON.stringify('production'),
|
||||
'process.env.LMS_ROOT_URL': JSON.stringify(process.env.LMS_ROOT_URL),
|
||||
'process.env.JWT_AUTH_COOKIE_HEADER_PAYLOAD': JSON.stringify(process.env.JWT_AUTH_COOKIE_HEADER_PAYLOAD),
|
||||
'process.env.EDXMKTG_USER_INFO_COOKIE_NAME': JSON.stringify(process.env.EDXMKTG_USER_INFO_COOKIE_NAME)
|
||||
}),
|
||||
new webpack.LoaderOptionsPlugin({ // This may not be needed; legacy option for loaders written for webpack 1
|
||||
minimize: true
|
||||
|
||||
Reference in New Issue
Block a user