diff --git a/common/static/common/js/discussion/utils.js b/common/static/common/js/discussion/utils.js index 8309681e48..69ef9d5ff1 100644 --- a/common/static/common/js/discussion/utils.js +++ b/common/static/common/js/discussion/utils.js @@ -252,33 +252,36 @@ }; DiscussionUtil.formErrorHandler = function(errorsField) { - return function(xhr, textStatus, error) { - var makeErrorElem, response, _i, _len, _ref, _results, $errorItem; - makeErrorElem = function(message) { - return edx.HtmlUtils.setHtml( - $('
  • ').addClass('post-error'), - message + return function(xhr) { + var makeErrorElem, response, i, $errorItem; + makeErrorElem = function(message, alertId) { + return edx.HtmlUtils.joinHtml( + edx.HtmlUtils.HTML('
  • '), + edx.HtmlUtils.template( + $('#new-post-alert-template').html() + )({ + message: message, + alertId: alertId + }), + edx.HtmlUtils.HTML('
  • ') ); }; errorsField.empty().show(); if (xhr.status === 400) { response = JSON.parse(xhr.responseText); if (response.errors) { - _ref = response.errors; - _results = []; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - error = _ref[_i]; - $errorItem = makeErrorElem(error); - _results.push(errorsField.append($errorItem)); + for (i = 0; i < response.errors.length; i++) { + $errorItem = makeErrorElem(response.errors[i], i); + edx.HtmlUtils.append(errorsField, $errorItem); } - return _results; } } else { - $errorItem = makeErrorElem( - gettext('We had some trouble processing your request. Please try again.') - ); - return errorsField.append($errorItem); + $errorItem = makeErrorElem('We had some trouble processing your request. Please try again.', 0); + edx.HtmlUtils.append(errorsField, $errorItem); } + + // Set focus on the first error displayed + $('div[role="alert"]', errorsField).first().focus(); }; }; diff --git a/common/static/common/js/spec/discussion/view/response_comment_view_spec.js b/common/static/common/js/spec/discussion/view/response_comment_view_spec.js index 859701a884..57d5fbfeea 100644 --- a/common/static/common/js/spec/discussion/view/response_comment_view_spec.js +++ b/common/static/common/js/spec/discussion/view/response_comment_view_spec.js @@ -195,7 +195,7 @@ expect($.ajax.calls.mostRecent().args[0].data.body).toEqual(this.updatedBody); expect(this.view.model.get('body')).toEqual(originalBody); expect(this.view.cancelEdit).not.toHaveBeenCalled(); - return expect(this.view.$('.edit-comment-form-errors *').length).toEqual(1); + return expect(this.view.$('.edit-comment-form-errors > *').length).toEqual(1); }); }); }); diff --git a/common/static/common/js/spec_helpers/discussion_spec_helper.js b/common/static/common/js/spec_helpers/discussion_spec_helper.js index 0fe17ce3b4..c255106e3c 100644 --- a/common/static/common/js/spec_helpers/discussion_spec_helper.js +++ b/common/static/common/js/spec_helpers/discussion_spec_helper.js @@ -74,7 +74,7 @@ templateNames = [ 'thread', 'thread-show', 'thread-edit', 'thread-response', 'thread-response-show', 'thread-response-edit', 'response-comment-show', 'response-comment-edit', 'thread-list-item', - 'discussion-home', 'search-alert', 'new-post', 'thread-type', 'new-post-menu-entry', + 'discussion-home', 'search-alert', 'new-post', 'thread-type', 'new-post-menu-entry', 'new-post-alert', 'new-post-menu-category', 'topic', 'post-user-display', 'inline-discussion', 'pagination', 'profile-thread', 'customwmd-prompt', 'nav-loading' ]; diff --git a/common/static/common/templates/discussion/new-post-alert.underscore b/common/static/common/templates/discussion/new-post-alert.underscore new file mode 100644 index 0000000000..8327588432 --- /dev/null +++ b/common/static/common/templates/discussion/new-post-alert.underscore @@ -0,0 +1,13 @@ + diff --git a/lms/static/sass/discussion/views/_create-edit-post.scss b/lms/static/sass/discussion/views/_create-edit-post.scss index c7b39b8316..21a9951db8 100644 --- a/lms/static/sass/discussion/views/_create-edit-post.scss +++ b/lms/static/sass/discussion/views/_create-edit-post.scss @@ -11,6 +11,11 @@ padding: $baseline; max-width: 1180px; + .post-errors { + padding: 0 !important; + list-style: none !important; + } + .post-field { margin-bottom: $baseline; @@ -183,23 +188,9 @@ .forum-new-post-form, .edit-post-form { .post-errors { - margin-bottom: $baseline; - border-radius: $forum-border-radius; padding: 0; - background: $error-color; - box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3) inset, 0 1px 0 rgba(255, 255, 255, .2); - color: $white; + margin: 0 0 $baseline 0; list-style: none; - - .post-error { - padding: ($baseline/2) $baseline 12px 45px; - border-bottom: 1px solid $forum-color-error; - background: url('#{$static-path}/images/white-error-icon.png') no-repeat 15px 14px; - - &:last-child { - border-bottom: none; - } - } } } diff --git a/lms/static/sass/shared/_alerts_pattern_library_shim.scss b/lms/static/sass/shared/_alerts_pattern_library_shim.scss index 4619135d9d..a5e17c993a 100644 --- a/lms/static/sass/shared/_alerts_pattern_library_shim.scss +++ b/lms/static/sass/shared/_alerts_pattern_library_shim.scss @@ -19,38 +19,49 @@ // #CONFIG // ---------------------------- -// alert colors -$alert-information-color: #6fa0ba; -$alert-warning-color: #fdbc56; -$alert-error-color: #b20610; -$alert-success-color: #25b85a; -$alert-background-color: #fcfcfc; -$alert-icon-color: #fcfcfc; -$alert-border-grey: #cdd7db; -$alert-shadow-grey: #eef1f2; - -// alert borders -$alert-border-radius: 0.3125rem; -$alert-border: 0.0625rem solid $alert-border-grey; +// Overrides for other things available in the UXPL but not here +// This is super gross. Don't do this in other places if you can avoid it. +$palette-brand-accent: #2991c3; +$palette-brand-back: #cce3f0; +$palette-warning-accent: #ffc01f; +$palette-warning-back: #fff9eb; +$palette-error-accent: #cb0712; +$palette-error-back: #feeced; +$palette-success-accent: #009b00; +$palette-success-back: #ecfaec; +$palette-grey-accent: #a0a0a0; +$palette-grey-back: #d9d9d9; +$spacing-vertical-xx-small: ($baseline / 4); +$spacing-vertical-x-small: ($baseline / 2); +$spacing-vertical-small: $baseline; +$spacing-horizontal-small: ($baseline / 2); +$spacing-horizontal-base: $baseline; +$font-size-small: 14px; +$bp-screen-md: 768px !default; // ---------------------------- // #UTILITIES // ---------------------------- -@mixin alert($alert-color) { - border-top: rem(2) solid $alert-color; +@mixin alert($shim-alert-color, $shim-alert-color-glow) { + border: 1px solid $shim-alert-color; + box-shadow: inset 0 0 0 4px $shim-alert-color-glow; .alert-icon { - color: $alert-icon-color; - background-color: $alert-color; + color: $white; + background-color: $shim-alert-color; } } @mixin alert-message($width) { - @include float(left); - width: $width; - padding: 1.25rem; - padding-top: 0; - padding-bottom: 0; + box-sizing: border-box; + + @media (min-width: $bp-screen-md) { + @include float(left); + width: $width; + padding: $spacing-vertical-small; + padding-top: 0; + padding-bottom: 0; + } :last-child { // keeps the message compact @@ -60,65 +71,104 @@ $alert-border: 0.0625rem solid $alert-border-grey; // everything below here gets added specificity pattern-library-shim .pattern-library-shim { - // ---------------------------- // #GENERAL // ---------------------------- - &.alert { - background-color: $alert-background-color; - border: $alert-border; - border-radius: $alert-border-radius; - border-top-left-radius: 0; - border-top-right-radius: 0; - padding: 1.25rem; + background-color: $white; + border: 1px solid $palette-grey-accent; + padding: $spacing-vertical-small $spacing-horizontal-base; + box-shadow: inset 0 0 0 4px $palette-grey-back; overflow: auto; - box-shadow: 0 rem(2) rem(2) 0 $alert-shadow-grey; + + &.alert-slim { + padding: $spacing-vertical-x-small; + + .alert-message { + padding: $spacing-vertical-small $spacing-horizontal-base; + font-size: $font-size-small; + + .copy { + margin-bottom: 0; + } + } + } + + &.alert-tiny { + padding: $spacing-vertical-x-small; + + .alert-message { + padding: $spacing-vertical-x-small $spacing-horizontal-small; + font-size: $font-size-small; + + .copy { + margin-bottom: 0; + + .icon { + display: inline-block; + margin-right: $baseline; + } + } + } + } } - &.alert-icon { - @include float(left); - display: block; + .alert-icon { + // hide icons on small screens + display: none; - // create a circle around the icon - border-radius: 50%; + @media (min-width: $bp-screen-md) { + @include float(left); + display: block; - // create room around the icon for the circle - padding: 0.625rem; + // create a circle around the icon + border-radius: 50%; + + // create room around the icon for the circle + padding: $spacing-vertical-x-small; + } } - &.alert-message-with-action { + .alert-message-with-action { // provide room for the action to be displayed next to the alert message @include alert-message(70%); } - &.alert-message { + .alert-message { @include alert-message(90%); } - &.alert-title { + .alert-title { @extend %hd-5; @extend %headings-emphasized; - // shift the section up to make the alert more compact - margin-top: -0.625rem; + @media (min-width: $bp-screen-md) { + // shift the section up to make the alert more compact + margin-top: - $spacing-vertical-x-small; + } } - &.alert-copy { + .alert-copy { @extend %copy-base; - // shift the message down to be in line with the icon - margin-top: 0.3125rem; + @media (min-width: $bp-screen-md) { + // shift the message down to be in line with the icon + margin-top: $spacing-vertical-xx-small; + } } - &.alert-copy-with-title { + .alert-copy-with-title { @extend %copy-base; } - &.alert-action { - @include float(right); - width: inherit; + .alert-action { + width: 100%; + + @media (min-width: $bp-screen-md) { + @include float(right); + width: inherit; + } } // ---------------------------- @@ -127,46 +177,21 @@ $alert-border: 0.0625rem solid $alert-border-grey; // information-based alert &.alert-information { - @include alert($alert-information-color); + @include alert($palette-brand-accent, $palette-brand-back); } // warning-based alert &.alert-warning { - @include alert($alert-warning-color); + @include alert($palette-warning-accent, $palette-warning-back); } // error-based alert &.alert-error { - @include alert($alert-error-color); + @include alert($palette-error-accent, $palette-error-back); } // success-based alert &.alert-success { - @include alert($alert-success-color); - } - - // added from _icons.scss - &.icon { - display: inline-block; - height: auto; - width: auto; - font-family: FontAwesome; - speak: none; - font-style: normal; - font-weight: normal; - font-variant: normal; - text-transform: none; - line-height: 1; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; - } - &.icon-bullhorn:before { - content: "\f0a1"; - } - - // handles negative margin on navigation bar - &.subsection-header { - margin-top: -4px; - margin-bottom: 14px; + @include alert($palette-success-accent, $palette-success-back); } } diff --git a/lms/templates/discussion/_underscore_templates.html b/lms/templates/discussion/_underscore_templates.html index 571da7b815..6c87246665 100644 --- a/lms/templates/discussion/_underscore_templates.html +++ b/lms/templates/discussion/_underscore_templates.html @@ -15,8 +15,8 @@ template_names = [ 'thread', 'thread-show', 'thread-edit', 'thread-response', 'thread-response-show', 'thread-response-edit', 'response-comment-show', 'response-comment-edit', 'thread-list-item', 'discussion-home', 'search-alert', - 'new-post', 'thread-type', 'new-post-menu-entry', 'new-post-menu-category', 'topic', 'post-user-display', - 'inline-discussion', 'pagination', 'profile-thread', 'customwmd-prompt', 'nav-loading' + 'new-post', 'new-post-menu-entry', 'new-post-menu-category', 'new-post-alert', 'topic', 'post-user-display', + 'inline-discussion', 'pagination', 'profile-thread', 'customwmd-prompt', 'nav-loading', 'thread-type' ] ## same, but without trailing "-template" in script ID - these templates does not contain any free variables