diff --git a/common/djangoapps/student/views.py b/common/djangoapps/student/views.py index 457e0c2790..7da86eaca6 100644 --- a/common/djangoapps/student/views.py +++ b/common/djangoapps/student/views.py @@ -2170,7 +2170,7 @@ def record_registration_attributions(request, user): def create_account(request, post_override=None): """ JSON call to create new edX account. - Used by form in signup_modal.html, which is included into navigation.html + Used by form in signup_modal.html, which is included into header.html """ # Check if ALLOW_PUBLIC_ACCOUNT_CREATION flag turned off to restrict user account creation if not configuration_helpers.get_value( diff --git a/common/test/acceptance/pages/lms/dashboard.py b/common/test/acceptance/pages/lms/dashboard.py index a636638f0e..2605ada811 100644 --- a/common/test/acceptance/pages/lms/dashboard.py +++ b/common/test/acceptance/pages/lms/dashboard.py @@ -215,7 +215,7 @@ class DashboardPage(PageObject): """ Return list username dropdown links. """ - return self.q(css='.user-dropdown-menu li a').text + return self.q(css='.user-dropdown-menu a').text @property def tabs_link_text(self): @@ -234,7 +234,7 @@ class DashboardPage(PageObject): """ Click on `Account` link. """ - self.q(css='.user-dropdown-menu li a').nth(2).click() + self.q(css='.user-dropdown-menu a').nth(1).click() @property def language_selector(self): diff --git a/lms/static/js/header/header.js b/lms/static/js/header/header.js new file mode 100644 index 0000000000..6803a6ca33 --- /dev/null +++ b/lms/static/js/header/header.js @@ -0,0 +1,172 @@ +/** + * Ensuring collapsible and accessible components on multiple + * screen sizes for the responsive lms header. +*/ + +function createMobileMenu() { + /** + * Dynamically create a mobile menu from all specified mobile links + * on the page. + */ + 'use strict'; + $('.mobile-nav-item').each(function() { + var mobileNavItem = $(this).clone().addClass('mobile-nav-link'); + mobileNavItem.attr('role', 'menuitem'); + // xss-lint: disable=javascript-jquery-append + $('.mobile-menu').append(mobileNavItem); + }); +} + +$(document).ready(function() { + 'use strict'; + var $hamburgerMenu; + var $mobileMenu; + // Toggling visibility for the user dropdown + $('.toggle-user-dropdown').click(function() { + var $dropdownMenu = $('.global-header .nav-item .dropdown-user-menu'); + var $userMenu = $('.user-dropdown'); + if ($dropdownMenu.is(':visible')) { + $dropdownMenu.hide(); + $userMenu.attr('aria-expanded', 'false'); + } else { + $dropdownMenu.show(); + $dropdownMenu.find('.dropdown-item')[0].focus(); + $userMenu.attr('aria-expanded', 'true'); + } + $('.toggle-user-dropdown').toggleClass('open'); + }); + + // Toggling menu visibility with the hamburger menu + $('.hamburger-menu').click(function() { + $hamburgerMenu = $('.hamburger-menu'); + $mobileMenu = $('.mobile-menu'); + if ($mobileMenu.is(':visible')) { + $mobileMenu.hide(); + $hamburgerMenu.attr('aria-expanded', 'false'); + } else { + $mobileMenu.show(); + $hamburgerMenu.attr('aria-expanded', 'true'); + } + $hamburgerMenu.toggleClass('open'); + }); + + // Hide hamburger menu if no nav items (sign in and register pages) + if ($('.mobile-nav-item').size() === 0) { + $('.hamburger-menu').css('display', 'none'); + } + + createMobileMenu(); +}); + +// Ensure click away hides the user dropdown +$(window).click(function(e) { + 'use strict'; + if (!$(e.target).is('.dropdown-item, .toggle-user-dropdown')) { + $('.global-header .nav-item .dropdown-user-menu').hide(); + } +}); + +// Accessibility keyboard controls for user dropdown and mobile menu +$(document).on('keydown', function(e) { + 'use strict'; + var isNext; + var nextLink; + var loopFirst; + var loopLast; + var isLastItem = $(e.target).parent().is(':last-child'); + var isToggle = $(e.target).hasClass('toggle-user-dropdown'); + var isHamburgerMenu = $(e.target).hasClass('hamburger-menu'); + var isMobileOption = $(e.target).parent().hasClass('mobile-nav-link'); + var isDropdownOption = !isMobileOption && $(e.target).parent().hasClass('dropdown-item'); + var $userMenu = $('.user-dropdown'); + var $hamburgerMenu = $('.hamburger-menu'); + var $toggleUserDropdown = $('.toggle-user-dropdown'); + + // Open or close relevant menu on enter or space click and focus on first element. + if ((e.keyCode === 13 || e.keyCode === 32) && (isToggle || isHamburgerMenu)) { + $(e.target).click(); + if (isHamburgerMenu) { + if ($('.mobile-menu').is(':visible')) { + $hamburgerMenu.attr('aria-expanded', true); + $('.mobile-menu .mobile-nav-link a').first().focus(); + } else { + $hamburgerMenu.attr('aria-expanded', false); + } + } else if (isToggle) { + if ($('.global-header .nav-item .dropdown-user-menu').is(':visible')) { + $userMenu.attr('aria-expanded', 'true'); + $('.dropdown-item a:first').focus(); + } else { + $userMenu.attr('aria-expanded', false); + } + } + // Don't allow for double click or page jump on Firefox browser + e.preventDefault(); + e.stopPropagation(); + } + + // Enable arrow functionality within the menu. + if (e.keyCode === 38 || e.keyCode === 40 && (isDropdownOption || isMobileOption || + (isHamburgerMenu && $hamburgerMenu.hasClass('open')) || isToggle && $toggleUserDropdown.hasClass('open'))) { + isNext = e.keyCode === 40; + if (isNext && !isHamburgerMenu && !isToggle && isLastItem) { + // Loop to the start from the final element + nextLink = isDropdownOption ? $toggleUserDropdown : $hamburgerMenu; + } else if (!isNext && (isHamburgerMenu || isToggle)) { + // Loop to the end when up arrow pressed from menu icon + nextLink = isHamburgerMenu ? $('.mobile-menu .mobile-nav-link a').last() + : $('.dropdown-user-menu .dropdown-nav-item').last().find('a'); + } else if (isNext && (isHamburgerMenu || isToggle)) { + // Loop to the first element from the menu icon + nextLink = isHamburgerMenu ? $('.mobile-menu .mobile-nav-link a').first() + : $('.dropdown-user-menu .dropdown-nav-item').first().find('a'); + } else { + // Loop up to the menu icon if first element in menu + if (!isNext && $(e.target).parent().is(':first-child') && !isHamburgerMenu && !isToggle) { + nextLink = isDropdownOption ? $toggleUserDropdown : $hamburgerMenu; + } else { + nextLink = isNext ? + $(e.target).parent().next().find('a') : // eslint-disable-line newline-per-chained-call + $(e.target).parent().prev().find('a'); // eslint-disable-line newline-per-chained-call + } + } + nextLink.focus(); + + // Don't let the screen scroll on navigation + e.preventDefault(); + e.stopPropagation(); + } + + // Escape clears out of the menu + if (e.keyCode === 27 && (isDropdownOption || isHamburgerMenu || isMobileOption || isToggle)) { + if (isDropdownOption || isToggle) { + $('.global-header .nav-item .dropdown-user-menu').hide(); + $toggleUserDropdown.focus(); + $userMenu.attr('aria-expanded', 'false'); + $('.toggle-user-dropdown').removeClass('open'); + } else { + $('.mobile-menu').hide(); + $hamburgerMenu.focus(); + $hamburgerMenu.attr('aria-expanded', 'false'); + $hamburgerMenu.removeClass('open'); + } + } + + // Loop when tabbing and using arrows + if ((e.keyCode === 9) && ((isDropdownOption && isLastItem) || (isMobileOption && isLastItem) || (isHamburgerMenu + && $hamburgerMenu.hasClass('open')) || (isToggle && $toggleUserDropdown.hasClass('open')))) { + nextLink = null; + loopFirst = isLastItem && !e.shiftKey && !isHamburgerMenu && !isToggle; + loopLast = (isHamburgerMenu || isToggle) && e.shiftKey; + if (!(loopFirst || loopLast)) { + return; + } + if (isDropdownOption || isToggle) { + nextLink = loopFirst ? $toggleUserDropdown : $('.dropdown-user-menu .dropdown-nav-item a').last(); + } else { + nextLink = loopFirst ? $hamburgerMenu : $('.mobile-menu .mobile-nav-link a').last(); + } + nextLink.focus(); + e.preventDefault(); + } +}); diff --git a/lms/static/sass/_build-base-v1.scss b/lms/static/sass/_build-base-v1.scss index e4171d400a..66652dddfc 100644 --- a/lms/static/sass/_build-base-v1.scss +++ b/lms/static/sass/_build-base-v1.scss @@ -8,6 +8,15 @@ @import 'base/mixins'; @import 'base/theme'; +// edX Bootstrap theme and variables support +@import 'bootstrap/theme'; +@import 'bootstrap/variables'; + +// Core Bootstrap functions, variables and mixins +@import 'bootstrap/scss/functions'; +@import 'bootstrap/scss/variables'; +@import 'bootstrap/scss/mixins/breakpoints'; + // Pattern Library shims @import 'edx-pattern-library-shims/base/variables'; @import 'edx-pattern-library-shims/buttons'; diff --git a/lms/static/sass/_build-course.scss b/lms/static/sass/_build-course.scss index 8f23625a03..84a1c06a86 100644 --- a/lms/static/sass/_build-course.scss +++ b/lms/static/sass/_build-course.scss @@ -3,11 +3,14 @@ // About: Sass compile for the LMS Courseware Elements that are shared between LTR and RTL UI. Configuration and vendor specific imports happen before this shared set of imports are compiled in the lms-course-*.scss files. -// Bootstrap support for use with shared partials +// edX Bootstrap theme and variables support @import 'bootstrap/theme'; +@import 'bootstrap/variables'; + +// Core Bootstrap functions, variables and mixins @import 'bootstrap/scss/functions'; @import 'bootstrap/scss/variables'; -@import "bootstrap/scss/mixins/breakpoints"; +@import 'bootstrap/scss/mixins/breakpoints'; // Base @import 'base/base'; @@ -75,6 +78,7 @@ // responsive @import 'base/layouts'; // temporary spot for responsive course +@import 'header'; // features @import 'features/course-sock'; diff --git a/lms/static/sass/_build-lms-v1.scss b/lms/static/sass/_build-lms-v1.scss index 9f4ce763a1..5c50516b07 100644 --- a/lms/static/sass/_build-lms-v1.scss +++ b/lms/static/sass/_build-lms-v1.scss @@ -3,12 +3,6 @@ // About: Sass compile for the LMS Elements that are shared between LTR and RTL UI. Configuration and vendor specific imports happen before this shared set of imports are compiled in the lms-main-*.scss files. -// Bootstrap support for use with shared partials -@import 'bootstrap/theme'; -@import 'bootstrap/scss/functions'; -@import 'bootstrap/scss/variables'; -@import "bootstrap/scss/mixins/breakpoints"; - // base - assets @import 'base/font_face'; @import 'base/extends'; @@ -18,6 +12,15 @@ // base - starter @import 'base/base'; +// edX Bootstrap theme and variables support +@import 'bootstrap/theme'; +@import 'bootstrap/variables'; + +// Core Bootstrap functions, variables and mixins +@import 'bootstrap/scss/functions'; +@import 'bootstrap/scss/variables'; +@import 'bootstrap/scss/mixins/breakpoints'; + // Pattern Library shims @import 'edx-pattern-library-shims/base/variables'; @import 'edx-pattern-library-shims/breadcrumbs'; @@ -85,6 +88,9 @@ @import 'mixins-inherited'; @import 'elements/system-feedback'; +// Responsive Design +@import 'header'; + // overrides @import 'developer'; // used for any developer-created scss that needs further polish/refactoring @import 'shame'; // used for any bad-form/orphaned scss diff --git a/lms/static/sass/_build-lms-v2.scss b/lms/static/sass/_build-lms-v2.scss index 26516c983b..81fa00ac64 100644 --- a/lms/static/sass/_build-lms-v2.scss +++ b/lms/static/sass/_build-lms-v2.scss @@ -2,11 +2,14 @@ // LMS: Shared Build Compile // Version 2 - introduces the Pattern Library -// Bootstrap support for use with shared partials +// edX Bootstrap theme and variables support @import 'bootstrap/theme'; +@import 'bootstrap/variables'; + +// Core Bootstrap functions, variables and mixins @import 'bootstrap/scss/functions'; @import 'bootstrap/scss/variables'; -@import "bootstrap/scss/mixins/breakpoints"; +@import 'bootstrap/scss/mixins/breakpoints'; // Configuration @import 'config'; @@ -36,3 +39,6 @@ @import 'features/course-search'; @import 'features/course-sock'; @import 'features/course-upgrade-message'; + +// Responsive Design +@import 'header'; diff --git a/lms/static/sass/_header.scss b/lms/static/sass/_header.scss new file mode 100644 index 0000000000..81f5faf489 --- /dev/null +++ b/lms/static/sass/_header.scss @@ -0,0 +1,361 @@ +/** + This file contains all the necessary styling for a uniform + navigation bar that can exist on any of the v1, v2 or bootstrap + pages. +*/ +.global-header { + box-sizing: border-box; + width: 100%; + overflow: hidden; + padding-bottom: $baseline/2; + border-bottom: 1px solid theme-color("primary"); + box-shadow: 0 1px 5px 0 rgba(0, 0, 0, 0.1); + background: theme-color("inverse"); + + /* + Logo and course identification block + */ + .header-logo { + display: inline; + + a { + @include float(left); + @include margin($baseline/2, 0, 0, $baseline); + + display: block; + + .logo { + @include float(left); + + width: $header-logo-width; + } + + @include media-breakpoint-down(sm) { + margin-left: calc(50% - 30px); + height: $header-logo-height; + width: auto; + } + } + + .course-header { + @include float(left); + @include margin($baseline, 0, 0, $baseline); + + font-size: $font-size-lg; + color: theme-color("dark"); + line-height: 1em; + display: none; + + .provider { + font-weight: $font-weight-bold; + } + + // Hide the course header for smaller screen sizes + @include media-breakpoint-up(md) { + display: block; + } + } + } + + /* + Main navigation buttons for Courses, programs, profile and explore buttons. + + There are two stylings for the two circumstances, first the mobile, followed + by the desktop styling + */ + // Desktop styling + @include media-breakpoint-up(md) { + .nav-links { + .nav-item { + margin: 0 $baseline; + + a { + text-decoration: none; + } + } + + .main { + @include float(left); + @include margin($baseline, 0, 0, $baseline); + + .nav-item { + @include float(left); + } + + .nav-tab { + text-transform: none; + padding: 0; + cursor: pointer; + margin: 0; + + a { + color: theme-color("secondary"); + padding: $baseline*0.35 $baseline*1.25 $baseline*0.75; + font-weight: $font-weight-normal; + display: inline-block; + margin-bottom: -1*$baseline/2; + border-bottom: 2px solid transparent; + cursor: pointer; + + &.active, + &:hover { + border-bottom-color: theme-color("dark"); + } + + &:hover { + cursor: pointer; + border-bottom-color: theme-color("primary"); + } + } + } + } + + .secondary { + @include float(right); + + margin: $baseline*0.6 $baseline 0 0; + + // All navigation items + .nav-item { + font-size: $font-size-base; + display: inline-block; + padding: $baseline/2 0 0; + margin: 0 $baseline/2; + + a { + color: theme-color("dark"); + font-weight: $font-weight-bold; + } + } + + + // Sign in, Register and Shopping Cart buttons + .btn { + border: 1px solid theme-color("primary"); + padding: $baseline/4 $baseline; + border-radius: $baseline/4; + cursor: pointer; + text-decoration: none; + } + + a.sign-in-btn, + .nav-item a.shopping-cart { + background-color: theme-color("primary"); + color: theme-color("inverse"); + border: 1px solid theme-color("inverse"); + font-weight: $font-weight-normal; + padding: $baseline/4 $baseline; + + &:hover { + background-color: theme-color("inverse"); + color: theme-color("primary"); + border-color: theme-color("primary"); + } + } + + a.register-btn { + background: theme-color("inverse"); + color: theme-color("primary"); + font-weight: $font-weight-normal; + + &:hover { + background-color: theme-color("primary"); + color: theme-color("inverse"); + } + } + + // User information + .user-image-frame { + border: 1px solid theme-color("light"); + margin: -1*$baseline/2 $baseline/4; + border-radius: $baseline/4; + width: $header-user-image-size; + } + + // Dropdown behavior + .toggle-user-dropdown { + text-decoration: none; + cursor: pointer; + } + + .dropdown-user-menu { + display: none; + border: 1px solid theme-color("secondary"); + position: absolute; + background-color: theme-color("inverse"); + color: theme-color("secondary"); + right: 30px; + top: 55px; + z-index: 10; + + .dropdown-item { + cursor: pointer; + overflow: hidden; + padding: 0; + + &:hover { + color: theme-color("dark"); + background-color: theme-color("light"); + } + + &:not(:last-child) { + border-bottom: 1px solid theme-color("light"); + } + + a { + font-weight: $font-weight-base; + padding: $baseline/2 $baseline*0.75; + display: inline-block; + width: 100%; + + &:focus { + outline: none; + color: theme-color("dark"); + background-color: theme-color("light"); + } + } + } + } + } + } + + .hamburger-menu { + display: none; + } + } + + // Responsive styling for mobile + @include media-breakpoint-down(sm) { + // Display the menu icon and allow for transition to an X on click + .hamburger-menu { + @include left(22px); + position: absolute; + top: $baseline; + width: 30px; + height: 20px; + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + -webkit-transition: 0.5s ease-in-out; + transition: 0.5s ease-in-out; + cursor: pointer; + outline: none; + + &:focus, + &:hover { + span { + background: theme-color("primary"); + height: 3px; + } + } + + span { + display: block; + position: absolute; + height: 2px; + width: 100%; + background: theme-color("secondary"); + border-radius: 9px; + opacity: 1; + left: 0; + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + -webkit-transition: 0.25s ease-in-out; + transition: 0.25s ease-in-out; + + &:nth-child(1) { + top: 0; + } + + &:nth-child(2), + &:nth-child(3) { + top: 6px; + } + + &:nth-child(4) { + top: 12px; + } + } + + &.open span { + &:nth-child(1) { + top: 18px; + width: 0%; + left: 50%; + } + + &:nth-child(2) { + -webkit-transform: rotate(45deg); + transform: rotate(45deg); + } + + &:nth-child(3) { + -webkit-transform: rotate(-45deg); + transform: rotate(-45deg); + } + + &:nth-child(4) { + top: 18px; + width: 0%; + left: 50%; + } + } + } + } +} + +/* + Mobile menu styling +*/ +.mobile-menu { + border-bottom: 1px solid theme-color('primary'); + + @include media-breakpoint-up(md) { + display: none !important; + } + + @include media-breakpoint-down(sm) { + display: none; + + // Override standard styling for the mobile menu links + .mobile-nav-link { + position: static; + transform: none; + + a { + font-size: $font-size-base; + font-weight: 600; + color: theme-color('dark'); + text-decoration: none; + outline: none; + display: block; + background-color: theme-color('inverse'); + border-radius: 0; + width: 100%; + padding: $baseline*0.6 $baseline; + border-bottom: 1px solid theme-color('light'); + text-align: left; + cursor: pointer; + + &:hover, + &:focus { + background-color: theme-color('dark'); + color: theme-color('inverse'); + } + + &::after { + content: '\00BB'; + padding-left: 4px; + } + } + } + } +} + +// Hide elements in menu bar when they exist in mobile +.hidden-mobile { + @include media-breakpoint-down(sm) { + &:not(.mobile-nav-link) { + display: none; + } + } +} diff --git a/lms/static/sass/base/_base.scss b/lms/static/sass/base/_base.scss index 6e2e1bcd6a..bfb5992c8e 100644 --- a/lms/static/sass/base/_base.scss +++ b/lms/static/sass/base/_base.scss @@ -254,10 +254,17 @@ mark { &:focus, &:active { - position: relative; - top: auto; + @include left(50%); + @include margin-left(-1 * $baseline * 1.5); + position: absolute; + top: $baseline/4; width: auto; height: auto; + background-color: black; margin: 0; + opacity: 0.8; + color: white !important; + text-decoration: none !important; + outline: none; } } diff --git a/lms/static/sass/bootstrap/_variables.scss b/lms/static/sass/bootstrap/_variables.scss index e9f009c39d..053f05e7ce 100644 --- a/lms/static/sass/bootstrap/_variables.scss +++ b/lms/static/sass/bootstrap/_variables.scss @@ -5,3 +5,11 @@ // #UNITS // ---------------------------- $baseline: 20px !default; + + +// ---------------------------- +// #COMPONENT SIZING +// ---------------------------- +$header-logo-width: 60px !default; +$header-logo-height: 40px !default; +$header-user-image-size: 40px !default; diff --git a/lms/static/sass/bootstrap/lms-main.scss b/lms/static/sass/bootstrap/lms-main.scss index 1f79c148e4..cd041ebd55 100644 --- a/lms/static/sass/bootstrap/lms-main.scss +++ b/lms/static/sass/bootstrap/lms-main.scss @@ -32,3 +32,6 @@ // Individual Pages @import "views/program-marketing-page"; + +// Responsive Design +@import '../header'; diff --git a/lms/static/sass/discussion/_build.scss b/lms/static/sass/discussion/_build.scss index 46c3d52941..b22a4e270e 100644 --- a/lms/static/sass/discussion/_build.scss +++ b/lms/static/sass/discussion/_build.scss @@ -4,11 +4,14 @@ // Set the relative path to the static root $static-path: '../..' !default; -// Bootstrap support for use with shared partials +// edX Bootstrap theme and variables support @import 'bootstrap/theme'; +@import 'bootstrap/variables'; + +// Core Bootstrap functions, variables and mixins @import 'bootstrap/scss/functions'; @import 'bootstrap/scss/variables'; -@import "bootstrap/scss/mixins/breakpoints"; +@import 'bootstrap/scss/mixins/breakpoints'; // Configuration @import '../config'; diff --git a/lms/static/sass/multicourse/_course_about.scss b/lms/static/sass/multicourse/_course_about.scss index be6b7771e1..3bd12d6c7a 100644 --- a/lms/static/sass/multicourse/_course_about.scss +++ b/lms/static/sass/multicourse/_course_about.scss @@ -11,7 +11,6 @@ border-bottom: 1px solid $border-color-3; box-shadow: inset 0 1px 5px 0 $shadow-l1; height: 280px; - margin-top: $header_image_margin; padding-top: 150px; overflow: hidden; position: relative; diff --git a/lms/static/sass/shared-v2/_navigation.scss b/lms/static/sass/shared-v2/_navigation.scss index 450286ea25..36dc66022b 100644 --- a/lms/static/sass/shared-v2/_navigation.scss +++ b/lms/static/sass/shared-v2/_navigation.scss @@ -14,10 +14,19 @@ &:focus, &:active { - position: relative; - top: auto; - width: auto; - height: auto; - margin: 0; + @include left(50%); + @include margin-left(-6.5em) + margin-top: 0; + padding: 10px 0.5em; + text-align: center; + position: absolute; + width: 12em; + z-index: 1050; + top: 0; + background-color: $black !important; + opacity: 0.8; + color: $white !important; + text-decoration: none; + outline: none; } } diff --git a/lms/templates/header.html b/lms/templates/header.html index 93f1b066a8..80fb9eacd2 100644 --- a/lms/templates/header.html +++ b/lms/templates/header.html @@ -1,4 +1,4 @@ ## mako <%page expression_filter="h" args="online_help_token"/> <%namespace name='static' file='static_content.html'/> -<%include file="${static.get_template_path(relative_path='navigation/navigation.html')}" args="online_help_token=online_help_token" /> +<%include file="${static.get_template_path(relative_path='header/header.html')}" args="online_help_token=online_help_token" /> diff --git a/lms/templates/header/header.html b/lms/templates/header/header.html new file mode 100644 index 0000000000..e287f7f722 --- /dev/null +++ b/lms/templates/header/header.html @@ -0,0 +1,132 @@ +## mako + +<%page expression_filter="h" args="online_help_token"/> + +<%namespace name='static' file='../static_content.html'/> +<%namespace file='../main.html' import="login_query"/> +<%! +from django.core.urlresolvers import reverse +from django.utils.translation import ugettext as _ + +from lms.djangoapps.ccx.overrides import get_current_ccx +from openedx.core.djangolib.markup import HTML, Text + +# App that handles subdomain specific branding +from branding import api as branding_api +# app that handles site status messages +from status.status import get_site_status_msg +from openedx.core.djangoapps.lang_pref.api import header_language_selector_is_enabled, released_languages + +# Waffle flag to enable and disable the responsive header +from openedx.core.djangoapps.waffle_utils import WaffleFlag, WaffleFlagNamespace +RESPONSIVE_HEADER_ENABLED = WaffleFlag(WaffleFlagNamespace(name='lms'), 'responsive_header_enabled') +%> + +## Provide a hook for themes to inject branding on top. +<%block name="navigation_top" /> + +## Add UI Toolkit components if using the Pattern Library +% if uses_pattern_library: + <%block name="js_extra"> + <%static:require_module module_name="js/header_factory" class_name="HeaderFactory"> + HeaderFactory(); + %static:require_module> + %block> +% endif + +<%block> +<% +course_id = course.id if course else None +site_status_msg = get_site_status_msg(course_id) +%> +% if site_status_msg: +
${site_status_msg}
+