Commit 9e864834 by David Baumgold

Unify system feedback templates

Also, a SystemFeedback model no longer has a `type`, it has an `intent`. This is
because SystemFeedback views have `type`, as well, and this prevents a naming
collision.
parent 1e7e3882
../../../templates/js/alert.underscore
\ No newline at end of file
../../../templates/js/notification.underscore
\ No newline at end of file
../../../templates/js/prompt.underscore
\ No newline at end of file
../../../templates/js/system-feedback.underscore
\ No newline at end of file
...@@ -8,27 +8,27 @@ describe "CMS.Models.SystemFeedback", -> ...@@ -8,27 +8,27 @@ describe "CMS.Models.SystemFeedback", ->
it "should have an empty title by default", -> it "should have an empty title by default", ->
expect(@model.get("title")).toEqual("") expect(@model.get("title")).toEqual("")
it "should not have a type set by default", -> it "should not have an intent set by default", ->
expect(@model.get("type")).toBeNull() expect(@model.get("intent")).toBeNull()
describe "CMS.Models.WarningMessage", -> describe "CMS.Models.WarningMessage", ->
beforeEach -> beforeEach ->
@model = new CMS.Models.WarningMessage() @model = new CMS.Models.WarningMessage()
it "should have the correct type", -> it "should have the correct intent", ->
expect(@model.get("type")).toEqual("warning") expect(@model.get("intent")).toEqual("warning")
describe "CMS.Models.ErrorMessage", -> describe "CMS.Models.ErrorMessage", ->
beforeEach -> beforeEach ->
@model = new CMS.Models.ErrorMessage() @model = new CMS.Models.ErrorMessage()
it "should have the correct type", -> it "should have the correct intent", ->
expect(@model.get("type")).toEqual("error") expect(@model.get("intent")).toEqual("error")
describe "CMS.Models.ConfirmationMessage", -> describe "CMS.Models.ConfirmationMessage", ->
beforeEach -> beforeEach ->
@model = new CMS.Models.ConfirmationMessage() @model = new CMS.Models.ConfirmationMessage()
it "should have the correct type", -> it "should have the correct intent", ->
expect(@model.get("type")).toEqual("confirmation") expect(@model.get("intent")).toEqual("confirmation")
tpl = readFixtures('system-feedback.underscore')
beforeEach -> beforeEach ->
setFixtures(sandbox({id: "page-alert"}))
appendSetFixtures(sandbox({id: "page-notification"}))
appendSetFixtures(sandbox({id: "page-prompt"}))
appendSetFixtures($("<script>", {id: "system-feedback-tpl", type: "text/template"}).text(tpl))
@addMatchers @addMatchers
toBeShown: -> toBeShown: ->
@actual.hasClass("is-shown") and not @actual.hasClass("is-hiding") @actual.hasClass("is-shown") and not @actual.hasClass("is-hiding")
...@@ -6,12 +12,7 @@ beforeEach -> ...@@ -6,12 +12,7 @@ beforeEach ->
@actual.hasClass("is-hiding") and not @actual.hasClass("is-shown") @actual.hasClass("is-hiding") and not @actual.hasClass("is-shown")
describe "CMS.Views.Alert as base class", -> describe "CMS.Views.Alert as base class", ->
tpl = readFixtures('alert.underscore')
beforeEach -> beforeEach ->
setFixtures(sandbox({id: "page-alert"}))
appendSetFixtures($("<script>", {id: "alert-tpl", type: "text/template"}).text(tpl))
@model = new CMS.Models.ConfirmationMessage({ @model = new CMS.Models.ConfirmationMessage({
title: "Portal" title: "Portal"
message: "Welcome to the Aperture Science Computer-Aided Enrichment Center" message: "Welcome to the Aperture Science Computer-Aided Enrichment Center"
...@@ -40,12 +41,7 @@ describe "CMS.Views.Alert as base class", -> ...@@ -40,12 +41,7 @@ describe "CMS.Views.Alert as base class", ->
expect(view.$('.wrapper')).toBeHiding() expect(view.$('.wrapper')).toBeHiding()
describe "CMS.Views.Prompt", -> describe "CMS.Views.Prompt", ->
tpl = readFixtures('prompt.underscore')
beforeEach -> beforeEach ->
setFixtures(sandbox({id: "page-prompt"}))
appendSetFixtures($("<script>", {id: "prompt-tpl", type: "text/template"}).text(tpl))
@model = new CMS.Models.ConfirmationMessage({ @model = new CMS.Models.ConfirmationMessage({
title: "Portal" title: "Portal"
message: "Welcome to the Aperture Science Computer-Aided Enrichment Center" message: "Welcome to the Aperture Science Computer-Aided Enrichment Center"
...@@ -62,8 +58,6 @@ describe "CMS.Views.Prompt", -> ...@@ -62,8 +58,6 @@ describe "CMS.Views.Prompt", ->
# expect($("body")).not.toHaveClass("prompt-is-shown") # expect($("body")).not.toHaveClass("prompt-is-shown")
describe "CMS.Views.Alert click events", -> describe "CMS.Views.Alert click events", ->
tpl = readFixtures('alert.underscore')
beforeEach -> beforeEach ->
@model = new CMS.Models.WarningMessage( @model = new CMS.Models.WarningMessage(
title: "Unsaved", title: "Unsaved",
...@@ -81,8 +75,6 @@ describe "CMS.Views.Alert click events", -> ...@@ -81,8 +75,6 @@ describe "CMS.Views.Alert click events", ->
) )
setFixtures(sandbox({id: "page-alert"}))
appendSetFixtures($("<script>", {id: "alert-tpl", type: "text/template"}).text(tpl))
@view = new CMS.Views.Alert({model: @model}) @view = new CMS.Views.Alert({model: @model})
it "should trigger the primary event on a primary click", -> it "should trigger the primary event on a primary click", ->
...@@ -100,14 +92,9 @@ describe "CMS.Views.Alert click events", -> ...@@ -100,14 +92,9 @@ describe "CMS.Views.Alert click events", ->
expect(@view.$(".action-secondary")).toHaveClass("cancel-button") expect(@view.$(".action-secondary")).toHaveClass("cancel-button")
describe "CMS.Views.Notification minShown and maxShown", -> describe "CMS.Views.Notification minShown and maxShown", ->
tpl = readFixtures('notification.underscore')
beforeEach -> beforeEach ->
setFixtures(sandbox({id: "page-notification"}))
appendSetFixtures($("<script>", {id: "notification-tpl", type: "text/template"}).text(tpl))
@model = new CMS.Models.SystemFeedback( @model = new CMS.Models.SystemFeedback(
type: "saving" intent: "saving"
title: "Saving" title: "Saving"
) )
spyOn(CMS.Views.Notification.prototype, 'show').andCallThrough() spyOn(CMS.Views.Notification.prototype, 'show').andCallThrough()
......
CMS.Models.SystemFeedback = Backbone.Model.extend({ CMS.Models.SystemFeedback = Backbone.Model.extend({
defaults: { defaults: {
"type": null, // "warning", "confirmation", "error", "announcement", "step-required", etc "intent": null, // "warning", "confirmation", "error", "announcement", "step-required", etc
"title": "", "title": "",
"message": "" "message": ""
/* could also have an "actions" hash: here is an example demonstrating /* could also have an "actions" hash: here is an example demonstrating
...@@ -32,18 +32,18 @@ CMS.Models.SystemFeedback = Backbone.Model.extend({ ...@@ -32,18 +32,18 @@ CMS.Models.SystemFeedback = Backbone.Model.extend({
CMS.Models.WarningMessage = CMS.Models.SystemFeedback.extend({ CMS.Models.WarningMessage = CMS.Models.SystemFeedback.extend({
defaults: $.extend({}, CMS.Models.SystemFeedback.prototype.defaults, { defaults: $.extend({}, CMS.Models.SystemFeedback.prototype.defaults, {
"type": "warning" "intent": "warning"
}) })
}); });
CMS.Models.ErrorMessage = CMS.Models.SystemFeedback.extend({ CMS.Models.ErrorMessage = CMS.Models.SystemFeedback.extend({
defaults: $.extend({}, CMS.Models.SystemFeedback.prototype.defaults, { defaults: $.extend({}, CMS.Models.SystemFeedback.prototype.defaults, {
"type": "error" "intent": "error"
}) })
}); });
CMS.Models.ConfirmationMessage = CMS.Models.SystemFeedback.extend({ CMS.Models.ConfirmationMessage = CMS.Models.SystemFeedback.extend({
defaults: $.extend({}, CMS.Models.SystemFeedback.prototype.defaults, { defaults: $.extend({}, CMS.Models.SystemFeedback.prototype.defaults, {
"type": "confirmation" "intent": "confirmation"
}) })
}); });
...@@ -23,7 +23,7 @@ CMS.Models.Section = Backbone.Model.extend({ ...@@ -23,7 +23,7 @@ CMS.Models.Section = Backbone.Model.extend({
showNotification: function() { showNotification: function() {
if(!this.msg) { if(!this.msg) {
this.msg = new CMS.Models.SystemFeedback({ this.msg = new CMS.Models.SystemFeedback({
type: "saving", intent: "saving",
title: gettext("Saving&hellip;") title: gettext("Saving&hellip;")
}); });
} }
......
...@@ -2,14 +2,15 @@ CMS.Views.Alert = Backbone.View.extend({ ...@@ -2,14 +2,15 @@ CMS.Views.Alert = Backbone.View.extend({
options: { options: {
type: "alert", type: "alert",
shown: true, // is this view currently being shown? shown: true, // is this view currently being shown?
icon: true, // should we render an icon related to the message intent?
closeIcon: true, // should we render a close button in the top right corner? closeIcon: true, // should we render a close button in the top right corner?
minShown: 0, // length of time after this view has been shown before it can be hidden (milliseconds) minShown: 0, // length of time after this view has been shown before it can be hidden (milliseconds)
maxShown: Infinity // length of time after this view has been shown before it will be automatically hidden (milliseconds) maxShown: Infinity // length of time after this view has been shown before it will be automatically hidden (milliseconds)
}, },
initialize: function() { initialize: function() {
var tpl = $("#"+this.options.type+"-tpl").text(); var tpl = $("#system-feedback-tpl").text();
if(!tpl) { if(!tpl) {
console.error("Couldn't load template from ID "+this.options.type+"-tpl"); console.error("Couldn't load system-feedback template");
} }
this.template = _.template(tpl); this.template = _.template(tpl);
this.setElement($("#page-"+this.options.type)); this.setElement($("#page-"+this.options.type));
...@@ -86,7 +87,8 @@ CMS.Views.Notification = CMS.Views.Alert.extend({ ...@@ -86,7 +87,8 @@ CMS.Views.Notification = CMS.Views.Alert.extend({
CMS.Views.Prompt = CMS.Views.Alert.extend({ CMS.Views.Prompt = CMS.Views.Alert.extend({
options: $.extend({}, CMS.Views.Alert.prototype.options, { options: $.extend({}, CMS.Views.Alert.prototype.options, {
type: "prompt", type: "prompt",
closeIcon: false closeIcon: false,
icon: false
}), }),
render: function() { render: function() {
if(!window.$body) { window.$body = $(document.body); } if(!window.$body) { window.$body = $(document.body); }
......
...@@ -32,14 +32,8 @@ ...@@ -32,14 +32,8 @@
<%include file="courseware_vendor_js.html"/> <%include file="courseware_vendor_js.html"/>
## js templates ## js templates
<script id="alert-tpl" type="text/template"> <script id="system-feedback-tpl" type="text/template">
<%static:include path="js/alert.underscore" /> <%static:include path="js/system-feedback.underscore" />
</script>
<script id="notification-tpl" type="text/template">
<%static:include path="js/notification.underscore" />
</script>
<script id="prompt-tpl" type="text/template">
<%static:include path="js/prompt.underscore" />
</script> </script>
## javascript ## javascript
......
<div class="wrapper wrapper-notification wrapper-notification-<%= type %>
<% if(obj.shown) { %>is-shown<% } else { %>is-hiding<% } %>
<% if(_.contains(['help', 'saving'], type)) { %>wrapper-notification-status<% } %>"
id="notification-<%= type %>"
aria-hidden="<% if(obj.shown) { %>false<% } else { %>true<% } %>"
aria-labelledby="notification-<%= type %>-title"
<% if (obj.message) { %>aria-describedby="notification-<%= type %>-description" <% } %>
<% if (obj.actions) { %>role="dialog"<% } %>
>
<div class="notification <%= type %> <% if(obj.actions) { %>has-actions<% } %>">
<% var iconText = {"warning": "&#x26A0;", "confirmation": "&#x2713;", "error": "&#x26A0;", "announcement": "&#x1F4E2;", "step-required": "&#xE0D1", "help": "&#x2753;", "saving": "&#x2699;"} %>
<i class="ss-icon ss-symbolicons-block icon icon-<%= type %>"><%= iconText[type] %></i>
<div class="copy">
<h2 class="title title-3" id="notification-<%= type %>-title"><%= title %></h2>
<% if(obj.message) { %><p class="message" id="notification-<%= type %>-description"><%= message %></p><% } %>
</div>
<% if(obj.actions) { %>
<nav class="nav-actions">
<h3 class="sr">Notification Actions</h3>
<ul>
<% if(actions.primary) { %>
<li class="nav-item">
<a href="#" class="button action-primary <%= actions.primary.class %>"><%= actions.primary.text %></a>
</li>
<% } %>
<% if(actions.secondary) {
_.each(actions.secondary, function(secondary) { %>
<li class="nav-item">
<a href="#" class="button action-secondary <%= secondary.class %>"><%= secondary.text %></a>
</li>
<% });
} %>
</ul>
</nav>
<% } %>
<% if(obj.closeIcon) { %>
<a href="#" rel="view" class="action action-close action-notification-close">
<i class="ss-icon ss-symbolicons-block icon icon-close">&#x2421;</i>
<span class="label">close notification</span>
</a>
<% } %>
</div>
</div>
<div class="wrapper wrapper-prompt wrapper-prompt-<%= type %>
<% if(obj.shown) { %>is-shown<% } else { %>is-hiding<% } %>
id="prompt-<%= type %>"
aria-hidden="<% if(obj.shown) { %>false<% } else { %>true<% } %>"
aria-labelledby="prompt-<%= type %>-title"
<% if (obj.message) { %>aria-describedby="prompt-<%= type %>-description" <% } %>
<% if (obj.actions) { %>role="dialog"<% } %>
>
<div class="prompt <%= type %> <% if(obj.actions) { %>has-actions<% } %>">
<div class="copy">
<h2 class="title title-3" id="prompt-<%= type %>-title"><%= title %></h2>
<% if(obj.message) { %><p class="message" id="prompt-<%= type %>-description"><%= message %></p><% } %>
</div>
<% if(obj.actions) { %>
<nav class="nav-actions">
<h3 class="sr">Prompt Actions</h3>
<ul>
<% if(actions.primary) { %>
<li class="nav-item">
<a href="#" class="button action-primary <%= actions.primary.class %>"><%= actions.primary.text %></a>
</li>
<% } %>
<% if(actions.secondary) {
_.each(actions.secondary, function(secondary) { %>
<li class="nav-item">
<a href="#" class="button action-secondary <%= secondary.class %>"><%= secondary.text %></a>
</li>
<% });
} %>
</ul>
</nav>
<% } %>
</div>
</div>
<div class="wrapper wrapper-alert wrapper-alert-<%= type %> <div class="wrapper wrapper-<%= type %> wrapper-<%= type %>-<%= intent %>
<% if(obj.shown) { %>is-shown<% } else { %>is-hiding<% } %> <% if(obj.shown) { %>is-shown<% } else { %>is-hiding<% } %>
id="alert-<%= type %>" <% if(_.contains(['help', 'saving'], intent)) { %>wrapper-<%= type %>-status<% } %>"
id="<%= type %>-<%= intent %>"
aria-hidden="<% if(obj.shown) { %>false<% } else { %>true<% } %>" aria-hidden="<% if(obj.shown) { %>false<% } else { %>true<% } %>"
aria-labelledby="alert-<%= type %>-title" aria-labelledby="<%= type %>-<%= intent %>-title"
<% if (obj.message) { %>aria-describedby="alert-<%= type %>-description" <% } %> <% if (obj.message) { %>aria-describedby="<%= type %>-<%= intent %>-description" <% } %>
<% if (obj.actions) { %>role="dialog"<% } %> <% if (obj.actions) { %>role="dialog"<% } %>
> >
<div class="alert <%= type %> <% if(obj.actions) { %>has-actions<% } %>"> <div class="<%= type %> <%= intent %> <% if(obj.actions) { %>has-actions<% } %>">
<% if(obj.icon) { %>
<% var iconText = {"warning": "&#x26A0;", "confirmation": "&#x2713;", "error": "&#x26A0;", "announcement": "&#x1F4E2;", "step-required": "&#xE0D1", "help": "&#x2753;", "saving": "&#x2699;"} %> <% var iconText = {"warning": "&#x26A0;", "confirmation": "&#x2713;", "error": "&#x26A0;", "announcement": "&#x1F4E2;", "step-required": "&#xE0D1", "help": "&#x2753;", "saving": "&#x2699;"} %>
<i class="ss-icon ss-symbolicons-block icon icon-<%= type %>"><%= iconText[type] %></i> <i class="ss-icon ss-symbolicons-block icon icon-<%= intent %>"><%= iconText[intent] %></i>
<% } %>
<div class="copy"> <div class="copy">
<h2 class="title title-3" id="alert-<%= type %>-title"><%= title %></h2> <h2 class="title title-3" id="<%= type %>-<%= intent %>-title"><%= title %></h2>
<% if(obj.message) { %><p class="message" id="alert-<%= type %>-description"><%= message %></p><% } %> <% if(obj.message) { %><p class="message" id="<%= type %>-<%= intent %>-description"><%= message %></p><% } %>
</div> </div>
<% if(obj.actions) { %> <% if(obj.actions) { %>
<nav class="nav-actions"> <nav class="nav-actions">
<h3 class="sr">Alert Actions</h3> <h3 class="sr"><%= type %> Actions</h3>
<ul> <ul>
<% if(actions.primary) { %> <% if(actions.primary) { %>
<li class="nav-item"> <li class="nav-item">
...@@ -36,9 +39,9 @@ ...@@ -36,9 +39,9 @@
<% } %> <% } %>
<% if(obj.closeIcon) { %> <% if(obj.closeIcon) { %>
<a href="#" rel="view" class="action action-close action-alert-close"> <a href="#" rel="view" class="action action-close action-<%= type %>-close">
<i class="ss-icon ss-symbolicons-block icon icon-close">&#x2421;</i> <i class="ss-icon ss-symbolicons-block icon icon-close">&#x2421;</i>
<span class="label">close alert</span> <span class="label">close <%= type %></span>
</a> </a>
<% } %> <% } %>
</div> </div>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment