Merge pull request #9265 from edx/ammar/use-studio-confirmation-dialog-in-lms
Confirm when leaving team
This commit is contained in:
@@ -92,7 +92,7 @@ def press_the_notification_button(_step, name):
|
||||
# the "Save" button at the UI level.
|
||||
# Instead, we use JavaScript to reliably click
|
||||
# the button.
|
||||
btn_css = 'div#page-notification a.action-%s' % name.lower()
|
||||
btn_css = 'div#page-notification button.action-%s' % name.lower()
|
||||
world.trigger_event(btn_css, event='focus')
|
||||
world.browser.execute_script("$('{}').click()".format(btn_css))
|
||||
world.wait_for_ajax_complete()
|
||||
@@ -284,7 +284,7 @@ def button_disabled(step, value):
|
||||
def _do_studio_prompt_action(intent, action):
|
||||
"""
|
||||
Wait for a studio prompt to appear and press the specified action button
|
||||
See cms/static/js/views/feedback_prompt.js for implementation
|
||||
See common/js/components/views/feedback_prompt.js for implementation
|
||||
"""
|
||||
assert intent in [
|
||||
'warning',
|
||||
@@ -299,7 +299,7 @@ def _do_studio_prompt_action(intent, action):
|
||||
|
||||
world.wait_for_present('div.wrapper-prompt.is-shown#prompt-{}'.format(intent))
|
||||
|
||||
action_css = 'li.nav-item > a.action-{}'.format(action)
|
||||
action_css = 'li.nav-item > button.action-{}'.format(action)
|
||||
world.trigger_event(action_css, event='focus')
|
||||
world.browser.execute_script("$('{}').click()".format(action_css))
|
||||
|
||||
|
||||
@@ -97,7 +97,7 @@ def delete_components(step, number):
|
||||
world.wait_for_xmodule()
|
||||
delete_btn_css = 'a.delete-button'
|
||||
prompt_css = 'div#prompt-warning'
|
||||
btn_css = '{} a.button.action-primary'.format(prompt_css)
|
||||
btn_css = '{} button.action-primary'.format(prompt_css)
|
||||
saving_mini_css = 'div#page-notification .wrapper-notification-mini'
|
||||
for _ in range(int(number)):
|
||||
world.css_click(delete_btn_css)
|
||||
|
||||
@@ -49,8 +49,7 @@ def get_an_error_dialog(step):
|
||||
|
||||
@step('I can click to go to the unit with the error$')
|
||||
def i_click_on_error_dialog(step):
|
||||
world.wait_for_visible(".button.action-primary")
|
||||
world.click_link_by_text('Correct failed component')
|
||||
world.css_click("button.action-primary")
|
||||
|
||||
problem_string = unicode(world.scenario_dict['COURSE'].id.make_usage_key("problem", 'ignore'))
|
||||
problem_string = u"Problem {}".format(problem_string[:problem_string.rfind('ignore')])
|
||||
|
||||
@@ -75,7 +75,7 @@ def i_press_the_section_delete_icon(step):
|
||||
|
||||
@step(u'I will confirm all alerts')
|
||||
def i_confirm_all_alerts(step):
|
||||
confirm_locator = '.prompt .nav-actions a.action-primary'
|
||||
confirm_locator = '.prompt .nav-actions button.action-primary'
|
||||
world.css_click(confirm_locator)
|
||||
|
||||
|
||||
|
||||
@@ -220,7 +220,6 @@ define([
|
||||
"coffee/spec/models/settings_grading_spec", "coffee/spec/models/textbook_spec",
|
||||
"coffee/spec/models/upload_spec",
|
||||
|
||||
"coffee/spec/views/course_info_spec", "coffee/spec/views/feedback_spec",
|
||||
"coffee/spec/views/metadata_edit_spec", "coffee/spec/views/module_edit_spec",
|
||||
"coffee/spec/views/textbook_spec", "coffee/spec/views/upload_spec",
|
||||
|
||||
@@ -254,8 +253,6 @@ define([
|
||||
"js/spec/views/license_spec",
|
||||
"js/spec/views/paging_spec",
|
||||
|
||||
"js/spec/views/utils/view_utils_spec",
|
||||
|
||||
"js/spec/views/pages/container_spec",
|
||||
"js/spec/views/pages/container_subviews_spec",
|
||||
"js/spec/views/pages/group_configurations_spec",
|
||||
|
||||
@@ -21,10 +21,8 @@ require ["jquery", "backbone", "coffee/src/main", "common/js/spec_helpers/ajax_h
|
||||
expect($.ajaxSettings.headers["X-CSRFToken"]).toEqual("stubCSRFToken")
|
||||
|
||||
describe "AJAX Errors", ->
|
||||
tpl = readFixtures('system-feedback.underscore')
|
||||
|
||||
beforeEach ->
|
||||
setFixtures($("<script>", {id: "system-feedback-tpl", type: "text/template"}).text(tpl))
|
||||
appendSetFixtures(sandbox({id: "page-notification"}))
|
||||
|
||||
it "successful AJAX request does not pop an error notification", ->
|
||||
|
||||
@@ -1,14 +1,12 @@
|
||||
define ["jquery", "jasmine", "common/js/spec_helpers/ajax_helpers", "squire"],
|
||||
($, jasmine, AjaxHelpers, Squire) ->
|
||||
|
||||
feedbackTpl = readFixtures('system-feedback.underscore')
|
||||
assetLibraryTpl = readFixtures('asset-library.underscore')
|
||||
assetTpl = readFixtures('asset.underscore')
|
||||
|
||||
describe "Asset view", ->
|
||||
beforeEach ->
|
||||
setFixtures($("<script>", {id: "asset-tpl", type: "text/template"}).text(assetTpl))
|
||||
appendSetFixtures($("<script>", {id: "system-feedback-tpl", type: "text/template"}).text(feedbackTpl))
|
||||
appendSetFixtures(sandbox({id: "page-prompt"}))
|
||||
|
||||
@promptSpies = jasmine.createSpyObj('Prompt.Warning', ["constructor", "show", "hide"])
|
||||
@@ -24,10 +22,10 @@ define ["jquery", "jasmine", "common/js/spec_helpers/ajax_helpers", "squire"],
|
||||
@savingSpies.show.andReturn(@savingSpies)
|
||||
|
||||
@injector = new Squire()
|
||||
@injector.mock("js/views/feedback_prompt", {
|
||||
@injector.mock("common/js/components/views/feedback_prompt", {
|
||||
"Warning": @promptSpies.constructor
|
||||
})
|
||||
@injector.mock("js/views/feedback_notification", {
|
||||
@injector.mock("common/js/components/views/feedback_notification", {
|
||||
"Confirmation": @confirmationSpies.constructor,
|
||||
"Mini": @savingSpies.constructor
|
||||
})
|
||||
@@ -139,7 +137,6 @@ define ["jquery", "jasmine", "common/js/spec_helpers/ajax_helpers", "squire"],
|
||||
beforeEach ->
|
||||
setFixtures($("<script>", {id: "asset-library-tpl", type: "text/template"}).text(assetLibraryTpl))
|
||||
appendSetFixtures($("<script>", {id: "asset-tpl", type: "text/template"}).text(assetTpl))
|
||||
appendSetFixtures($("<script>", {id: "system-feedback-tpl", type: "text/template"}).text(feedbackTpl))
|
||||
window.analytics = jasmine.createSpyObj('analytics', ['track'])
|
||||
window.course_location_analytics = jasmine.createSpy()
|
||||
appendSetFixtures(sandbox({id: "asset_table_body"}))
|
||||
@@ -149,7 +146,7 @@ define ["jquery", "jasmine", "common/js/spec_helpers/ajax_helpers", "squire"],
|
||||
@promptSpies.show.andReturn(@promptSpies)
|
||||
|
||||
@injector = new Squire()
|
||||
@injector.mock("js/views/feedback_prompt", {
|
||||
@injector.mock("common/js/components/views/feedback_prompt", {
|
||||
"Warning": @promptSpies.constructor
|
||||
})
|
||||
|
||||
|
||||
@@ -1,315 +0,0 @@
|
||||
define ["jquery", "js/views/feedback", "js/views/feedback_notification", "js/views/feedback_alert",
|
||||
"js/views/feedback_prompt", "sinon"],
|
||||
($, SystemFeedback, NotificationView, AlertView, PromptView, sinon) ->
|
||||
|
||||
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")
|
||||
toBeHiding: ->
|
||||
@actual.hasClass("is-hiding") and not @actual.hasClass("is-shown")
|
||||
toContainText: (text) ->
|
||||
# remove this when we upgrade jasmine-jquery
|
||||
trimmedText = $.trim(@actual.text())
|
||||
if text and $.isFunction(text.test)
|
||||
return text.test(trimmedText)
|
||||
else
|
||||
return trimmedText.indexOf(text) != -1;
|
||||
toHaveBeenPrevented: ->
|
||||
# remove this when we upgrade jasmine-jquery
|
||||
eventName = @actual.eventName
|
||||
selector = @actual.selector
|
||||
@message = ->
|
||||
[
|
||||
"Expected event #{eventName} to have been prevented on #{selector}",
|
||||
"Expected event #{eventName} not to have been prevented on #{selector}"
|
||||
]
|
||||
return jasmine.JQuery.events.wasPrevented(selector, eventName)
|
||||
|
||||
describe "SystemFeedback", ->
|
||||
beforeEach ->
|
||||
@options =
|
||||
title: "Portal"
|
||||
message: "Welcome to the Aperture Science Computer-Aided Enrichment Center"
|
||||
# it will be interesting to see when this.render is called, so lets spy on it
|
||||
@renderSpy = spyOn(AlertView.Confirmation.prototype, 'render').andCallThrough()
|
||||
@showSpy = spyOn(AlertView.Confirmation.prototype, 'show').andCallThrough()
|
||||
@hideSpy = spyOn(AlertView.Confirmation.prototype, 'hide').andCallThrough()
|
||||
@clock = sinon.useFakeTimers()
|
||||
|
||||
afterEach ->
|
||||
@clock.restore()
|
||||
|
||||
it "requires a type and an intent", ->
|
||||
neither = =>
|
||||
new SystemFeedback(@options)
|
||||
noType = =>
|
||||
options = $.extend({}, @options)
|
||||
options.intent = "confirmation"
|
||||
new SystemFeedback(options)
|
||||
noIntent = =>
|
||||
options = $.extend({}, @options)
|
||||
options.type = "alert"
|
||||
new SystemFeedback(options)
|
||||
both = =>
|
||||
options = $.extend({}, @options)
|
||||
options.type = "alert"
|
||||
options.intent = "confirmation"
|
||||
new SystemFeedback(options)
|
||||
|
||||
expect(neither).toThrow()
|
||||
expect(noType).toThrow()
|
||||
expect(noIntent).toThrow()
|
||||
expect(both).not.toThrow()
|
||||
|
||||
# for simplicity, we'll use AlertView.Confirmation from here on,
|
||||
# which extends and proxies to SystemFeedback
|
||||
|
||||
it "does not show on initalize", ->
|
||||
view = new AlertView.Confirmation(@options)
|
||||
expect(@renderSpy).not.toHaveBeenCalled()
|
||||
expect(@showSpy).not.toHaveBeenCalled()
|
||||
|
||||
# Disabled flaky test TNL-559
|
||||
xit "renders the template", ->
|
||||
view = new AlertView.Confirmation(@options)
|
||||
view.show()
|
||||
|
||||
expect(view.$(".action-close")).toBeDefined()
|
||||
expect(view.$('.wrapper')).toBeShown()
|
||||
expect(view.$el).toContainText(@options.title)
|
||||
expect(view.$el).toContainText(@options.message)
|
||||
|
||||
# Disabled flaky test TNL-559
|
||||
xit "close button sends a .hide() message", ->
|
||||
view = new AlertView.Confirmation(@options).show()
|
||||
view.$(".action-close").click()
|
||||
expect(@hideSpy).toHaveBeenCalled()
|
||||
@clock.tick(900)
|
||||
expect(view.$('.wrapper')).toBeHiding()
|
||||
|
||||
describe "PromptView", ->
|
||||
# for some reason, expect($("body")) blows up the test runner, so this test
|
||||
# just exercises the Prompt rather than asserting on anything. Best I can
|
||||
# do for now. :(
|
||||
it "changes class on body", ->
|
||||
# expect($("body")).not.toHaveClass("prompt-is-shown")
|
||||
view = new PromptView.Confirmation({
|
||||
title: "Portal"
|
||||
message: "Welcome to the Aperture Science Computer-Aided Enrichment Center"
|
||||
})
|
||||
# expect($("body")).toHaveClass("prompt-is-shown")
|
||||
view.hide()
|
||||
# expect($("body")).not.toHaveClass("prompt-is-shown")
|
||||
|
||||
describe "NotificationView.Mini", ->
|
||||
beforeEach ->
|
||||
@view = new NotificationView.Mini()
|
||||
|
||||
it "should have minShown set to 1250 by default", ->
|
||||
expect(@view.options.minShown).toEqual(1250)
|
||||
|
||||
it "should have closeIcon set to false by default", ->
|
||||
expect(@view.options.closeIcon).toBeFalsy()
|
||||
|
||||
# Disabled flaky test TNL-559
|
||||
xdescribe "SystemFeedback click events", ->
|
||||
beforeEach ->
|
||||
@primaryClickSpy = jasmine.createSpy('primaryClick')
|
||||
@secondaryClickSpy = jasmine.createSpy('secondaryClick')
|
||||
@view = new NotificationView.Warning(
|
||||
title: "Unsaved",
|
||||
message: "Your content is currently Unsaved.",
|
||||
actions:
|
||||
primary:
|
||||
text: "Save",
|
||||
class: "save-button",
|
||||
click: @primaryClickSpy
|
||||
secondary:
|
||||
text: "Revert",
|
||||
class: "cancel-button",
|
||||
click: @secondaryClickSpy
|
||||
)
|
||||
@view.show()
|
||||
|
||||
it "should trigger the primary event on a primary click", ->
|
||||
@view.$(".action-primary").click()
|
||||
expect(@primaryClickSpy).toHaveBeenCalled()
|
||||
expect(@secondaryClickSpy).not.toHaveBeenCalled()
|
||||
|
||||
it "should trigger the secondary event on a secondary click", ->
|
||||
@view.$(".action-secondary").click()
|
||||
expect(@secondaryClickSpy).toHaveBeenCalled()
|
||||
expect(@primaryClickSpy).not.toHaveBeenCalled()
|
||||
|
||||
it "should apply class to primary action", ->
|
||||
expect(@view.$(".action-primary")).toHaveClass("save-button")
|
||||
|
||||
it "should apply class to secondary action", ->
|
||||
expect(@view.$(".action-secondary")).toHaveClass("cancel-button")
|
||||
|
||||
it "should preventDefault on primary action", ->
|
||||
spyOnEvent(".action-primary", "click")
|
||||
@view.$(".action-primary").click()
|
||||
expect("click").toHaveBeenPreventedOn(".action-primary")
|
||||
|
||||
it "should preventDefault on secondary action", ->
|
||||
spyOnEvent(".action-secondary", "click")
|
||||
@view.$(".action-secondary").click()
|
||||
expect("click").toHaveBeenPreventedOn(".action-secondary")
|
||||
|
||||
# Disabled flaky test TNL-559
|
||||
xdescribe "SystemFeedback not preventing events", ->
|
||||
beforeEach ->
|
||||
@clickSpy = jasmine.createSpy('clickSpy')
|
||||
@view = new AlertView.Confirmation(
|
||||
title: "It's all good"
|
||||
message: "No reason for this alert"
|
||||
actions:
|
||||
primary:
|
||||
text: "Whatever"
|
||||
click: @clickSpy
|
||||
preventDefault: false
|
||||
)
|
||||
@view.show()
|
||||
|
||||
it "should not preventDefault", ->
|
||||
spyOnEvent(".action-primary", "click")
|
||||
@view.$(".action-primary").click()
|
||||
expect("click").not.toHaveBeenPreventedOn(".action-primary")
|
||||
expect(@clickSpy).toHaveBeenCalled()
|
||||
|
||||
# Disabled flaky test TNL-559
|
||||
xdescribe "SystemFeedback multiple secondary actions", ->
|
||||
beforeEach ->
|
||||
@secondarySpyOne = jasmine.createSpy('secondarySpyOne')
|
||||
@secondarySpyTwo = jasmine.createSpy('secondarySpyTwo')
|
||||
@view = new NotificationView.Warning(
|
||||
title: "No Primary",
|
||||
message: "Pick a secondary action",
|
||||
actions:
|
||||
secondary: [
|
||||
{
|
||||
text: "Option One"
|
||||
class: "option-one"
|
||||
click: @secondarySpyOne
|
||||
}, {
|
||||
text: "Option Two"
|
||||
class: "option-two"
|
||||
click: @secondarySpyTwo
|
||||
}
|
||||
]
|
||||
)
|
||||
@view.show()
|
||||
|
||||
it "should render both", ->
|
||||
expect(@view.el).toContain(".action-secondary.option-one")
|
||||
expect(@view.el).toContain(".action-secondary.option-two")
|
||||
expect(@view.el).not.toContain(".action-secondary.option-one.option-two")
|
||||
expect(@view.$(".action-secondary.option-one")).toContainText("Option One")
|
||||
expect(@view.$(".action-secondary.option-two")).toContainText("Option Two")
|
||||
|
||||
it "should differentiate clicks (1)", ->
|
||||
@view.$(".option-one").click()
|
||||
expect(@secondarySpyOne).toHaveBeenCalled()
|
||||
expect(@secondarySpyTwo).not.toHaveBeenCalled()
|
||||
|
||||
it "should differentiate clicks (2)", ->
|
||||
@view.$(".option-two").click()
|
||||
expect(@secondarySpyOne).not.toHaveBeenCalled()
|
||||
expect(@secondarySpyTwo).toHaveBeenCalled()
|
||||
|
||||
describe "NotificationView minShown and maxShown", ->
|
||||
beforeEach ->
|
||||
@showSpy = spyOn(NotificationView.Confirmation.prototype, 'show')
|
||||
@showSpy.andCallThrough()
|
||||
@hideSpy = spyOn(NotificationView.Confirmation.prototype, 'hide')
|
||||
@hideSpy.andCallThrough()
|
||||
@clock = sinon.useFakeTimers()
|
||||
|
||||
afterEach ->
|
||||
@clock.restore()
|
||||
|
||||
# Disabled flaky test TNL-559
|
||||
xit "should not have minShown or maxShown by default", ->
|
||||
view = new NotificationView.Confirmation()
|
||||
expect(view.options.minShown).toEqual(0)
|
||||
expect(view.options.maxShown).toEqual(Infinity)
|
||||
|
||||
# Disabled flaky test TNL-559
|
||||
xit "a minShown view should not hide too quickly", ->
|
||||
view = new NotificationView.Confirmation({minShown: 1000})
|
||||
view.show()
|
||||
expect(view.$('.wrapper')).toBeShown()
|
||||
|
||||
# call hide() on it, but the minShown should prevent it from hiding right away
|
||||
view.hide()
|
||||
expect(view.$('.wrapper')).toBeShown()
|
||||
|
||||
# wait for the minShown timeout to expire, and check again
|
||||
@clock.tick(1001)
|
||||
expect(view.$('.wrapper')).toBeHiding()
|
||||
|
||||
# Disabled flaky test TNL-559
|
||||
xit "a maxShown view should hide by itself", ->
|
||||
view = new NotificationView.Confirmation({maxShown: 1000})
|
||||
view.show()
|
||||
expect(view.$('.wrapper')).toBeShown()
|
||||
|
||||
# wait for the maxShown timeout to expire, and check again
|
||||
@clock.tick(1001)
|
||||
expect(view.$('.wrapper')).toBeHiding()
|
||||
|
||||
# Disabled flaky test TNL-559
|
||||
xit "a minShown view can stay visible longer", ->
|
||||
view = new NotificationView.Confirmation({minShown: 1000})
|
||||
view.show()
|
||||
expect(view.$('.wrapper')).toBeShown()
|
||||
|
||||
# wait for the minShown timeout to expire, and check again
|
||||
@clock.tick(1001)
|
||||
expect(@hideSpy).not.toHaveBeenCalled()
|
||||
expect(view.$('.wrapper')).toBeShown()
|
||||
|
||||
# can now hide immediately
|
||||
view.hide()
|
||||
expect(view.$('.wrapper')).toBeHiding()
|
||||
|
||||
# Disabled flaky test TNL-559
|
||||
xit "a maxShown view can hide early", ->
|
||||
view = new NotificationView.Confirmation({maxShown: 1000})
|
||||
view.show()
|
||||
expect(view.$('.wrapper')).toBeShown()
|
||||
|
||||
# wait 50 milliseconds, and hide it early
|
||||
@clock.tick(50)
|
||||
view.hide()
|
||||
expect(view.$('.wrapper')).toBeHiding()
|
||||
|
||||
# wait for timeout to expire, make sure it doesn't do anything weird
|
||||
@clock.tick(1000)
|
||||
expect(view.$('.wrapper')).toBeHiding()
|
||||
|
||||
it "a view can have both maxShown and minShown", ->
|
||||
view = new NotificationView.Confirmation({minShown: 1000, maxShown: 2000})
|
||||
view.show()
|
||||
|
||||
# can't hide early
|
||||
@clock.tick(50)
|
||||
view.hide()
|
||||
expect(view.$('.wrapper')).toBeShown()
|
||||
@clock.tick(1000)
|
||||
expect(view.$('.wrapper')).toBeHiding()
|
||||
|
||||
# show it again, and let it hide automatically
|
||||
view.show()
|
||||
@clock.tick(1050)
|
||||
expect(view.$('.wrapper')).toBeShown()
|
||||
@clock.tick(1000)
|
||||
expect(view.$('.wrapper')).toBeHiding()
|
||||
@@ -1,9 +1,9 @@
|
||||
define ["js/models/textbook", "js/models/chapter", "js/collections/chapter", "js/models/course",
|
||||
"js/collections/textbook", "js/views/show_textbook", "js/views/edit_textbook", "js/views/list_textbooks",
|
||||
"js/views/edit_chapter", "js/views/feedback_prompt", "js/views/feedback_notification", "js/views/utils/view_utils",
|
||||
"common/js/spec_helpers/ajax_helpers", "js/spec_helpers/modal_helpers", "jasmine-stealth"],
|
||||
"js/views/edit_chapter", "common/js/components/views/feedback_prompt",
|
||||
"common/js/components/views/feedback_notification", "common/js/components/utils/view_utils","common/js/spec_helpers/ajax_helpers",
|
||||
"js/spec_helpers/modal_helpers", "jasmine-stealth"],
|
||||
(Textbook, Chapter, ChapterSet, Course, TextbookSet, ShowTextbook, EditTextbook, ListTextbooks, EditChapter, Prompt, Notification, ViewUtils, AjaxHelpers, modal_helpers) ->
|
||||
feedbackTpl = readFixtures('system-feedback.underscore')
|
||||
|
||||
beforeEach ->
|
||||
# remove this when we upgrade jasmine-jquery
|
||||
@@ -20,7 +20,6 @@ define ["js/models/textbook", "js/models/chapter", "js/collections/chapter", "js
|
||||
|
||||
beforeEach ->
|
||||
setFixtures($("<script>", {id: "show-textbook-tpl", type: "text/template"}).text(tpl))
|
||||
appendSetFixtures($("<script>", {id: "system-feedback-tpl", type: "text/template"}).text(feedbackTpl))
|
||||
appendSetFixtures(sandbox({id: "page-notification"}))
|
||||
appendSetFixtures(sandbox({id: "page-prompt"}))
|
||||
@model = new Textbook({name: "Life Sciences", id: "0life-sciences"})
|
||||
@@ -110,7 +109,6 @@ define ["js/models/textbook", "js/models/chapter", "js/collections/chapter", "js
|
||||
beforeEach ->
|
||||
setFixtures($("<script>", {id: "edit-textbook-tpl", type: "text/template"}).text(tpl))
|
||||
appendSetFixtures($("<script>", {id: "edit-chapter-tpl", type: "text/template"}).text(chapterTpl))
|
||||
appendSetFixtures($("<script>", {id: "system-feedback-tpl", type: "text/template"}).text(feedbackTpl))
|
||||
appendSetFixtures(sandbox({id: "page-notification"}))
|
||||
appendSetFixtures(sandbox({id: "page-prompt"}))
|
||||
@model = new Textbook({name: "Life Sciences", editing: true})
|
||||
@@ -232,7 +230,6 @@ define ["js/models/textbook", "js/models/chapter", "js/collections/chapter", "js
|
||||
#
|
||||
# beforeEach ->
|
||||
# setFixtures($("<script>", {id: "no-textbooks-tpl", type: "text/template"}).text(noTextbooksTpl))
|
||||
# appendSetFixtures($("<script>", {id: "system-feedback-tpl", type: "text/template"}).text(feedbackTpl))
|
||||
# @showSpies = spyOnConstructor("ShowTextbook", ["render"])
|
||||
# @showSpies.render.andReturn(@showSpies) # equivalent of `return this`
|
||||
# showEl = $("<li>")
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
define ["js/models/uploads", "js/views/uploads", "js/models/chapter", "common/js/spec_helpers/ajax_helpers", "js/spec_helpers/modal_helpers"], (FileUpload, UploadDialog, Chapter, AjaxHelpers, modal_helpers) ->
|
||||
|
||||
feedbackTpl = readFixtures('system-feedback.underscore')
|
||||
|
||||
describe "UploadDialog", ->
|
||||
tpl = readFixtures("upload-dialog.underscore")
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
define ["domReady", "jquery", "underscore.string", "backbone", "gettext",
|
||||
"js/views/feedback_notification",
|
||||
"common/js/components/views/feedback_notification",
|
||||
"coffee/src/ajax_prefix", "jquery.cookie"],
|
||||
(domReady, $, str, Backbone, gettext, NotificationView) ->
|
||||
main = ->
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
define ["jquery", "jquery.ui", "backbone", "js/views/feedback_prompt", "js/views/feedback_notification",
|
||||
"coffee/src/views/module_edit", "js/models/module_info", "js/utils/module"],
|
||||
define ["jquery", "jquery.ui", "backbone", "common/js/components/views/feedback_prompt",
|
||||
"common/js/components/views/feedback_notification", "coffee/src/views/module_edit", "js/models/module_info", "js/utils/module"],
|
||||
($, ui, Backbone, PromptView, NotificationView, ModuleEditView, ModuleModel, ModuleUtils) ->
|
||||
class TabsEdit extends Backbone.View
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
define [
|
||||
"jquery", "backbone", "xblock/runtime.v1", "URI", "gettext",
|
||||
"js/utils/modal", "js/views/feedback_notification"
|
||||
"js/utils/modal", "common/js/components/views/feedback_notification"
|
||||
], ($, Backbone, XBlock, URI, gettext, ModalUtils, NotificationView) ->
|
||||
|
||||
@BaseRuntime = {}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
require(["domReady", "jquery", "underscore", "gettext", "js/views/feedback_notification", "js/views/feedback_prompt",
|
||||
"js/utils/date_utils", "js/utils/module", "js/utils/handle_iframe_binding",
|
||||
"jquery.ui", "jquery.leanModal", "jquery.form", "jquery.smoothScroll"],
|
||||
require(["domReady", "jquery", "underscore", "gettext", "common/js/components/views/feedback_notification",
|
||||
"common/js/components/views/feedback_prompt", "js/utils/date_utils",
|
||||
"js/utils/module", "js/utils/handle_iframe_binding", "jquery.ui", "jquery.leanModal",
|
||||
"jquery.form", "jquery.smoothScroll"],
|
||||
function(domReady, $, _, gettext, NotificationView, PromptView, DateUtils, ModuleUtils, IframeUtils)
|
||||
{
|
||||
|
||||
|
||||
@@ -7,10 +7,10 @@ define([ // jshint ignore:line
|
||||
'js/certificates/models/certificate',
|
||||
'js/certificates/views/certificate_details',
|
||||
'js/certificates/views/certificate_preview',
|
||||
'js/views/feedback_notification',
|
||||
'common/js/components/views/feedback_notification',
|
||||
'common/js/spec_helpers/ajax_helpers',
|
||||
'common/js/spec_helpers/template_helpers',
|
||||
'js/spec_helpers/view_helpers',
|
||||
'common/js/spec_helpers/view_helpers',
|
||||
'js/spec_helpers/validation_helpers',
|
||||
'js/certificates/spec/custom_matchers'
|
||||
],
|
||||
|
||||
@@ -7,10 +7,10 @@ define([ // jshint ignore:line
|
||||
'js/certificates/models/signatory',
|
||||
'js/certificates/collections/certificates',
|
||||
'js/certificates/views/certificate_editor',
|
||||
'js/views/feedback_notification',
|
||||
'common/js/components/views/feedback_notification',
|
||||
'common/js/spec_helpers/ajax_helpers',
|
||||
'common/js/spec_helpers/template_helpers',
|
||||
'js/spec_helpers/view_helpers',
|
||||
'common/js/spec_helpers/view_helpers',
|
||||
'js/spec_helpers/validation_helpers',
|
||||
'js/certificates/spec/custom_matchers'
|
||||
],
|
||||
|
||||
@@ -6,7 +6,7 @@ define([ // jshint ignore:line
|
||||
'js/models/course',
|
||||
'js/certificates/views/certificate_preview',
|
||||
'common/js/spec_helpers/template_helpers',
|
||||
'js/spec_helpers/view_helpers',
|
||||
'common/js/spec_helpers/view_helpers',
|
||||
'common/js/spec_helpers/ajax_helpers'
|
||||
],
|
||||
function(_, $, Course, CertificatePreview, TemplateHelpers, ViewHelpers, AjaxHelpers) {
|
||||
|
||||
@@ -10,7 +10,7 @@ define([ // jshint ignore:line
|
||||
'js/certificates/views/certificate_item',
|
||||
'js/certificates/views/certificates_list',
|
||||
'js/certificates/views/certificate_preview',
|
||||
'js/views/feedback_notification',
|
||||
'common/js/components/views/feedback_notification',
|
||||
'common/js/spec_helpers/ajax_helpers',
|
||||
'common/js/spec_helpers/template_helpers',
|
||||
'js/certificates/spec/custom_matchers'
|
||||
|
||||
@@ -8,7 +8,7 @@ define([ // jshint ignore:line
|
||||
'js/views/baseview',
|
||||
'js/certificates/models/signatory',
|
||||
'js/certificates/views/signatory_details',
|
||||
'js/views/utils/view_utils'
|
||||
'common/js/components/utils/view_utils'
|
||||
],
|
||||
function($, _, str, gettext, BaseView, SignatoryModel, SignatoryDetailsView, ViewUtils) {
|
||||
'use strict';
|
||||
|
||||
@@ -6,8 +6,8 @@ define([ // jshint ignore:line
|
||||
'underscore',
|
||||
'gettext',
|
||||
'js/views/baseview',
|
||||
'js/views/utils/view_utils',
|
||||
'js/views/feedback_notification'
|
||||
'common/js/components/utils/view_utils',
|
||||
'common/js/components/views/feedback_notification'
|
||||
],
|
||||
function(_, gettext, BaseView, ViewUtils, NotificationView) {
|
||||
'use strict';
|
||||
|
||||
@@ -7,7 +7,7 @@ define([ // jshint ignore:line
|
||||
'backbone',
|
||||
'gettext',
|
||||
'js/utils/templates',
|
||||
'js/views/utils/view_utils',
|
||||
'common/js/components/utils/view_utils',
|
||||
'js/views/baseview',
|
||||
'js/certificates/views/signatory_editor'
|
||||
],
|
||||
|
||||
@@ -6,9 +6,9 @@ define([ // jshint ignore:line
|
||||
'backbone',
|
||||
'gettext',
|
||||
'js/utils/templates',
|
||||
'js/views/utils/view_utils',
|
||||
'js/views/feedback_prompt',
|
||||
'js/views/feedback_notification',
|
||||
'common/js/components/utils/view_utils',
|
||||
'common/js/components/views/feedback_prompt',
|
||||
'common/js/components/views/feedback_notification',
|
||||
'js/models/uploads',
|
||||
'js/views/uploads'
|
||||
],
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
define(['gettext', 'js/views/feedback_prompt'], function(gettext, PromptView) {
|
||||
define(['gettext', 'common/js/components/views/feedback_prompt'], function(gettext, PromptView) {
|
||||
'use strict';
|
||||
return function (hasUnit, editUnitUrl, courselikeHomeUrl, library, errMsg) {
|
||||
var dialog;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
define(["domReady", "jquery", "underscore", "js/utils/cancel_on_escape", "js/views/utils/create_course_utils",
|
||||
"js/views/utils/create_library_utils", "js/views/utils/view_utils"],
|
||||
"js/views/utils/create_library_utils", "common/js/components/utils/view_utils"],
|
||||
function (domReady, $, _, CancelOnEscape, CreateCourseUtilsFactory, CreateLibraryUtilsFactory, ViewUtils) {
|
||||
"use strict";
|
||||
var CreateCourseUtils = new CreateCourseUtilsFactory({
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
define(["backbone", "gettext", "js/views/feedback_notification", "js/utils/module"],
|
||||
define(["backbone", "gettext", "common/js/components/views/feedback_notification", "js/utils/module"],
|
||||
function(Backbone, gettext, NotificationView, ModuleUtils) {
|
||||
|
||||
var Section = Backbone.Model.extend({
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
define(["js/utils/drag_and_drop", "js/views/feedback_notification", "common/js/spec_helpers/ajax_helpers", "jquery", "underscore"],
|
||||
define(["js/utils/drag_and_drop", "common/js/components/views/feedback_notification", "common/js/spec_helpers/ajax_helpers", "jquery", "underscore"],
|
||||
function (ContentDragger, Notification, AjaxHelpers, $, _) {
|
||||
describe("Overview drag and drop functionality", function () {
|
||||
beforeEach(function () {
|
||||
|
||||
@@ -12,7 +12,6 @@ function ($, _, Squire) {
|
||||
'metadata-file-uploader-item.underscore'
|
||||
),
|
||||
locator = 'locator',
|
||||
feedbackTpl = readFixtures('system-feedback.underscore'),
|
||||
modelStub = {
|
||||
default_value: 'http://example.org/test_1',
|
||||
display_name: 'File Upload',
|
||||
|
||||
@@ -12,7 +12,6 @@ function ($, _, Squire) {
|
||||
TranslationsItenTemplate = readFixtures(
|
||||
'video/metadata-translations-item.underscore'
|
||||
),
|
||||
feedbackTpl = readFixtures('system-feedback.underscore'),
|
||||
modelStub = {
|
||||
default_value: {
|
||||
'en': 'en.srt',
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
define([ "jquery", "common/js/spec_helpers/ajax_helpers", "URI", "js/views/assets",
|
||||
"js/collections/asset", "js/spec_helpers/view_helpers"],
|
||||
"js/collections/asset", "common/js/spec_helpers/view_helpers"],
|
||||
function ($, AjaxHelpers, URI, AssetsView, AssetCollection, ViewHelpers) {
|
||||
|
||||
describe("Assets", function() {
|
||||
|
||||
@@ -4,8 +4,8 @@ define([
|
||||
'js/views/group_configuration_details', 'js/views/group_configurations_list', 'js/views/group_configuration_editor',
|
||||
'js/views/group_configuration_item', 'js/views/experiment_group_edit', 'js/views/content_group_list',
|
||||
'js/views/content_group_details', 'js/views/content_group_editor', 'js/views/content_group_item',
|
||||
'js/views/feedback_notification', 'common/js/spec_helpers/ajax_helpers', 'common/js/spec_helpers/template_helpers',
|
||||
'js/spec_helpers/view_helpers', 'jasmine-stealth'
|
||||
'common/js/components/views/feedback_notification', 'common/js/spec_helpers/ajax_helpers', 'common/js/spec_helpers/template_helpers',
|
||||
'common/js/spec_helpers/view_helpers', 'jasmine-stealth'
|
||||
], function(
|
||||
_, Course, GroupConfigurationModel, GroupModel, GroupConfigurationCollection, GroupCollection,
|
||||
GroupConfigurationDetailsView, GroupConfigurationsListView, GroupConfigurationEditorView,
|
||||
|
||||
@@ -75,8 +75,6 @@ define(["jquery", "underscore", "common/js/spec_helpers/ajax_helpers", "URI", "j
|
||||
var pagingContainer;
|
||||
|
||||
beforeEach(function () {
|
||||
var feedbackTpl = readFixtures('system-feedback.underscore');
|
||||
setFixtures($("<script>", { id: "system-feedback-tpl", type: "text/template" }).text(feedbackTpl));
|
||||
pagingContainer = new MockPagingView({page_size: PAGE_SIZE});
|
||||
});
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
define(["jquery", "underscore", "underscore.string", "common/js/spec_helpers/ajax_helpers",
|
||||
"common/js/spec_helpers/template_helpers", "js/spec_helpers/edit_helpers",
|
||||
"js/views/feedback_prompt", "js/views/pages/container", "js/views/pages/container_subviews",
|
||||
"js/models/xblock_info", "js/views/utils/xblock_utils"],
|
||||
"common/js/components/views/feedback_prompt", "js/views/pages/container",
|
||||
"js/views/pages/container_subviews", "js/models/xblock_info", "js/views/utils/xblock_utils"],
|
||||
function ($, _, str, AjaxHelpers, TemplateHelpers, EditHelpers, Prompt, ContainerPage, ContainerSubviews,
|
||||
XBlockInfo, XBlockUtils) {
|
||||
var VisibilityState = XBlockUtils.VisibilityState;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
define(["jquery", "common/js/spec_helpers/ajax_helpers", "js/views/utils/view_utils", "js/views/pages/course_outline",
|
||||
define(["jquery", "common/js/spec_helpers/ajax_helpers", "common/js/components/utils/view_utils", "js/views/pages/course_outline",
|
||||
"js/models/xblock_outline_info", "js/utils/date_utils", "js/spec_helpers/edit_helpers",
|
||||
"common/js/spec_helpers/template_helpers"],
|
||||
function($, AjaxHelpers, ViewUtils, CourseOutlinePage, XBlockOutlineInfo, DateUtils, EditHelpers, TemplateHelpers) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
define(["jquery", "common/js/spec_helpers/ajax_helpers", "js/spec_helpers/view_helpers", "js/views/course_rerun",
|
||||
"js/views/utils/create_course_utils", "js/views/utils/view_utils", "jquery.simulate"],
|
||||
define(["jquery", "common/js/spec_helpers/ajax_helpers", "common/js/spec_helpers/view_helpers", "js/views/course_rerun",
|
||||
"js/views/utils/create_course_utils", "common/js/components/utils/view_utils", "jquery.simulate"],
|
||||
function ($, AjaxHelpers, ViewHelpers, CourseRerunUtils, CreateCourseUtilsFactory, ViewUtils) {
|
||||
describe("Create course rerun page", function () {
|
||||
var selectors = {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
define(["jquery", "common/js/spec_helpers/ajax_helpers", "js/spec_helpers/view_helpers", "js/index",
|
||||
"js/views/utils/view_utils"],
|
||||
define(["jquery", "common/js/spec_helpers/ajax_helpers", "common/js/spec_helpers/view_helpers", "js/index",
|
||||
"common/js/components/utils/view_utils"],
|
||||
function ($, AjaxHelpers, ViewHelpers, IndexUtils, ViewUtils) {
|
||||
describe("Course listing page", function () {
|
||||
var mockIndexPageHTML = readFixtures('mock/mock-index-page.underscore');
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
define([
|
||||
"jquery", "common/js/spec_helpers/ajax_helpers", "js/spec_helpers/view_helpers",
|
||||
"js/factories/manage_users_lib", "js/views/utils/view_utils"
|
||||
"jquery", "common/js/spec_helpers/ajax_helpers", "common/js/spec_helpers/view_helpers",
|
||||
"js/factories/manage_users_lib", "common/js/components/utils/view_utils"
|
||||
],
|
||||
function ($, AjaxHelpers, ViewHelpers, ManageUsersFactory, ViewUtils) {
|
||||
"use strict";
|
||||
describe("Library Instructor Access Page", function () {
|
||||
const changeRoleUrl = "dummy_change_role_url/@@EMAIL@@";
|
||||
var team_member_fixture = readFixtures("team-member.underscore");
|
||||
var systemFeedbackFixture = readFixtures("system-feedback.underscore");
|
||||
|
||||
function setRole(email, role){
|
||||
var user_li = $("li.user-item[data-email="+ email + "]");
|
||||
@@ -27,7 +26,6 @@ function ($, AjaxHelpers, ViewHelpers, ManageUsersFactory, ViewUtils) {
|
||||
ViewHelpers.installMockAnalytics();
|
||||
setFixtures(mockHTML);
|
||||
appendSetFixtures($("<script>", { id: "team-member-tpl", type: "text/template"}).text(team_member_fixture));
|
||||
appendSetFixtures($("<script>", { id: "system-feedback-tpl", type: "text/template"}).text(systemFeedbackFixture));
|
||||
ManageUsersFactory(
|
||||
"Mock Library",
|
||||
[
|
||||
@@ -122,7 +120,6 @@ function ($, AjaxHelpers, ViewHelpers, ManageUsersFactory, ViewUtils) {
|
||||
ViewHelpers.installMockAnalytics();
|
||||
setFixtures(mockHTML);
|
||||
appendSetFixtures($("<script>", { id: "team-member-tpl", type: "text/template"}).text(team_member_fixture));
|
||||
appendSetFixtures($("<script>", { id: "system-feedback-tpl", type: "text/template"}).text(systemFeedbackFixture));
|
||||
ManageUsersFactory(
|
||||
"Mock Library",
|
||||
[
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
define(["jquery", "common/js/spec_helpers/ajax_helpers", "common/js/spec_helpers/template_helpers",
|
||||
"js/spec_helpers/view_helpers", "js/views/utils/view_utils", "js/views/unit_outline", "js/models/xblock_info"],
|
||||
"common/js/spec_helpers/view_helpers", "common/js/components/utils/view_utils", "js/views/unit_outline", "js/models/xblock_info"],
|
||||
function ($, AjaxHelpers, TemplateHelpers, ViewHelpers, ViewUtils, UnitOutlineView, XBlockInfo) {
|
||||
|
||||
describe("UnitOutlineView", function() {
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
/**
|
||||
* Provides helper methods for invoking Studio modal windows in Jasmine tests.
|
||||
*/
|
||||
define(["jquery", "js/views/feedback_notification", "js/views/feedback_prompt", "common/js/spec_helpers/template_helpers"],
|
||||
define(["jquery", "common/js/components/views/feedback_notification", "common/js/components/views/feedback_prompt",
|
||||
"common/js/spec_helpers/template_helpers"],
|
||||
function($, NotificationView, Prompt, TemplateHelpers) {
|
||||
var installViewTemplates, createFeedbackSpy, verifyFeedbackShowing,
|
||||
verifyFeedbackHidden, createNotificationSpy, verifyNotificationShowing,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* Provides helper methods for invoking Studio modal windows in Jasmine tests.
|
||||
*/
|
||||
define(["jquery", "common/js/spec_helpers/template_helpers", "js/spec_helpers/view_helpers"],
|
||||
define(["jquery", "common/js/spec_helpers/template_helpers", "common/js/spec_helpers/view_helpers"],
|
||||
function($, TemplateHelpers, ViewHelpers) {
|
||||
var installModalTemplates, getModalElement, getModalWindow, getModalTitle, isShowingModal,
|
||||
hideModalIfShowing, pressModalButton, cancelModal, cancelModalIfShowing;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
define(["jquery", "jquery.ui", "underscore", "gettext", "js/views/feedback_notification", "draggabilly",
|
||||
define(["jquery", "jquery.ui", "underscore", "gettext", "common/js/components/views/feedback_notification", "draggabilly",
|
||||
"js/utils/module"],
|
||||
function ($, ui, _, gettext, NotificationView, Draggabilly, ModuleUtils) {
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
define(["js/views/baseview", "underscore", "gettext", "js/views/feedback_prompt", "js/views/feedback_notification"],
|
||||
define(["js/views/baseview", "underscore", "gettext", "common/js/components/views/feedback_prompt",
|
||||
"common/js/components/views/feedback_notification"],
|
||||
function(BaseView, _, gettext, PromptView, NotificationView) {
|
||||
var AssetView = BaseView.extend({
|
||||
initialize: function() {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
define(["jquery", "underscore", "gettext", "js/views/baseview", "js/models/asset", "js/views/paging",
|
||||
"js/views/asset", "js/views/paging_header", "common/js/components/views/paging_footer",
|
||||
"js/utils/modal", "js/views/utils/view_utils", "js/views/feedback_notification",
|
||||
"js/utils/modal", "common/js/components/utils/view_utils", "common/js/components/views/feedback_notification",
|
||||
"text!templates/asset-library.underscore",
|
||||
"jquery.fileupload-process", "jquery.fileupload-validate"],
|
||||
function($, _, gettext, BaseView, AssetModel, PagingView, AssetView, PagingHeader, PagingFooter,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
define(["jquery", "underscore", "backbone", "gettext", "js/utils/handle_iframe_binding", "js/utils/templates",
|
||||
"js/views/utils/view_utils"],
|
||||
"common/js/components/utils/view_utils"],
|
||||
function ($, _, Backbone, gettext, IframeUtils, TemplateUtils, ViewUtils) {
|
||||
/*
|
||||
This view is extended from backbone to provide useful functionality for all Studio views.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* This is a simple component that renders add buttons for all available XBlock template types.
|
||||
*/
|
||||
define(["jquery", "underscore", "gettext", "js/views/baseview", "js/views/utils/view_utils",
|
||||
define(["jquery", "underscore", "gettext", "js/views/baseview", "common/js/components/utils/view_utils",
|
||||
"js/views/components/add_xblock_button", "js/views/components/add_xblock_menu"],
|
||||
function ($, _, gettext, BaseView, ViewUtils, AddXBlockButton, AddXBlockMenu) {
|
||||
var AddXBlockComponent = BaseView.extend({
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
define(["jquery", "underscore", "js/views/xblock", "js/utils/module", "gettext", "js/views/feedback_notification",
|
||||
define(["jquery", "underscore", "js/views/xblock", "js/utils/module", "gettext", "common/js/components/views/feedback_notification",
|
||||
"jquery.ui"], // The container view uses sortable, which is provided by jquery.ui.
|
||||
function ($, _, XBlockView, ModuleUtils, gettext, NotificationView) {
|
||||
var studioXBlockWrapperClass = '.studio-xblock-wrapper';
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* It is expected to be backed by a Group model.
|
||||
*/
|
||||
define([
|
||||
'js/views/list_item', 'js/views/content_group_editor', 'js/views/content_group_details', 'gettext', "js/views/utils/view_utils"
|
||||
'js/views/list_item', 'js/views/content_group_editor', 'js/views/content_group_details', 'gettext', "common/js/components/utils/view_utils"
|
||||
], function(ListItemView, ContentGroupEditorView, ContentGroupDetailsView, gettext) {
|
||||
'use strict';
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
define(["js/views/baseview", "codemirror", "js/views/feedback_notification", "js/views/course_info_helper", "js/utils/modal"],
|
||||
define(["js/views/baseview", "codemirror", "common/js/components/views/feedback_notification", "js/views/course_info_helper", "js/utils/modal"],
|
||||
function(BaseView, CodeMirror, NotificationView, CourseInfoHelper, ModalUtils) {
|
||||
|
||||
// the handouts view is dumb right now; it needs tied to a model and all that jazz
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
define(["js/views/baseview", "codemirror", "js/models/course_update",
|
||||
"js/views/feedback_prompt", "js/views/feedback_notification", "js/views/course_info_helper", "js/utils/modal"],
|
||||
"common/js/components/views/feedback_prompt", "common/js/components/views/feedback_notification",
|
||||
"js/views/course_info_helper", "js/utils/modal"],
|
||||
function(BaseView, CodeMirror, CourseUpdateModel, PromptView, NotificationView, CourseInfoHelper, ModalUtils) {
|
||||
|
||||
var CourseInfoUpdateView = BaseView.extend({
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
* - changes cause a refresh of the entire section rather than just the view for the changed xblock
|
||||
* - adding units will automatically redirect to the unit page rather than showing them inline
|
||||
*/
|
||||
define(["jquery", "underscore", "js/views/xblock_outline", "js/views/utils/view_utils", "js/views/utils/xblock_utils",
|
||||
define(["jquery", "underscore", "js/views/xblock_outline", "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"],
|
||||
function(
|
||||
$, _, XBlockOutlineView, ViewUtils, XBlockViewUtils,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
define(["domReady", "jquery", "underscore", "js/views/utils/create_course_utils", "js/views/utils/view_utils"],
|
||||
define(["domReady", "jquery", "underscore", "js/views/utils/create_course_utils", "common/js/components/utils/view_utils"],
|
||||
function (domReady, $, _, CreateCourseUtilsFactory, ViewUtils) {
|
||||
var CreateCourseUtils = new CreateCourseUtilsFactory({
|
||||
name: '.rerun-course-name',
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
define(["js/views/baseview", "underscore", "jquery", "js/views/edit_chapter", "js/views/feedback_notification"],
|
||||
define(["js/views/baseview", "underscore", "jquery", "js/views/edit_chapter", "common/js/components/views/feedback_notification"],
|
||||
function(BaseView, _, $, EditChapterView, NotificationView) {
|
||||
var EditTextbook = BaseView.extend({
|
||||
initialize: function() {
|
||||
|
||||
@@ -1,146 +0,0 @@
|
||||
define(["jquery", "underscore", "underscore.string", "backbone", "js/utils/templates"],
|
||||
function($, _, str, Backbone, TemplateUtils) {
|
||||
var SystemFeedback = Backbone.View.extend({
|
||||
options: {
|
||||
title: "",
|
||||
message: "",
|
||||
intent: null, // "warning", "confirmation", "error", "announcement", "step-required", etc
|
||||
type: null, // "alert", "notification", or "prompt": set by subclass
|
||||
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)
|
||||
|
||||
/* Could also have an "actions" hash: here is an example demonstrating
|
||||
the expected structure. For each action, by default the framework
|
||||
will call preventDefault on the click event before the function is
|
||||
run; to make it not do that, just pass `preventDefault: false` in
|
||||
the action object.
|
||||
|
||||
actions: {
|
||||
primary: {
|
||||
"text": "Save",
|
||||
"class": "action-save",
|
||||
"click": function(view) {
|
||||
// do something when Save is clicked
|
||||
}
|
||||
},
|
||||
secondary: [
|
||||
{
|
||||
"text": "Cancel",
|
||||
"class": "action-cancel",
|
||||
"click": function(view) {}
|
||||
}, {
|
||||
"text": "Discard Changes",
|
||||
"class": "action-discard",
|
||||
"click": function(view) {}
|
||||
}
|
||||
]
|
||||
}
|
||||
*/
|
||||
},
|
||||
|
||||
initialize: function() {
|
||||
if (!this.options.type) {
|
||||
throw "SystemFeedback: type required (given " +
|
||||
JSON.stringify(this.options) + ")";
|
||||
}
|
||||
if (!this.options.intent) {
|
||||
throw "SystemFeedback: intent required (given " +
|
||||
JSON.stringify(this.options) + ")";
|
||||
}
|
||||
this.template = TemplateUtils.loadTemplate("system-feedback");
|
||||
this.setElement($("#page-" + this.options.type));
|
||||
// handle single "secondary" action
|
||||
if (this.options.actions && this.options.actions.secondary &&
|
||||
!_.isArray(this.options.actions.secondary)) {
|
||||
this.options.actions.secondary = [this.options.actions.secondary];
|
||||
}
|
||||
return this;
|
||||
},
|
||||
|
||||
// public API: show() and hide()
|
||||
show: function() {
|
||||
clearTimeout(this.hideTimeout);
|
||||
this.options.shown = true;
|
||||
this.shownAt = new Date();
|
||||
this.render();
|
||||
if ($.isNumeric(this.options.maxShown)) {
|
||||
this.hideTimeout = setTimeout(_.bind(this.hide, this),
|
||||
this.options.maxShown);
|
||||
}
|
||||
return this;
|
||||
},
|
||||
|
||||
hide: function() {
|
||||
if (this.shownAt && $.isNumeric(this.options.minShown) &&
|
||||
this.options.minShown > new Date() - this.shownAt) {
|
||||
clearTimeout(this.hideTimeout);
|
||||
this.hideTimeout = setTimeout(_.bind(this.hide, this),
|
||||
this.options.minShown - (new Date() - this.shownAt));
|
||||
} else {
|
||||
this.options.shown = false;
|
||||
delete this.shownAt;
|
||||
this.render();
|
||||
}
|
||||
return this;
|
||||
},
|
||||
|
||||
// the rest of the API should be considered semi-private
|
||||
events: {
|
||||
"click .action-close": "hide",
|
||||
"click .action-primary": "primaryClick",
|
||||
"click .action-secondary": "secondaryClick"
|
||||
},
|
||||
|
||||
render: function() {
|
||||
// there can be only one active view of a given type at a time: only
|
||||
// one alert, only one notification, only one prompt. Therefore, we'll
|
||||
// use a singleton approach.
|
||||
var singleton = SystemFeedback["active_" + this.options.type];
|
||||
if (singleton && singleton !== this) {
|
||||
singleton.stopListening();
|
||||
singleton.undelegateEvents();
|
||||
}
|
||||
this.$el.html(this.template(this.options));
|
||||
SystemFeedback["active_" + this.options.type] = this;
|
||||
return this;
|
||||
},
|
||||
|
||||
primaryClick: function(event) {
|
||||
var actions, primary;
|
||||
actions = this.options.actions;
|
||||
if (!actions) { return; }
|
||||
primary = actions.primary;
|
||||
if (!primary) { return; }
|
||||
if (primary.preventDefault !== false) {
|
||||
event.preventDefault();
|
||||
}
|
||||
if (primary.click) {
|
||||
primary.click.call(event.target, this, event);
|
||||
}
|
||||
},
|
||||
|
||||
secondaryClick: function(event) {
|
||||
var actions, secondaryList, secondary, i;
|
||||
actions = this.options.actions;
|
||||
if (!actions) { return; }
|
||||
secondaryList = actions.secondary;
|
||||
if (!secondaryList) { return; }
|
||||
// which secondary action was clicked?
|
||||
i = 0; // default to the first secondary action (easier for testing)
|
||||
if (event && event.target) {
|
||||
i = _.indexOf(this.$(".action-secondary"), event.target);
|
||||
}
|
||||
secondary = secondaryList[i];
|
||||
if (secondary.preventDefault !== false) {
|
||||
event.preventDefault();
|
||||
}
|
||||
if (secondary.click) {
|
||||
secondary.click.call(event.target, this, event);
|
||||
}
|
||||
}
|
||||
});
|
||||
return SystemFeedback;
|
||||
});
|
||||
@@ -1,37 +0,0 @@
|
||||
define(["jquery", "underscore", "underscore.string", "js/views/feedback"], function($, _, str, SystemFeedbackView) {
|
||||
var Alert = SystemFeedbackView.extend({
|
||||
options: $.extend({}, SystemFeedbackView.prototype.options, {
|
||||
type: "alert"
|
||||
}),
|
||||
slide_speed: 900,
|
||||
show: function() {
|
||||
SystemFeedbackView.prototype.show.apply(this, arguments);
|
||||
this.$el.hide();
|
||||
this.$el.slideDown(this.slide_speed);
|
||||
return this;
|
||||
},
|
||||
hide: function () {
|
||||
this.$el.slideUp({
|
||||
duration: this.slide_speed
|
||||
});
|
||||
setTimeout(_.bind(SystemFeedbackView.prototype.hide, this, arguments),
|
||||
this.slideSpeed);
|
||||
}
|
||||
});
|
||||
|
||||
// create Alert.Warning, Alert.Confirmation, etc
|
||||
var capitalCamel, intents;
|
||||
capitalCamel = _.compose(str.capitalize, str.camelize);
|
||||
intents = ["warning", "error", "confirmation", "announcement", "step-required", "help", "mini"];
|
||||
_.each(intents, function(intent) {
|
||||
var subclass;
|
||||
subclass = Alert.extend({
|
||||
options: $.extend({}, Alert.prototype.options, {
|
||||
intent: intent
|
||||
})
|
||||
});
|
||||
Alert[capitalCamel(intent)] = subclass;
|
||||
});
|
||||
|
||||
return Alert;
|
||||
});
|
||||
@@ -1,29 +0,0 @@
|
||||
define(["jquery", "underscore", "underscore.string", "js/views/feedback"], function($, _, str, SystemFeedbackView) {
|
||||
var Notification = SystemFeedbackView.extend({
|
||||
options: $.extend({}, SystemFeedbackView.prototype.options, {
|
||||
type: "notification",
|
||||
closeIcon: false
|
||||
})
|
||||
});
|
||||
|
||||
// create Notification.Warning, Notification.Confirmation, etc
|
||||
var capitalCamel, intents;
|
||||
capitalCamel = _.compose(str.capitalize, str.camelize);
|
||||
intents = ["warning", "error", "confirmation", "announcement", "step-required", "help", "mini"];
|
||||
_.each(intents, function(intent) {
|
||||
var subclass;
|
||||
subclass = Notification.extend({
|
||||
options: $.extend({}, Notification.prototype.options, {
|
||||
intent: intent
|
||||
})
|
||||
});
|
||||
Notification[capitalCamel(intent)] = subclass;
|
||||
});
|
||||
|
||||
// set more sensible defaults for Notification.Mini views
|
||||
var miniOptions = Notification.Mini.prototype.options;
|
||||
miniOptions.minShown = 1250;
|
||||
miniOptions.closeIcon = false;
|
||||
|
||||
return Notification;
|
||||
});
|
||||
@@ -1,35 +0,0 @@
|
||||
define(["jquery", "underscore", "underscore.string", "js/views/feedback"], function($, _, str, SystemFeedbackView) {
|
||||
var Prompt = SystemFeedbackView.extend({
|
||||
options: $.extend({}, SystemFeedbackView.prototype.options, {
|
||||
type: "prompt",
|
||||
closeIcon: false,
|
||||
icon: false
|
||||
}),
|
||||
render: function() {
|
||||
if(!window.$body) { window.$body = $(document.body); }
|
||||
if(this.options.shown) {
|
||||
$body.addClass('prompt-is-shown');
|
||||
} else {
|
||||
$body.removeClass('prompt-is-shown');
|
||||
}
|
||||
// super() in Javascript has awkward syntax :(
|
||||
return SystemFeedbackView.prototype.render.apply(this, arguments);
|
||||
}
|
||||
});
|
||||
|
||||
// create Prompt.Warning, Prompt.Confirmation, etc
|
||||
var capitalCamel, intents;
|
||||
capitalCamel = _.compose(str.capitalize, str.camelize);
|
||||
intents = ["warning", "error", "confirmation", "announcement", "step-required", "help", "mini"];
|
||||
_.each(intents, function(intent) {
|
||||
var subclass;
|
||||
subclass = Prompt.extend({
|
||||
options: $.extend({}, Prompt.prototype.options, {
|
||||
intent: intent
|
||||
})
|
||||
});
|
||||
Prompt[capitalCamel(intent)] = subclass;
|
||||
});
|
||||
|
||||
return Prompt;
|
||||
});
|
||||
@@ -12,7 +12,7 @@
|
||||
* to the DOM.
|
||||
*/
|
||||
define([
|
||||
'js/views/baseview', 'jquery', "gettext", "js/views/utils/view_utils"
|
||||
'js/views/baseview', 'jquery', "gettext", "common/js/components/utils/view_utils"
|
||||
], function(
|
||||
BaseView, $, gettext, ViewUtils
|
||||
) {
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
* saved by this view. Note this may be a parent model.
|
||||
*/
|
||||
define([
|
||||
'js/views/baseview', 'js/views/utils/view_utils', 'underscore', 'gettext'
|
||||
'js/views/baseview', 'common/js/components/utils/view_utils', 'underscore', 'gettext'
|
||||
], function(BaseView, ViewUtils, _, gettext) {
|
||||
'use strict';
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
define(["js/views/baseview", "jquery", "js/views/edit_textbook", "js/views/show_textbook", "js/views/utils/view_utils"],
|
||||
define(["js/views/baseview", "jquery", "js/views/edit_textbook", "js/views/show_textbook", "common/js/components/utils/view_utils"],
|
||||
function(BaseView, $, EditTextbookView, ShowTextbookView, ViewUtils) {
|
||||
var ListTextbooks = BaseView.extend({
|
||||
initialize: function() {
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
/*
|
||||
Code for editing users and assigning roles within a course or library team context.
|
||||
*/
|
||||
define(['jquery', 'underscore', 'gettext', "js/views/baseview", 'js/views/feedback_prompt', 'js/views/utils/view_utils'],
|
||||
define(['jquery', 'underscore', 'gettext', "js/views/baseview",
|
||||
'common/js/components/views/feedback_prompt', 'common/js/components/utils/view_utils'],
|
||||
function ($, _, gettext, BaseView, PromptView, ViewUtils) {
|
||||
'use strict';
|
||||
var default_messages = {
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* It is invoked using the edit method which is passed an existing rendered xblock,
|
||||
* and upon save an optional refresh function can be invoked to update the display.
|
||||
*/
|
||||
define(["jquery", "underscore", "gettext", "js/views/modals/base_modal", "js/views/utils/view_utils",
|
||||
define(["jquery", "underscore", "gettext", "js/views/modals/base_modal", "common/js/components/utils/view_utils",
|
||||
"js/models/xblock_info", "js/views/xblock_editor"],
|
||||
function($, _, gettext, BaseModal, ViewUtils, XBlockInfo, XBlockEditorView) {
|
||||
"strict mode";
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
define(["domReady", "jquery", "jquery.ui", "underscore", "gettext", "js/views/feedback_notification",
|
||||
"js/utils/cancel_on_escape", "js/utils/date_utils", "js/utils/module", "js/views/utils/view_utils"],
|
||||
define(["domReady", "jquery", "jquery.ui", "underscore", "gettext", "common/js/components/views/feedback_notification",
|
||||
"js/utils/cancel_on_escape", "js/utils/date_utils", "js/utils/module", "common/js/components/utils/view_utils"],
|
||||
function (domReady, $, ui, _, gettext, NotificationView, CancelOnEscape,
|
||||
DateUtils, ModuleUtils, ViewUtils) {
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
define(["js/views/baseview", "underscore", "gettext", "js/models/assignment_grade", "js/views/feedback_notification"],
|
||||
define(["js/views/baseview", "underscore", "gettext", "js/models/assignment_grade", "common/js/components/views/feedback_notification"],
|
||||
function(BaseView, _, gettext, AssignmentGrade, NotificationView) {
|
||||
var l10nNotGraded = gettext('Not Graded');
|
||||
var OverviewAssignmentGrader = BaseView.extend({
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
define(["jquery", "underscore", "js/views/utils/view_utils", "js/views/container", "js/utils/module", "gettext",
|
||||
"js/views/feedback_notification", "js/views/paging_header", "common/js/components/views/paging_footer"],
|
||||
define(["jquery", "underscore", "common/js/components/utils/view_utils", "js/views/container", "js/utils/module", "gettext",
|
||||
"common/js/components/views/feedback_notification", "js/views/paging_header", "common/js/components/views/paging_footer"],
|
||||
function ($, _, ViewUtils, ContainerView, ModuleUtils, gettext, NotificationView, PagingHeader, PagingFooter) {
|
||||
var PagedContainerView = ContainerView.extend({
|
||||
initialize: function(options){
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* XBlockContainerPage is used to display Studio's container page for an xblock which has children.
|
||||
* This page allows the user to understand and manipulate the xblock and its children.
|
||||
*/
|
||||
define(["jquery", "underscore", "gettext", "js/views/pages/base_page", "js/views/utils/view_utils",
|
||||
define(["jquery", "underscore", "gettext", "js/views/pages/base_page", "common/js/components/utils/view_utils",
|
||||
"js/views/container", "js/views/xblock", "js/views/components/add_xblock", "js/views/modals/edit_xblock",
|
||||
"js/models/xblock_info", "js/views/xblock_string_field_editor", "js/views/pages/container_subviews",
|
||||
"js/views/unit_outline", "js/views/utils/xblock_utils"],
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* Subviews (usually small side panels) for XBlockContainerPage.
|
||||
*/
|
||||
define(["jquery", "underscore", "gettext", "js/views/baseview", "js/views/utils/view_utils",
|
||||
define(["jquery", "underscore", "gettext", "js/views/baseview", "common/js/components/utils/view_utils",
|
||||
"js/views/utils/xblock_utils"],
|
||||
function ($, _, gettext, BaseView, ViewUtils, XBlockViewUtils) {
|
||||
var VisibilityState = XBlockViewUtils.VisibilityState,
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
* This page is used to show the user an outline of the course.
|
||||
*/
|
||||
define(["jquery", "underscore", "gettext", "js/views/pages/base_page", "js/views/utils/xblock_utils",
|
||||
"js/views/course_outline", "js/views/utils/view_utils", "js/views/feedback_alert",
|
||||
"js/views/feedback_notification"],
|
||||
"js/views/course_outline", "common/js/components/utils/view_utils", "common/js/components/views/feedback_alert",
|
||||
"common/js/components/views/feedback_notification"],
|
||||
function ($, _, gettext, BasePage, XBlockViewUtils, CourseOutlineView, ViewUtils, AlertView, NoteView) {
|
||||
var expandedLocators, CourseOutlinePage;
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
define(["js/views/validation", "codemirror", "underscore", "jquery", "jquery.ui", "js/utils/date_utils", "js/models/uploads",
|
||||
"js/views/uploads", "js/utils/change_on_enter", "js/views/license", "js/models/license",
|
||||
"js/views/feedback_notification", "jquery.timepicker", "date"],
|
||||
"common/js/components/views/feedback_notification", "jquery.timepicker", "date"],
|
||||
function(ValidatingView, CodeMirror, _, $, ui, DateUtils, FileUploadModel,
|
||||
FileUploadDialog, TriggerChangeEventOnEnter, LicenseView, LicenseModel, NotificationView) {
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
define(["js/views/baseview", "underscore", "gettext", "js/views/feedback_notification", "js/views/feedback_prompt"],
|
||||
define(["js/views/baseview", "underscore", "gettext", "common/js/components/views/feedback_notification",
|
||||
"common/js/components/views/feedback_prompt"],
|
||||
function(BaseView, _, gettext, NotificationView, PromptView) {
|
||||
var ShowTextbook = BaseView.extend({
|
||||
initialize: function() {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* Provides utilities for validating courses during creation, for both new courses and reruns.
|
||||
*/
|
||||
define(["jquery", "gettext", "js/views/utils/view_utils", "js/views/utils/create_utils_base"],
|
||||
define(["jquery", "gettext", "common/js/components/utils/view_utils", "js/views/utils/create_utils_base"],
|
||||
function ($, gettext, ViewUtils, CreateUtilsFactory) {
|
||||
"use strict";
|
||||
return function (selectors, classes) {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* Provides utilities for validating libraries during creation.
|
||||
*/
|
||||
define(["jquery", "gettext", "js/views/utils/view_utils", "js/views/utils/create_utils_base"],
|
||||
define(["jquery", "gettext", "common/js/components/utils/view_utils", "js/views/utils/create_utils_base"],
|
||||
function ($, gettext, ViewUtils, CreateUtilsFactory) {
|
||||
"use strict";
|
||||
return function (selectors, classes) {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* Mixin class for creation of things like courses and libraries.
|
||||
*/
|
||||
define(["jquery", "underscore", "gettext", "js/views/utils/view_utils"],
|
||||
define(["jquery", "underscore", "gettext", "common/js/components/utils/view_utils"],
|
||||
function ($, _, gettext, ViewUtils) {
|
||||
return function (selectors, classes, keyLengthViolationMessage, keyFieldSelectors, nonEmptyCheckFieldSelectors) {
|
||||
var self = this;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* Provides utilities for views to work with xblocks.
|
||||
*/
|
||||
define(["jquery", "underscore", "gettext", "js/views/utils/view_utils", "js/utils/module"],
|
||||
define(["jquery", "underscore", "gettext", "common/js/components/utils/view_utils", "js/utils/module"],
|
||||
function($, _, gettext, ViewUtils, ModuleUtils) {
|
||||
var addXBlock, deleteXBlock, createUpdateRequestData, updateXBlockField, VisibilityState,
|
||||
getXBlockVisibilityClass, getXBlockListTypeClass, updateXBlockFields;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
define(["js/views/baseview", "underscore", "jquery", "gettext", "js/views/feedback_notification", "js/views/feedback_alert", "js/views/baseview", "jquery.smoothScroll"],
|
||||
define(["js/views/baseview", "underscore", "jquery", "gettext", "common/js/components/views/feedback_notification", "common/js/components/views/feedback_alert", "js/views/baseview", "jquery.smoothScroll"],
|
||||
function(BaseView, _, $, gettext, NotificationView, AlertView) {
|
||||
|
||||
var ValidatingView = BaseView.extend({
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
* - scroll_offset - the scroll offset to use for the locator being shown
|
||||
* - edit_display_name - true if the shown xblock's display name should be in inline edit mode
|
||||
*/
|
||||
define(["jquery", "underscore", "gettext", "js/views/baseview", "js/views/utils/view_utils",
|
||||
define(["jquery", "underscore", "gettext", "js/views/baseview", "common/js/components/utils/view_utils",
|
||||
"js/views/utils/xblock_utils", "js/views/xblock_string_field_editor"],
|
||||
function($, _, gettext, BaseView, ViewUtils, XBlockViewUtils, XBlockStringFieldEditor) {
|
||||
|
||||
|
||||
@@ -83,7 +83,8 @@
|
||||
border-color: $blue-d2;
|
||||
}
|
||||
|
||||
a {
|
||||
button {
|
||||
@extend %btn-no-style;
|
||||
color: $blue;
|
||||
|
||||
&:hover {
|
||||
@@ -102,7 +103,8 @@
|
||||
color: $gray-d4;
|
||||
}
|
||||
|
||||
a {
|
||||
button {
|
||||
@extend %btn-no-style;
|
||||
color: $orange;
|
||||
|
||||
&:hover {
|
||||
@@ -120,7 +122,8 @@
|
||||
border-color: $red-d2;
|
||||
}
|
||||
|
||||
a {
|
||||
button {
|
||||
@extend %btn-no-style;
|
||||
color: $red-l1;
|
||||
|
||||
&:hover {
|
||||
@@ -138,7 +141,8 @@
|
||||
border-color: $blue-d2;
|
||||
}
|
||||
|
||||
a {
|
||||
button {
|
||||
@extend %btn-no-style;
|
||||
color: $blue;
|
||||
|
||||
&:hover {
|
||||
@@ -156,7 +160,8 @@
|
||||
border-color: $green-d2;
|
||||
}
|
||||
|
||||
a {
|
||||
button {
|
||||
@extend %btn-no-style;
|
||||
color: $green;
|
||||
|
||||
&:hover {
|
||||
@@ -174,7 +179,8 @@
|
||||
border-color: $pink-d2;
|
||||
}
|
||||
|
||||
a {
|
||||
button {
|
||||
@extend %btn-no-style;
|
||||
color: $pink;
|
||||
|
||||
&:hover {
|
||||
|
||||
@@ -48,11 +48,6 @@ import json
|
||||
<script type="text/javascript" src="${static.url("js/vendor/require.js")}"></script>
|
||||
<script type="text/javascript" src="${static.url("cms/js/require-config.js")}"></script>
|
||||
|
||||
## js templates
|
||||
<script id="system-feedback-tpl" type="text/template">
|
||||
<%static:include path="js/system-feedback.underscore" />
|
||||
</script>
|
||||
|
||||
<!-- view -->
|
||||
<div class="wrapper wrapper-view" dir="${static.dir_rtl()}">
|
||||
<% online_help_token = self.online_help_token() if hasattr(self, 'online_help_token') else None %>
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
/**
|
||||
* Provides useful utilities for views.
|
||||
*/
|
||||
define(["jquery", "underscore", "gettext", "js/views/feedback_notification", "js/views/feedback_prompt"],
|
||||
;(function (define) {
|
||||
'use strict';
|
||||
define(["jquery", "underscore", "gettext", "common/js/components/views/feedback_notification",
|
||||
"common/js/components/views/feedback_prompt"],
|
||||
function ($, _, gettext, NotificationView, PromptView) {
|
||||
var toggleExpandCollapse, showLoadingIndicator, hideLoadingIndicator, confirmThenRunOperation,
|
||||
runOperationShowingMessage, disableElementWhileRunning, getScrollOffset, setScrollOffset,
|
||||
@@ -246,3 +249,4 @@ define(["jquery", "underscore", "gettext", "js/views/feedback_notification", "js
|
||||
'checkTotalKeyLengthViolations': checkTotalKeyLengthViolations
|
||||
};
|
||||
});
|
||||
}).call(this, define || RequireJS.define);
|
||||
152
common/static/common/js/components/views/feedback.js
Normal file
152
common/static/common/js/components/views/feedback.js
Normal file
@@ -0,0 +1,152 @@
|
||||
;(function (define) {
|
||||
'use strict';
|
||||
define(["jquery",
|
||||
"underscore",
|
||||
"underscore.string",
|
||||
"backbone",
|
||||
"text!common/templates/components/system-feedback.underscore"],
|
||||
function($, _, str, Backbone, systemFeedbackTemplate) {
|
||||
var SystemFeedback = Backbone.View.extend({
|
||||
options: {
|
||||
title: "",
|
||||
message: "",
|
||||
intent: null, // "warning", "confirmation", "error", "announcement", "step-required", etc
|
||||
type: null, // "alert", "notification", or "prompt": set by subclass
|
||||
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)
|
||||
|
||||
/* Could also have an "actions" hash: here is an example demonstrating
|
||||
the expected structure. For each action, by default the framework
|
||||
will call preventDefault on the click event before the function is
|
||||
run; to make it not do that, just pass `preventDefault: false` in
|
||||
the action object.
|
||||
|
||||
actions: {
|
||||
primary: {
|
||||
"text": "Save",
|
||||
"class": "action-save",
|
||||
"click": function(view) {
|
||||
// do something when Save is clicked
|
||||
}
|
||||
},
|
||||
secondary: [
|
||||
{
|
||||
"text": "Cancel",
|
||||
"class": "action-cancel",
|
||||
"click": function(view) {}
|
||||
}, {
|
||||
"text": "Discard Changes",
|
||||
"class": "action-discard",
|
||||
"click": function(view) {}
|
||||
}
|
||||
]
|
||||
}
|
||||
*/
|
||||
},
|
||||
|
||||
initialize: function() {
|
||||
if (!this.options.type) {
|
||||
throw "SystemFeedback: type required (given " +
|
||||
JSON.stringify(this.options) + ")";
|
||||
}
|
||||
if (!this.options.intent) {
|
||||
throw "SystemFeedback: intent required (given " +
|
||||
JSON.stringify(this.options) + ")";
|
||||
}
|
||||
this.setElement($("#page-" + this.options.type));
|
||||
// handle single "secondary" action
|
||||
if (this.options.actions && this.options.actions.secondary &&
|
||||
!_.isArray(this.options.actions.secondary)) {
|
||||
this.options.actions.secondary = [this.options.actions.secondary];
|
||||
}
|
||||
return this;
|
||||
},
|
||||
|
||||
// public API: show() and hide()
|
||||
show: function() {
|
||||
clearTimeout(this.hideTimeout);
|
||||
this.options.shown = true;
|
||||
this.shownAt = new Date();
|
||||
this.render();
|
||||
if ($.isNumeric(this.options.maxShown)) {
|
||||
this.hideTimeout = setTimeout(_.bind(this.hide, this),
|
||||
this.options.maxShown);
|
||||
}
|
||||
return this;
|
||||
},
|
||||
|
||||
hide: function() {
|
||||
if (this.shownAt && $.isNumeric(this.options.minShown) &&
|
||||
this.options.minShown > new Date() - this.shownAt) {
|
||||
clearTimeout(this.hideTimeout);
|
||||
this.hideTimeout = setTimeout(_.bind(this.hide, this),
|
||||
this.options.minShown - (new Date() - this.shownAt));
|
||||
} else {
|
||||
this.options.shown = false;
|
||||
delete this.shownAt;
|
||||
this.render();
|
||||
}
|
||||
return this;
|
||||
},
|
||||
|
||||
// the rest of the API should be considered semi-private
|
||||
events: {
|
||||
"click .action-close": "hide",
|
||||
"click .action-primary": "primaryClick",
|
||||
"click .action-secondary": "secondaryClick"
|
||||
},
|
||||
|
||||
render: function() {
|
||||
// there can be only one active view of a given type at a time: only
|
||||
// one alert, only one notification, only one prompt. Therefore, we'll
|
||||
// use a singleton approach.
|
||||
var singleton = SystemFeedback["active_" + this.options.type];
|
||||
if (singleton && singleton !== this) {
|
||||
singleton.stopListening();
|
||||
singleton.undelegateEvents();
|
||||
}
|
||||
this.$el.html(_.template(systemFeedbackTemplate)(this.options));
|
||||
SystemFeedback["active_" + this.options.type] = this;
|
||||
return this;
|
||||
},
|
||||
|
||||
primaryClick: function(event) {
|
||||
var actions, primary;
|
||||
actions = this.options.actions;
|
||||
if (!actions) { return; }
|
||||
primary = actions.primary;
|
||||
if (!primary) { return; }
|
||||
if (primary.preventDefault !== false) {
|
||||
event.preventDefault();
|
||||
}
|
||||
if (primary.click) {
|
||||
primary.click.call(event.target, this, event);
|
||||
}
|
||||
},
|
||||
|
||||
secondaryClick: function(event) {
|
||||
var actions, secondaryList, secondary, i;
|
||||
actions = this.options.actions;
|
||||
if (!actions) { return; }
|
||||
secondaryList = actions.secondary;
|
||||
if (!secondaryList) { return; }
|
||||
// which secondary action was clicked?
|
||||
i = 0; // default to the first secondary action (easier for testing)
|
||||
if (event && event.target) {
|
||||
i = _.indexOf(this.$(".action-secondary"), event.target);
|
||||
}
|
||||
secondary = secondaryList[i];
|
||||
if (secondary.preventDefault !== false) {
|
||||
event.preventDefault();
|
||||
}
|
||||
if (secondary.click) {
|
||||
secondary.click.call(event.target, this, event);
|
||||
}
|
||||
}
|
||||
});
|
||||
return SystemFeedback;
|
||||
});
|
||||
}).call(this, define || RequireJS.define);
|
||||
42
common/static/common/js/components/views/feedback_alert.js
Normal file
42
common/static/common/js/components/views/feedback_alert.js
Normal file
@@ -0,0 +1,42 @@
|
||||
;(function (define) {
|
||||
'use strict';
|
||||
define(["jquery", "underscore", "underscore.string", "common/js/components/views/feedback"],
|
||||
function($, _, str, SystemFeedbackView) {
|
||||
str = str || _.str;
|
||||
var Alert = SystemFeedbackView.extend({
|
||||
options: $.extend({}, SystemFeedbackView.prototype.options, {
|
||||
type: "alert"
|
||||
}),
|
||||
slide_speed: 900,
|
||||
show: function() {
|
||||
SystemFeedbackView.prototype.show.apply(this, arguments);
|
||||
this.$el.hide();
|
||||
this.$el.slideDown(this.slide_speed);
|
||||
return this;
|
||||
},
|
||||
hide: function () {
|
||||
this.$el.slideUp({
|
||||
duration: this.slide_speed
|
||||
});
|
||||
setTimeout(_.bind(SystemFeedbackView.prototype.hide, this, arguments),
|
||||
this.slideSpeed);
|
||||
}
|
||||
});
|
||||
|
||||
// create Alert.Warning, Alert.Confirmation, etc
|
||||
var capitalCamel, intents;
|
||||
capitalCamel = _.compose(str.capitalize, str.camelize);
|
||||
intents = ["warning", "error", "confirmation", "announcement", "step-required", "help", "mini"];
|
||||
_.each(intents, function(intent) {
|
||||
var subclass;
|
||||
subclass = Alert.extend({
|
||||
options: $.extend({}, Alert.prototype.options, {
|
||||
intent: intent
|
||||
})
|
||||
});
|
||||
Alert[capitalCamel(intent)] = subclass;
|
||||
});
|
||||
|
||||
return Alert;
|
||||
});
|
||||
}).call(this, define || RequireJS.define);
|
||||
@@ -0,0 +1,34 @@
|
||||
;(function (define) {
|
||||
'use strict';
|
||||
define(["jquery", "underscore", "underscore.string", "common/js/components/views/feedback"],
|
||||
function($, _, str, SystemFeedbackView) {
|
||||
str = str || _.str;
|
||||
var Notification = SystemFeedbackView.extend({
|
||||
options: $.extend({}, SystemFeedbackView.prototype.options, {
|
||||
type: "notification",
|
||||
closeIcon: false
|
||||
})
|
||||
});
|
||||
|
||||
// create Notification.Warning, Notification.Confirmation, etc
|
||||
var capitalCamel, intents;
|
||||
capitalCamel = _.compose(str.capitalize, str.camelize);
|
||||
intents = ["warning", "error", "confirmation", "announcement", "step-required", "help", "mini"];
|
||||
_.each(intents, function(intent) {
|
||||
var subclass;
|
||||
subclass = Notification.extend({
|
||||
options: $.extend({}, Notification.prototype.options, {
|
||||
intent: intent
|
||||
})
|
||||
});
|
||||
Notification[capitalCamel(intent)] = subclass;
|
||||
});
|
||||
|
||||
// set more sensible defaults for Notification.Mini views
|
||||
var miniOptions = Notification.Mini.prototype.options;
|
||||
miniOptions.minShown = 1250;
|
||||
miniOptions.closeIcon = false;
|
||||
|
||||
return Notification;
|
||||
});
|
||||
}).call(this, define || RequireJS.define);
|
||||
40
common/static/common/js/components/views/feedback_prompt.js
Normal file
40
common/static/common/js/components/views/feedback_prompt.js
Normal file
@@ -0,0 +1,40 @@
|
||||
;(function (define) {
|
||||
'use strict';
|
||||
define(["jquery", "underscore", "underscore.string", "common/js/components/views/feedback"],
|
||||
function($, _, str, SystemFeedbackView) {
|
||||
str = str || _.str;
|
||||
var Prompt = SystemFeedbackView.extend({
|
||||
options: $.extend({}, SystemFeedbackView.prototype.options, {
|
||||
type: "prompt",
|
||||
closeIcon: false,
|
||||
icon: false
|
||||
}),
|
||||
render: function() {
|
||||
if(!window.$body) { window.$body = $(document.body); }
|
||||
if(this.options.shown) {
|
||||
$body.addClass('prompt-is-shown');
|
||||
} else {
|
||||
$body.removeClass('prompt-is-shown');
|
||||
}
|
||||
// super() in Javascript has awkward syntax :(
|
||||
return SystemFeedbackView.prototype.render.apply(this, arguments);
|
||||
}
|
||||
});
|
||||
|
||||
// create Prompt.Warning, Prompt.Confirmation, etc
|
||||
var capitalCamel, intents;
|
||||
capitalCamel = _.compose(str.capitalize, str.camelize);
|
||||
intents = ["warning", "error", "confirmation", "announcement", "step-required", "help", "mini"];
|
||||
_.each(intents, function(intent) {
|
||||
var subclass;
|
||||
subclass = Prompt.extend({
|
||||
options: $.extend({}, Prompt.prototype.options, {
|
||||
intent: intent
|
||||
})
|
||||
});
|
||||
Prompt[capitalCamel(intent)] = subclass;
|
||||
});
|
||||
|
||||
return Prompt;
|
||||
});
|
||||
}).call(this, define || RequireJS.define);
|
||||
336
common/static/common/js/spec/components/feedback_spec.js
Normal file
336
common/static/common/js/spec/components/feedback_spec.js
Normal file
@@ -0,0 +1,336 @@
|
||||
// Generated by CoffeeScript 1.6.1
|
||||
(function() {
|
||||
|
||||
define(["jquery", "common/js/components/views/feedback", "common/js/components/views/feedback_notification", "common/js/components/views/feedback_alert", "common/js/components/views/feedback_prompt", "sinon"], function($, SystemFeedback, NotificationView, AlertView, PromptView, sinon) {
|
||||
var tpl;
|
||||
tpl = readFixtures('system-feedback.underscore');
|
||||
beforeEach(function() {
|
||||
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));
|
||||
return this.addMatchers({
|
||||
toBeShown: function() {
|
||||
return this.actual.hasClass("is-shown") && !this.actual.hasClass("is-hiding");
|
||||
},
|
||||
toBeHiding: function() {
|
||||
return this.actual.hasClass("is-hiding") && !this.actual.hasClass("is-shown");
|
||||
},
|
||||
toContainText: function(text) {
|
||||
var trimmedText;
|
||||
trimmedText = $.trim(this.actual.text());
|
||||
if (text && $.isFunction(text.test)) {
|
||||
return text.test(trimmedText);
|
||||
} else {
|
||||
return trimmedText.indexOf(text) !== -1;
|
||||
}
|
||||
},
|
||||
toHaveBeenPrevented: function() {
|
||||
var eventName, selector;
|
||||
eventName = this.actual.eventName;
|
||||
selector = this.actual.selector;
|
||||
this.message = function() {
|
||||
return ["Expected event " + eventName + " to have been prevented on " + selector, "Expected event " + eventName + " not to have been prevented on " + selector];
|
||||
};
|
||||
return jasmine.JQuery.events.wasPrevented(selector, eventName);
|
||||
}
|
||||
});
|
||||
});
|
||||
describe("SystemFeedback", function() {
|
||||
beforeEach(function() {
|
||||
this.options = {
|
||||
title: "Portal",
|
||||
message: "Welcome to the Aperture Science Computer-Aided Enrichment Center"
|
||||
};
|
||||
this.renderSpy = spyOn(AlertView.Confirmation.prototype, 'render').andCallThrough();
|
||||
this.showSpy = spyOn(AlertView.Confirmation.prototype, 'show').andCallThrough();
|
||||
this.hideSpy = spyOn(AlertView.Confirmation.prototype, 'hide').andCallThrough();
|
||||
return this.clock = sinon.useFakeTimers();
|
||||
});
|
||||
afterEach(function() {
|
||||
return this.clock.restore();
|
||||
});
|
||||
it("requires a type and an intent", function() {
|
||||
var both, neither, noIntent, noType,
|
||||
_this = this;
|
||||
neither = function() {
|
||||
return new SystemFeedback(_this.options);
|
||||
};
|
||||
noType = function() {
|
||||
var options;
|
||||
options = $.extend({}, _this.options);
|
||||
options.intent = "confirmation";
|
||||
return new SystemFeedback(options);
|
||||
};
|
||||
noIntent = function() {
|
||||
var options;
|
||||
options = $.extend({}, _this.options);
|
||||
options.type = "alert";
|
||||
return new SystemFeedback(options);
|
||||
};
|
||||
both = function() {
|
||||
var options;
|
||||
options = $.extend({}, _this.options);
|
||||
options.type = "alert";
|
||||
options.intent = "confirmation";
|
||||
return new SystemFeedback(options);
|
||||
};
|
||||
expect(neither).toThrow();
|
||||
expect(noType).toThrow();
|
||||
expect(noIntent).toThrow();
|
||||
return expect(both).not.toThrow();
|
||||
});
|
||||
it("does not show on initalize", function() {
|
||||
var view;
|
||||
view = new AlertView.Confirmation(this.options);
|
||||
expect(this.renderSpy).not.toHaveBeenCalled();
|
||||
return expect(this.showSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
xit("renders the template", function() {
|
||||
var view;
|
||||
view = new AlertView.Confirmation(this.options);
|
||||
view.show();
|
||||
expect(view.$(".action-close")).toBeDefined();
|
||||
expect(view.$('.wrapper')).toBeShown();
|
||||
expect(view.$el).toContainText(this.options.title);
|
||||
return expect(view.$el).toContainText(this.options.message);
|
||||
});
|
||||
return xit("close button sends a .hide() message", function() {
|
||||
var view;
|
||||
view = new AlertView.Confirmation(this.options).show();
|
||||
view.$(".action-close").click();
|
||||
expect(this.hideSpy).toHaveBeenCalled();
|
||||
this.clock.tick(900);
|
||||
return expect(view.$('.wrapper')).toBeHiding();
|
||||
});
|
||||
});
|
||||
describe("PromptView", function() {
|
||||
return it("changes class on body", function() {
|
||||
var view;
|
||||
view = new PromptView.Confirmation({
|
||||
title: "Portal",
|
||||
message: "Welcome to the Aperture Science Computer-Aided Enrichment Center"
|
||||
});
|
||||
return view.hide();
|
||||
});
|
||||
});
|
||||
describe("NotificationView.Mini", function() {
|
||||
beforeEach(function() {
|
||||
return this.view = new NotificationView.Mini();
|
||||
});
|
||||
it("should have minShown set to 1250 by default", function() {
|
||||
return expect(this.view.options.minShown).toEqual(1250);
|
||||
});
|
||||
return it("should have closeIcon set to false by default", function() {
|
||||
return expect(this.view.options.closeIcon).toBeFalsy();
|
||||
});
|
||||
});
|
||||
xdescribe("SystemFeedback click events", function() {
|
||||
beforeEach(function() {
|
||||
this.primaryClickSpy = jasmine.createSpy('primaryClick');
|
||||
this.secondaryClickSpy = jasmine.createSpy('secondaryClick');
|
||||
this.view = new NotificationView.Warning({
|
||||
title: "Unsaved",
|
||||
message: "Your content is currently Unsaved.",
|
||||
actions: {
|
||||
primary: {
|
||||
text: "Save",
|
||||
"class": "save-button",
|
||||
click: this.primaryClickSpy
|
||||
},
|
||||
secondary: {
|
||||
text: "Revert",
|
||||
"class": "cancel-button",
|
||||
click: this.secondaryClickSpy
|
||||
}
|
||||
}
|
||||
});
|
||||
return this.view.show();
|
||||
});
|
||||
it("should trigger the primary event on a primary click", function() {
|
||||
this.view.$(".action-primary").click();
|
||||
expect(this.primaryClickSpy).toHaveBeenCalled();
|
||||
return expect(this.secondaryClickSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
it("should trigger the secondary event on a secondary click", function() {
|
||||
this.view.$(".action-secondary").click();
|
||||
expect(this.secondaryClickSpy).toHaveBeenCalled();
|
||||
return expect(this.primaryClickSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
it("should apply class to primary action", function() {
|
||||
return expect(this.view.$(".action-primary")).toHaveClass("save-button");
|
||||
});
|
||||
it("should apply class to secondary action", function() {
|
||||
return expect(this.view.$(".action-secondary")).toHaveClass("cancel-button");
|
||||
});
|
||||
it("should preventDefault on primary action", function() {
|
||||
spyOnEvent(".action-primary", "click");
|
||||
this.view.$(".action-primary").click();
|
||||
return expect("click").toHaveBeenPreventedOn(".action-primary");
|
||||
});
|
||||
return it("should preventDefault on secondary action", function() {
|
||||
spyOnEvent(".action-secondary", "click");
|
||||
this.view.$(".action-secondary").click();
|
||||
return expect("click").toHaveBeenPreventedOn(".action-secondary");
|
||||
});
|
||||
});
|
||||
xdescribe("SystemFeedback not preventing events", function() {
|
||||
beforeEach(function() {
|
||||
this.clickSpy = jasmine.createSpy('clickSpy');
|
||||
this.view = new AlertView.Confirmation({
|
||||
title: "It's all good",
|
||||
message: "No reason for this alert",
|
||||
actions: {
|
||||
primary: {
|
||||
text: "Whatever",
|
||||
click: this.clickSpy,
|
||||
preventDefault: false
|
||||
}
|
||||
}
|
||||
});
|
||||
return this.view.show();
|
||||
});
|
||||
return it("should not preventDefault", function() {
|
||||
spyOnEvent(".action-primary", "click");
|
||||
this.view.$(".action-primary").click();
|
||||
expect("click").not.toHaveBeenPreventedOn(".action-primary");
|
||||
return expect(this.clickSpy).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
xdescribe("SystemFeedback multiple secondary actions", function() {
|
||||
beforeEach(function() {
|
||||
this.secondarySpyOne = jasmine.createSpy('secondarySpyOne');
|
||||
this.secondarySpyTwo = jasmine.createSpy('secondarySpyTwo');
|
||||
this.view = new NotificationView.Warning({
|
||||
title: "No Primary",
|
||||
message: "Pick a secondary action",
|
||||
actions: {
|
||||
secondary: [
|
||||
{
|
||||
text: "Option One",
|
||||
"class": "option-one",
|
||||
click: this.secondarySpyOne
|
||||
}, {
|
||||
text: "Option Two",
|
||||
"class": "option-two",
|
||||
click: this.secondarySpyTwo
|
||||
}
|
||||
]
|
||||
}
|
||||
});
|
||||
return this.view.show();
|
||||
});
|
||||
it("should render both", function() {
|
||||
expect(this.view.el).toContain(".action-secondary.option-one");
|
||||
expect(this.view.el).toContain(".action-secondary.option-two");
|
||||
expect(this.view.el).not.toContain(".action-secondary.option-one.option-two");
|
||||
expect(this.view.$(".action-secondary.option-one")).toContainText("Option One");
|
||||
return expect(this.view.$(".action-secondary.option-two")).toContainText("Option Two");
|
||||
});
|
||||
it("should differentiate clicks (1)", function() {
|
||||
this.view.$(".option-one").click();
|
||||
expect(this.secondarySpyOne).toHaveBeenCalled();
|
||||
return expect(this.secondarySpyTwo).not.toHaveBeenCalled();
|
||||
});
|
||||
return it("should differentiate clicks (2)", function() {
|
||||
this.view.$(".option-two").click();
|
||||
expect(this.secondarySpyOne).not.toHaveBeenCalled();
|
||||
return expect(this.secondarySpyTwo).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
return describe("NotificationView minShown and maxShown", function() {
|
||||
beforeEach(function() {
|
||||
this.showSpy = spyOn(NotificationView.Confirmation.prototype, 'show');
|
||||
this.showSpy.andCallThrough();
|
||||
this.hideSpy = spyOn(NotificationView.Confirmation.prototype, 'hide');
|
||||
this.hideSpy.andCallThrough();
|
||||
return this.clock = sinon.useFakeTimers();
|
||||
});
|
||||
afterEach(function() {
|
||||
return this.clock.restore();
|
||||
});
|
||||
xit("should not have minShown or maxShown by default", function() {
|
||||
var view;
|
||||
view = new NotificationView.Confirmation();
|
||||
expect(view.options.minShown).toEqual(0);
|
||||
return expect(view.options.maxShown).toEqual(Infinity);
|
||||
});
|
||||
xit("a minShown view should not hide too quickly", function() {
|
||||
var view;
|
||||
view = new NotificationView.Confirmation({
|
||||
minShown: 1000
|
||||
});
|
||||
view.show();
|
||||
expect(view.$('.wrapper')).toBeShown();
|
||||
view.hide();
|
||||
expect(view.$('.wrapper')).toBeShown();
|
||||
this.clock.tick(1001);
|
||||
return expect(view.$('.wrapper')).toBeHiding();
|
||||
});
|
||||
xit("a maxShown view should hide by itself", function() {
|
||||
var view;
|
||||
view = new NotificationView.Confirmation({
|
||||
maxShown: 1000
|
||||
});
|
||||
view.show();
|
||||
expect(view.$('.wrapper')).toBeShown();
|
||||
this.clock.tick(1001);
|
||||
return expect(view.$('.wrapper')).toBeHiding();
|
||||
});
|
||||
xit("a minShown view can stay visible longer", function() {
|
||||
var view;
|
||||
view = new NotificationView.Confirmation({
|
||||
minShown: 1000
|
||||
});
|
||||
view.show();
|
||||
expect(view.$('.wrapper')).toBeShown();
|
||||
this.clock.tick(1001);
|
||||
expect(this.hideSpy).not.toHaveBeenCalled();
|
||||
expect(view.$('.wrapper')).toBeShown();
|
||||
view.hide();
|
||||
return expect(view.$('.wrapper')).toBeHiding();
|
||||
});
|
||||
xit("a maxShown view can hide early", function() {
|
||||
var view;
|
||||
view = new NotificationView.Confirmation({
|
||||
maxShown: 1000
|
||||
});
|
||||
view.show();
|
||||
expect(view.$('.wrapper')).toBeShown();
|
||||
this.clock.tick(50);
|
||||
view.hide();
|
||||
expect(view.$('.wrapper')).toBeHiding();
|
||||
this.clock.tick(1000);
|
||||
return expect(view.$('.wrapper')).toBeHiding();
|
||||
});
|
||||
return it("a view can have both maxShown and minShown", function() {
|
||||
var view;
|
||||
view = new NotificationView.Confirmation({
|
||||
minShown: 1000,
|
||||
maxShown: 2000
|
||||
});
|
||||
view.show();
|
||||
this.clock.tick(50);
|
||||
view.hide();
|
||||
expect(view.$('.wrapper')).toBeShown();
|
||||
this.clock.tick(1000);
|
||||
expect(view.$('.wrapper')).toBeHiding();
|
||||
view.show();
|
||||
this.clock.tick(1050);
|
||||
expect(view.$('.wrapper')).toBeShown();
|
||||
this.clock.tick(1000);
|
||||
return expect(view.$('.wrapper')).toBeHiding();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
}).call(this);
|
||||
@@ -1,5 +1,7 @@
|
||||
define(["jquery", "underscore", "js/views/baseview", "js/views/utils/view_utils", "js/spec_helpers/edit_helpers"],
|
||||
function ($, _, BaseView, ViewUtils, ViewHelpers) {
|
||||
;(function (define) {
|
||||
'use strict';
|
||||
define(["jquery", "underscore", "common/js/components/utils/view_utils", "common/js/spec_helpers/view_helpers", 'jasmine-stealth'],
|
||||
function ($, _, ViewUtils, ViewHelpers) {
|
||||
|
||||
describe("ViewUtils", function() {
|
||||
describe("disabled element while running", function() {
|
||||
@@ -90,3 +92,4 @@ define(["jquery", "underscore", "js/views/baseview", "js/views/utils/view_utils"
|
||||
});
|
||||
});
|
||||
});
|
||||
}).call(this, define || RequireJS.define);
|
||||
@@ -1,16 +1,18 @@
|
||||
/**
|
||||
* Provides helper methods for invoking Studio modal windows in Jasmine tests.
|
||||
*/
|
||||
define(["jquery", "js/views/feedback_notification", "js/views/feedback_prompt", 'common/js/spec_helpers/ajax_helpers',
|
||||
"common/js/spec_helpers/template_helpers"],
|
||||
function($, NotificationView, Prompt, AjaxHelpers, TemplateHelpers) {
|
||||
;(function (define) {
|
||||
'use strict';
|
||||
define(["jquery", "common/js/components/views/feedback_notification", "common/js/components/views/feedback_prompt",
|
||||
'common/js/spec_helpers/ajax_helpers'],
|
||||
function($, NotificationView, Prompt, AjaxHelpers) {
|
||||
var installViewTemplates, createFeedbackSpy, verifyFeedbackShowing,
|
||||
verifyFeedbackHidden, createNotificationSpy, verifyNotificationShowing,
|
||||
verifyNotificationHidden, createPromptSpy, confirmPrompt, inlineEdit, verifyInlineEditChange,
|
||||
installMockAnalytics, removeMockAnalytics, verifyPromptShowing, verifyPromptHidden;
|
||||
installMockAnalytics, removeMockAnalytics, verifyPromptShowing, verifyPromptHidden,
|
||||
clickDeleteItem, patchAndVerifyRequest, submitAndVerifyFormSuccess, submitAndVerifyFormError;
|
||||
|
||||
installViewTemplates = function(append) {
|
||||
TemplateHelpers.installTemplate('system-feedback', !append);
|
||||
installViewTemplates = function() {
|
||||
appendSetFixtures('<div id="page-notification"></div>');
|
||||
};
|
||||
|
||||
@@ -144,3 +146,4 @@ define(["jquery", "js/views/feedback_notification", "js/views/feedback_prompt",
|
||||
'submitAndVerifyFormError': submitAndVerifyFormError
|
||||
};
|
||||
});
|
||||
}).call(this, define || RequireJS.define);
|
||||
@@ -21,17 +21,16 @@
|
||||
|
||||
<% 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>
|
||||
<button class="action-primary <%= actions.primary.class %>"><%= actions.primary.text %></button>
|
||||
</li>
|
||||
<% } %>
|
||||
<% if(actions.secondary) {
|
||||
_.each(actions.secondary, function(secondary) { %>
|
||||
<li class="nav-item">
|
||||
<a href="#" class="button action-secondary <%= secondary.class %>"><%= secondary.text %></a>
|
||||
<button class="action-secondary <%= secondary.class %>"><%= secondary.text %></button>
|
||||
</li>
|
||||
<% });
|
||||
} %>
|
||||
@@ -159,7 +159,9 @@
|
||||
'common-requirejs/include/common/js/spec/components/paginated_view_spec.js',
|
||||
'common-requirejs/include/common/js/spec/components/paging_collection_spec.js',
|
||||
'common-requirejs/include/common/js/spec/components/paging_header_spec.js',
|
||||
'common-requirejs/include/common/js/spec/components/paging_footer_spec.js'
|
||||
'common-requirejs/include/common/js/spec/components/paging_footer_spec.js',
|
||||
'common-requirejs/include/common/js/spec/components/view_utils_spec.js',
|
||||
'common-requirejs/include/common/js/spec/components/feedback_spec.js'
|
||||
]);
|
||||
|
||||
}).call(this, requirejs, define);
|
||||
|
||||
@@ -44,6 +44,7 @@ lib_paths:
|
||||
- coffee/src/jquery.immediateDescendents.js
|
||||
- js/vendor/requirejs/text.js
|
||||
- js/vendor/sinon-1.7.1.js
|
||||
- js/vendor/jasmine-stealth.js
|
||||
|
||||
# Paths to source JavaScript files
|
||||
src_paths:
|
||||
|
||||
@@ -437,3 +437,10 @@
|
||||
-webkit-font-smoothing: antialiased;
|
||||
speak: none;
|
||||
}
|
||||
|
||||
%btn-no-style {
|
||||
background: transparent;
|
||||
border: 0;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ Teams pages.
|
||||
from .course_page import CoursePage
|
||||
from .discussion import InlineDiscussionPage
|
||||
from ..common.paging import PaginatedUIMixin
|
||||
from ...pages.studio.utils import confirm_prompt
|
||||
|
||||
from .fields import FieldsMixin
|
||||
|
||||
@@ -334,14 +335,17 @@ class TeamPage(CoursePage, PaginatedUIMixin):
|
||||
"""Verifies that team leave link is present"""
|
||||
return self.q(css='.leave-team-link').present
|
||||
|
||||
def click_leave_team_link(self, remaining_members=0):
|
||||
def click_leave_team_link(self, remaining_members=0, cancel=False):
|
||||
""" Click on Leave Team link"""
|
||||
self.q(css='.leave-team-link').first.click()
|
||||
self.wait_for(
|
||||
lambda: self.join_team_button_present,
|
||||
description="Join Team button did not become present"
|
||||
)
|
||||
self.wait_for_capacity_text(remaining_members)
|
||||
confirm_prompt(self, cancel, require_notification=False)
|
||||
|
||||
if cancel is False:
|
||||
self.wait_for(
|
||||
lambda: self.join_team_button_present,
|
||||
description="Join Team button did not become present"
|
||||
)
|
||||
self.wait_for_capacity_text(remaining_members)
|
||||
|
||||
@property
|
||||
def team_members(self):
|
||||
|
||||
@@ -59,7 +59,7 @@ def press_the_notification_button(page, name):
|
||||
# the "Save" button at the UI level.
|
||||
# Instead, we use JavaScript to reliably click
|
||||
# the button.
|
||||
btn_css = 'div#page-notification a.action-%s' % name.lower()
|
||||
btn_css = 'div#page-notification button.action-%s' % name.lower()
|
||||
page.browser.execute_script("$('{}').focus().click()".format(btn_css))
|
||||
page.wait_for_ajax()
|
||||
|
||||
@@ -177,7 +177,7 @@ def get_codemirror_value(page, index=0, find_prefix="$"):
|
||||
)
|
||||
|
||||
|
||||
def confirm_prompt(page, cancel=False):
|
||||
def confirm_prompt(page, cancel=False, require_notification=None):
|
||||
"""
|
||||
Ensures that a modal prompt and confirmation button are visible, then clicks the button. The prompt is canceled iff
|
||||
cancel is True.
|
||||
@@ -185,7 +185,8 @@ def confirm_prompt(page, cancel=False):
|
||||
page.wait_for_element_visibility('.prompt', 'Prompt is visible')
|
||||
confirmation_button_css = '.prompt .action-' + ('secondary' if cancel else 'primary')
|
||||
page.wait_for_element_visibility(confirmation_button_css, 'Confirmation button is visible')
|
||||
click_css(page, confirmation_button_css, require_notification=(not cancel))
|
||||
require_notification = (not cancel) if require_notification is None else require_notification
|
||||
click_css(page, confirmation_button_css, require_notification=require_notification)
|
||||
|
||||
|
||||
def set_input_value(page, css, value):
|
||||
|
||||
@@ -21,7 +21,7 @@ define([
|
||||
];
|
||||
|
||||
beforeEach(function () {
|
||||
setFixtures('<div class="teams-content"><div class="msg-content"><div class="copy"></div></div></div>');
|
||||
setFixtures('<div id="page-prompt"></div><div class="teams-content"><div class="msg-content"><div class="copy"></div></div></div>');
|
||||
DiscussionSpecHelper.setUnderscoreFixtures();
|
||||
});
|
||||
|
||||
@@ -74,19 +74,29 @@ define([
|
||||
return profileView;
|
||||
};
|
||||
|
||||
clickLeaveTeam = function(requests, view) {
|
||||
clickLeaveTeam = function(requests, view, options) {
|
||||
expect(view.$(leaveTeamLinkSelector).length).toBe(1);
|
||||
|
||||
// click on Leave Team link under Team Details
|
||||
view.$(leaveTeamLinkSelector).click();
|
||||
|
||||
// expect a request to DELETE the team membership
|
||||
AjaxHelpers.expectJsonRequest(requests, 'DELETE', 'api/team/v0/team_membership/test-team,bilbo');
|
||||
AjaxHelpers.respondWithNoContent(requests);
|
||||
if (!options.cancel) {
|
||||
// click on Confirm button on dialog
|
||||
$('.prompt.warning .action-primary').click();
|
||||
|
||||
// expect a request to refetch the user's team memberships
|
||||
AjaxHelpers.expectJsonRequest(requests, 'GET', '/api/team/v0/teams/test-team');
|
||||
AjaxHelpers.respondWithJson(requests, createTeamModelData({country: 'US', language: 'en'}));
|
||||
// expect a request to DELETE the team membership
|
||||
AjaxHelpers.expectJsonRequest(requests, 'DELETE', 'api/team/v0/team_membership/test-team,bilbo');
|
||||
AjaxHelpers.respondWithNoContent(requests);
|
||||
|
||||
// expect a request to refetch the user's team memberships
|
||||
AjaxHelpers.expectJsonRequest(requests, 'GET', '/api/team/v0/teams/test-team');
|
||||
AjaxHelpers.respondWithJson(requests, createTeamModelData({country: 'US', language: 'en'}));
|
||||
} else {
|
||||
var requestCount = requests.length;
|
||||
// click on Cancel button on dialog
|
||||
$('.prompt.warning .action-secondary').click();
|
||||
expect(requests.length).toBe(requestCount);
|
||||
}
|
||||
};
|
||||
|
||||
describe('DiscussionsView', function() {
|
||||
@@ -111,7 +121,7 @@ define([
|
||||
view = createTeamProfileView(requests, {membership: DEFAULT_MEMBERSHIP});
|
||||
|
||||
expect(view.$('.new-post-btn').length).toEqual(1);
|
||||
clickLeaveTeam(requests, view);
|
||||
clickLeaveTeam(requests, view, {cancel: false});
|
||||
expect(view.$('.new-post-btn').length).toEqual(0);
|
||||
});
|
||||
});
|
||||
@@ -178,10 +188,21 @@ define([
|
||||
requests, {country: 'US', language: 'en', membership: DEFAULT_MEMBERSHIP}
|
||||
);
|
||||
assertTeamDetails(view, 1, true);
|
||||
clickLeaveTeam(requests, view);
|
||||
clickLeaveTeam(requests, view, {cancel: false});
|
||||
assertTeamDetails(view, 0, false);
|
||||
});
|
||||
|
||||
it("wouldn't do anything if user click on Cancel button on dialog", function() {
|
||||
var requests = AjaxHelpers.requests(this);
|
||||
|
||||
var view = createTeamProfileView(
|
||||
requests, {country: 'US', language: 'en', membership: DEFAULT_MEMBERSHIP}
|
||||
);
|
||||
assertTeamDetails(view, 1, true);
|
||||
clickLeaveTeam(requests, view, {cancel: true});
|
||||
assertTeamDetails(view, 1, true);
|
||||
});
|
||||
|
||||
it('shows correct error messages', function () {
|
||||
var requests = AjaxHelpers.requests(this);
|
||||
|
||||
@@ -189,7 +210,10 @@ define([
|
||||
var view = createTeamProfileView(
|
||||
requests, {country: 'US', language: 'en', membership: DEFAULT_MEMBERSHIP}
|
||||
);
|
||||
// click leave team link
|
||||
view.$('.leave-team-link').click();
|
||||
// click Confirm button on dialog
|
||||
$('.prompt.warning .action-primary').click();
|
||||
AjaxHelpers.respondWithTextError(requests, 400, errorMessage);
|
||||
expect($('.msg-content .copy').text().trim()).toBe(expectedMessage);
|
||||
};
|
||||
|
||||
@@ -4,10 +4,11 @@
|
||||
;(function (define) {
|
||||
'use strict';
|
||||
define(['backbone', 'underscore', 'gettext', 'teams/js/views/team_discussion',
|
||||
'common/js/components/utils/view_utils',
|
||||
'teams/js/views/team_utils',
|
||||
'text!teams/templates/team-profile.underscore',
|
||||
'text!teams/templates/team-member.underscore'],
|
||||
function (Backbone, _, gettext, TeamDiscussionView, TeamUtils, teamTemplate, teamMemberTemplate) {
|
||||
function (Backbone, _, gettext, TeamDiscussionView, ViewUtils, TeamUtils, teamTemplate, teamMemberTemplate) {
|
||||
var TeamProfileView = Backbone.View.extend({
|
||||
|
||||
errorMessage: gettext("An error occurred. Try again."),
|
||||
@@ -72,20 +73,28 @@
|
||||
leaveTeam: function (event) {
|
||||
event.preventDefault();
|
||||
var view = this;
|
||||
$.ajax({
|
||||
type: 'DELETE',
|
||||
url: view.teamMembershipDetailUrl.replace('team_id', view.model.get('id'))
|
||||
}).done(function (data) {
|
||||
view.model.fetch()
|
||||
.done(function() {
|
||||
view.teamEvents.trigger('teams:update', {
|
||||
action: 'leave',
|
||||
team: view.model
|
||||
});
|
||||
ViewUtils.confirmThenRunOperation(
|
||||
gettext("Leave this team?"),
|
||||
gettext("If you leave, you can no longer post in this team's discussions. Your place will be available to another learner."),
|
||||
gettext("Confirm"),
|
||||
function() {
|
||||
$.ajax({
|
||||
type: 'DELETE',
|
||||
url: view.teamMembershipDetailUrl.replace('team_id', view.model.get('id'))
|
||||
}).done(function (data) {
|
||||
view.model.fetch()
|
||||
.done(function() {
|
||||
view.teamEvents.trigger('teams:update', {
|
||||
action: 'leave',
|
||||
team: view.model
|
||||
});
|
||||
});
|
||||
}).fail(function (data) {
|
||||
TeamUtils.parseAndShowMessage(data, view.errorMessage);
|
||||
});
|
||||
}).fail(function (data) {
|
||||
TeamUtils.parseAndShowMessage(data, view.errorMessage);
|
||||
});
|
||||
}
|
||||
);
|
||||
$('.wrapper-prompt').focus();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<%namespace name='static' file='/static_content.html'/>
|
||||
<%inherit file="/main.html" />
|
||||
|
||||
<%block name="bodyclass">view-teams is-in-course course</%block>
|
||||
<%block name="bodyclass">view-teams is-in-course course js</%block>
|
||||
<%block name="pagetitle">${_("Teams")}</%block>
|
||||
|
||||
<%block name="headextra">
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
// base - elements
|
||||
@import 'elements/typography';
|
||||
@import 'elements/controls';
|
||||
@import 'elements/system-feedback';
|
||||
@import 'elements/creative-commons';
|
||||
|
||||
// shared - course
|
||||
@@ -76,6 +75,10 @@
|
||||
// news
|
||||
@import 'news';
|
||||
|
||||
@import 'mixins';
|
||||
@import 'mixins-inherited';
|
||||
@import 'elements/system-feedback';
|
||||
|
||||
// overrides
|
||||
@import 'developer'; // used for any developer-created scss that needs further polish/refactoring
|
||||
@import 'shame'; // used for any bad-form/orphaned scss
|
||||
|
||||
1
lms/static/sass/_mixins-inherited.scss
Symbolic link
1
lms/static/sass/_mixins-inherited.scss
Symbolic link
@@ -0,0 +1 @@
|
||||
../../../common/static/sass/_mixins-inherited.scss
|
||||
1
lms/static/sass/_mixins.scss
Symbolic link
1
lms/static/sass/_mixins.scss
Symbolic link
@@ -0,0 +1 @@
|
||||
../../../common/static/sass/_mixins.scss
|
||||
@@ -198,3 +198,22 @@ footer .references {
|
||||
.course-content .discussion-post.edit-post-form .topic-submenu {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
|
||||
// LMS system feedback button overrides
|
||||
.is-in-course .wrapper-prompt .nav-actions {
|
||||
button {
|
||||
font-family: inherit;
|
||||
}
|
||||
|
||||
.action-primary {
|
||||
@extend %t-action4;
|
||||
}
|
||||
|
||||
.action-secondary {
|
||||
@extend %btn-no-style;
|
||||
@extend %t-strong;
|
||||
box-shadow: none;
|
||||
text-shadow: none;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -134,6 +134,68 @@ $green-u1: desaturate($green,15%);
|
||||
$green-u2: desaturate($green,30%);
|
||||
$green-u3: desaturate($green,45%);
|
||||
|
||||
$yellow: rgb(255, 252, 221); // yellow color used by LMS
|
||||
//$yellow: rgb(237, 189, 60); // yellow color used by Studio
|
||||
$yellow-l1: tint($yellow,20%);
|
||||
$yellow-l2: tint($yellow,40%);
|
||||
$yellow-l3: tint($yellow,60%);
|
||||
$yellow-l4: tint($yellow,80%);
|
||||
$yellow-l5: tint($yellow,90%);
|
||||
$yellow-d1: shade($yellow,20%);
|
||||
$yellow-d2: shade($yellow,40%);
|
||||
$yellow-d3: shade($yellow,60%);
|
||||
$yellow-d4: shade($yellow,80%);
|
||||
$yellow-s1: saturate($yellow,15%);
|
||||
$yellow-s2: saturate($yellow,30%);
|
||||
$yellow-s3: saturate($yellow,45%);
|
||||
$yellow-u1: desaturate($yellow,15%);
|
||||
$yellow-u2: desaturate($yellow,30%);
|
||||
$yellow-u3: desaturate($yellow,45%);
|
||||
|
||||
$blue: rgb(0, 120, 176);
|
||||
$blue-l1: tint($blue,20%);
|
||||
$blue-l2: tint($blue,40%);
|
||||
$blue-l3: tint($blue,60%);
|
||||
$blue-l4: tint($blue,80%);
|
||||
$blue-l5: tint($blue,90%);
|
||||
$blue-d1: shade($blue,20%);
|
||||
$blue-d2: shade($blue,40%);
|
||||
$blue-d3: shade($blue,60%);
|
||||
$blue-d4: shade($blue,80%);
|
||||
$blue-s1: saturate($blue,15%);
|
||||
$blue-s2: saturate($blue,30%);
|
||||
$blue-s3: saturate($blue,45%);
|
||||
$blue-u1: desaturate($blue,15%);
|
||||
$blue-u2: desaturate($blue,30%);
|
||||
$blue-u3: desaturate($blue,45%);
|
||||
$blue-t0: rgba($blue, 0.125);
|
||||
$blue-t1: rgba($blue, 0.25);
|
||||
$blue-t2: rgba($blue, 0.50);
|
||||
$blue-t3: rgba($blue, 0.75);
|
||||
|
||||
$orange: rgb(237, 189, 60);
|
||||
$orange-l1: tint($orange,20%);
|
||||
$orange-l2: tint($orange,40%);
|
||||
$orange-l3: tint($orange,60%);
|
||||
$orange-l4: tint($orange,80%);
|
||||
$orange-l5: tint($orange,90%);
|
||||
$orange-d1: shade($orange,20%);
|
||||
$orange-d2: shade($orange,40%);
|
||||
$orange-d3: shade($orange,60%);
|
||||
$orange-d4: shade($orange,80%);
|
||||
$orange-s1: saturate($orange,15%);
|
||||
$orange-s2: saturate($orange,30%);
|
||||
$orange-s3: saturate($orange,45%);
|
||||
$orange-u1: desaturate($orange,15%);
|
||||
$orange-u2: desaturate($orange,30%);
|
||||
$orange-u3: desaturate($orange,45%);
|
||||
|
||||
// ====================
|
||||
|
||||
// copied from cms/static/sass/_variables.scss
|
||||
$ui-notification-height: ($baseline*10);
|
||||
|
||||
|
||||
// ====================
|
||||
|
||||
// COLORS: social platforms
|
||||
@@ -144,8 +206,7 @@ $linkedin-blue: #0077B5;
|
||||
// ====================
|
||||
|
||||
// TODO: both blue and yellow variables differ from CMS rgb value, need to confirm change to CMS variable is ok in current platform uses before switching.
|
||||
$blue: rgb(0, 120, 176);
|
||||
$yellow: rgb(255, 252, 221);
|
||||
//$yellow: rgb(255, 252, 221);
|
||||
|
||||
// ====================
|
||||
|
||||
|
||||
@@ -145,9 +145,960 @@
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// prompts
|
||||
|
||||
// notifications
|
||||
|
||||
// alerts
|
||||
|
||||
|
||||
// all the below sass is copied from cms/static/sass/elements/_system-feedback.scss
|
||||
|
||||
// studio - elements - system feedback
|
||||
// ====================
|
||||
|
||||
// messages
|
||||
.message {
|
||||
@extend %t-copy-sub1;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.message-status {
|
||||
@include border-top-radius(2px);
|
||||
@include box-sizing(border-box);
|
||||
@extend %t-strong;
|
||||
display: none;
|
||||
border-bottom: 2px solid $yellow-d2;
|
||||
margin: 0 0 $baseline 0;
|
||||
padding: ($baseline/2) $baseline;
|
||||
background: $yellow-d1;
|
||||
color: $white;
|
||||
|
||||
.feedback-symbol {
|
||||
@extend %t-icon5;
|
||||
position: relative;
|
||||
top: 1px;
|
||||
display: inline-block;
|
||||
margin-right: ($baseline/2);
|
||||
}
|
||||
|
||||
.text {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
&.error {
|
||||
border-color: $red-d3;
|
||||
background: $red-l1;
|
||||
}
|
||||
|
||||
&.is-shown {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// alerts, notifications, prompts, and status communication
|
||||
// ====================
|
||||
|
||||
// shared
|
||||
.wrapper-notification, .wrapper-alert, .prompt {
|
||||
@include box-sizing(border-box);
|
||||
|
||||
.copy {
|
||||
@extend %t-copy-sub1;
|
||||
}
|
||||
}
|
||||
|
||||
.wrapper-notification, .wrapper-alert, .prompt {
|
||||
background: $gray-d3;
|
||||
|
||||
.copy {
|
||||
color: $gray-l2;
|
||||
|
||||
.title {
|
||||
color: $white;
|
||||
}
|
||||
|
||||
.nav-actions {
|
||||
|
||||
.action-primary {
|
||||
color: $gray-d4;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.alert, .notification, .prompt {
|
||||
|
||||
// types - confirm
|
||||
&.confirm {
|
||||
|
||||
.nav-actions .action-primary {
|
||||
@include blue-button();
|
||||
@extend %t-action4;
|
||||
border-color: $blue-d2;
|
||||
}
|
||||
|
||||
.action-secondary {
|
||||
color: $blue;
|
||||
|
||||
&:hover {
|
||||
color: $blue-s2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// types - warning
|
||||
&.warning {
|
||||
|
||||
.nav-actions .action-primary {
|
||||
@include orange-button();
|
||||
@extend %t-action4;
|
||||
border-color: $orange-d2;
|
||||
color: $gray-d4;
|
||||
}
|
||||
|
||||
.action-secondary {
|
||||
color: $orange;
|
||||
|
||||
&:hover {
|
||||
color: $orange-s2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// types - error
|
||||
&.error {
|
||||
|
||||
.nav-actions .action-primary {
|
||||
@include red-button();
|
||||
@extend %t-action4;
|
||||
border-color: $red-d2;
|
||||
}
|
||||
|
||||
.action-secondary {
|
||||
color: $red-l1;
|
||||
|
||||
&:hover {
|
||||
color: $red;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// types - announcement
|
||||
&.announcement {
|
||||
|
||||
.nav-actions .action-primary {
|
||||
@include blue-button();
|
||||
@extend %t-action4;
|
||||
border-color: $blue-d2;
|
||||
}
|
||||
|
||||
.action-secondary {
|
||||
color: $blue;
|
||||
|
||||
&:hover {
|
||||
color: $blue-s2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// types - confirmation
|
||||
&.confirmation {
|
||||
|
||||
.nav-actions .action-primary {
|
||||
@include green-button();
|
||||
@extend %t-action4;
|
||||
border-color: $green-d2;
|
||||
}
|
||||
|
||||
.action-secondary {
|
||||
color: $green;
|
||||
|
||||
&:hover {
|
||||
color: $green-s2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// types - step required
|
||||
&.step-required {
|
||||
|
||||
.nav-actions .action-primary {
|
||||
@include pink-button();
|
||||
@extend %t-action4;
|
||||
border-color: $pink-d2;
|
||||
}
|
||||
|
||||
.action-secondary {
|
||||
color: $pink;
|
||||
|
||||
&:hover {
|
||||
color: $pink-s1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// prompts
|
||||
.wrapper-prompt {
|
||||
@extend %ui-depth5;
|
||||
@include transition(all $tmg-f3 ease-in-out 0s);
|
||||
position: fixed;
|
||||
top: 0;
|
||||
background: $black-t1;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
text-align: center;
|
||||
|
||||
&:before {
|
||||
content: '';
|
||||
display: inline-block;
|
||||
height: 100%;
|
||||
vertical-align: middle;
|
||||
margin-right: -0.25em; /* Adjusts for spacing */
|
||||
}
|
||||
|
||||
.prompt {
|
||||
border-radius: ($baseline/5);
|
||||
box-shadow: 0 0 3px $shadow-d1;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
width: $baseline*17.5;
|
||||
border: 4px solid $black;
|
||||
@include text-align(left);
|
||||
|
||||
.copy {
|
||||
border-top: 4px solid $blue;
|
||||
padding: $baseline;
|
||||
}
|
||||
|
||||
.nav-actions {
|
||||
box-shadow: inset 0 1px 2px $shadow-d1;
|
||||
border-top: 1px solid $black-t1;
|
||||
padding: ($baseline*0.75) $baseline;
|
||||
background: $gray-d4;
|
||||
|
||||
.nav-item {
|
||||
display: inline-block;
|
||||
@include margin-right($baseline*0.75);
|
||||
|
||||
&:last-child {
|
||||
@include margin-right(0);
|
||||
}
|
||||
}
|
||||
|
||||
.action-primary {
|
||||
@extend %t-action4;
|
||||
@extend %t-strong;
|
||||
}
|
||||
|
||||
.action-secondary {
|
||||
@extend %t-action4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// types of prompts - error
|
||||
.prompt.error {
|
||||
|
||||
.feedback-symbol {
|
||||
color: $red-l1;
|
||||
}
|
||||
|
||||
.copy {
|
||||
border-top-color: $red-l1;
|
||||
}
|
||||
}
|
||||
|
||||
// types of prompts - confirmation
|
||||
.prompt.confirmation {
|
||||
|
||||
.feedback-symbol {
|
||||
color: $green;
|
||||
}
|
||||
|
||||
.copy {
|
||||
border-top-color: $green;
|
||||
}
|
||||
}
|
||||
|
||||
// types of prompts - error
|
||||
.prompt.warning {
|
||||
|
||||
.feedback-symbol {
|
||||
color: $orange;
|
||||
}
|
||||
|
||||
.copy {
|
||||
border-top-color: $orange;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ====================
|
||||
|
||||
// notifications
|
||||
.wrapper-notification {
|
||||
@extend %ui-depth5;
|
||||
@include clearfix();
|
||||
box-shadow: 0 -1px 3px $shadow, inset 0 3px 1px $blue;
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
padding: $baseline ($baseline*2);
|
||||
|
||||
&.wrapper-notification-warning {
|
||||
box-shadow: 0 -1px 3px $shadow, inset 0 3px 1px $orange;
|
||||
|
||||
.feedback-symbol {
|
||||
color: $orange;
|
||||
}
|
||||
}
|
||||
|
||||
&.wrapper-notification-error {
|
||||
box-shadow: 0 -1px 3px $shadow, inset 0 3px 1px $red-l1;
|
||||
|
||||
.feedback-symbol {
|
||||
color: $red-l1;
|
||||
}
|
||||
}
|
||||
|
||||
&.wrapper-notification-confirmation {
|
||||
box-shadow: 0 -1px 3px $shadow, inset 0 3px 1px $green;
|
||||
|
||||
.feedback-symbol {
|
||||
color: $green;
|
||||
}
|
||||
}
|
||||
|
||||
&.wrapper-notification-mini {
|
||||
box-shadow: 0 -1px 3px $shadow, inset 0 3px 1px $pink;
|
||||
}
|
||||
|
||||
// shorter/status notifications
|
||||
&.wrapper-notification-status {
|
||||
@include border-top-radius(3px);
|
||||
right: ($baseline);
|
||||
width: auto;
|
||||
border: 4px solid $black;
|
||||
border-bottom: none;
|
||||
padding: ($baseline/2) $baseline;
|
||||
|
||||
.notification {
|
||||
@include box-sizing(border-box);
|
||||
@include clearfix();
|
||||
width: 100%;
|
||||
max-width: none;
|
||||
min-width: none;
|
||||
|
||||
.feedback-symbol, .copy {
|
||||
float: none;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.feedback-symbol {
|
||||
width: $baseline;
|
||||
height: ($baseline*1.25);
|
||||
margin-right: ($baseline/4);
|
||||
line-height: 3rem;
|
||||
}
|
||||
|
||||
.copy {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// help notifications
|
||||
&.wrapper-notification-help {
|
||||
@include border-top-radius(3px);
|
||||
width: ($baseline*14);
|
||||
right: ($baseline);
|
||||
border: 4px solid $black;
|
||||
border-bottom: none;
|
||||
padding: $baseline;
|
||||
|
||||
.notification {
|
||||
@include box-sizing(border-box);
|
||||
@include clearfix();
|
||||
width: 100%;
|
||||
max-width: none;
|
||||
min-width: none;
|
||||
|
||||
.feedback-symbol {
|
||||
width: $baseline;
|
||||
margin-right: ($baseline*0.75);
|
||||
}
|
||||
|
||||
.action-notification-close {
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.copy {
|
||||
width: ($baseline*10);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.notification {
|
||||
@include box-sizing(border-box);
|
||||
@include clearfix();
|
||||
margin: 0 auto;
|
||||
width: flex-grid(12);
|
||||
max-width: $fg-max-width;
|
||||
min-width: $fg-min-width;
|
||||
|
||||
strong {
|
||||
@extend %t-strong;
|
||||
}
|
||||
|
||||
.feedback-symbol, .copy {
|
||||
float: left;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.feedback-symbol {
|
||||
@include transition (color $tmg-f1 ease-in-out 0s);
|
||||
@extend %t-icon3;
|
||||
width: flex-grid(1, 12);
|
||||
height: ($baseline*1.25);
|
||||
margin-top: ($baseline/4);
|
||||
margin-right: flex-gutter();
|
||||
text-align: right;
|
||||
color: $white;
|
||||
}
|
||||
|
||||
.copy {
|
||||
@extend %t-copy-sub1;
|
||||
width: flex-grid(10, 12);
|
||||
color: $gray-l2;
|
||||
|
||||
.title {
|
||||
@extend %t-title7;
|
||||
margin-bottom: 0;
|
||||
color: $white;
|
||||
}
|
||||
}
|
||||
|
||||
// with actions
|
||||
&.has-actions {
|
||||
|
||||
.feedback-symbol {
|
||||
width: flex-grid(1, 12);
|
||||
}
|
||||
|
||||
.copy {
|
||||
width: flex-grid(7, 12);
|
||||
@include margin-right(flex-gutter());
|
||||
}
|
||||
|
||||
.nav-actions {
|
||||
width: flex-grid(4, 12);
|
||||
@include float(left);
|
||||
margin-top: ($baseline/4);
|
||||
text-align: right;
|
||||
|
||||
.nav-item {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
@include margin-right($baseline/2);
|
||||
|
||||
&:last-child {
|
||||
@include margin-right(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.action-primary {
|
||||
@include blue-button();
|
||||
@extend %t-strong;
|
||||
border-color: $blue-d2;
|
||||
}
|
||||
|
||||
.action-secondary {
|
||||
|
||||
@extend %t-action4;
|
||||
}
|
||||
}
|
||||
|
||||
&.confirmation {
|
||||
|
||||
.copy {
|
||||
margin-top: ($baseline/5);
|
||||
}
|
||||
}
|
||||
|
||||
&.mini {
|
||||
width: auto;
|
||||
max-width: none;
|
||||
min-width: 0;
|
||||
|
||||
.feedback-symbol {
|
||||
@include animation(rotateCW $tmg-s3 linear infinite);
|
||||
width: 25px;
|
||||
margin: -4px 10px 0 0;
|
||||
@include transform-origin(52% 60%);
|
||||
}
|
||||
|
||||
.copy {
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.title {
|
||||
@extend %cont-truncated;
|
||||
}
|
||||
|
||||
.copy p {
|
||||
@extend %cont-text-sr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ====================
|
||||
|
||||
// alerts
|
||||
.wrapper-alert {
|
||||
@extend %ui-depth2;
|
||||
@include box-sizing(border-box);
|
||||
box-shadow: 0 1px 1px $white, inset 0 2px 2px $shadow-d1, inset 0 -4px 1px $blue;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
width: 100%;
|
||||
border-top: 1px solid $black;
|
||||
padding: $baseline ($baseline*2) ($baseline*1.5) ($baseline*2);
|
||||
background: $gray-d3;
|
||||
|
||||
// needed since page load is very slow
|
||||
display: none;
|
||||
|
||||
// needed since page load is very slow
|
||||
&.is-shown {
|
||||
display: block;
|
||||
}
|
||||
|
||||
&.wrapper-alert-warning {
|
||||
box-shadow: 0 1px 1px $white, inset 0 2px 2px $shadow-d1, inset 0 -4px 1px $orange;
|
||||
|
||||
.feedback-symbol {
|
||||
color: $orange;
|
||||
}
|
||||
}
|
||||
|
||||
&.wrapper-alert-error {
|
||||
box-shadow: 0 1px 1px $white, inset 0 2px 2px $shadow-d1, inset 0 -4px 1px $red-l1;
|
||||
|
||||
.feedback-symbol {
|
||||
color: $red-l1;
|
||||
}
|
||||
}
|
||||
|
||||
&.wrapper-alert-confirmation {
|
||||
box-shadow: 0 1px 1px $white, inset 0 2px 2px $shadow-d1, inset 0 -4px 1px $green;
|
||||
|
||||
.feedback-symbol {
|
||||
color: $green;
|
||||
}
|
||||
}
|
||||
|
||||
&.wrapper-alert-announcement {
|
||||
box-shadow: 0 1px 1px $white, inset 0 2px 2px $shadow-d1, inset 0 -4px 1px $blue;
|
||||
|
||||
.feedback-symbol {
|
||||
color: $blue;
|
||||
}
|
||||
}
|
||||
|
||||
&.wrapper-alert-step-required {
|
||||
box-shadow: 0 1px 1px $white, inset 0 2px 2px $shadow-d1, inset 0 -4px 1px $pink;
|
||||
|
||||
.feedback-symbol {
|
||||
color: $pink;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// adopted alerts
|
||||
.alert {
|
||||
@include box-sizing(border-box);
|
||||
@include clearfix();
|
||||
margin: 0 auto;
|
||||
width: flex-grid(12);
|
||||
max-width: $fg-max-width;
|
||||
min-width: $fg-min-width;
|
||||
color: $white;
|
||||
|
||||
strong {
|
||||
@extend %t-strong;
|
||||
}
|
||||
|
||||
.feedback-symbol, .copy {
|
||||
float: left;
|
||||
}
|
||||
|
||||
.feedback-symbol {
|
||||
@include transition (color $tmg-f1 ease-in-out 0s);
|
||||
@extend %t-icon3;
|
||||
width: flex-grid(1, 12);
|
||||
margin: ($baseline/4) flex-gutter() 0 0;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.copy {
|
||||
width: flex-grid(10, 12);
|
||||
margin-top: ($baseline/2);
|
||||
color: $gray-l2;
|
||||
|
||||
.title {
|
||||
@extend %t-title7;
|
||||
margin-bottom: 0;
|
||||
color: $white;
|
||||
}
|
||||
}
|
||||
|
||||
// with actions
|
||||
&.has-actions {
|
||||
|
||||
.feedback-symbol {
|
||||
width: flex-grid(1, 12);
|
||||
}
|
||||
|
||||
.copy {
|
||||
width: flex-grid(7, 12);
|
||||
@include margin-right(flex-gutter());
|
||||
}
|
||||
|
||||
.nav-actions {
|
||||
width: flex-grid(4, 12);
|
||||
@include float(left);
|
||||
margin-top: ($baseline/2);
|
||||
text-align: right;
|
||||
|
||||
.nav-item {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
@include margin-right($baseline/2);
|
||||
|
||||
&:last-child {
|
||||
@include margin-right(0);
|
||||
}
|
||||
|
||||
.action-primary {
|
||||
@extend %t-action4;
|
||||
@extend %t-strong;
|
||||
}
|
||||
|
||||
.action-secondary {
|
||||
@extend %t-action4;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// with cancel
|
||||
.action-alert-close {
|
||||
@include border-bottom-radius(($baseline/5));
|
||||
position: absolute;
|
||||
top: -($baseline/10);
|
||||
right: $baseline;
|
||||
padding: ($baseline/4) ($baseline/2) 0 ($baseline/2);
|
||||
background: $gray-d4;
|
||||
text-align: center;
|
||||
|
||||
.label {
|
||||
@extend %cont-text-sr;
|
||||
}
|
||||
|
||||
.icon {
|
||||
@extend %t-icon6;
|
||||
color: $white;
|
||||
width: auto;
|
||||
margin: 0;
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background: $gray-d1;
|
||||
}
|
||||
}
|
||||
|
||||
// with dismiss (to sunset action-alert-clos)
|
||||
.action-dismiss {
|
||||
|
||||
.button {
|
||||
// I tried moving the btn-secondary-white into lms/static/sass/elements/_controls.scss
|
||||
// but sass compiler fails to find ui-btn-secondary, ui-btn-secondary is defined in
|
||||
// lms/static/sass/_mixins.scss. I also tried reordering the _mixins.scss import in
|
||||
// lms/static/sass/_build-lms.scss but issue is still there, so i made it optional.
|
||||
// Making this optional wouldn't cause any issue for confirmation dialog at-least.
|
||||
@extend %btn-secondary-white !optional;
|
||||
padding:($baseline/4) ($baseline/2);
|
||||
}
|
||||
|
||||
.icon,.button-copy {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.icon {
|
||||
@extend %t-icon4;
|
||||
margin-right: ($baseline/4);
|
||||
}
|
||||
|
||||
.button-copy {
|
||||
@extend %t-copy-sub1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ====================
|
||||
|
||||
// js enabled
|
||||
.js {
|
||||
|
||||
// prompt set-up
|
||||
.wrapper-prompt {
|
||||
visibility: hidden;
|
||||
pointer-events: none;
|
||||
|
||||
.prompt {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// prompt showing
|
||||
&.prompt-is-shown {
|
||||
|
||||
.wrapper-prompt.is-shown {
|
||||
visibility: visible;
|
||||
pointer-events: auto;
|
||||
|
||||
.prompt {
|
||||
@include animation(bounceIn $tmg-f1 ease-in-out 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// prompt hiding
|
||||
&.prompt-is-hiding {
|
||||
|
||||
.wrapper-prompt {
|
||||
|
||||
.prompt {
|
||||
@include animation(bounceOut $tmg-f1 ease-in-out 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// alert showing/hiding done by jQuery
|
||||
.wrapper-alert { }
|
||||
|
||||
// notification showing/hiding
|
||||
.wrapper-notification {
|
||||
bottom: -($ui-notification-height);
|
||||
|
||||
// varying animations
|
||||
&.is-shown {
|
||||
@include animation(notificationSlideUp $tmg-s1 ease-in-out 1);
|
||||
@include animation-fill-mode(forwards);
|
||||
}
|
||||
|
||||
&.is-hiding {
|
||||
@include animation(notificationSlideDown $tmg-s1 ease-in-out 1);
|
||||
@include animation-fill-mode(forwards);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ====================
|
||||
|
||||
// block-level messages and validation
|
||||
.wrapper-message {
|
||||
|
||||
.message {
|
||||
@extend %t-copy-sub1;
|
||||
background-color: $gray-d2;
|
||||
padding: ($baseline/2) ($baseline*0.75);
|
||||
color: $white;
|
||||
|
||||
.icon {
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
&.information {
|
||||
@extend %t-copy-sub1;
|
||||
background-color: $gray-l5;
|
||||
color: $gray-d2;
|
||||
}
|
||||
|
||||
&.validation {
|
||||
background-color: $gray-d2;
|
||||
color: $white;
|
||||
|
||||
a {
|
||||
color: $blue-l2;
|
||||
}
|
||||
}
|
||||
|
||||
&.has-warnings {
|
||||
border-bottom: 3px solid $orange;
|
||||
|
||||
.fa-warning {
|
||||
margin-right: ($baseline/2);
|
||||
color: $orange;
|
||||
}
|
||||
}
|
||||
|
||||
&.has-errors {
|
||||
border-bottom: 3px solid $red-l2;
|
||||
|
||||
.fa-exclamation-circle {
|
||||
margin-right: ($baseline/2);
|
||||
color: $red-l2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.message-list {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.message-actions {
|
||||
padding: ($baseline/2) $baseline;
|
||||
background-color: $gray-d1;
|
||||
|
||||
.actions-list {
|
||||
@extend %actions-list !optional;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ====================
|
||||
|
||||
// temporary
|
||||
body.uxdesign.alerts {
|
||||
|
||||
.content-primary, .content-supplementary {
|
||||
@include box-sizing(border-box);
|
||||
float: left;
|
||||
}
|
||||
|
||||
.content-primary {
|
||||
@extend %ui-window;
|
||||
width: flex-grid(12, 12);
|
||||
@include margin-right(flex-gutter());
|
||||
padding: $baseline ($baseline*1.5);
|
||||
|
||||
> section {
|
||||
margin-bottom: ($baseline*2);
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
ul {
|
||||
|
||||
li {
|
||||
@include clearfix();
|
||||
width: flex-grid(12, 12);
|
||||
margin-bottom: ($baseline/4);
|
||||
border-bottom: 1px solid $gray-l4;
|
||||
padding-bottom: ($baseline/4);
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
border-bottom: none;
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
a {
|
||||
@include float(left);
|
||||
width: flex-grid(5, 12);
|
||||
@include margin-right(flex-gutter());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ====================
|
||||
|
||||
// artifact styles
|
||||
.main-wrapper {
|
||||
|
||||
.alert {
|
||||
@extend %t-copy-sub1;
|
||||
padding: 15px 20px;
|
||||
margin-bottom: ($baseline*1.5);
|
||||
border-radius: 3px;
|
||||
border: 1px solid #edbd3c;
|
||||
border-radius: 3px;
|
||||
background: #fbf6e1;
|
||||
// background: #edbd3c;
|
||||
@include clearfix();
|
||||
|
||||
.alert-message {
|
||||
@include float(left);
|
||||
margin: 4px 0 0 0;
|
||||
color: $gray-d3;
|
||||
}
|
||||
|
||||
strong {
|
||||
@extend %t-strong;
|
||||
}
|
||||
|
||||
.alert-action {
|
||||
@include float(left);
|
||||
|
||||
&.secondary {
|
||||
@include orange-button;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
body.error {
|
||||
background: $gray-d4;
|
||||
color: $gray-d3;
|
||||
|
||||
.primary-header {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.error-prompt {
|
||||
width: 700px;
|
||||
margin: 150px auto;
|
||||
padding: 60px 50px 90px;
|
||||
border-radius: 3px;
|
||||
background: $white;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
h1 {
|
||||
@extend %t-title1;
|
||||
@extend %t-light;
|
||||
float: none;
|
||||
margin: 0;
|
||||
color: $gray-d3;
|
||||
}
|
||||
|
||||
.description {
|
||||
@extend %t-copy-lead2;
|
||||
margin-bottom: 50px;
|
||||
}
|
||||
|
||||
.back-button {
|
||||
@include blue-button();
|
||||
@extend %t-action1;
|
||||
padding: 14px 40px 18px;
|
||||
}
|
||||
}
|
||||
|
||||
.advance-modules-remove-text {
|
||||
margin-top: ($baseline/2);
|
||||
}
|
||||
|
||||
@@ -125,6 +125,7 @@ from branding import api as branding_api
|
||||
</head>
|
||||
|
||||
<body class="${static.dir_rtl()} <%block name='bodyclass'/> lang_${LANGUAGE_CODE}">
|
||||
<div id="page-prompt"></div>
|
||||
% if not disable_window_wrap:
|
||||
<div class="window-wrap" dir="${static.dir_rtl()}">
|
||||
% endif
|
||||
|
||||
Reference in New Issue
Block a user