diff --git a/cms/djangoapps/contentstore/features/common.py b/cms/djangoapps/contentstore/features/common.py
index 4a500c9e1680..cd9c00c09ca5 100644
--- a/cms/djangoapps/contentstore/features/common.py
+++ b/cms/djangoapps/contentstore/features/common.py
@@ -43,9 +43,9 @@ def i_confirm_with_ok(_step):
@step(u'I press the "([^"]*)" delete icon$')
def i_press_the_category_delete_icon(_step, category):
if category == 'section':
- css = 'a.delete-button.delete-section-button span.delete-icon'
+ css = 'a.action.delete-section-button'
elif category == 'subsection':
- css = 'a.delete-button.delete-subsection-button span.delete-icon'
+ css = 'a.action.delete-subsection-button'
else:
assert False, 'Invalid category: %s' % category
world.css_click(css)
@@ -254,7 +254,7 @@ def create_course_with_unit():
world.wait_for_js_to_load()
css_selectors = [
- 'div.section-item a.expand-collapse-icon', 'a.new-unit-item'
+ 'div.section-item a.expand-collapse', 'a.new-unit-item'
]
for selector in css_selectors:
world.css_click(selector)
diff --git a/cms/djangoapps/contentstore/features/section.py b/cms/djangoapps/contentstore/features/section.py
index b6f55969bbb3..b1e9ee2e1228 100644
--- a/cms/djangoapps/contentstore/features/section.py
+++ b/cms/djangoapps/contentstore/features/section.py
@@ -29,7 +29,7 @@ def i_have_added_new_section(_step):
@step('I click the Edit link for the release date$')
def i_click_the_edit_link_for_the_release_date(_step):
- button_css = 'div.section-published-date a.edit-button'
+ button_css = 'div.section-published-date a.edit-release-date'
world.css_click(button_css)
@@ -88,7 +88,7 @@ def i_see_a_release_date_for_my_section(_step):
status_text = world.css_text(css)
# e.g. 11/06/2012 at 16:25
- msg = 'Will Release:'
+ msg = 'Release date:'
date_regex = r'(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) \d\d?, \d{4}'
if not re.search(date_regex, status_text):
print status_text, date_regex
@@ -117,7 +117,7 @@ def the_section_release_date_picker_not_visible(_step):
def the_section_release_date_is_updated(_step):
css = 'span.published-status'
status_text = world.css_text(css)
- assert_equal(status_text, 'Will Release: 12/25/2013 at 00:00 UTC')
+ assert_equal(status_text, 'Release date: 12/25/2013 at 00:00 UTC')
def save_section_name(name):
diff --git a/cms/static/coffee/spec/views/overview_spec.coffee b/cms/static/coffee/spec/views/overview_spec.coffee
index 2082e4747bb7..6aaa954c6c50 100644
--- a/cms/static/coffee/spec/views/overview_spec.coffee
+++ b/cms/static/coffee/spec/views/overview_spec.coffee
@@ -6,65 +6,89 @@ define ["js/views/overview", "js/views/feedback_notification", "sinon", "js/base
appendSetFixtures """
"""
-
+
appendSetFixtures """
-
-
-
Section Release Date
-
-
-
-
-
-
-
-
On the date set above, this section – – will be released to students. Any units marked private will only be visible to admins.
-
-
-
SaveCancel
-
-
+
+
"""
-
+
appendSetFixtures """
-
+
"""
-
+
appendSetFixtures """
-
- -
+
+
+ -
+
+
+
+
+ -
-
-
-
+
+
+
- -
+
-
-
+
- -
-
+ -
+
-
+ -
+
+
+
+
+
+
"""
-
+
spyOn(Overview, 'saveSetSectionScheduleDate').andCallThrough()
# Have to do this here, as it normally gets bound in document.ready()
- $('a.save-button').click(Overview.saveSetSectionScheduleDate)
+ $('a.action-save').click(Overview.saveSetSectionScheduleDate)
$('a.delete-section-button').click(deleteSection)
$(".edit-subsection-publish-settings .start-date").datepicker()
@@ -79,22 +103,29 @@ define ["js/views/overview", "js/views/feedback_notification", "sinon", "js/base
'.unit',
'.unit-drag-handle',
'ol.sortable-unit-list',
- 'li.branch, article.subsection-body'
+ 'li.courseware-subsection, article.subsection-body'
)
-
+
+ Overview.overviewDragger.makeDraggable(
+ '.courseware-subsection',
+ '.subsection-drag-handle',
+ '.sortable-subsection-list',
+ 'section'
+ )
+
afterEach ->
delete window.analytics
delete window.course_location_analytics
@notificationSpy.reset()
-
+
it "should save model when save is clicked", ->
- $('a.edit-button').click()
- $('a.save-button').click()
+ $('a.edit-release-date').click()
+ $('a.action-save').click()
expect(Overview.saveSetSectionScheduleDate).toHaveBeenCalled()
it "should show a confirmation on save", ->
- $('a.edit-button').click()
- $('a.save-button').click()
+ $('a.edit-release-date').click()
+ $('a.action-save').click()
expect(@notificationSpy).toHaveBeenCalled()
# Fails sporadically in Jenkins.
@@ -113,7 +144,7 @@ define ["js/views/overview", "js/views/feedback_notification", "sinon", "js/base
# $('a.delete-section-button').click()
# $('a.action-primary').click()
# expect(@notificationSpy).toHaveBeenCalled()
-
+
describe "findDestination", ->
it "correctly finds the drop target of a drag", ->
$ele = $('#unit-1')
@@ -123,26 +154,55 @@ define ["js/views/overview", "js/views/feedback_notification", "sinon", "js/base
destination = Overview.overviewDragger.findDestination($ele, 1)
expect(destination.ele).toBe($('#unit-2'))
expect(destination.attachMethod).toBe('before')
-
- it "can drag and drop across section boundaries, with special handling for first element", ->
+
+ it "can drag and drop across section boundaries, with special handling for single sibling", ->
$ele = $('#unit-1')
+ $unit4 = $('#unit-4')
$ele.offset(
- top: $('#unit-4').offset().top + 8
+ top: $unit4.offset().top + 8
left: $ele.offset().left
)
+ # Dragging down, we will insert after.
destination = Overview.overviewDragger.findDestination($ele, 1)
- expect(destination.ele).toBe($('#unit-4'))
- # Dragging down into first element, we have a fudge factor makes it easier to drag at beginning.
+ expect(destination.ele).toBe($unit4)
+ expect(destination.attachMethod).toBe('after')
+
+ # Dragging up, we will insert before.
+ destination = Overview.overviewDragger.findDestination($ele, -1)
+ expect(destination.ele).toBe($unit4)
expect(destination.attachMethod).toBe('before')
- # Now past the "fudge factor".
+
+ # If past the end the drop target, will attach after.
$ele.offset(
- top: $('#unit-4').offset().top + 12
+ top: $unit4.offset().top + $unit4.height() + 1
left: $ele.offset().left
)
- destination = Overview.overviewDragger.findDestination($ele, 1)
- expect(destination.ele).toBe($('#unit-4'))
+ destination = Overview.overviewDragger.findDestination($ele, 0)
+ expect(destination.ele).toBe($unit4)
expect(destination.attachMethod).toBe('after')
-
+
+
+ $unit0 = $('#unit-0')
+ # If before the start the drop target, will attach before.
+ $ele.offset(
+ top: $unit0.offset().top - 16
+ left: $ele.offset().left
+ )
+ destination = Overview.overviewDragger.findDestination($ele, 0)
+ expect(destination.ele).toBe($unit0)
+ expect(destination.attachMethod).toBe('before')
+
+ it """can drop before the first element, even if element being dragged is
+ slightly before the first element""", ->
+ $ele = $('#subsection-2')
+ $ele.offset(
+ top: $('#subsection-0').offset().top - 5
+ left: $ele.offset().left
+ )
+ destination = Overview.overviewDragger.findDestination($ele, -1)
+ expect(destination.ele).toBe($('#subsection-0'))
+ expect(destination.attachMethod).toBe('before')
+
it "can drag and drop across section boundaries, with special handling for last element", ->
$ele = $('#unit-4')
$ele.offset(
@@ -161,7 +221,21 @@ define ["js/views/overview", "js/views/feedback_notification", "sinon", "js/base
destination = Overview.overviewDragger.findDestination($ele, -1)
expect(destination.ele).toBe($('#unit-3'))
expect(destination.attachMethod).toBe('before')
-
+
+ it """can drop past the last element, even if element being dragged is
+ slightly before/taller then the last element""", ->
+ $ele = $('#subsection-2')
+ $ele.offset(
+ # Make the top 1 before the top of the last element in the list.
+ # This mimics the problem when the element being dropped is taller then then
+ # the last element in the list.
+ top: $('#subsection-4').offset().top - 1
+ left: $ele.offset().left
+ )
+ destination = Overview.overviewDragger.findDestination($ele, 1)
+ expect(destination.ele).toBe($('#subsection-4'))
+ expect(destination.attachMethod).toBe('after')
+
it "can drag into an empty list", ->
$ele = $('#unit-1')
$ele.offset(
@@ -171,7 +245,7 @@ define ["js/views/overview", "js/views/feedback_notification", "sinon", "js/base
destination = Overview.overviewDragger.findDestination($ele, 1)
expect(destination.ele).toBe($('#subsection-list-3'))
expect(destination.attachMethod).toBe('prepend')
-
+
it "reports a null destination on a failed drag", ->
$ele = $('#unit-1')
$ele.offset(
@@ -182,7 +256,7 @@ define ["js/views/overview", "js/views/feedback_notification", "sinon", "js/base
ele: null
attachMethod: ""
)
-
+
it "can drag into a collapsed list", ->
$('#subsection-2').addClass('collapsed')
$ele = $('#unit-2')
@@ -194,7 +268,7 @@ define ["js/views/overview", "js/views/feedback_notification", "sinon", "js/base
expect(destination.ele).toBe($('#subsection-list-2'))
expect(destination.parentList).toBe($('#subsection-2'))
expect(destination.attachMethod).toBe('prepend')
-
+
describe "onDragStart", ->
it "sets the dragState to its default values", ->
expect(Overview.overviewDragger.dragState).toEqual({})
@@ -211,7 +285,7 @@ define ["js/views/overview", "js/views/feedback_notification", "sinon", "js/base
lastY: 0,
dragDirection: 0
)
-
+
it "collapses expanded elements", ->
expect($('#subsection-1')).not.toHaveClass('collapsed')
Overview.overviewDragger.onDragStart(
@@ -221,7 +295,7 @@ define ["js/views/overview", "js/views/feedback_notification", "sinon", "js/base
)
expect($('#subsection-1')).toHaveClass('collapsed')
expect($('#subsection-1')).toHaveClass('expand-on-drop')
-
+
describe "onDragMove", ->
beforeEach ->
@scrollSpy = spyOn(window, 'scrollBy').andCallThrough()
@@ -239,7 +313,7 @@ define ["js/views/overview", "js/views/feedback_notification", "sinon", "js/base
)
expect($('#unit-2')).toHaveClass('drop-target drop-target-before')
expect($ele).toHaveClass('valid-drop')
-
+
it "does not add CSS class to the drop destination if out of bounds", ->
$ele = $('#unit-1')
dragY = $ele.offset().top + 10
@@ -252,19 +326,19 @@ define ["js/views/overview", "js/views/feedback_notification", "sinon", "js/base
)
expect($('#unit-2')).not.toHaveClass('drop-target drop-target-before')
expect($ele).not.toHaveClass('valid-drop')
-
+
it "scrolls up if necessary", ->
Overview.overviewDragger.onDragMove(
{element: $('#unit-1')}, '', {clientY: 2}
)
expect(@scrollSpy).toHaveBeenCalledWith(0, -10)
-
+
it "scrolls down if necessary", ->
Overview.overviewDragger.onDragMove(
{element: $('#unit-1')}, '', {clientY: (window.innerHeight - 5)}
)
expect(@scrollSpy).toHaveBeenCalledWith(0, 10)
-
+
describe "onDragEnd", ->
beforeEach ->
@reorderSpy = spyOn(Overview.overviewDragger, 'handleReorder')
@@ -310,8 +384,8 @@ define ["js/views/overview", "js/views/feedback_notification", "sinon", "js/base
$('#subsection-1').addClass('expand-on-drop')
Overview.overviewDragger.onDragEnd(
{element: $('#subsection-1')},
- null,
- null
+ null,
+ null
)
expect($('#subsection-1')).not.toHaveClass('collapsed')
expect($('#subsection-1')).not.toHaveClass('expand-on-drop')
@@ -323,7 +397,7 @@ define ["js/views/overview", "js/views/feedback_notification", "sinon", "js/base
Overview.overviewDragger.dragState.parentList = $('#subsection-2')
Overview.overviewDragger.onDragEnd(
{element: $('#unit-1')},
- null,
+ null,
{clientX: $('#unit-1').offset().left}
)
expect($('#subsection-2')).not.toHaveClass('collapsed')
diff --git a/cms/static/js/base.js b/cms/static/js/base.js
index 174ab10c89cc..b2b3d971236e 100644
--- a/cms/static/js/base.js
+++ b/cms/static/js/base.js
@@ -25,7 +25,7 @@ domReady(function() {
$('body').addClass('js');
- $('.unit .item-actions .delete-button').bind('click', deleteUnit);
+ $('.unit .item-actions .delete-unit-button').bind('click', deleteUnit);
$('.new-unit-item').bind('click', createNewUnit);
// lean/simple modal
@@ -243,17 +243,17 @@ function createNewUnit(e) {
function deleteUnit(e) {
e.preventDefault();
- _deleteItem($(this).parents('li.leaf'), 'Unit');
+ _deleteItem($(this).parents('li.courseware-unit'), 'Unit');
}
function deleteSubsection(e) {
e.preventDefault();
- _deleteItem($(this).parents('li.branch'), 'Subsection');
+ _deleteItem($(this).parents('li.courseware-subsection'), 'Subsection');
}
function deleteSection(e) {
e.preventDefault();
- _deleteItem($(this).parents('section.branch'), 'Section');
+ _deleteItem($(this).parents('section.courseware-section'), 'Section');
}
function _deleteItem($el, type) {
diff --git a/cms/static/js/views/overview.js b/cms/static/js/views/overview.js
index 9dfb339b0cfa..1a4daa826d5d 100644
--- a/cms/static/js/views/overview.js
+++ b/cms/static/js/views/overview.js
@@ -1,9 +1,9 @@
define(["domReady", "jquery", "jquery.ui", "underscore", "gettext", "js/views/feedback_notification", "draggabilly",
- "js/utils/modal", "js/utils/cancel_on_escape", "js/utils/get_date", "js/utils/module"],
- function (domReady, $, ui, _, gettext, NotificationView, Draggabilly, ModalUtils, CancelOnEscape,
+ "js/utils/cancel_on_escape", "js/utils/get_date", "js/utils/module"],
+ function (domReady, $, ui, _, gettext, NotificationView, Draggabilly, CancelOnEscape,
DateUtils, ModuleUtils) {
- var modalSelector = '.edit-subsection-publish-settings';
+ var modalSelector = '.edit-section-publish-settings';
var toggleSections = function(e) {
e.preventDefault();
@@ -21,18 +21,24 @@ define(["domReady", "jquery", "jquery.ui", "underscore", "gettext", "js/views/fe
if ($button.hasClass('is-activated')) {
$section.addClass('collapsed');
// first child in order to avoid the icons on the subsection lists which are not in the first child
- $section.find('header .expand-collapse-icon').removeClass('collapse').addClass('expand');
+ $section.find('header .expand-collapse').removeClass('collapse').addClass('expand');
} else {
$section.removeClass('collapsed');
// first child in order to avoid the icons on the subsection lists which are not in the first child
- $section.find('header .expand-collapse-icon').removeClass('expand').addClass('collapse');
+ $section.find('header .expand-collapse').removeClass('expand').addClass('collapse');
}
};
var toggleSubmodules = function(e) {
e.preventDefault();
$(this).toggleClass('expand').toggleClass('collapse');
- $(this).closest('.branch, .window').toggleClass('collapsed');
+ $(this).closest('.is-collapsible, .window').toggleClass('collapsed');
+ };
+
+
+ var closeModalNew = function () {
+ $('body').removeClass('dialog-is-shown');
+ $('.edit-section-publish-settings').removeClass('is-shown');
};
var editSectionPublishDate = function (e) {
@@ -45,15 +51,16 @@ define(["domReady", "jquery", "jquery.ui", "underscore", "gettext", "js/views/fe
$modal.find('.save-button').hide();
}
$modal.find('.section-name').html('"' + $(this).closest('.courseware-section').find('.section-name-span').text() + '"');
- ModalUtils.showModal();
+ $('body').addClass('dialog-is-shown');
+ $('.edit-section-publish-settings').addClass('is-shown');
};
var saveSetSectionScheduleDate = function (e) {
e.preventDefault();
var datetime = DateUtils(
- $('.edit-subsection-publish-settings .start-date'),
- $('.edit-subsection-publish-settings .start-time')
+ $('.edit-section-publish-settings .start-date'),
+ $('.edit-section-publish-settings .start-time')
);
var locator = $(modalSelector).attr('data-locator');
@@ -89,19 +96,19 @@ define(["domReady", "jquery", "jquery.ui", "underscore", "gettext", "js/views/fe
var $thisSection = $('.courseware-section[data-locator="' + locator + '"]');
var html = _.template(
'' +
- '' + gettext("Will Release:") + ' ' +
+ '' + gettext("Release date:") + ' ' +
gettext("{month}/{day}/{year} at {hour}:{minute} UTC") +
'' +
- '' +
- gettext("Edit") +
- '',
+ ' ' +
+ gettext("Edit section release date") +
+ '',
{year: datetime.getUTCFullYear(), month: pad2(datetime.getUTCMonth() + 1), day: pad2(datetime.getUTCDate()),
hour: pad2(datetime.getUTCHours()), minute: pad2(datetime.getUTCMinutes()),
locator: locator},
{interpolate: /\{(.+?)\}/g});
$thisSection.find('.section-published-date').html(html);
- ModalUtils.hideModal();
saving.hide();
+ closeModalNew();
});
};
@@ -159,7 +166,7 @@ define(["domReady", "jquery", "jquery.ui", "underscore", "gettext", "js/views/fe
var $saveButton = $newSubsection.find('.new-subsection-name-save');
var $cancelButton = $newSubsection.find('.new-subsection-name-cancel');
- var parent = $(this).parents("section.branch").data("locator");
+ var parent = $(this).parents("section.courseware-section").data("locator");
$saveButton.data('parent', parent);
$saveButton.data('category', $(this).data('category'));
@@ -197,7 +204,7 @@ define(["domReady", "jquery", "jquery.ui", "underscore", "gettext", "js/views/fe
var cancelNewSubsection = function (e) {
e.preventDefault();
- $(this).parents('li.branch').remove();
+ $(this).parents('li.courseware-subsection').remove();
};
var overviewDragger = {
@@ -212,6 +219,7 @@ define(["domReady", "jquery", "jquery.ui", "underscore", "gettext", "js/views/fe
*/
findDestination: function (ele, yChange) {
var eleY = ele.offset().top;
+ var eleYEnd = eleY + ele.height();
var containers = $(ele.data('droppable-class'));
for (var i = 0; i < containers.length; i++) {
@@ -226,7 +234,15 @@ define(["domReady", "jquery", "jquery.ui", "underscore", "gettext", "js/views/fe
// position of the container
var parentList = container.parents(ele.data('parent-location-selector')).first();
if (parentList.hasClass('collapsed')) {
- if (Math.abs(eleY - parentList.offset().top) < 10) {
+ var parentListTop = parentList.offset().top;
+ // To make it easier to drop subsections into collapsed sections (which have
+ // a lot of visual padding around them), allow a fudge factor around the
+ // parent element.
+ var collapseFudge = 10;
+ if (Math.abs(eleY - parentListTop) < collapseFudge ||
+ (eleY > parentListTop &&
+ eleYEnd - collapseFudge <= parentListTop + parentList.height())
+ ) {
return {
ele: container,
attachMethod: 'prepend',
@@ -260,25 +276,64 @@ define(["domReady", "jquery", "jquery.ui", "underscore", "gettext", "js/views/fe
// Facilitate dropping into the beginning or end of a list
// (coming from opposite direction) via a "fudge factor". Math.min is for Jasmine test.
var fudge = Math.min(Math.ceil(siblingHeight / 2), 20);
- // Dragging up into end of list.
- if (j == siblings.length - 1 && yChange < 0 && Math.abs(eleY - siblingYEnd) <= fudge) {
- return {
- ele: $sibling,
- attachMethod: 'after'
- };
- }
- // Dragging down into beginning of list.
- else if (j == 0 && yChange > 0 && Math.abs(eleY - siblingY) <= fudge) {
- return {
- ele: $sibling,
- attachMethod: 'before'
- };
+
+ // Dragging to top or bottom of a list with only one element is tricky
+ // because the element being dragged may be the same size as the sibling.
+ if (siblings.length == 1) {
+ // Element being dragged is within the drop target. Use the direction
+ // of the drag (yChange) to determine before or after.
+ if (eleY + fudge >= siblingY && eleYEnd - fudge <= siblingYEnd) {
+ return {
+ ele: $sibling,
+ attachMethod: yChange > 0 ? 'after' : 'before'
+ };
+ }
+ // Element being dragged is before the drop target.
+ else if (Math.abs(eleYEnd - siblingY) <= fudge) {
+ return {
+ ele: $sibling,
+ attachMethod: 'before'
+ };
+ }
+ // Element being dragged is after the drop target.
+ else if (Math.abs(eleY - siblingYEnd) <= fudge) {
+ return {
+ ele: $sibling,
+ attachMethod: 'after'
+ };
+ }
}
- else if (eleY >= siblingY && eleY <= siblingYEnd) {
- return {
- ele: $sibling,
- attachMethod: eleY - siblingY <= siblingHeight / 2 ? 'before' : 'after'
- };
+ else {
+ // Dragging up into end of list.
+ if (j == siblings.length - 1 && yChange < 0 && Math.abs(eleY - siblingYEnd) <= fudge) {
+ return {
+ ele: $sibling,
+ attachMethod: 'after'
+ };
+ }
+ // Dragging up or down into beginning of list.
+ else if (j == 0 && Math.abs(eleY - siblingY) <= fudge) {
+ return {
+ ele: $sibling,
+ attachMethod: 'before'
+ };
+ }
+ // Dragging down into end of list. Special handling required because
+ // the element being dragged may be taller then the element being dragged over
+ // (if eleY can never be >= siblingY, general case at the end does not work).
+ else if (j == siblings.length - 1 && yChange > 0 &&
+ Math.abs(eleYEnd - siblingYEnd) <= fudge) {
+ return {
+ ele: $sibling,
+ attachMethod: 'after'
+ };
+ }
+ else if (eleY >= siblingY && eleY <= siblingYEnd) {
+ return {
+ ele: $sibling,
+ attachMethod: eleY - siblingY <= siblingHeight / 2 ? 'before' : 'after'
+ };
+ }
}
}
}
@@ -310,7 +365,7 @@ define(["domReady", "jquery", "jquery.ui", "underscore", "gettext", "js/views/fe
};
if (!ele.hasClass('collapsed')) {
ele.addClass('collapsed');
- ele.find('.expand-collapse-icon').first().addClass('expand').removeClass('collapse');
+ ele.find('.expand-collapse').first().addClass('expand').removeClass('collapse');
// onDragStart gets called again after the collapse, so we can't just store a variable in the dragState.
ele.addClass(this.expandOnDropClass);
}
@@ -406,7 +461,7 @@ define(["domReady", "jquery", "jquery.ui", "underscore", "gettext", "js/views/fe
expandElement: function (ele) {
ele.removeClass('collapsed');
- ele.find('.expand-collapse-icon').first().removeClass('expand').addClass('collapse');
+ ele.find('.expand-collapse').first().removeClass('expand').addClass('collapse');
},
/*
@@ -500,13 +555,12 @@ define(["domReady", "jquery", "jquery.ui", "underscore", "gettext", "js/views/fe
}
});
$('.toggle-button-sections').bind('click', toggleSections);
- $('.expand-collapse-icon').bind('click', toggleSubmodules);
+ $('.expand-collapse').bind('click', toggleSubmodules);
var $body = $('body');
- $body.on('click', '.section-published-date .edit-button', editSectionPublishDate);
- $body.on('click', '.section-published-date .schedule-button', editSectionPublishDate);
- $body.on('click', '.edit-subsection-publish-settings .save-button', saveSetSectionScheduleDate);
- $body.on('click', '.edit-subsection-publish-settings .cancel-button', ModalUtils.hideModal);
+ $body.on('click', '.section-published-date .edit-release-date', editSectionPublishDate);
+ $body.on('click', '.edit-section-publish-settings .action-save', saveSetSectionScheduleDate);
+ $body.on('click', '.edit-section-publish-settings .action-cancel', closeModalNew);
$('.new-courseware-section-button').bind('click', addNewSection);
$('.new-subsection-item').bind('click', addNewSubsection);
@@ -530,7 +584,7 @@ define(["domReady", "jquery", "jquery.ui", "underscore", "gettext", "js/views/fe
'.unit',
'.unit-drag-handle',
'ol.sortable-unit-list',
- 'li.branch, article.subsection-body'
+ 'li.courseware-subsection, article.subsection-body'
);
});
diff --git a/cms/static/sass/_shame.scss b/cms/static/sass/_shame.scss
index 409e9098e563..461835686476 100644
--- a/cms/static/sass/_shame.scss
+++ b/cms/static/sass/_shame.scss
@@ -46,12 +46,6 @@
// ====================
-// needed for poorly scoped margin rules on all content elements
-.branch .sortable-unit-list {
- margin-bottom: 0;
-}
-
-
// yes we have no boldness today - need to fix the resets
body strong,
body b {
diff --git a/cms/static/sass/elements/_edit_dialog.scss b/cms/static/sass/elements/_edit_dialog.scss
new file mode 100644
index 000000000000..490a74b8bb67
--- /dev/null
+++ b/cms/static/sass/elements/_edit_dialog.scss
@@ -0,0 +1,129 @@
+// studio - elements - editing dialog
+// ========================
+
+body.course.feature-edit-dialog {
+
+ // dialog
+ .wrapper-dialog {
+ @extend %ui-depth5;
+ @include transition(all $tmg-f2 ease-in-out);
+ position: fixed;
+ top: 0;
+ background: $black-t2;
+ width: 100%;
+ height: 100%;
+ text-align: center;
+
+ &:before {
+ content: '';
+ display: inline-block;
+ height: 100%;
+ vertical-align: middle;
+ margin-right: -0.25em; /* Adjusts for spacing */
+ }
+
+ .dialog {
+ @include box-sizing(border-box);
+ display: inline-block;
+ vertical-align: middle;
+ width: $baseline*23;
+ box-shadow: 0px 0px 7px $shadow-d1;
+ border-radius: ($baseline/5);
+ background-color: $gray-l4;
+ padding: 7px;
+ text-align: left;
+
+ .title {
+ @extend %t-title5;
+ margin-bottom: ($baseline/2);
+ font-weight: 600;
+ color: $black;
+ }
+
+ .message {
+ @extend %t-copy-sub2;
+ color: $gray;
+ }
+
+ .error {
+ color: $white;
+ }
+
+ form {
+ padding: 0;
+
+ .form-content {
+ box-shadow: 0 0 3px $shadow-d1;
+ padding: ($baseline*1.5);
+ background-color: $white;
+ }
+
+ .field {
+ margin-bottom: ($baseline/2);
+ }
+
+ label {
+ @include font-size(14);
+ display: block;
+ font-weight: bold;
+ }
+
+ input[type="text"] {
+ @extend %t-copy-sub2;
+ }
+
+ .actions {
+ padding: ($baseline*0.75) $baseline ($baseline/2) $baseline;
+
+ .action-item {
+ @extend %t-action4;
+ display: inline-block;
+ margin-right: ($baseline*0.75);
+
+ &:last-child {
+ margin-right: 0;
+ }
+ }
+
+ .action-primary {
+ @include blue-button();
+ @include font-size(12); // needed due to bad button mixins for now
+ border-color: $blue-d1;
+ color: $white;
+ }
+
+ a {
+ color: $blue;
+
+ &:hover {
+ color: $blue-s2;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // dialog set-up
+ .wrapper-dialog {
+ visibility: hidden;
+ pointer-events: none;
+
+ .dialog {
+ opacity: 0;
+ }
+ }
+
+ // dialog showing/hiding
+ &.dialog-is-shown {
+
+ .wrapper-dialog.is-shown {
+ visibility: visible;
+ pointer-events: auto;
+
+ .dialog {
+ opacity: 1.0;
+ }
+ }
+ }
+}
diff --git a/cms/static/sass/style-app.scss b/cms/static/sass/style-app.scss
index 09409f779c14..f6b20b06db02 100644
--- a/cms/static/sass/style-app.scss
+++ b/cms/static/sass/style-app.scss
@@ -38,3 +38,4 @@
@import 'elements/modal'; // interstitial UI, dialogs, modal windows
@import 'elements/vendor'; // overrides to vendor-provided styling
@import 'elements/uploads';
+@import 'elements/edit_dialog';
diff --git a/cms/static/sass/views/_outline.scss b/cms/static/sass/views/_outline.scss
index 7a787bb5f086..50bc5bfec7d3 100644
--- a/cms/static/sass/views/_outline.scss
+++ b/cms/static/sass/views/_outline.scss
@@ -3,212 +3,178 @@
.view-outline {
- input.courseware-unit-search-input {
- float: left;
- width: 260px;
- background-color: #fff;
+ // page structure
+ .content-primary,
+ .content-supplementary {
+ @include box-sizing(border-box);
+ float: left;
}
- .branch {
+ .content-primary {
+ width: flex-grid(9, 12);
+ margin-right: flex-gutter();
- .section-item {
- @include clearfix();
+ .no-outline-content {
+ @extend %ui-well;
+ padding: ($baseline*2);
+ background-color: $gray-l4;
+ text-align: center;
+ color: $gray;
- .details {
- display: block;
- float: left;
- margin-bottom: 0;
- width: 650px;
+ .new-button {
+ @include font-size(14);
+ margin-left: $baseline;
+
+ [class^="icon-"] {
+ margin-right: ($baseline/2);
}
+ }
+ }
+ }
- .gradable-status {
- float: right;
- position: relative;
- top: -4px;
- right: 50px;
- width: 100px;
+ .content-supplementary {
+ width: flex-grid(3, 12);
+ }
- .status-label {
- @include font-size(12);
- position: absolute;
- top: 2px;
- right: -5px;
- display: none;
- width: 110px;
- padding: 5px 40px 5px 10px;
- border-radius: 3px;
- color: $lightGrey;
- text-align: right;
- font-weight: bold;
- line-height: 16px;
- }
- .menu-toggle {
- z-index: 10;
- position: absolute;
- top: 0;
- right: 5px;
- padding: 5px;
- color: $mediumGrey;
-
- &:hover, &.is-active {
- color: $blue;
- }
- }
+ // page header bits
+ .toggle-button-sections {
+ @extend %t-copy-sub2;
+ position: relative;
+ display: none;
+ float: right;
+ margin-top: ($baseline/4);
+ color: $gray-l1;
- [class^="icon-"] {
- vertical-align: middle;
- margin-top: -5px;
- display: inline-block;
- }
-
- .menu {
- @include font-size(12);
- @include transition(opacity $tmg-f2 linear 0s);
- border-radius: 4px;
- box-shadow: 0 1px 2px rgba(0, 0, 0, .2);
- z-index: 1;
- display: none;
- opacity: 0.0;
- position: absolute;
- top: -1px;
- right: 0;
- margin: 0;
- padding: 8px 12px;
- background: $white;
- border: 1px solid $mediumGrey;
-
-
- li {
- width: 115px;
- margin-bottom: 3px;
- padding-bottom: 3px;
- border-bottom: 1px solid $lightGrey;
-
- &:last-child {
- margin-bottom: 0;
- padding-bottom: 0;
- border: none;
-
- a {
- color: $darkGrey;
- }
- }
- }
+ &.is-shown {
+ display: block;
+ }
- a {
- color: $blue;
+ .label {
+ display: inline-block;
+ }
+ }
- &.is-selected {
- font-weight: bold;
- }
- }
- }
- // dropdown state
- &.is-active {
+ // new section, subsection, unit
+ .new-section-name,
+ .new-subsection-name-input {
+ @include font-size(16);
+ display: inline-block;
+ width: 515px;
+ padding: ($baseline/4);
+ vertical-align: top;
+ }
- .menu {
- z-index: 1000;
- display: block;
- opacity: 1.0;
- }
+ .new-subsection-name-input {
+ @include font-size(14);
+ }
+ .new-section-name-save,
+ .new-subsection-name-save {
+ @include blue-button;
+ margin: 0 5px;
+ padding: 4px 20px 7px;
+ color: $white;
+ }
- .menu-toggle {
- z-index: 10000;
- }
- }
+ .new-section-name-cancel,
+ .new-subsection-name-cancel {
+ @include white-button;
+ padding: 4px 20px 7px;
+ color: $gray-l1;
+ }
- // set state
- &.is-set {
+ .new-subsection-item,
+ .new-unit-item {
+ @extend %ui-btn-flat-outline;
+ width: 100%;
+ margin: 0 0 ($baseline/2) 0;
+ border: 1px solid $gray-l3;
+ padding: ($baseline/2) 0;
+ color: $gray-l2;
- .menu-toggle {
- color: $blue;
- }
- .status-label {
- display: block;
- color: $blue;
- }
- }
- }
- }
+ &:hover {
+ box-shadow: none;
+ background-image: none;
}
+ }
+ .courseware-unit-new {
+ margin-right: ($baseline*1.5);
+ }
- .courseware-section {
- @extend %ui-window;
- @include transition(background $tmg-avg ease-in-out 0);
- position: relative;
- margin-top: ($baseline);
- padding-bottom: ($baseline/2);
- &.collapsed {
- padding-bottom: 0;
+ // general action list styles (section and subsection)
+ .expand-collapse {
+ @include transition(all $tmg-f2 linear 0s);
+ display: inline-block;
+ vertical-align: top;
+ margin: 0 ($baseline/4);
+ color: $gray-l2;
+
+ &:hover {
+ color: $blue;
}
- label {
- float: left;
- line-height: 29px;
+ .ui-toggle-expansion {
+ @include transition(all $tmg-f2 ease-in-out 0s);
+ @include font-size(18);
+ display: inline-block;
+ vertical-align: middle;
+ margin-right: ($baseline/4);
+ color: $gray-l3;
}
- .datepair {
- float: left;
- margin-left: 10px;
+ &.expand .ui-toggle-expansion {
+ @include transform(rotate(-90deg));
+ @include transform-origin(50% 50%);
}
- .section-published-date {
- position: absolute;
- top: 19px;
- right: 80px;
- padding: 4px 10px;
- border-radius: 3px;
- background: $lightGrey;
- text-align: right;
+ }
- .published-status {
- @include font-size(12);
- margin-right: 15px;
+ .actions-list {
+ display: inline-block;
+ margin-bottom: 0;
+ }
- strong {
- font-weight: bold;
- }
- }
+ .actions-item {
+ @include font-size(13);
+ display: inline-block;
+ padding: 0 4px;
+ vertical-align: middle;
- .schedule-button {
- @include blue-button;
- }
+ .action {
+ min-width: ($baseline*.75);
+ color: $gray-l2;
- .edit-button {
- @include blue-button;
- }
+ &:hover,
+ &.is-set {
+ color: $blue;
+ visibility: visible;
+ }
- .schedule-button,
- .edit-button {
- @include font-size(11);
- padding: 3px 15px 5px;
- }
- }
+ //reset old drag handle style
+ &.drag-handle {
+ float: none;
+ margin: 0;
+ background: transparent url(../img/drag-handles.png) right 5px no-repeat;
+ text-align: center;
+ }
- .datepair .date,
- .datepair .time {
- @include font-size(13);
- box-shadow: none;
- padding-left: 0;
- padding-right: 0;
- border: none;
- background: none;
- font-weight: bold;
- color: $blue;
- cursor: pointer;
}
+ }
- .datepair .date {
- width: 80px;
- }
- .datepair .time {
- width: 65px;
+ // section styles
+ .courseware-section {
+ @extend %ui-window;
+ @include transition(background $tmg-avg ease-in-out 0);
+ position: relative;
+ padding: ($baseline*1.5) $baseline $baseline $baseline;
+
+ &.collapsed {
+ padding-bottom: 0;
}
&.collapsed .subsection-list,
@@ -217,467 +183,387 @@
display: none !important;
}
- header {
- min-height: 75px;
- @include clearfix();
+ &.new-section {
+ padding: ($baseline*1.5) $baseline 0 $baseline;
- .item-details, .section-published-date {
+ header {
+ @include clearfix();
+ height: auto;
+ border-bottom: 0;
+ .expand-collapse {
+ display: none;
}
.item-details {
- display: inline-block;
- padding: 20px 0 10px 0;
- @include clearfix();
-
- .section-name {
- @include font-size(19);
- float: left;
- margin-right: 10px;
- width: 350px;
- font-weight: bold;
- color: $blue;
- }
+ width: auto;
- .section-name-span {
- @include transition(color $tmg-f2 linear 0s);
- cursor: pointer;
+ .section-name {
+ float: none;
+ width: 100%;
+ }
+ }
+ }
+ }
- &:hover {
- color: $orange;
- }
- }
+ .section {
+ @include clearfix();
+ min-height: 65px; // needed to align with edit input
+ margin-bottom: 0;
+ border: 0;
+ padding: 0;
- .section-name-edit {
- position: relative;
- width: 400px;
- background: $white;
+ // section name area
+ .item-details {
+ @include clearfix();
+ width: 400px;
+ float: none;
+ display: inline-block;
+ padding: 0 0 ($baseline/2) 0;
- input {
- @include font-size(16);
- }
+ .section-name {
+ @include font-size(19);
+ margin-right: ($baseline/2);
+ }
- .save-button {
- @include blue-button;
- padding: 7px 20px 7px;
- margin-right: 5px;
- }
+ .section-name-span {
+ @include transition(color $tmg-f2 linear 0s);
+ cursor: pointer;
- .cancel-button {
- @include white-button;
- padding: 7px 20px 7px;
+ &:hover {
+ color: $blue;
}
}
- .section-published-date {
- float: right;
- border-radius: 3px;
- background: $lightGrey;
-
- .published-status {
- @include font-size(12);
- margin-right: 15px;
-
- strong {
- font-weight: bold;
- }
- }
+ .section-name-edit {
+ position: relative;
+ width: ($baseline*20);
+ background: $white;
- .schedule-button {
- @include blue-button;
+ input {
+ @include font-size(16);
}
- .edit-button {
+ .save-button {
@include blue-button;
+ padding: 7px $baseline 7px;
+ margin-right: ($baseline/4);
}
- .schedule-button,
- .edit-button {
- @include font-size(11);
- padding: 0 15px 2px 15px;
- }
+ .cancel-button {
+ @include white-button;
+ padding: 7px $baseline 7px;
}
+ }
+ }
- .gradable-status {
- position: absolute;
- top: 20px;
- right: 70px;
- width: 145px;
-
- .status-label {
- @include font-size(12);
- border-radius: 3px;
- position: absolute;
- top: 0;
- right: 2px;
- display: none;
- width: 100px;
- padding: 10px 35px 10px 10px;
- background: $lightGrey;
- color: $lightGrey;
- text-align: right;
- font-weight: bold;
- line-height: 16px;
- }
-
- .menu-toggle {
- z-index: 10;
- position: absolute;
- top: 2px;
- right: 5px;
- padding: 5px;
- color: $lightGrey;
-
- &:hover, &.is-active {
- color: $blue;
- }
-
- }
-
- .menu {
- @include font-size(12);
- @include transition(opacity $tmg-f2 linear 0s, display $tmg-f2 linear 0s);
- border-radius: 4px;
- box-shadow: 0 1px 2px rgba(0, 0, 0, .2);
- z-index: 1;
- display: none;
- opacity: 0.0;
- position: absolute;
- top: -1px;
- left: 2px;
- margin: 0;
- padding: 8px 12px;
- background: $white;
- border: 1px solid $mediumGrey;
-
-
-
- li {
- width: 115px;
- margin-bottom: 3px;
- padding-bottom: 3px;
- border-bottom: 1px solid $lightGrey;
-
- &:last-child {
- margin-bottom: 0;
- padding-bottom: 0;
- border: none;
-
- a {
- color: $darkGrey;
- }
- }
- }
-
- a {
-
- &.is-selected {
- font-weight: bold;
- }
- }
- }
- // dropdown state
- &.is-active {
+ // section specific action styles
+ .item-actions {
+ position: relative;
+ display: inline-block;
+ float: right;
+ margin-bottom: ($baseline/2);
+ top: 0;
+ }
- .menu {
- z-index: 1000;
- display: block;
- opacity: 1.0;
- }
+ .actions-item {
+ padding: 0 0 0 8px;
+ &:last-child {
+ padding-right: 4px;
+ }
- .menu-toggle {
- z-index: 10000;
- }
+ &.pubdate {
+ padding-right: 0;
}
- // set state
- &.is-set {
+ .action {
- .menu-toggle {
- color: $blue;
+ &.pubdate {
+ visibility: hidden;
}
- .status-label {
- display: block;
+ &:hover,
+ &.is-set {
color: $blue;
+ visibility: visible;
}
}
- float: left;
- padding: 21px 0 0;
- }
- }
+ .section-published-date {
+ padding: ($baseline/5) ($baseline/2);
+ border-radius: 3px;
+ background: $gray-l5;
+ text-align: right;
- .item-actions {
- margin-top: 21px;
- margin-right: 12px;
+ .published-status {
+ @include font-size(12);
+ margin-right: 15px;
- .edit-button,
- .delete-button {
- margin-top: -3px;
+ strong {
+ font-weight: bold;
}
- }
+ }
- .expand-collapse-icon {
- @include transition(none);
- float: left;
- margin: 25px 6px 16px 16px;
+ &.released .section-published-date {
+ background-color: transparent;
+ color: $gray-l1;
- &.expand {
- background-position: 0 0;
- }
-
- &.collapsed {
+ a {
+ color: $gray-l2;
+ &:hover {
+ color: $blue;
+ }
}
+ }
}
-
- .drag-handle {
- margin-left: 11px;
- }
+ }
}
+ }
- h3 {
- @include font-size(19);
- font-weight: 700;
- color: $blue;
- }
- .section-name-span {
- @include transition(color $tmg-f2 linear 0s);
- cursor: pointer;
+ // subsection styles
+ .courseware-subsection {
+ @include clearfix();
+ padding: 3px 0;
- &:hover {
- color: $orange;
- }
+ &.visible {
+ border-left: 5px solid $green;
}
- .section-name-form {
- margin-bottom: 15px;
+ &.mixed {
+ border-left: 5px solid $yellow-s1;
}
- .section-name-edit {
- input {
- @include font-size(16);
- }
+ .status {
+ @extend %cont-text-sr;
+ }
- .save-button {
- @include blue-button;
- padding: 7px 20px 7px;
- margin-right: 5px;
- }
+ .section-item {
+ @include transition(background $tmg-avg ease-in-out 0);
+ @include font-size(13);
+ position: relative;
+ display: block;
+ background-color: $gray-l5;
+ padding: 6px 8px 8px 16px;
- .cancel-button {
- @include white-button;
- padding: 7px 20px 7px;
+ &:hover {
+ background: $blue-l5;
+
+ .item-actions {
+ display: block;
}
+ }
+
+ &.editing {
+ background: $orange-l4;
+ }
}
- h4 {
- @include font-size(12);
- color: #878e9d;
+ .details {
+ display: block;
+ margin-bottom: 0;
+ width: 600px;
- strong {
- font-weight: bold;
- }
+ a {
+ color: $baseFontColor;
+ }
}
+ }
+
+ // gradable drop down
+ .gradable-status {
+ display: inline-block;
+ position: relative;
- .list-header {
- @include linear-gradient(top, transparent, rgba(0, 0, 0, .1));
- background-color: #ced2db;
- border-radius: 3px 3px 0 0;
+ .status-label {
+ @include font-size(12);
+ width: 110px;
+ padding: 5px 40px 5px 10px;
+ border-radius: 3px;
+ color: transparent;
+ text-align: right;
+ font-weight: bold;
+ line-height: 16px;
}
- .subsection-list {
- margin: 0 12px;
+ .menu-toggle {
+ @extend %ui-depth1;
+ position: absolute;
+ top: 0;
+ right: 5px;
+ padding: 2px 5px;
+ color: $gray-l2;
- > ol {
- @include tree-view;
- border-top-width: 0;
- }
+ &:hover,
+ &.is-active {
+ color: $blue;
+ }
+
+ &:focus {
+ outline: 0;
+ }
}
- &.new-section {
- header {
- @include clearfix();
- height: auto;
- }
+ // gradable dropdown menu default
+ .menu {
+ @include font-size(12);
+ @include transition(opacity $tmg-f2 linear 0s);
+ display: none;
+ opacity: 0.0;
+ z-index: 1;
+ position: absolute;
+ top: -4px;
+ right: 0;
+ margin: 0;
+ box-shadow: 0 1px 2px rgba(0, 0, 0, .2);
+ border: 1px solid $gray-l2;
+ border-radius: 4px;
+ padding: 8px 12px;
+ background: $white;
+
+ li {
+ width: 115px;
+ margin-bottom: 3px;
+ border-bottom: 1px solid $gray-l4;
+ padding-bottom: 3px;
+
+ &:last-child {
+ margin-bottom: 0;
+ border: none;
+ padding-bottom: 0;
- .expand-collapse-icon {
- visibility: hidden;
+ .gradable-status-notgraded {
+ color: $gray;
+ }
}
+ }
- .item-details {
- padding: 25px 0 0 0;
+ a {
+ color: $blue;
- .section-name {
- float: none;
- width: 100%;
- }
+ &.is-selected {
+ font-weight: bold;
}
+ }
}
- }
- .toggle-button-sections {
- @include font-size(12);
- display: none;
- position: relative;
- float: right;
- margin-top: ($baseline/4);
- color: $darkGrey;
-
- &.is-shown {
- display: block;
- }
+ // gradable dropdown state
+ &.is-active {
- [class^="icon-"] {
- @include font-size(11);
- border-radius: 20px;
- position: relative;
- top: -1px;
- display: inline-block;
- margin-right: 2px;
- line-height: 5px;
+ .menu {
+ @extend %ui-depth3;
+ display: block;
+ opacity: 1.0;
}
- .label {
- display: inline-block;
+ .menu-toggle {
+ @extend %ui-depth4;
}
- }
+ }
- .new-section-name,
- .new-subsection-name-input {
- width: 515px;
- }
+ // set state
+ &.is-set {
- .new-section-name-save,
- .new-subsection-name-save {
- @include blue-button;
- padding: 4px 20px 7px;
- margin: 0 5px;
- color: #fff !important;
- }
+ .menu-toggle {
+ color: $blue;
+ }
- .new-section-name-cancel,
- .new-subsection-name-cancel {
- @include white-button;
- padding: 4px 20px 7px;
- color: #8891a1 !important;
+ .status-label {
+ display: block;
+ color: $blue;
+ }
+ }
}
- .dummy-calendar {
- display: none;
- position: absolute;
- top: 55px;
- left: 110px;
- z-index: 9999;
- border: 1px solid #3C3C3C;
- box-shadow: 0 1px 15px rgba(0, 0, 0, .2);
+ .courseware-subsection .sortable-unit-list {
+ margin: ($baseline/4) 0 0 0;
}
- .preview {
- background: url(../img/preview.jpg) center top no-repeat;
- }
+ // unit styles
+ .courseware-unit {
+ margin: -1px 0 0 ($baseline*1.75);
- .edit-subsection-publish-settings {
- display: none;
- position: fixed;
- top: 100px;
- left: 50%;
- z-index: 99999;
- width: 600px;
- margin-left: -300px;
- background: #fff;
- text-align: center;
+ &.add-new-unit {
+ margin: 5px ($baseline*1.75) 0 ($baseline*1.75);
+ }
- .settings {
- padding: 40px;
- }
+ .section-item {
+ border: 0;
+ background-color: $white;
+ }
- h3 {
- @include font-size(34);
- font-weight: 300;
- }
+ .public-item {
+ color: $black;
+ }
- .picker {
- @include clearfix();
- margin: 30px 0 65px;
+ .private-item {
+ color: $gray-l1;
+ }
- .field {
- float: left;
- margin-right: ($baseline/2);
+ .draft-item {
+ color: $yellow-d1;
+ }
- &:first-child {
- margin-left: ($baseline*5);
- }
+ .draft-item:after,
+ .public-item:after,
+ .private-item:after {
+ @include font-size(9);
+ margin-left: 3px;
+ font-weight: 600;
+ text-transform: uppercase;
+ }
- &:last-child {
- margin-right: 0;
- }
+ .draft-item:after {
+ content: "- draft";
+ }
- label, input {
- display: block;
- text-align: left;
- }
+ .private-item:after {
+ content: "- private";
+ }
+ }
- label {
- @extend %t-copy-sub1;
- margin-bottom: ($baseline/4);
- }
- }
- }
- .description {
- @include font-size(14);
- float: left;
- margin-top: 30px;
- line-height: 20px;
- width: 100%;
- }
+ // modal to edit section publish settings
+ .edit-section-publish-settings {
- strong {
- font-weight: 700;
- }
+ .picker {
+ @include clearfix();
- .start-date,
- .start-time {
- @include font-size(19);
- }
- .save-button {
- @include blue-button;
- margin-right: 10px;
- }
+ .field {
+ float: left;
+ margin-right: ($baseline/2);
- .cancel-button {
- @include white-button;
- }
+ label, input {
+ display: block;
+ text-align: left;
+ }
- .save-button,
- .cancel-button {
- @include font-size(16);
+ label {
+ @extend %t-copy-sub1;
+ margin-bottom: ($baseline/4);
+ }
}
+ }
}
- .collapse-all-button {
- @include font-size(13);
- float: right;
- margin-top: 10px;
- color: $darkGrey;
- }
+
// UI: DnD - specific elems/cases - section
.courseware-section {
.draggable-drop-indicator-before {
top: -($baseline/2);
+ left: 0;
}
.draggable-drop-indicator-after {
bottom: -13px;
+ left: 0;
}
// CASE: DnD - empty subsection with unit dropping
diff --git a/cms/static/sass/views/_subsection.scss b/cms/static/sass/views/_subsection.scss
index d6da939115d9..c64a9f79c177 100644
--- a/cms/static/sass/views/_subsection.scss
+++ b/cms/static/sass/views/_subsection.scss
@@ -33,6 +33,7 @@
}
label {
+ @extend %t-title8;
margin-bottom: ($baseline/4);
}
}
@@ -201,12 +202,6 @@
input {
font-size: 14px;
}
-
- .sortable-unit-list {
- ol {
- @include tree-view;
- }
- }
}
.subsection-name-input {
@@ -237,8 +232,8 @@
}
.notice {
+ @extend %t-copy-sub2;
margin-top: 6px;
- font-size: 11px;
color: #999;
}
}
@@ -295,9 +290,105 @@
}
}
+ .sortable-unit-list {
+
+ .courseware-unit {
+ @include font-size(13);
+ @include clearfix();
+ margin: -1px 0 0 0;
+
+ .section-item {
+ @include transition(background $tmg-avg ease-in-out 0);
+ @include font-size(13);
+ position: relative;
+ display: block;
+ padding: 6px 8px 8px 16px;
+
+ &:hover {
+ background: $blue-l5;
+ }
+ }
+
+ .public-item {
+ color: $black;
+ }
+
+ .private-item {
+ color: $gray-l1;
+ }
+
+ .draft-item {
+ color: $yellow-d1;
+ }
+
+ .draft-item:after,
+ .public-item:after,
+ .private-item:after {
+ @include font-size(9);
+ margin-left: 3px;
+ font-weight: 600;
+ text-transform: uppercase;
+ }
+
+ .draft-item:after {
+ content: "- draft";
+ }
+
+ .private-item:after {
+ content: "- private";
+ }
+ }
+
+ .actions-list {
+ display: inline-block;
+ margin-bottom: 0;
+ }
+
+ .actions-item {
+ @include font-size(13);
+ display: inline-block;
+ padding: 0 4px;
+ vertical-align: middle;
+
+ .action {
+ min-width: ($baseline*.75);
+ color: $gray-l2;
+
+ &:hover,
+ &.is-set {
+ color: $blue;
+ visibility: visible;
+ }
+
+ //reset old drag handle style
+ &.drag-handle {
+ float: none;
+ margin: 0;
+ background: transparent url(../img/drag-handles.png) right 5px no-repeat;
+ text-align: center;
+ }
+ }
+ }
+
+ .new-unit-item {
+ @extend %ui-btn-flat-outline;
+ width: 100%;
+ margin: 0 0 ($baseline/2) 0;
+ border: 1px solid $gray-l3;
+ padding: ($baseline/2) 0;
+ color: $gray-l2;
+
+ &:hover {
+ box-shadow: none;
+ background-image: none;
+ }
+ }
+ }
+
.gradable {
label {
+ @extend %t-title8;
display: inline-block;
vertical-align: top;
}
diff --git a/cms/static/sass/views/_unit.scss b/cms/static/sass/views/_unit.scss
index 50685123a298..663fa3161ee0 100644
--- a/cms/static/sass/views/_unit.scss
+++ b/cms/static/sass/views/_unit.scss
@@ -885,6 +885,14 @@ body.unit {
// ====================
// Unit Page Sidebar
+
+.sidebar {
+
+ label {
+ @extend %t-title8;
+ }
+}
+
.unit-settings {
.window-contents {
@@ -910,12 +918,14 @@ body.unit {
}
}
+
+
input[type="radio"] {
margin-right: 7px;
}
.status {
- font-size: 12px;
+ @extend %t-copy-sub2;
strong {
font-weight: 700;
@@ -1025,37 +1035,95 @@ body.unit {
font-size: 8px;
}
- .window-contents > ol {
- @include tree-view;
+ .unit-tree-location {
+
+ .section-name {
+ @extend %t-title8;
+ }
+
+
+ .subsection,
+ .courseware-unit {
+ margin: ($baseline/4) 0 0 ($baseline);
+ }
+
+ .courseware-unit .section-item {
+ background-color: transparent;
+ }
.section-item {
+ @include transition(background $tmg-avg ease-in-out 0);
@include box-sizing(border-box);
+ @extend %t-copy-sub2;
display: inline-block;
width: 100%;
- font-size: 11px;
- padding: 2px 8px 4px;
+ background: $gray-l5;
+ padding: 6px 8px 8px 16px;
+ vertical-align: top;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
- }
+ color: $gray;
+
+ &:hover {
+ background: $blue-l5;
+ color: $blue;
+ }
- ol {
- .section-item {
- padding-left: $baseline;
+ &.editing {
+ background-color: $orange-l3;
}
- .new-unit-item {
- margin-left: $baseline;
+ .public-item {
+ color: $black;
+ }
+
+ .private-item {
+ color: $gray-l1;
+ }
+
+ .draft-item {
+ color: $yellow-d1;
+ }
+
+ .public-item:hover,
+ .private-item:hover,
+ .draft-item:hover {
+ color: $blue;
}
- }
- ol ol {
- .section-item {
- padding-left: 34px;
+ .draft-item:after,
+ .public-item:after,
+ .private-item:after {
+ @include font-size(9);
+ margin-left: 3px;
+ font-weight: 600;
+ text-transform: uppercase;
+ }
+
+ .draft-item:after {
+ content: "- draft";
}
- .new-unit-item {
- margin: 0 0 $baseline 41px;
+ .private-item:after {
+ content: "- private";
+ }
+ }
+
+ .new-unit-item {
+ @extend %ui-btn-flat-outline;
+ @extend %t-action4;
+ width: 90%;
+ margin: 0 0 ($baseline/2) ($baseline/4);
+ border: 1px solid transparent;
+ padding: ($baseline/4) ($baseline/2);
+ font-weight: normal;
+ color: $gray-l2;
+ text-align: left;
+
+ &:hover {
+ box-shadow: none;
+ background-image: none;
}
}
}
diff --git a/cms/templates/overview.html b/cms/templates/overview.html
index 61b00278a434..c346f97e5ca2 100644
--- a/cms/templates/overview.html
+++ b/cms/templates/overview.html
@@ -7,7 +7,7 @@
from xmodule.modulestore.django import loc_mapper
%>
<%block name="title">${_("Course Outline")}%block>
-<%block name="bodyclass">is-signedin course view-outline%block>
+<%block name="bodyclass">is-signedin course view-outline feature-edit-dialog%block>
<%namespace name='static' file='static_content.html'/>
<%namespace name="units" file="widgets/units.html" />
@@ -49,64 +49,71 @@
<%block name="header_extras">
+
+
+
%block>
@@ -135,130 +142,177 @@ ${_("Page Actions")}
-
-
-
-
- <%
- course_locator = loc_mapper().translate_location(
- context_course.location.course_id, context_course.location, False, True
- )
- %>
-
- % for section in sections:
- <%
- section_locator = loc_mapper().translate_location(
- context_course.location.course_id, section.location, False, True
- )
- %>
-
- <%include file="widgets/_ui-dnd-indicator-before.html" />
-
-
-
-
-
-
-
- <%
- if section.start is not None:
- start_date_str = section.start.strftime('%m/%d/%Y')
- start_time_str = section.start.strftime('%H:%M')
- else:
- start_date_str = ''
- start_time_str = ''
- %>
- %if section.start is None:
-
${_("This section has not been released.")}
-
${_("Schedule")}
- %else:
-
${_("Will Release:")}
- ${date_utils.get_default_time_display(section.start)}
-
${_("Edit")}
- %endif
-
-
-
-
-
-
-
-
- % for subsection in section.get_children():
- <%
- subsection_locator = loc_mapper().translate_location(
- context_course.location.course_id, subsection.location, False, True
- )
- %>
- -
-
- <%include file="widgets/_ui-dnd-indicator-before.html" />
-
-
-
-
-
-
-
-
+
+
+
+
+
+ <%
+ course_locator = loc_mapper().translate_location(
+ context_course.location.course_id, context_course.location, False, True
+ )
+ %>
+
+ % for section in sections:
+ <%
+ section_locator = loc_mapper().translate_location(
+ context_course.location.course_id, section.location, False, True
+ )
+ %>
+
+ <%include file="widgets/_ui-dnd-indicator-before.html" />
+
+
+ ${_('Expand/collapse this section')}
+
+
+
- ${units.enum_units(subsection)}
-
- <%include file="widgets/_ui-dnd-indicator-after.html" />
-
- % endfor
- -
- <%include file="widgets/_ui-dnd-indicator-initial.html" />
-
-
-
-
- <%include file="widgets/_ui-dnd-indicator-after.html" />
-
- % endfor
-
-
-
+
+
+
+
+ -
+
+ <%
+ if section.start is not None:
+ start_date_str = section.start.strftime('%m/%d/%Y')
+ start_time_str = section.start.strftime('%H:%M')
+ else:
+ start_date_str = ''
+ start_time_str = ''
+ %>
+ %if section.start is None:
+
${_("This section is not scheduled for release")}
+
${_("Schedule")}
+ %else:
+
${_("Release date:")}
+ ${date_utils.get_default_time_display(section.start)}
+
${_("Edit section release date")}
+ %endif
+
+
+ -
+ ${_('Delete section')}
+
+ -
+ ${_("Drag to reorder section")}
+
+
+
+
+
+
+
+ % for subsection in section.get_children():
+ <%
+ subsection_locator = loc_mapper().translate_location(
+ context_course.location.course_id, subsection.location, False, True
+ )
+ %>
+ -
+
+ <%include file="widgets/_ui-dnd-indicator-before.html" />
+
+
+ ${units.enum_units(subsection)}
+
+ <%include file="widgets/_ui-dnd-indicator-after.html" />
+
+ % endfor
+ -
+ <%include file="widgets/_ui-dnd-indicator-initial.html" />
+
+
+
+
+
+
+
+ <%include file="widgets/_ui-dnd-indicator-after.html" />
+
+ % endfor
+
+
+
+
+
+
-
-
-
${_("Section Release Date")}
-
-
-
-
+
+
+
+
%block>
diff --git a/cms/templates/unit.html b/cms/templates/unit.html
index 2318e9cd9725..1151b4c5523c 100644
--- a/cms/templates/unit.html
+++ b/cms/templates/unit.html
@@ -46,7 +46,7 @@
-
+
% for locator in components:
@@ -147,8 +147,8 @@ ${_("Add New Component")}
diff --git a/cms/templates/widgets/units.html b/cms/templates/widgets/units.html
index edc32ed947f2..a5862a28d463 100644
--- a/cms/templates/widgets/units.html
+++ b/cms/templates/widgets/units.html
@@ -1,3 +1,4 @@
+<%! from django.utils.translation import ugettext as _ %>
<%! from django.core.urlresolvers import reverse %>
<%! from contentstore.utils import compute_unit_state %>
<%! from xmodule.modulestore.django import loc_mapper %>
@@ -18,7 +19,7 @@
<%
unit_locator = loc_mapper().translate_location(context_course.location.course_id, unit.location, False, True)
%>
- -
<%include file="_ui-dnd-indicator-before.html" />
@@ -32,14 +33,18 @@
%>
@@ -47,11 +52,11 @@
<%include file="_ui-dnd-indicator-after.html" />
% endfor
- -
+
-
<%include file="_ui-dnd-indicator-initial.html" />
- New Unit
+ ${_("New Unit")}
diff --git a/common/static/sass/_mixins-inherited.scss b/common/static/sass/_mixins-inherited.scss
index 7a3cb1633d69..b59d193d5f9c 100644
--- a/common/static/sass/_mixins-inherited.scss
+++ b/common/static/sass/_mixins-inherited.scss
@@ -354,8 +354,8 @@
}
@mixin tree-view {
- border: 1px solid $mediumGrey;
- background: $lightGrey;
+ border: 0;
+ background: $white;
.branch {
margin-bottom: 0;
@@ -374,7 +374,7 @@
font-size: 13px;
&:hover {
- background: $orange-l4;
+ background: $blue-l5;
.item-actions {
display: block;
@@ -403,11 +403,11 @@
}
.private-item {
- color: #a4aab7;
+ color: $gray-l1;
}
.draft-item {
- color: #9f7d10;
+ color: $yellow-d1;
}
}