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.
This commit is contained in:
@@ -1 +0,0 @@
|
||||
../../../templates/js/alert.underscore
|
||||
@@ -1 +0,0 @@
|
||||
../../../templates/js/notification.underscore
|
||||
@@ -1 +0,0 @@
|
||||
../../../templates/js/prompt.underscore
|
||||
1
cms/static/coffee/fixtures/system-feedback.underscore
Symbolic link
1
cms/static/coffee/fixtures/system-feedback.underscore
Symbolic link
@@ -0,0 +1 @@
|
||||
../../../templates/js/system-feedback.underscore
|
||||
@@ -8,27 +8,27 @@ describe "CMS.Models.SystemFeedback", ->
|
||||
it "should have an empty title by default", ->
|
||||
expect(@model.get("title")).toEqual("")
|
||||
|
||||
it "should not have a type set by default", ->
|
||||
expect(@model.get("type")).toBeNull()
|
||||
it "should not have an intent set by default", ->
|
||||
expect(@model.get("intent")).toBeNull()
|
||||
|
||||
|
||||
describe "CMS.Models.WarningMessage", ->
|
||||
beforeEach ->
|
||||
@model = new CMS.Models.WarningMessage()
|
||||
|
||||
it "should have the correct type", ->
|
||||
expect(@model.get("type")).toEqual("warning")
|
||||
it "should have the correct intent", ->
|
||||
expect(@model.get("intent")).toEqual("warning")
|
||||
|
||||
describe "CMS.Models.ErrorMessage", ->
|
||||
beforeEach ->
|
||||
@model = new CMS.Models.ErrorMessage()
|
||||
|
||||
it "should have the correct type", ->
|
||||
expect(@model.get("type")).toEqual("error")
|
||||
it "should have the correct intent", ->
|
||||
expect(@model.get("intent")).toEqual("error")
|
||||
|
||||
describe "CMS.Models.ConfirmationMessage", ->
|
||||
beforeEach ->
|
||||
@model = new CMS.Models.ConfirmationMessage()
|
||||
|
||||
it "should have the correct type", ->
|
||||
expect(@model.get("type")).toEqual("confirmation")
|
||||
it "should have the correct intent", ->
|
||||
expect(@model.get("intent")).toEqual("confirmation")
|
||||
|
||||
@@ -1,4 +1,10 @@
|
||||
tpl = readFixtures('system-feedback.underscore')
|
||||
|
||||
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
|
||||
toBeShown: ->
|
||||
@actual.hasClass("is-shown") and not @actual.hasClass("is-hiding")
|
||||
@@ -6,12 +12,7 @@ beforeEach ->
|
||||
@actual.hasClass("is-hiding") and not @actual.hasClass("is-shown")
|
||||
|
||||
describe "CMS.Views.Alert as base class", ->
|
||||
tpl = readFixtures('alert.underscore')
|
||||
|
||||
beforeEach ->
|
||||
setFixtures(sandbox({id: "page-alert"}))
|
||||
appendSetFixtures($("<script>", {id: "alert-tpl", type: "text/template"}).text(tpl))
|
||||
|
||||
@model = new CMS.Models.ConfirmationMessage({
|
||||
title: "Portal"
|
||||
message: "Welcome to the Aperture Science Computer-Aided Enrichment Center"
|
||||
@@ -40,12 +41,7 @@ describe "CMS.Views.Alert as base class", ->
|
||||
expect(view.$('.wrapper')).toBeHiding()
|
||||
|
||||
describe "CMS.Views.Prompt", ->
|
||||
tpl = readFixtures('prompt.underscore')
|
||||
|
||||
beforeEach ->
|
||||
setFixtures(sandbox({id: "page-prompt"}))
|
||||
appendSetFixtures($("<script>", {id: "prompt-tpl", type: "text/template"}).text(tpl))
|
||||
|
||||
@model = new CMS.Models.ConfirmationMessage({
|
||||
title: "Portal"
|
||||
message: "Welcome to the Aperture Science Computer-Aided Enrichment Center"
|
||||
@@ -62,8 +58,6 @@ describe "CMS.Views.Prompt", ->
|
||||
# expect($("body")).not.toHaveClass("prompt-is-shown")
|
||||
|
||||
describe "CMS.Views.Alert click events", ->
|
||||
tpl = readFixtures('alert.underscore')
|
||||
|
||||
beforeEach ->
|
||||
@model = new CMS.Models.WarningMessage(
|
||||
title: "Unsaved",
|
||||
@@ -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})
|
||||
|
||||
it "should trigger the primary event on a primary click", ->
|
||||
@@ -100,14 +92,9 @@ describe "CMS.Views.Alert click events", ->
|
||||
expect(@view.$(".action-secondary")).toHaveClass("cancel-button")
|
||||
|
||||
describe "CMS.Views.Notification minShown and maxShown", ->
|
||||
tpl = readFixtures('notification.underscore')
|
||||
|
||||
beforeEach ->
|
||||
setFixtures(sandbox({id: "page-notification"}))
|
||||
appendSetFixtures($("<script>", {id: "notification-tpl", type: "text/template"}).text(tpl))
|
||||
|
||||
@model = new CMS.Models.SystemFeedback(
|
||||
type: "saving"
|
||||
intent: "saving"
|
||||
title: "Saving"
|
||||
)
|
||||
spyOn(CMS.Views.Notification.prototype, 'show').andCallThrough()
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
CMS.Models.SystemFeedback = Backbone.Model.extend({
|
||||
defaults: {
|
||||
"type": null, // "warning", "confirmation", "error", "announcement", "step-required", etc
|
||||
"intent": null, // "warning", "confirmation", "error", "announcement", "step-required", etc
|
||||
"title": "",
|
||||
"message": ""
|
||||
/* could also have an "actions" hash: here is an example demonstrating
|
||||
@@ -32,18 +32,18 @@ CMS.Models.SystemFeedback = Backbone.Model.extend({
|
||||
|
||||
CMS.Models.WarningMessage = CMS.Models.SystemFeedback.extend({
|
||||
defaults: $.extend({}, CMS.Models.SystemFeedback.prototype.defaults, {
|
||||
"type": "warning"
|
||||
"intent": "warning"
|
||||
})
|
||||
});
|
||||
|
||||
CMS.Models.ErrorMessage = CMS.Models.SystemFeedback.extend({
|
||||
defaults: $.extend({}, CMS.Models.SystemFeedback.prototype.defaults, {
|
||||
"type": "error"
|
||||
"intent": "error"
|
||||
})
|
||||
});
|
||||
|
||||
CMS.Models.ConfirmationMessage = CMS.Models.SystemFeedback.extend({
|
||||
defaults: $.extend({}, CMS.Models.SystemFeedback.prototype.defaults, {
|
||||
"type": "confirmation"
|
||||
"intent": "confirmation"
|
||||
})
|
||||
});
|
||||
|
||||
@@ -23,7 +23,7 @@ CMS.Models.Section = Backbone.Model.extend({
|
||||
showNotification: function() {
|
||||
if(!this.msg) {
|
||||
this.msg = new CMS.Models.SystemFeedback({
|
||||
type: "saving",
|
||||
intent: "saving",
|
||||
title: gettext("Saving…")
|
||||
});
|
||||
}
|
||||
|
||||
@@ -2,14 +2,15 @@ CMS.Views.Alert = Backbone.View.extend({
|
||||
options: {
|
||||
type: "alert",
|
||||
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?
|
||||
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)
|
||||
},
|
||||
initialize: function() {
|
||||
var tpl = $("#"+this.options.type+"-tpl").text();
|
||||
var tpl = $("#system-feedback-tpl").text();
|
||||
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.setElement($("#page-"+this.options.type));
|
||||
@@ -86,7 +87,8 @@ CMS.Views.Notification = CMS.Views.Alert.extend({
|
||||
CMS.Views.Prompt = CMS.Views.Alert.extend({
|
||||
options: $.extend({}, CMS.Views.Alert.prototype.options, {
|
||||
type: "prompt",
|
||||
closeIcon: false
|
||||
closeIcon: false,
|
||||
icon: false
|
||||
}),
|
||||
render: function() {
|
||||
if(!window.$body) { window.$body = $(document.body); }
|
||||
|
||||
@@ -32,14 +32,8 @@
|
||||
<%include file="courseware_vendor_js.html"/>
|
||||
|
||||
## js templates
|
||||
<script id="alert-tpl" type="text/template">
|
||||
<%static:include path="js/alert.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 id="system-feedback-tpl" type="text/template">
|
||||
<%static:include path="js/system-feedback.underscore" />
|
||||
</script>
|
||||
|
||||
## javascript
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
<div class="wrapper wrapper-alert wrapper-alert-<%= type %>
|
||||
<% if(obj.shown) { %>is-shown<% } else { %>is-hiding<% } %>
|
||||
id="alert-<%= type %>"
|
||||
aria-hidden="<% if(obj.shown) { %>false<% } else { %>true<% } %>"
|
||||
aria-labelledby="alert-<%= type %>-title"
|
||||
<% if (obj.message) { %>aria-describedby="alert-<%= type %>-description" <% } %>
|
||||
<% if (obj.actions) { %>role="dialog"<% } %>
|
||||
>
|
||||
<div class="alert <%= type %> <% if(obj.actions) { %>has-actions<% } %>">
|
||||
<% var iconText = {"warning": "⚠", "confirmation": "✓", "error": "⚠", "announcement": "📢", "step-required": "", "help": "❓", "saving": "⚙"} %>
|
||||
<i class="ss-icon ss-symbolicons-block icon icon-<%= type %>"><%= iconText[type] %></i>
|
||||
|
||||
<div class="copy">
|
||||
<h2 class="title title-3" id="alert-<%= type %>-title"><%= title %></h2>
|
||||
<% if(obj.message) { %><p class="message" id="alert-<%= type %>-description"><%= message %></p><% } %>
|
||||
</div>
|
||||
|
||||
<% if(obj.actions) { %>
|
||||
<nav class="nav-actions">
|
||||
<h3 class="sr">Alert 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-alert-close">
|
||||
<i class="ss-icon ss-symbolicons-block icon icon-close">␡</i>
|
||||
<span class="label">close alert</span>
|
||||
</a>
|
||||
<% } %>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,46 +0,0 @@
|
||||
<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": "⚠", "confirmation": "✓", "error": "⚠", "announcement": "📢", "step-required": "", "help": "❓", "saving": "⚙"} %>
|
||||
<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">␡</i>
|
||||
<span class="label">close notification</span>
|
||||
</a>
|
||||
<% } %>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,35 +0,0 @@
|
||||
<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>
|
||||
48
cms/templates/js/system-feedback.underscore
Normal file
48
cms/templates/js/system-feedback.underscore
Normal file
@@ -0,0 +1,48 @@
|
||||
<div class="wrapper wrapper-<%= type %> wrapper-<%= type %>-<%= intent %>
|
||||
<% if(obj.shown) { %>is-shown<% } else { %>is-hiding<% } %>
|
||||
<% if(_.contains(['help', 'saving'], intent)) { %>wrapper-<%= type %>-status<% } %>"
|
||||
id="<%= type %>-<%= intent %>"
|
||||
aria-hidden="<% if(obj.shown) { %>false<% } else { %>true<% } %>"
|
||||
aria-labelledby="<%= type %>-<%= intent %>-title"
|
||||
<% if (obj.message) { %>aria-describedby="<%= type %>-<%= intent %>-description" <% } %>
|
||||
<% if (obj.actions) { %>role="dialog"<% } %>
|
||||
>
|
||||
<div class="<%= type %> <%= intent %> <% if(obj.actions) { %>has-actions<% } %>">
|
||||
<% if(obj.icon) { %>
|
||||
<% var iconText = {"warning": "⚠", "confirmation": "✓", "error": "⚠", "announcement": "📢", "step-required": "", "help": "❓", "saving": "⚙"} %>
|
||||
<i class="ss-icon ss-symbolicons-block icon icon-<%= intent %>"><%= iconText[intent] %></i>
|
||||
<% } %>
|
||||
|
||||
<div class="copy">
|
||||
<h2 class="title title-3" id="<%= type %>-<%= intent %>-title"><%= title %></h2>
|
||||
<% if(obj.message) { %><p class="message" id="<%= type %>-<%= intent %>-description"><%= message %></p><% } %>
|
||||
</div>
|
||||
|
||||
<% if(obj.actions) { %>
|
||||
<nav class="nav-actions">
|
||||
<h3 class="sr"><%= type %> 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-<%= type %>-close">
|
||||
<i class="ss-icon ss-symbolicons-block icon icon-close">␡</i>
|
||||
<span class="label">close <%= type %></span>
|
||||
</a>
|
||||
<% } %>
|
||||
</div>
|
||||
</div>
|
||||
Reference in New Issue
Block a user