diff --git a/cms/djangoapps/contentstore/features/common.py b/cms/djangoapps/contentstore/features/common.py
index 4a500c9e16..cd9c00c09c 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 b6f55969bb..b1e9ee2e12 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 2082e4747b..6aaa954c6c 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
-
-
- Release Day
-
-
-
-
-
On the date set above, this section – – will be released to students. Any units marked private will only be visible to admins.
-
-
-
Save Cancel
-
-
+
+
"""
-
+
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.attachMethod).toBe('before')
- # Now past the "fudge factor".
- $ele.offset(
- top: $('#unit-4').offset().top + 12
- left: $ele.offset().left
- )
- destination = Overview.overviewDragger.findDestination($ele, 1)
- expect(destination.ele).toBe($('#unit-4'))
+ 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')
+
+ # If past the end the drop target, will attach after.
+ $ele.offset(
+ top: $unit4.offset().top + $unit4.height() + 1
+ left: $ele.offset().left
+ )
+ 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 174ab10c89..b2b3d97123 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 9dfb339b0c..1a4daa826d 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 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'
+ };
+ }
}
- // Dragging down into beginning of list.
- else if (j == 0 && yChange > 0 && Math.abs(eleY - siblingY) <= fudge) {
- return {
- ele: $sibling,
- attachMethod: 'before'
- };
- }
- 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 409e9098e5..4618356864 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 0000000000..490a74b8bb
--- /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 09409f779c..f6b20b06db 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 7a787bb5f0..50bc5bfec7 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;
- .gradable-status {
- float: right;
- position: relative;
- top: -4px;
- right: 50px;
- width: 100px;
-
- .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;
- }
- }
-
- [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;
- }
- }
- }
-
- a {
- color: $blue;
-
- &.is-selected {
- font-weight: bold;
- }
- }
- }
-
- // dropdown state
- &.is-active {
-
- .menu {
- z-index: 1000;
- display: block;
- opacity: 1.0;
- }
-
- .menu-toggle {
- z-index: 10000;
- }
- }
-
- // set state
- &.is-set {
-
- .menu-toggle {
- color: $blue;
- }
-
- .status-label {
- display: block;
- color: $blue;
- }
- }
+ [class^="icon-"] {
+ margin-right: ($baseline/2);
}
}
}
+ }
+
+ .content-supplementary {
+ width: flex-grid(3, 12);
+ }
+ // page header bits
+ .toggle-button-sections {
+ @extend %t-copy-sub2;
+ position: relative;
+ display: none;
+ float: right;
+ margin-top: ($baseline/4);
+ color: $gray-l1;
+
+ &.is-shown {
+ display: block;
+ }
+
+ .label {
+ display: inline-block;
+ }
+ }
+
+
+ // 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;
+ }
+
+ .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;
+ }
+
+ .new-section-name-cancel,
+ .new-subsection-name-cancel {
+ @include white-button;
+ padding: 4px 20px 7px;
+ color: $gray-l1;
+ }
+
+ .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;
+
+
+ &:hover {
+ box-shadow: none;
+ background-image: none;
+ }
+ }
+
+ .courseware-unit-new {
+ margin-right: ($baseline*1.5);
+ }
+
+
+ // 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;
+ }
+
+ .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;
+ }
+
+ &.expand .ui-toggle-expansion {
+ @include transform(rotate(-90deg));
+ @include transform-origin(50% 50%);
+ }
+
+ }
+
+ .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;
+ }
+
+ }
+ }
+
+
+ // section styles
.courseware-section {
@extend %ui-window;
@include transition(background $tmg-avg ease-in-out 0);
position: relative;
- margin-top: ($baseline);
- padding-bottom: ($baseline/2);
+ padding: ($baseline*1.5) $baseline $baseline $baseline;
&.collapsed {
- padding-bottom: 0;
- }
-
- label {
- float: left;
- line-height: 29px;
- }
-
- .datepair {
- float: left;
- margin-left: 10px;
- }
-
- .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;
-
- strong {
- font-weight: bold;
- }
- }
-
- .schedule-button {
- @include blue-button;
- }
-
- .edit-button {
- @include blue-button;
- }
-
- .schedule-button,
- .edit-button {
- @include font-size(11);
- padding: 3px 15px 5px;
- }
- }
-
- .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;
+ padding-bottom: 0;
}
&.collapsed .subsection-list,
@@ -217,62 +183,119 @@
display: none !important;
}
- header {
- min-height: 75px;
+ &.new-section {
+ padding: ($baseline*1.5) $baseline 0 $baseline;
+
+ header {
@include clearfix();
+ height: auto;
+ border-bottom: 0;
- .item-details, .section-published-date {
-
+ .expand-collapse {
+ display: none;
}
.item-details {
- display: inline-block;
- padding: 20px 0 10px 0;
- @include clearfix();
+ width: auto;
- .section-name {
- @include font-size(19);
- float: left;
- margin-right: 10px;
- width: 350px;
- font-weight: bold;
- color: $blue;
- }
+ .section-name {
+ float: none;
+ width: 100%;
+ }
+ }
+ }
+ }
- .section-name-span {
- @include transition(color $tmg-f2 linear 0s);
- cursor: pointer;
+ .section {
+ @include clearfix();
+ min-height: 65px; // needed to align with edit input
+ margin-bottom: 0;
+ border: 0;
+ padding: 0;
- &:hover {
- color: $orange;
- }
- }
+ // section name area
+ .item-details {
+ @include clearfix();
+ width: 400px;
+ float: none;
+ display: inline-block;
+ padding: 0 0 ($baseline/2) 0;
- .section-name-edit {
- position: relative;
- width: 400px;
- background: $white;
+ .section-name {
+ @include font-size(19);
+ margin-right: ($baseline/2);
+ }
- input {
- @include font-size(16);
+ .section-name-span {
+ @include transition(color $tmg-f2 linear 0s);
+ cursor: pointer;
+
+ &:hover {
+ color: $blue;
+ }
+ }
+
+ .section-name-edit {
+ position: relative;
+ width: ($baseline*20);
+ background: $white;
+
+ input {
+ @include font-size(16);
}
.save-button {
@include blue-button;
- padding: 7px 20px 7px;
- margin-right: 5px;
+ padding: 7px $baseline 7px;
+ margin-right: ($baseline/4);
}
.cancel-button {
@include white-button;
- padding: 7px 20px 7px;
+ padding: 7px $baseline 7px;
+ }
+ }
+ }
+
+
+ // section specific action styles
+ .item-actions {
+ position: relative;
+ display: inline-block;
+ float: right;
+ margin-bottom: ($baseline/2);
+ top: 0;
+ }
+
+ .actions-item {
+ padding: 0 0 0 8px;
+
+ &:last-child {
+ padding-right: 4px;
+ }
+
+ &.pubdate {
+ padding-right: 0;
+ }
+
+ .action {
+
+ &.pubdate {
+ visibility: hidden;
+ }
+
+ &:hover,
+ &.is-set {
+ color: $blue;
+ visibility: visible;
}
}
.section-published-date {
- float: right;
+ padding: ($baseline/5) ($baseline/2);
border-radius: 3px;
- background: $lightGrey;
+ background: $gray-l5;
+ text-align: right;
.published-status {
@include font-size(12);
@@ -283,401 +306,264 @@
}
}
- .schedule-button {
- @include blue-button;
- }
+ &.released .section-published-date {
+ background-color: transparent;
+ color: $gray-l1;
- .edit-button {
- @include blue-button;
- }
+ a {
+ color: $gray-l2;
- .schedule-button,
- .edit-button {
- @include font-size(11);
- padding: 0 15px 2px 15px;
- }
- }
-
- .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 {
+ &:hover {
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 {
-
- .menu {
- z-index: 1000;
- display: block;
- opacity: 1.0;
- }
-
-
- .menu-toggle {
- z-index: 10000;
}
}
-
- // set state
- &.is-set {
-
- .menu-toggle {
- color: $blue;
- }
-
- .status-label {
- display: block;
- color: $blue;
- }
- }
-
- float: left;
- padding: 21px 0 0;
}
}
+ }
+
+
+ // subsection styles
+ .courseware-subsection {
+ @include clearfix();
+ padding: 3px 0;
+
+ &.visible {
+ border-left: 5px solid $green;
+ }
+
+ &.mixed {
+ border-left: 5px solid $yellow-s1;
+ }
+
+ .status {
+ @extend %cont-text-sr;
+ }
+
+ .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;
+
+ &:hover {
+ background: $blue-l5;
.item-actions {
- margin-top: 21px;
- margin-right: 12px;
-
- .edit-button,
- .delete-button {
- margin-top: -3px;
- }
- }
-
- .expand-collapse-icon {
- @include transition(none);
- float: left;
- margin: 25px 6px 16px 16px;
-
- &.expand {
- background-position: 0 0;
- }
-
- &.collapsed {
-
- }
- }
-
- .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;
-
- &:hover {
- color: $orange;
- }
- }
-
- .section-name-form {
- margin-bottom: 15px;
- }
-
- .section-name-edit {
- input {
- @include font-size(16);
- }
-
- .save-button {
- @include blue-button;
- padding: 7px 20px 7px;
- margin-right: 5px;
- }
-
- .cancel-button {
- @include white-button;
- padding: 7px 20px 7px;
- }
- }
-
- h4 {
- @include font-size(12);
- color: #878e9d;
-
- strong {
- font-weight: bold;
- }
- }
-
- .list-header {
- @include linear-gradient(top, transparent, rgba(0, 0, 0, .1));
- background-color: #ced2db;
- border-radius: 3px 3px 0 0;
- }
-
- .subsection-list {
- margin: 0 12px;
-
- > ol {
- @include tree-view;
- border-top-width: 0;
- }
- }
-
- &.new-section {
-
- header {
- @include clearfix();
- height: auto;
- }
-
- .expand-collapse-icon {
- visibility: hidden;
- }
-
- .item-details {
- padding: 25px 0 0 0;
-
- .section-name {
- float: none;
- width: 100%;
- }
- }
- }
- }
-
- .toggle-button-sections {
- @include font-size(12);
- display: none;
- position: relative;
- float: right;
- margin-top: ($baseline/4);
- color: $darkGrey;
-
- &.is-shown {
display: block;
+ }
}
- [class^="icon-"] {
- @include font-size(11);
- border-radius: 20px;
- position: relative;
- top: -1px;
- display: inline-block;
- margin-right: 2px;
- line-height: 5px;
+ &.editing {
+ background: $orange-l4;
}
+ }
- .label {
- display: inline-block;
- }
- }
-
- .new-section-name,
- .new-subsection-name-input {
- width: 515px;
- }
-
- .new-section-name-save,
- .new-subsection-name-save {
- @include blue-button;
- padding: 4px 20px 7px;
- margin: 0 5px;
- color: #fff !important;
- }
-
- .new-section-name-cancel,
- .new-subsection-name-cancel {
- @include white-button;
- padding: 4px 20px 7px;
- color: #8891a1 !important;
- }
-
- .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);
- }
-
- .preview {
- background: url(../img/preview.jpg) center top no-repeat;
- }
-
- .edit-subsection-publish-settings {
- display: none;
- position: fixed;
- top: 100px;
- left: 50%;
- z-index: 99999;
+ .details {
+ display: block;
+ margin-bottom: 0;
width: 600px;
- margin-left: -300px;
- background: #fff;
- text-align: center;
- .settings {
- padding: 40px;
+ a {
+ color: $baseFontColor;
+ }
+ }
+ }
+
+ // gradable drop down
+ .gradable-status {
+ display: inline-block;
+ position: relative;
+
+ .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;
+ }
+
+ .menu-toggle {
+ @extend %ui-depth1;
+ position: absolute;
+ top: 0;
+ right: 5px;
+ padding: 2px 5px;
+ color: $gray-l2;
+
+ &:hover,
+ &.is-active {
+ color: $blue;
}
- h3 {
- @include font-size(34);
- font-weight: 300;
+ &:focus {
+ outline: 0;
}
+ }
- .picker {
- @include clearfix();
- margin: 30px 0 65px;
- .field {
- float: left;
- margin-right: ($baseline/2);
+ // 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;
- &:first-child {
- margin-left: ($baseline*5);
- }
+ li {
+ width: 115px;
+ margin-bottom: 3px;
+ border-bottom: 1px solid $gray-l4;
+ padding-bottom: 3px;
- &:last-child {
- margin-right: 0;
- }
+ &:last-child {
+ margin-bottom: 0;
+ border: none;
+ padding-bottom: 0;
- label, input {
- display: block;
- text-align: left;
- }
-
- label {
- @extend %t-copy-sub1;
- margin-bottom: ($baseline/4);
- }
+ .gradable-status-notgraded {
+ color: $gray;
}
+ }
}
- .description {
- @include font-size(14);
- float: left;
- margin-top: 30px;
- line-height: 20px;
- width: 100%;
+ a {
+ color: $blue;
+
+ &.is-selected {
+ font-weight: bold;
+ }
+ }
+ }
+
+ // gradable dropdown state
+ &.is-active {
+
+ .menu {
+ @extend %ui-depth3;
+ display: block;
+ opacity: 1.0;
}
- strong {
- font-weight: 700;
+ .menu-toggle {
+ @extend %ui-depth4;
+ }
+ }
+
+ // set state
+ &.is-set {
+
+ .menu-toggle {
+ color: $blue;
}
- .start-date,
- .start-time {
- @include font-size(19);
- }
-
- .save-button {
- @include blue-button;
- margin-right: 10px;
- }
-
- .cancel-button {
- @include white-button;
- }
-
- .save-button,
- .cancel-button {
- @include font-size(16);
+ .status-label {
+ display: block;
+ color: $blue;
}
+ }
}
- .collapse-all-button {
- @include font-size(13);
- float: right;
- margin-top: 10px;
- color: $darkGrey;
+ .courseware-subsection .sortable-unit-list {
+ margin: ($baseline/4) 0 0 0;
}
+ // unit styles
+ .courseware-unit {
+ margin: -1px 0 0 ($baseline*1.75);
+
+ &.add-new-unit {
+ margin: 5px ($baseline*1.75) 0 ($baseline*1.75);
+ }
+
+ .section-item {
+ border: 0;
+ background-color: $white;
+ }
+
+ .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";
+ }
+ }
+
+
+ // modal to edit section publish settings
+ .edit-section-publish-settings {
+
+ .picker {
+ @include clearfix();
+
+
+ .field {
+ float: left;
+ margin-right: ($baseline/2);
+
+ label, input {
+ display: block;
+ text-align: left;
+ }
+
+ label {
+ @extend %t-copy-sub1;
+ margin-bottom: ($baseline/4);
+ }
+ }
+ }
+ }
+
+
+
// 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 d6da939115..c64a9f79c1 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 50685123a2..663fa3161e 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;
- ol {
- .section-item {
- padding-left: $baseline;
+ &:hover {
+ background: $blue-l5;
+ color: $blue;
}
- .new-unit-item {
- margin-left: $baseline;
+ &.editing {
+ background-color: $orange-l3;
+ }
+
+ .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;
+ }
+
+ .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";
}
}
- ol ol {
- .section-item {
- padding-left: 34px;
- }
+ .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;
- .new-unit-item {
- margin: 0 0 $baseline 41px;
+ &:hover {
+ box-shadow: none;
+ background-image: none;
}
}
}
diff --git a/cms/templates/overview.html b/cms/templates/overview.html
index 61b00278a4..c346f97e5c 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 @@ require(["domReady!", "jquery", "js/models/location", "js/models/section", "js/v
<%block name="header_extras">
+
+
+
%block>
@@ -135,130 +142,177 @@ require(["domReady!", "jquery", "js/models/location", "js/models/section", "js/v
-
-
+
+
+
-
- <%
- 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" />
+
+ <%
+ 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')}
-
-
-
- <%
- 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" />
-
-
-
-
-
-
-
-
+
+
- ${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
+
+
+
+
+
+
+
${_("What can I do on this page?")}
+
${_("You can create new sections and subsections, set the release date for sections, and create new units in existing subsections. You can set the assignment type for subsections that are to be graded, and you can open a subsection for further editing.")}
+
+
${_("In addition, you can drag and drop sections, subsections, and units to reorganize your course.")}
+
+
+
-
-
-
${_("Section Release Date")}
-
-
-
${_("Release Day")}
-
+
+
+
+
%block>
diff --git a/cms/templates/unit.html b/cms/templates/unit.html
index 2318e9cd97..1151b4c552 100644
--- a/cms/templates/unit.html
+++ b/cms/templates/unit.html
@@ -46,7 +46,7 @@ require(["domReady!", "jquery", "js/models/module_info", "coffee/src/views/unit"
- ${_("Display Name:")}
+ ${_("Display Name:")}
% for locator in components:
@@ -147,8 +147,8 @@ require(["domReady!", "jquery", "js/models/module_info", "coffee/src/views/unit"
diff --git a/cms/templates/widgets/units.html b/cms/templates/widgets/units.html
index edc32ed947..a5862a28d4 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 @@ This def will enumerate through a passed in subsection and list all of the units
<%
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 @@ This def will enumerate through a passed in subsection and list all of the units
%>
@@ -47,11 +52,11 @@ This def will enumerate through a passed in subsection and list all of the units
<%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 7a3cb1633d..b59d193d5f 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;
}
}