feat: Update new files notification banner styles (#33197)
Uses the updated styles for the notification based on the new designs. Includes a button to open view the files directly in the notification. This also fix a bug where the notification was not appearing when paste a whole Unit.
This commit is contained in:
@@ -1406,11 +1406,16 @@ class ContentStoreTest(ContentStoreTestCase):
|
||||
self.assertEqual(resp.status_code, 404)
|
||||
return
|
||||
|
||||
assets_url = reverse_course_url(
|
||||
'assets_handler',
|
||||
course.location.course_key
|
||||
)
|
||||
self.assertContains(
|
||||
resp,
|
||||
'<article class="outline outline-complex outline-course" data-locator="{locator}" data-course-key="{course_key}">'.format( # lint-amnesty, pylint: disable=line-too-long
|
||||
'<article class="outline outline-complex outline-course" data-locator="{locator}" data-course-key="{course_key}" data-course-assets="{assets_url}">'.format( # lint-amnesty, pylint: disable=line-too-long
|
||||
locator=str(course.location),
|
||||
course_key=str(course.id),
|
||||
assets_url=assets_url,
|
||||
),
|
||||
status_code=200,
|
||||
html=True
|
||||
|
||||
@@ -9,6 +9,7 @@ from unittest.mock import Mock, patch
|
||||
|
||||
from django.http import Http404
|
||||
from django.test.client import RequestFactory
|
||||
from django.urls import reverse
|
||||
from pytz import UTC
|
||||
from urllib.parse import quote
|
||||
|
||||
@@ -57,11 +58,16 @@ class ContainerPageTestCase(StudioPageTestCase, LibraryTestCase):
|
||||
self.store.publish(self.vertical.location, self.user.id)
|
||||
|
||||
def test_container_html(self):
|
||||
assets_url = reverse(
|
||||
'assets_handler', kwargs={'course_key_string': str(self.child_container.location.course_key)}
|
||||
)
|
||||
self._test_html_content(
|
||||
self.child_container,
|
||||
expected_section_tag=(
|
||||
'<section class="wrapper-xblock level-page is-hidden studio-xblock-wrapper" '
|
||||
'data-locator="{0}" data-course-key="{0.course_key}">'.format(self.child_container.location)
|
||||
'data-locator="{0}" data-course-key="{0.course_key}" data-course-assets="{1}">'.format(
|
||||
self.child_container.location, assets_url
|
||||
)
|
||||
),
|
||||
expected_breadcrumbs=(
|
||||
'<li class="nav-item">\\s*<a href="/course/{course}{section_parameters}">Week 1<\\/a>.*'
|
||||
@@ -86,11 +92,16 @@ class ContainerPageTestCase(StudioPageTestCase, LibraryTestCase):
|
||||
self._create_block(draft_container, "html", "Child HTML")
|
||||
|
||||
def test_container_html(xblock):
|
||||
assets_url = reverse(
|
||||
'assets_handler', kwargs={'course_key_string': str(draft_container.location.course_key)}
|
||||
)
|
||||
self._test_html_content(
|
||||
xblock,
|
||||
expected_section_tag=(
|
||||
'<section class="wrapper-xblock level-page is-hidden studio-xblock-wrapper" '
|
||||
'data-locator="{0}" data-course-key="{0.course_key}">'.format(draft_container.location)
|
||||
'data-locator="{0}" data-course-key="{0.course_key}" data-course-assets="{1}">'.format(
|
||||
draft_container.location, assets_url
|
||||
)
|
||||
),
|
||||
expected_breadcrumbs=(
|
||||
'<a href="/course/{course}{subsection_parameters}">Lesson 1</a>.*'
|
||||
|
||||
@@ -10,10 +10,11 @@
|
||||
*/
|
||||
define(['jquery', 'underscore', 'js/views/xblock_outline', 'edx-ui-toolkit/js/utils/string-utils',
|
||||
'common/js/components/utils/view_utils', 'js/views/utils/xblock_utils',
|
||||
'js/models/xblock_outline_info', 'js/views/modals/course_outline_modals', 'js/utils/drag_and_drop'],
|
||||
'js/models/xblock_outline_info', 'js/views/modals/course_outline_modals', 'js/utils/drag_and_drop',
|
||||
'common/js/components/views/feedback_notification', 'common/js/components/views/feedback_prompt',],
|
||||
function(
|
||||
$, _, XBlockOutlineView, StringUtils, ViewUtils, XBlockViewUtils,
|
||||
XBlockOutlineInfo, CourseOutlineModalsFactory, ContentDragger
|
||||
XBlockOutlineInfo, CourseOutlineModalsFactory, ContentDragger, NotificationView, PromptView
|
||||
) {
|
||||
var CourseOutlineView = XBlockOutlineView.extend({
|
||||
// takes XBlockOutlineInfo as a model
|
||||
@@ -380,13 +381,29 @@ function(
|
||||
}));
|
||||
}
|
||||
if (newFiles.length) {
|
||||
notices.push(() => new NotificationView.Confirmation({
|
||||
title: gettext("New files were added to this course's Files & Uploads"),
|
||||
notices.push(() => new NotificationView.Info({
|
||||
title: gettext("New file(s) added to Files & Uploads."),
|
||||
message: (
|
||||
gettext("The following required files were imported to this course:") +
|
||||
" " + newFiles.join(", ")
|
||||
),
|
||||
closeIcon: true,
|
||||
actions: {
|
||||
primary: {
|
||||
text: gettext('View files'),
|
||||
click: function(notification) {
|
||||
const article = document.querySelector('[data-course-assets]');
|
||||
const assetsUrl = $(article).attr('data-course-assets');
|
||||
window.location.href = assetsUrl;
|
||||
return;
|
||||
}
|
||||
},
|
||||
secondary: {
|
||||
text: gettext('Dismiss'),
|
||||
click: function(notification) {
|
||||
return notification.hide();
|
||||
}
|
||||
}
|
||||
}
|
||||
}));
|
||||
}
|
||||
if (notices.length) {
|
||||
|
||||
@@ -293,13 +293,29 @@ function($, _, Backbone, gettext, BasePage, ViewUtils, ContainerView, XBlockView
|
||||
}));
|
||||
}
|
||||
if (newFiles.length) {
|
||||
notices.push(() => new NotificationView.Confirmation({
|
||||
title: gettext("New files were added to this course's Files & Uploads"),
|
||||
notices.push(() => new NotificationView.Info({
|
||||
title: gettext("New file(s) added to Files & Uploads."),
|
||||
message: (
|
||||
gettext("The following required files were imported to this course:") +
|
||||
" " + newFiles.join(", ")
|
||||
),
|
||||
closeIcon: true,
|
||||
actions: {
|
||||
primary: {
|
||||
text: gettext('View files'),
|
||||
click: function(notification) {
|
||||
const section = document.querySelector('[data-course-assets]');
|
||||
const assetsUrl = $(section).attr('data-course-assets');
|
||||
window.location.href = assetsUrl;
|
||||
return;
|
||||
}
|
||||
},
|
||||
secondary: {
|
||||
text: gettext('Dismiss'),
|
||||
click: function(notification) {
|
||||
return notification.hide();
|
||||
}
|
||||
}
|
||||
}
|
||||
}));
|
||||
}
|
||||
if (notices.length) {
|
||||
|
||||
@@ -401,6 +401,14 @@
|
||||
}
|
||||
}
|
||||
|
||||
&.wrapper-notification-info {
|
||||
box-shadow: 0 -1px 3px $shadow, inset 0 3px 1px $blue;
|
||||
|
||||
.feedback-symbol {
|
||||
color: $blue;
|
||||
}
|
||||
}
|
||||
|
||||
&.wrapper-notification-mini {
|
||||
box-shadow: 0 -1px 3px $shadow, inset 0 3px 1px $pink;
|
||||
}
|
||||
@@ -554,15 +562,35 @@
|
||||
}
|
||||
|
||||
.action-primary {
|
||||
@include blue-button();
|
||||
@extend %btn-primary-blue;
|
||||
@extend %sizing;
|
||||
|
||||
@extend %t-strong;
|
||||
.action-button-text {
|
||||
display: inline-block;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
border-color: $blue-d2;
|
||||
.icon {
|
||||
display: inline-block;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
// CASE: new/create button
|
||||
&.new-button,
|
||||
&.button-new {
|
||||
@extend %btn-primary-green;
|
||||
@extend %sizing;
|
||||
}
|
||||
}
|
||||
|
||||
.action-secondary {
|
||||
@extend %t-action4;
|
||||
color: $white;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
color: $gray-l3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ else:
|
||||
%>
|
||||
</%def>
|
||||
<%!
|
||||
from django.urls import reverse
|
||||
from django.utils.translation import gettext as _
|
||||
|
||||
from cms.djangoapps.contentstore.helpers import xblock_studio_url, xblock_type_display_name
|
||||
@@ -166,7 +167,10 @@ from openedx.core.djangolib.markup import HTML, Text
|
||||
|
||||
<article class="content-primary">
|
||||
<div class="container-message wrapper-message"></div>
|
||||
<section class="wrapper-xblock level-page is-hidden studio-xblock-wrapper" data-locator="${xblock_locator}" data-course-key="${xblock_locator.course_key}">
|
||||
<%
|
||||
assets_url = reverse('assets_handler', kwargs={'course_key_string': str(xblock_locator.course_key)})
|
||||
%>
|
||||
<section class="wrapper-xblock level-page is-hidden studio-xblock-wrapper" data-locator="${xblock_locator}" data-course-key="${xblock_locator.course_key}" data-course-assets="${assets_url}">
|
||||
</section>
|
||||
<div class="ui-loading">
|
||||
<p><span class="spin"><span class="icon fa fa-refresh" aria-hidden="true"></span></span> <span class="copy">${_("Loading")}</span></p>
|
||||
|
||||
@@ -278,9 +278,10 @@ from django.urls import reverse
|
||||
>
|
||||
<%
|
||||
course_locator = context_course.location
|
||||
assets_url = reverse('assets_handler', kwargs={'course_key_string': str(course_locator.course_key)})
|
||||
%>
|
||||
<h2 class="sr">${_("Course Outline")}</h2>
|
||||
<article class="outline outline-complex outline-course" data-locator="${course_locator}" data-course-key="${course_locator.course_key}">
|
||||
<article class="outline outline-complex outline-course" data-locator="${course_locator}" data-course-key="${course_locator.course_key}" data-course-assets="${assets_url}">
|
||||
</article>
|
||||
</div>
|
||||
<div class="ui-loading">
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
// create Notification.Warning, Notification.Confirmation, etc
|
||||
var capitalCamel, intents, miniOptions;
|
||||
capitalCamel = _.compose(str.capitalize, str.camelize);
|
||||
intents = ['warning', 'error', 'confirmation', 'announcement', 'step-required', 'help', 'mini'];
|
||||
intents = ['warning', 'error', 'confirmation', 'announcement', 'step-required', 'help', 'mini', 'info'];
|
||||
_.each(intents, function(intent) {
|
||||
var subclass;
|
||||
subclass = Notification.extend({
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
>
|
||||
<div class="<%- type %> <%- intent %> <% if(obj.actions) { %>has-actions<% } %>">
|
||||
<% if(obj.icon) { %>
|
||||
<% var iconClass = {"warning": "warning", "confirmation": "check", "error": "warning", "announcement": "bullhorn", "step-required": "exclamation-circle", "help": "question", "mini": "cog"} %>
|
||||
<% var iconClass = {"warning": "warning", "confirmation": "check", "error": "warning", "announcement": "bullhorn", "step-required": "exclamation-circle", "help": "question", "mini": "cog", "info": "info-circle"} %>
|
||||
<span class="feedback-symbol fa fa-<%- iconClass[intent] %>" aria-hidden="true"></span>
|
||||
<% } %>
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
<% if(actions.secondary) {
|
||||
_.each(actions.secondary, function(secondary) { %>
|
||||
<li class="nav-item">
|
||||
<button class="action-secondary <%- secondary.class %>"><%- secondary.text %></button>
|
||||
<a class="action-secondary <%- secondary.class %>" tabindex="0"><%- secondary.text %></a>
|
||||
</li>
|
||||
<% });
|
||||
} %>
|
||||
|
||||
Reference in New Issue
Block a user