diff --git a/lms/static/sass/bootstrap/_components.scss b/lms/static/sass/bootstrap/_components.scss index d1216d3c69..4004ba94de 100644 --- a/lms/static/sass/bootstrap/_components.scss +++ b/lms/static/sass/bootstrap/_components.scss @@ -13,7 +13,13 @@ // Alerts .alert { + display: flex; + .icon-alert { - margin-right: $baseline / 4; + margin-right: $baseline; + } + + .message-actions { + margin-left: $baseline; } } diff --git a/lms/static/sass/elements/_banners.scss b/lms/static/sass/elements/_banners.scss index 110becf6ac..2269eba511 100644 --- a/lms/static/sass/elements/_banners.scss +++ b/lms/static/sass/elements/_banners.scss @@ -3,98 +3,114 @@ $full-width-banner-img-width: 1140px !default; $full-width-banner-margin: 20px; .full-width-banner { + position: relative; + + .banner-background-wrapper { + height: $full-width-banner-img-height; + width: 100%; + overflow: hidden; position: relative; + background: $black; - .banner-background-wrapper { - height: $full-width-banner-img-height; - width: 100%; - overflow: hidden; - position: relative; - background: $black; + &::before { + content: ''; + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + background: $black; + opacity: 0.65; - &:before { - content: ''; - position: absolute; - top: 0; - right: 0; - bottom: 0; - left: 0; - background: $black; - opacity: 0.65; - - @media(min-width: $bp-screen-md) { - opacity: 0.4; - } - } + @media (min-width: $bp-screen-md) { + opacity: 0.4; + } } + } - .banner-background-image { - height: $full-width-banner-img-height; + .banner-background-image { + height: $full-width-banner-img-height; - @media(min-width: $full-width-banner-img-width) { - height: auto; - width: 100%; - } + @media (min-width: $full-width-banner-img-width) { + height: auto; + width: 100%; } + } - .banner-content { - position: absolute; - top: 0; - left: $full-width-banner-margin; - right: $full-width-banner-margin; - } + .banner-content { + position: absolute; + top: 0; + left: $full-width-banner-margin; + right: $full-width-banner-margin; + } } .page-banner { - max-width: $lms-max-width; - margin: 0 auto; + max-width: $lms-max-width; + margin: 0 auto; - .user-messages { - padding-top: $baseline; + .user-messages { + padding-top: $baseline; - // Hack: force override the global important rule - // that courseware links don't have an underline. - a:hover { - color: $link-color; - text-decoration: underline !important; - } + // Hack: force override the global important rule + // that courseware links don't have an underline. + a:hover { + color: $link-color; + text-decoration: underline !important; + } + } + + .alert { + display: flex; + padding: $baseline; + border: 1px solid; + + &:not(:last-child) { + margin-bottom: $baseline / 2; } - .alert { - margin-bottom: $baseline !important; - padding: $baseline; - border: 1px solid; - - .icon-alert { - margin-right: $baseline / 4; - } - - &.alert-info { - color: $state-info-text; - background-color: $state-info-bg; - border-color: $state-info-border; - box-shadow: none; - } - - &.alert-success { - color: $state-success-text; - background-color: $state-success-bg; - border-color: $state-success-border; - box-shadow: none; - } - - &.alert-warning { - color: $state-warning-text; - background-color: $state-warning-bg; - border-color: $state-warning-border; - box-shadow: none; - } - - &.alert-danger { - color: $state-danger-text; - background-color: $state-danger-bg; - border-color: $state-danger-border; - box-shadow: none; - } + .icon-alert { + @include margin-right($baseline); } + + .message-actions { + @include margin-left($baseline); + } + + &.alert-info { + color: $state-info-text; + background-color: $state-info-bg; + border-color: $state-info-border; + box-shadow: none; + line-height: initial; + + a, + a:visited, + .btn-link { + color: $state-info-text-link; + font-weight: bold; + } + } + + &.alert-success { + color: $state-success-text; + background-color: $state-success-bg; + border-color: $state-success-border; + box-shadow: none; + } + + &.alert-warning { + color: $state-warning-text; + background-color: $state-warning-bg; + border-color: $state-warning-border; + box-shadow: none; + } + + &.alert-danger { + color: $state-danger-text; + background-color: $state-danger-bg; + border-color: $state-danger-border; + box-shadow: none; + } + } } diff --git a/lms/static/sass/features/_learner-profile.scss b/lms/static/sass/features/_learner-profile.scss index 3a480a565b..dfe8fd9688 100644 --- a/lms/static/sass/features/_learner-profile.scss +++ b/lms/static/sass/features/_learner-profile.scss @@ -112,6 +112,16 @@ background-color: $white; } + .page-banner { + background-color: $gray-l4; + max-width: none; + + .user-messages { + max-width: $lms-max-width; + margin: auto; + } + } + .ui-loading-indicator { @extend .ui-loading-base; @@ -253,7 +263,7 @@ width: 100%; margin: 0 auto; - border: 1px solid $gray-l3; + border-bottom: 1px solid $gray-l3; background-color: $gray-l4; padding: ($baseline*0.75) 0; @@ -262,7 +272,7 @@ border: none; box-shadow: none; - padding: 0 ($baseline*3); + padding: 0; } .u-field-title { @@ -297,18 +307,21 @@ .wrapper-profile-sections { @extend .container; - @include padding($baseline*1.5, $baseline*1.5, $baseline*1.5, 0); + @include padding($baseline*1.5, 0, $baseline*1.5, 0); + display: flex; + flex-wrap: wrap; min-width: 0; @media (max-width: $learner-profile-container-flex) { // Switch to map-get($grid-breakpoints,md) for bootstrap @include margin-left(0); - @include padding($baseline*1.5, 0, $baseline*1.5, 0); } } .profile-header { - @include padding(0, $baseline*2, $baseline, $baseline*3); + max-width: $lms-max-width; + margin: auto; + padding: $baseline 0 0; @media (max-width: $learner-profile-container-flex) { // Switch to map-get($grid-breakpoints,md) for bootstrap @include padding(0, $baseline*2, $baseline, $baseline*0.75); @@ -333,9 +346,6 @@ } .wrapper-profile-section-one { - @include float(left); - @include margin-left($baseline*3); - width: 300px; background-color: $white; border-top: 5px solid $blue; @@ -459,9 +469,8 @@ @include float(left); @include padding-left($baseline); - width: calc(100% - 380px); - max-width: $learner-profile-container-flex; // Switch to map-get($grid-breakpoints,md) for bootstrap font-family: $sans-serif; + flex-grow: 1; @media (max-width: $learner-profile-container-flex) { // Switch to map-get($grid-breakpoints,md) for bootstrap width: 90%; diff --git a/lms/static/sass/partials/base/_variables.scss b/lms/static/sass/partials/base/_variables.scss index ba72516e19..f954ab5e79 100644 --- a/lms/static/sass/partials/base/_variables.scss +++ b/lms/static/sass/partials/base/_variables.scss @@ -227,7 +227,8 @@ $state-success-text: $black !default; $state-success-bg: #dff0d8 !default; $state-success-border: darken($state-success-bg, 5%) !default; -$state-info-text: $black !default; +$state-info-text: #31708f !default; +$state-info-text-link: #245269 !default; $state-info-bg: #d9edf7 !default; $state-info-border: darken($state-info-bg, 7%) !default; diff --git a/lms/static/sass/shared-v2/_components.scss b/lms/static/sass/shared-v2/_components.scss index 576c779d2c..12ce69cbef 100644 --- a/lms/static/sass/shared-v2/_components.scss +++ b/lms/static/sass/shared-v2/_components.scss @@ -1,92 +1,99 @@ // TODO: tabs should be added to the Pattern Library .tabs { - @include clearfix(); - @extend %reset-lists; - @include border-top-radius(4px); - padding: ($baseline*0.75) 0 ($baseline*0.75) 0; + @include clearfix(); - .tab { - @include float(left); - list-style: none; - margin-bottom: 0; + @extend %reset-lists; - &.prominent { - @include margin-right(16px); - background: rgba(255, 255, 255, 0.5); - border-radius: 3px; - } + @include border-top-radius(4px); - &.prominent + li { - @include border-left(1px solid $lms-border-color); - @include padding-left($baseline*0.75); - } + padding: ($baseline*0.75) 0 ($baseline*0.75) 0; - a, - a:visited { - @include padding($baseline/2, $baseline*0.75, 13px, $baseline*0.75); - display: block; - text-align: center; - text-decoration: none; - border-style: solid; - border-width: 0 0 4px 0; - border-bottom-color: transparent; - color: $lms-inactive-color; - font-size: 14px; + .tab { + @include float(left); - &:hover, - &:focus { - color: $lms-active-color; - border-bottom-color: $lms-active-color; - } + list-style: none; + margin-bottom: 0; - &.active { - color: $uxpl-blue-hover-active; - border-bottom-color: $uxpl-blue-hover-active; - background-color: transparent; - } - } + &.prominent { + @include margin-right(16px); + + background: rgba(255, 255, 255, 0.5); + border-radius: 3px; } + + &.prominent + li { + @include border-left(1px solid $lms-border-color); + @include padding-left($baseline*0.75); + } + + a, + a:visited { + @include padding($baseline/2, $baseline*0.75, 13px, $baseline*0.75); + + display: block; + text-align: center; + text-decoration: none; + border-style: solid; + border-width: 0 0 4px; + border-bottom-color: transparent; + color: $lms-inactive-color; + font-size: 14px; + + &:hover, + &:focus { + color: $lms-active-color; + border-bottom-color: $lms-active-color; + } + + &.active { + color: $uxpl-blue-hover-active; + border-bottom-color: $uxpl-blue-hover-active; + background-color: transparent; + } + } + } } // TODO: search box should be in the Pattern Library .page-header-search { + display: inline-block; + + .search-form { display: inline-block; + } - .search-form { - display: inline-block; - } - - .search-box { - display: inline-block; - position: relative; - vertical-align: middle; - } - - .search-input { - width: 12rem; - } - - .action-search { - text-shadow: none; - vertical-align: middle; - padding: $baseline/5 $baseline/2; - } - - .action-clear { - @include right(0); - @include margin(0, ($baseline/4), 0, 0); - position: absolute; - top: 0; - color: $lms-gray; - padding: $baseline/4; - - // STATE: hover and focus - &:hover, - &:focus { - color: $lms-label-color; - border-width: 0; - } + .search-box { + display: inline-block; + position: relative; + vertical-align: middle; + } + + .search-input { + width: 12rem; + } + + .action-search { + text-shadow: none; + vertical-align: middle; + padding: $baseline/5 $baseline/2; + } + + .action-clear { + @include right(0); + @include margin(0, ($baseline/4), 0, 0); + + position: absolute; + top: 0; + color: $lms-gray; + padding: $baseline/4; + + // STATE: hover and focus + &:hover, + &:focus { + color: $lms-label-color; + border-width: 0; } + } } .page-banner { @@ -94,11 +101,16 @@ margin: 0 auto; .alert { + display: flex; margin-top: $baseline; border: 1px solid; .icon-alert { - margin-right: $baseline / 4; + @include margin-right($baseline); + } + + .message-actions { + @include margin-left($baseline); } &.alert-info { @@ -134,7 +146,8 @@ .wrapper-preview-menu { @include clearfix(); @include box-sizing(border-box); - margin: 0 auto 0; + + margin: 0 auto; padding: ($baseline*0.75); background-color: $lms-preview-menu-color; @@ -150,6 +163,7 @@ .preview-actions { @include margin-left(0); + display: inline-block; margin-bottom: 0; @@ -158,6 +172,7 @@ .action-preview-label { @include margin-right($baseline/2); + display: inline-block; margin-bottom: 0; vertical-align: middle; @@ -189,12 +204,12 @@ } .section { - .icon { - width: 20px; - text-align: center; - } + .icon { + width: 20px; + text-align: center; + } } .section:not(:first-child) { - margin-top: $baseline; + margin-top: $baseline; } diff --git a/openedx/core/djangoapps/util/tests/test_user_messages.py b/openedx/core/djangoapps/util/tests/test_user_messages.py index b94c0d7c65..bcbcc5ea7e 100644 --- a/openedx/core/djangoapps/util/tests/test_user_messages.py +++ b/openedx/core/djangoapps/util/tests/test_user_messages.py @@ -30,9 +30,9 @@ class UserMessagesTestCase(TestCase): MessageMiddleware().process_request(self.request) @ddt.data( - ('Rock & Roll', 'Rock & Roll'), - (Text('Rock & Roll'), 'Rock & Roll'), - (HTML('
Hello, world!
'), 'Hello, world!
') + ('Rock & Roll', ''), + (Text('Rock & Roll'), ''), + (HTML('Hello, world!
'), '') ) @ddt.unpack def test_message_escaping(self, message, expected_message_html): diff --git a/openedx/core/djangoapps/util/user_messages.py b/openedx/core/djangoapps/util/user_messages.py index 961d6288d4..22ae96769d 100644 --- a/openedx/core/djangoapps/util/user_messages.py +++ b/openedx/core/djangoapps/util/user_messages.py @@ -87,7 +87,7 @@ class UserMessageCollection(): raise NotImplementedError('Subclasses must define a namespace for messages.') @classmethod - def get_message_html(self, body_html, title=None): + def get_message_html(self, body_html, title=None, dismissable=False): """ Returns the entire HTML snippet for the message. @@ -96,16 +96,35 @@ class UserMessageCollection(): not use a title can just pass the body_html. """ if title: - return Text(_('{header_open}{title}{header_close}{body}')).format( + title_area = Text(_('{header_open}{title}{header_close}')).format( header_open=HTML('') ) - return body_html + else: + title_area = '' + if dismissable: + dismiss_button = HTML( + '' + ).format( + dismiss_text=Text(_("Dismiss")) + ) + else: + dismiss_button = '' + return Text('{title_area}{body_area}{dismiss_button}').format( + title_area=title_area, + body_area=HTML('').format( + body_html=body_html, + ), + dismiss_button=dismiss_button, + ) @classmethod - def register_user_message(self, request, message_type, body_html, title=None): + def register_user_message(self, request, message_type, body_html, **kwargs): """ Register a message to be shown to the user in the next page. @@ -113,9 +132,10 @@ class UserMessageCollection(): message_type (UserMessageType): the user message type body_html (str): body of the message in html format title (str): optional title for the message as plain text + dismissable (bool): shows a dismiss button (defaults to no button) """ assert isinstance(message_type, UserMessageType) - message = Text(self.get_message_html(body_html, title)) + message = Text(self.get_message_html(body_html, **kwargs)) messages.add_message(request, message_type.value, Text(message), extra_tags=self.get_namespace()) @classmethod diff --git a/openedx/features/learner_profile/__init__.py b/openedx/features/learner_profile/__init__.py index d1d21fdd14..50ce2da8d4 100644 --- a/openedx/features/learner_profile/__init__.py +++ b/openedx/features/learner_profile/__init__.py @@ -11,3 +11,7 @@ WAFFLE_FLAG_NAMESPACE = WaffleFlagNamespace(name='learner_profile') # Waffle flag to show achievements on the learner profile. # TODO: LEARNER-2443: 08/2017: Remove flag after rollout. SHOW_ACHIEVEMENTS_FLAG = WaffleFlag(WAFFLE_FLAG_NAMESPACE, 'show_achievements') + +# Waffle flag for showing a message about the new profile features. +# TODO: LEARNER-2554: 09/2017: Remove flag once message is no longer needed. +SHOW_PROFILE_MESSAGE = WaffleFlag(WAFFLE_FLAG_NAMESPACE, 'show_message') diff --git a/openedx/features/learner_profile/static/learner_profile/js/learner_profile_factory.js b/openedx/features/learner_profile/static/learner_profile/js/learner_profile_factory.js index 321b1080bc..aa5dbeca66 100644 --- a/openedx/features/learner_profile/static/learner_profile/js/learner_profile_factory.js +++ b/openedx/features/learner_profile/static/learner_profile/js/learner_profile_factory.js @@ -25,6 +25,11 @@ return function(options) { var $learnerProfileElement = $('.wrapper-profile'); + // TODO: LEARNER-2554: 09/2017: Remove this hiding logic when the message is removed. + $('.action-dismiss').click(function() { + $('.user-messages').hide(); + }); + var accountSettingsModel = new AccountSettingsModel( _.extend( options.account_settings_data, diff --git a/openedx/features/learner_profile/static/learner_profile/js/views/learner_profile_view.js b/openedx/features/learner_profile/static/learner_profile/js/views/learner_profile_view.js index 59ee8a93ad..5510a03eb0 100644 --- a/openedx/features/learner_profile/static/learner_profile/js/views/learner_profile_view.js +++ b/openedx/features/learner_profile/static/learner_profile/js/views/learner_profile_view.js @@ -57,6 +57,13 @@ $('.wrapper-profile-section-container-one').removeClass('is-hidden'); $('.wrapper-profile-section-container-two').removeClass('is-hidden'); + // Only show accomplishments if this is a full profile + if (this.showFullProfile()) { + $('.learner-achievements').removeClass('is-hidden'); + } else { + $('.learner-achievements').addClass('is-hidden'); + } + if (this.showFullProfile() && (this.options.accountSettingsModel.get('accomplishments_shared'))) { tabs = [ {view: this.sectionTwoView, title: gettext('About Me'), url: 'about_me'}, diff --git a/openedx/features/learner_profile/templates/learner_profile/learner_profile.html b/openedx/features/learner_profile/templates/learner_profile/learner_profile.html index 9acbffea95..2160c7ecae 100644 --- a/openedx/features/learner_profile/templates/learner_profile/learner_profile.html +++ b/openedx/features/learner_profile/templates/learner_profile/learner_profile.html @@ -26,17 +26,17 @@ from openedx.core.djangolib.markup import HTML${_("Loading")}