Commit 8a23f432 by frances botsford

Merge pull request #1896 from edx/frances/fix/studio-outline-cleanup

FED Cleanup of Studio Outline page
parents 8554c3f0 1618c916
......@@ -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)
......
......@@ -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):
......
......@@ -6,65 +6,89 @@ define ["js/views/overview", "js/views/feedback_notification", "sinon", "js/base
appendSetFixtures """
<div class="section-published-date">
<span class="published-status">
<strong>Will Release:</strong> 06/12/2013 at 04:00 UTC
<strong>Release date:</strong> 06/12/2013 at 04:00 UTC
</span>
<a href="#" class="edit-button" data-date="06/12/2013" data-time="04:00" data-locator="i4x://pfogg/42/chapter/d6b47f7b084f49debcaf67fe5436c8e2">Edit</a>
<a href="#" class="edit-release-date action " data-date="06/12/2013" data-time="04:00" data-locator="i4x://pfogg/42/chapter/d6b47f7b084f49debcaf67fe5436c8e2"><i class="icon-time"></i> <span class="sr">Edit section release date</span></a>
</div>
"""
appendSetFixtures """
<div class="edit-subsection-publish-settings">
<div class="settings">
<h3>Section Release Date</h3>
<div class="picker datepair">
<div class="field field-start-date">
<label for="">Release Day</label>
<div class="wrapper wrapper-dialog wrapper-dialog-edit-sectionrelease edit-section-publish-settings" aria-describedby="dialog-edit-sectionrelease-description" aria-labelledby="dialog-edit-sectionrelease-title" aria-hidden="" role="dialog">
<div class="dialog confirm">
<form class="edit-sectionrelease-dialog" action="#">
<div class="form-content">
<h2 class="title dialog-edit-sectionrelease-title">Section Release Date</h2>
<p id="dialog-edit-sectionrelease-description" class="message">On the date set below, this section - <strong class="section-name"></strong> - will be released to students. Any units marked private will only be visible to admins.</p>
<ul class="list-input picker datepair">
<li class="field field-start-date">
<label for="start_date">Release Day</label>
<input class="start-date date" type="text" name="start_date" value="04/08/1990" placeholder="MM/DD/YYYY" class="date" size='15' autocomplete="off"/>
</div>
<div class="field field-start-time">
<label for="">Release Time (<abbr title="Coordinated Universal Time">UTC</abbr>)</label>
</li>
<li class="field field-start-time">
<label for="start_time">Release Time (<abbr title="Coordinated Universal Time">UTC</abbr>)</label>
<input class="start-time time" type="text" name="start_time" value="12:00" placeholder="HH:MM" class="time" size='10' autocomplete="off"/>
</li>
</ul>
</div>
<div class="description">
<p>On the date set above, this section – <strong class="section-name"></strong> – will be released to students. Any units marked private will only be visible to admins.</p>
</div>
</div>
<a href="#" class="save-button">Save</a><a href="#" class="cancel-button">Cancel</a>
<div class="actions">
<h3 class="sr">Form Actions</h3>
<ul>
<li class="action-item">
<a href="#" class="button action-primary action-save">Save</a>
</li>
<li class="action-item">
<a href="#" class="button action-secondary action-cancel">Cancel</a>
</li>
</ul>
</div>
</form>
</div>
"""
appendSetFixtures """
<section class="courseware-section branch" data-locator="a-location-goes-here">
<section class="courseware-section is-collapsible is-draggable" data-parent="a-parent-locator-goes-here" data-locator="a-location-goes-here">
<li class="branch collapsed id-holder" data-locator="an-id-goes-here">
<a href="#" class="delete-section-button"></a>
<a href="#" data-tooltip="Delete this section" class="delete-section-button"><i class="icon-trash"></i> <span class="sr">Delete section</span></a>
</li>
</section>
"""
appendSetFixtures """
<ol>
<li class="subsection-list branch" id="subsection-1" data-locator="subsection-1-id">
<section>
<ol class="sortable-subsection-list">
<li class="courseware-subsection is-collapsible id-holder is-draggable" id="subsection-0" data-locator="subsection-0-id" style="margin:5px">
<ol class="sortable-unit-list" id="subsection-list-0">
<li class="courseware-unit unit is-draggable" id="unit-0" data-parent="subsection-0-id" data-locator="zero-unit-id"></li>
</ol>
</li>
<li class="courseware-subsection is-collapsible id-holder is-draggable" id="subsection-1" data-locator="subsection-1-id" style="margin:5px">
<ol class="sortable-unit-list" id="subsection-list-1">
<li class="unit" id="unit-1" data-parent="subsection-1-id" data-locator="first-unit-id"></li>
<li class="unit" id="unit-2" data-parent="subsection-1-id" data-locator="second-unit-id"></li>
<li class="unit" id="unit-3" data-parent="subsection-1-id" data-locator="third-unit-id"></li>
<li class="courseware-unit unit is-draggable" id="unit-1" data-parent="subsection-1-id" data-locator="first-unit-id"></li>
<li class="courseware-unit unit is-draggable" id="unit-2" data-parent="subsection-1-id" data-locator="second-unit-id"></li>
<li class="courseware-unit unit is-draggable" id="unit-3" data-parent="subsection-1-id" data-locator="third-unit-id"></li>
</ol>
</li>
<li class="subsection-list branch" id="subsection-2" data-locator="subsection-2-id">
<li class="courseware-subsection is-collapsible id-holder is-draggable" id="subsection-2" data-locator="subsection-2-id" style="margin:5px">
<ol class="sortable-unit-list" id="subsection-list-2">
<li class="unit" id="unit-4" data-parent="subsection-2" data-locator="fourth-unit-id"></li>
<li class="courseware-unit unit is-draggable" id="unit-4" data-parent="subsection-2" data-locator="fourth-unit-id"></li>
</ol>
</li>
<li class="subsection-list branch" id="subsection-3" data-locator="subsection-3-id">
<ol class="sortable-unit-list" id="subsection-list-3">
<li class="courseware-subsection is-collapsible id-holder is-draggable" id="subsection-3" data-locator="subsection-3-id" style="margin:5px">
<ol class="sortable-unit-list" id="subsection-list-3"></ol>
</li>
<li class="courseware-subsection is-collapsible id-holder is-draggable" id="subsection-4" data-locator="subsection-4-id" style="margin:5px">
<ol class="sortable-unit-list" id="subsection-list-4">
<li class="courseware-unit unit is-draggable" id="unit-5" data-parent="subsection-4-id" data-locator="fifth-unit-id"></li>
</ol>
</li>
</ol>
</section>
"""
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,7 +103,14 @@ 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 ->
......@@ -88,13 +119,13 @@ define ["js/views/overview", "js/views/feedback_notification", "sinon", "js/base
@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.
......@@ -124,25 +155,54 @@ define ["js/views/overview", "js/views/feedback_notification", "sinon", "js/base
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(
......@@ -162,6 +222,20 @@ define ["js/views/overview", "js/views/feedback_notification", "sinon", "js/base
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(
......
......@@ -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) {
......
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(
'<span class="published-status">' +
'<strong>' + gettext("Will Release:") + '&nbsp;</strong>' +
'<strong>' + gettext("Release date:") + '&nbsp;</strong>' +
gettext("{month}/{day}/{year} at {hour}:{minute} UTC") +
'</span>' +
'<a href="#" class="edit-button" data-date="{month}/{day}/{year}" data-time="{hour}:{minute}" data-locator="{locator}">' +
gettext("Edit") +
'</a>',
'<a href="#" class="edit-release-date action" data-date="{month}/{day}/{year}" data-time="{hour}:{minute}" data-locator="{locator}"><i class="icon-time"></i> <span class="sr">' +
gettext("Edit section release date") +
'</span></a>',
{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,6 +276,34 @@ 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 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 {
// Dragging up into end of list.
if (j == siblings.length - 1 && yChange < 0 && Math.abs(eleY - siblingYEnd) <= fudge) {
return {
......@@ -267,13 +311,23 @@ define(["domReady", "jquery", "jquery.ui", "underscore", "gettext", "js/views/fe
attachMethod: 'after'
};
}
// Dragging down into beginning of list.
else if (j == 0 && yChange > 0 && Math.abs(eleY - siblingY) <= fudge) {
// 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,
......@@ -284,6 +338,7 @@ define(["domReady", "jquery", "jquery.ui", "underscore", "gettext", "js/views/fe
}
}
}
}
// Failed drag
return {
ele: null,
......@@ -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'
);
});
......
......@@ -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 {
......
// 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;
}
}
}
}
......@@ -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';
......@@ -3,212 +3,178 @@
.view-outline {
input.courseware-unit-search-input {
// page structure
.content-primary,
.content-supplementary {
@include box-sizing(border-box);
float: left;
width: 260px;
background-color: #fff;
}
.branch {
.content-primary {
width: flex-grid(9, 12);
margin-right: flex-gutter();
.section-item {
@include clearfix();
.details {
display: block;
float: left;
margin-bottom: 0;
width: 650px;
}
.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;
.no-outline-content {
@extend %ui-well;
padding: ($baseline*2);
background-color: $gray-l4;
text-align: center;
color: $gray;
&:hover, &.is-active {
color: $blue;
}
}
.new-button {
@include font-size(14);
margin-left: $baseline;
[class^="icon-"] {
vertical-align: middle;
margin-top: -5px;
display: inline-block;
margin-right: ($baseline/2);
}
.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;
}
}
.content-supplementary {
width: flex-grid(3, 12);
}
// dropdown state
&.is-active {
.menu {
z-index: 1000;
// 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;
opacity: 1.0;
}
.menu-toggle {
z-index: 10000;
.label {
display: inline-block;
}
}
// set state
&.is-set {
.menu-toggle {
color: $blue;
// 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;
}
.status-label {
display: block;
color: $blue;
}
}
.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;
.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;
&:hover {
box-shadow: none;
background-image: none;
}
label {
float: left;
line-height: 29px;
}
.datepair {
float: left;
margin-left: 10px;
.courseware-unit-new {
margin-right: ($baseline*1.5);
}
.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;
// 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;
strong {
font-weight: bold;
}
&:hover {
color: $blue;
}
.schedule-button {
@include blue-button;
.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;
}
.edit-button {
@include blue-button;
&.expand .ui-toggle-expansion {
@include transform(rotate(-90deg));
@include transform-origin(50% 50%);
}
.schedule-button,
.edit-button {
@include font-size(11);
padding: 3px 15px 5px;
}
.actions-list {
display: inline-block;
margin-bottom: 0;
}
.datepair .date,
.datepair .time {
.actions-item {
@include font-size(13);
box-shadow: none;
padding-left: 0;
padding-right: 0;
border: none;
background: none;
font-weight: bold;
display: inline-block;
padding: 0 4px;
vertical-align: middle;
.action {
min-width: ($baseline*.75);
color: $gray-l2;
&:hover,
&.is-set {
color: $blue;
cursor: pointer;
visibility: visible;
}
.datepair .date {
width: 80px;
//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 .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,26 +183,47 @@
display: none !important;
}
&.new-section {
padding: ($baseline*1.5) $baseline 0 $baseline;
header {
min-height: 75px;
@include clearfix();
height: auto;
border-bottom: 0;
.expand-collapse {
display: none;
}
.item-details, .section-published-date {
.item-details {
width: auto;
.section-name {
float: none;
width: 100%;
}
}
}
}
.section {
@include clearfix();
min-height: 65px; // needed to align with edit input
margin-bottom: 0;
border: 0;
padding: 0;
// section name area
.item-details {
display: inline-block;
padding: 20px 0 10px 0;
@include clearfix();
width: 400px;
float: none;
display: inline-block;
padding: 0 0 ($baseline/2) 0;
.section-name {
@include font-size(19);
float: left;
margin-right: 10px;
width: 350px;
font-weight: bold;
color: $blue;
margin-right: ($baseline/2);
}
.section-name-span {
......@@ -244,13 +231,13 @@
cursor: pointer;
&:hover {
color: $orange;
color: $blue;
}
}
.section-name-edit {
position: relative;
width: 400px;
width: ($baseline*20);
background: $white;
input {
......@@ -259,20 +246,56 @@
.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-published-date {
// 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 {
padding: ($baseline/5) ($baseline/2);
border-radius: 3px;
background: $lightGrey;
background: $gray-l5;
text-align: right;
.published-status {
@include font-size(12);
......@@ -283,93 +306,144 @@
}
}
.schedule-button {
@include blue-button;
&.released .section-published-date {
background-color: transparent;
color: $gray-l1;
a {
color: $gray-l2;
&:hover {
color: $blue;
}
}
}
}
}
}
}
.edit-button {
@include blue-button;
// subsection styles
.courseware-subsection {
@include clearfix();
padding: 3px 0;
&.visible {
border-left: 5px solid $green;
}
.schedule-button,
.edit-button {
@include font-size(11);
padding: 0 15px 2px 15px;
&.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 {
display: block;
}
}
&.editing {
background: $orange-l4;
}
}
.details {
display: block;
margin-bottom: 0;
width: 600px;
a {
color: $baseFontColor;
}
}
}
// gradable drop down
.gradable-status {
position: absolute;
top: 20px;
right: 70px;
width: 145px;
display: inline-block;
position: relative;
.status-label {
@include font-size(12);
width: 110px;
padding: 5px 40px 5px 10px;
border-radius: 3px;
position: absolute;
top: 0;
right: 2px;
display: none;
width: 100px;
padding: 10px 35px 10px 10px;
background: $lightGrey;
color: $lightGrey;
color: transparent;
text-align: right;
font-weight: bold;
line-height: 16px;
}
.menu-toggle {
z-index: 10;
@extend %ui-depth1;
position: absolute;
top: 2px;
top: 0;
right: 5px;
padding: 5px;
color: $lightGrey;
padding: 2px 5px;
color: $gray-l2;
&:hover, &.is-active {
&:hover,
&.is-active {
color: $blue;
}
&:focus {
outline: 0;
}
}
// gradable dropdown menu default
.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;
@include transition(opacity $tmg-f2 linear 0s);
display: none;
opacity: 0.0;
z-index: 1;
position: absolute;
top: -1px;
left: 2px;
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;
border: 1px solid $mediumGrey;
li {
width: 115px;
margin-bottom: 3px;
border-bottom: 1px solid $gray-l4;
padding-bottom: 3px;
border-bottom: 1px solid $lightGrey;
&:last-child {
margin-bottom: 0;
padding-bottom: 0;
border: none;
padding-bottom: 0;
a {
color: $darkGrey;
.gradable-status-notgraded {
color: $gray;
}
}
}
a {
color: $blue;
&.is-selected {
font-weight: bold;
......@@ -377,18 +451,17 @@
}
}
// dropdown state
// gradable dropdown state
&.is-active {
.menu {
z-index: 1000;
@extend %ui-depth3;
display: block;
opacity: 1.0;
}
.menu-toggle {
z-index: 10000;
@extend %ui-depth4;
}
}
......@@ -404,220 +477,67 @@
color: $blue;
}
}
float: left;
padding: 21px 0 0;
}
}
.item-actions {
margin-top: 21px;
margin-right: 12px;
.edit-button,
.delete-button {
margin-top: -3px;
}
.courseware-subsection .sortable-unit-list {
margin: ($baseline/4) 0 0 0;
}
.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);
}
// unit styles
.courseware-unit {
margin: -1px 0 0 ($baseline*1.75);
.save-button {
@include blue-button;
padding: 7px 20px 7px;
margin-right: 5px;
&.add-new-unit {
margin: 5px ($baseline*1.75) 0 ($baseline*1.75);
}
.cancel-button {
@include white-button;
padding: 7px 20px 7px;
}
.section-item {
border: 0;
background-color: $white;
}
h4 {
@include font-size(12);
color: #878e9d;
strong {
font-weight: bold;
}
.public-item {
color: $black;
}
.list-header {
@include linear-gradient(top, transparent, rgba(0, 0, 0, .1));
background-color: #ced2db;
border-radius: 3px 3px 0 0;
.private-item {
color: $gray-l1;
}
.subsection-list {
margin: 0 12px;
> ol {
@include tree-view;
border-top-width: 0;
}
.draft-item {
color: $yellow-d1;
}
&.new-section {
header {
@include clearfix();
height: auto;
.draft-item:after,
.public-item:after,
.private-item:after {
@include font-size(9);
margin-left: 3px;
font-weight: 600;
text-transform: uppercase;
}
.expand-collapse-icon {
visibility: hidden;
.draft-item:after {
content: "- draft";
}
.item-details {
padding: 25px 0 0 0;
.section-name {
float: none;
width: 100%;
}
}
.private-item:after {
content: "- private";
}
}
.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;
}
.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;
width: 600px;
margin-left: -300px;
background: #fff;
text-align: center;
.settings {
padding: 40px;
}
h3 {
@include font-size(34);
font-weight: 300;
}
// modal to edit section publish settings
.edit-section-publish-settings {
.picker {
@include clearfix();
margin: 30px 0 65px;
.field {
float: left;
margin-right: ($baseline/2);
&:first-child {
margin-left: ($baseline*5);
}
&:last-child {
margin-right: 0;
}
label, input {
display: block;
text-align: left;
......@@ -629,55 +549,21 @@
}
}
}
.description {
@include font-size(14);
float: left;
margin-top: 30px;
line-height: 20px;
width: 100%;
}
strong {
font-weight: 700;
}
.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);
}
}
.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
......
......@@ -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;
}
......
......@@ -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;
}
ol ol {
.section-item {
padding-left: 34px;
.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";
}
}
.new-unit-item {
margin: 0 0 $baseline 41px;
@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;
}
}
}
......
......@@ -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,29 +49,31 @@ require(["domReady!", "jquery", "js/models/location", "js/models/section", "js/v
<%block name="header_extras">
<script type="text/template" id="new-section-template">
<section class="courseware-section branch new-section">
<header>
<a href="#" data-tooltip="${_('Collapse/expand this section')}" class="expand-collapse-icon collapse"></a>
<section class="courseware-section new-section is-collapsible is-draggable">
<header class="section">
<a href="#" data-tooltip="${_('Expand/collapse this section')}" class="action expand-collapse collapse"><i class="icon-caret-down ui-toggle-expansion"></i><span class="sr">${_('Expand/collapse this section')}</span></a>
<div class="item-details">
<h3 class="section-name">
<form class="section-name-form">
<input type="text" value="${_('New Section Name')}" class="new-section-name" />
<input type="submit" class="new-section-name-save" data-parent="${parent_locator}"
data-category="${new_section_category}" value="${_('Save')}" />
<input type="button" class="new-section-name-cancel" value="${_('Cancel')}" /></h3>
<input type="button" class="new-section-name-cancel" value="${_('Cancel')}" />
</form>
</h3>
</div>
</header>
</section>
</script>
<script type="text/template" id="blank-slate-template">
<section class="courseware-section branch new-section">
<section class="courseware-section new-section">
<header>
<a href="#" data-tooltip="${_('Collapse/expand this section')}" class="expand-collapse-icon collapse"></a>
<a href="#" data-tooltip="${_('Expand/collapse this section')}" class="action expand-collapse"><i class="icon-caret-down ui-toggle-dd"></i><span class="sr">${_('Expand/collapse this section')}</span></a>
<div class="item-details">
<h3 class="section-name">
<span class="section-name-span">Click here to set the section name</span>
<span class="section-name-span">${_('Add a new section name')}</span>
<form class="section-name-form">
<input type="text" value="${_('New Section Name')}" class="new-section-name" />
<input type="submit" class="new-section-name-save" data-parent="${parent_locator}"
......@@ -88,10 +90,9 @@ require(["domReady!", "jquery", "js/models/location", "js/models/section", "js/v
</script>
<script type="text/template" id="new-subsection-template">
<li class="branch collapsed">
<li class="courseware-subsection collapsed is-draggable is-collapsible">
<div class="section-item editing">
<form class="new-subsection-form">
<span class="folder-icon"></span>
<span class="subsection-name">
<input type="text" value="${_('New Subsection')}" class="new-subsection-name-input" />
</span>
......@@ -102,12 +103,18 @@ require(["domReady!", "jquery", "js/models/location", "js/models/section", "js/v
<ol>
<li>
<a href="unit.html" class="new-unit-item">
<span class="new-unit-icon"></span>${_('New Unit')}
<i class="icon-plus"></i> ${_('New Unit')}
</a>
</li>
</ol>
</li>
</script>
<script type="text/template" id="no-outline-content">
<div class="no-outline-content">
<p>${_("You haven't added any sections to your course outline yet.")} <a href="#" class="button new-button"><i class="icon-plus"></i>${_("Add your first section")}</a></p>
</div>
</script>
</%block>
<%block name="content">
......@@ -135,8 +142,9 @@ require(["domReady!", "jquery", "js/models/location", "js/models/section", "js/v
</header>
</div>
<div class="main-wrapper">
<div class="inner-wrapper">
<div class="wrapper-content wrapper">
<section class="content">
<article class="content-primary" role="main">
<div class="wrapper-dnd">
<%
......@@ -151,15 +159,21 @@ require(["domReady!", "jquery", "js/models/location", "js/models/section", "js/v
context_course.location.course_id, section.location, False, True
)
%>
<section class="courseware-section branch is-draggable" data-parent="${course_locator}"
<section class="courseware-section is-collapsible is-draggable" data-parent="${course_locator}"
data-locator="${section_locator}">
<%include file="widgets/_ui-dnd-indicator-before.html" />
<header>
<a href="#" data-tooltip="${_('Expand/collapse this section')}" class="expand-collapse-icon collapse"></a>
<header class="section">
<a href="#" data-tooltip="${_('Expand/collapse this section')}" class="action expand-collapse collapse"><i class="icon-caret-down ui-toggle-expansion"></i><span class="sr">${_('Expand/collapse this section')}</span></a>
<div class="item-details" data-locator="${section_locator}">
<h3 class="section-name" data-name="${section.display_name_with_default | h}"></h3>
</div>
<div class="item-actions">
<ul class="actions-list">
<li class="actions-item pubdate">
<div class="section-published-date">
<%
if section.start is not None:
......@@ -170,28 +184,26 @@ require(["domReady!", "jquery", "js/models/location", "js/models/section", "js/v
start_time_str = ''
%>
%if section.start is None:
<span class="published-status">${_("This section has not been released.")}</span>
<a href="#" class="schedule-button" data-date="" data-time="" data-locator="${section_locator}">${_("Schedule")}</a>
<span class="published-status">${_("This section is not scheduled for release")}</span>
<a href="#" class="edit-release-date action" data-date="" data-time="" data-locator="${section_locator}"><i class="icon-time"></i> <span class="sr">${_("Schedule")}</span></a>
%else:
<span class="published-status"><strong>${_("Will Release:")}</strong>
<span class="published-status"><strong>${_("Release date:")}</strong>
${date_utils.get_default_time_display(section.start)}</span>
<a href="#" class="edit-button" data-date="${start_date_str}"
data-time="${start_time_str}" data-locator="${section_locator}">${_("Edit")}</a>
<a href="#" class="edit-release-date action" data-date="${start_date_str}" data-time="${start_time_str}" data-locator="${section_locator}"><i class="icon-time"></i> <span class="sr">${_("Edit section release date")}</span></a>
%endif
</div>
</div>
<div class="item-actions">
<a href="#" data-tooltip="${_('Delete this section')}" class="delete-button delete-section-button"><span class="delete-icon"></span></a>
<span data-tooltip="${_('Drag to reorder')}" class="drag-handle section-drag-handle"></span>
</li>
<li class="actions-item delete">
<a href="#" data-tooltip="${_('Delete this section')}" class="action delete-section-button"><i class="icon-trash"></i> <span class="sr">${_('Delete section')}</span></a>
</li>
<li class="actions-item drag">
<span data-tooltip="${_('Drag to reorder')}" class="drag-handle section-drag-handle action"><span class="sr"> ${_("Drag to reorder section")}</span></span>
</li>
</ul>
</div>
</header>
<div class="subsection-list">
<div class="list-header">
<a href="#" class="new-subsection-item" data-category="${new_subsection_category}">
<span class="new-folder-icon"></span>${_("New Subsection")}
</a>
</div>
<ol class="sortable-subsection-list">
% for subsection in section.get_children():
<%
......@@ -199,26 +211,32 @@ require(["domReady!", "jquery", "js/models/location", "js/models/section", "js/v
context_course.location.course_id, subsection.location, False, True
)
%>
<li class="courseware-subsection branch collapsed id-holder is-draggable"
<li class="courseware-subsection collapsed id-holder is-draggable is-collapsible "
data-parent="${section_locator}" data-locator="${subsection_locator}">
<%include file="widgets/_ui-dnd-indicator-before.html" />
<div class="section-item">
<div class="details">
<a href="#" data-tooltip="${_('Expand/collapse this subsection')}" class="expand-collapse-icon expand"></a>
<a href="#" data-tooltip="${_('Expand/collapse this subsection')}" class="action expand-collapse expand"><i class="icon-caret-down ui-toggle-expansion"></i><span class="sr">${_('Expand/collapse this subsection')}</span></a>
<a href="${subsection_locator.url_reverse('subsection')}">
<span class="folder-icon"></span>
<span class="subsection-name"><span class="subsection-name-value">${subsection.display_name_with_default}</span></span>
</a>
</div>
<div class="gradable-status" data-initial-status="${subsection.format if subsection.format is not None else _('Not Graded')}">
</div>
<div class="item-actions">
<a href="#" data-tooltip="${_('Delete this subsection')}" class="delete-button delete-subsection-button"><span class="delete-icon"></span></a>
<span data-tooltip="${_('Drag to reorder')}" class="drag-handle subsection-drag-handle"></span>
<ul class="actions-list">
<li class="actions-item grades">
<div class="gradable-status" data-initial-status="${subsection.format if subsection.format is not None else _('Not Graded')}"></div>
</li>
<li class="actions-item delete">
<a href="#" data-tooltip="${_('Delete this subsection')}" class="action delete-subsection-button"><i class="icon-trash"></i> <span class="sr">${_("Delete subsection")}</span></a>
</li>
<li class="actions-item drag">
<span data-tooltip="${_('Drag to reorder')}" class="drag-handle subsection-drag-handle action"></span>
</li>
</ul>
</div>
</div>
${units.enum_units(subsection)}
......@@ -230,6 +248,13 @@ require(["domReady!", "jquery", "js/models/location", "js/models/section", "js/v
<%include file="widgets/_ui-dnd-indicator-initial.html" />
</li>
</ol>
<div class="list-header new-subsection">
<a href="#" class="new-subsection-item" data-category="${new_subsection_category}">
<i class="icon-plus"></i> ${_("New Subsection")}
</a>
</div>
</div>
<%include file="widgets/_ui-dnd-indicator-after.html" />
......@@ -237,28 +262,57 @@ require(["domReady!", "jquery", "js/models/location", "js/models/section", "js/v
% endfor
</article>
</div>
</article>
<aside class="content-supplementary" role="complimentary">
<div class="bit">
<h3 class="title-3">${_("What can I do on this page?")}</h3>
<p>${_("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.")}</p>
<p>${_("In addition, you can drag and drop sections, subsections, and units to reorganize your course.")}</p>
</div>
</aside>
</section>
</div>
<footer></footer>
<div class="edit-subsection-publish-settings showAsModal">
<div class="settings">
<h3>${_("Section Release Date")}</h3>
<div class="picker datepair">
<div class="field field-start-date">
<label for="">${_("Release Day")}</label>
<div
class="wrapper wrapper-dialog wrapper-dialog-edit-sectionrelease edit-section-publish-settings"
aria-describedby="dialog-edit-sectionrelease-description"
aria-labelledby="dialog-edit-sectionrelease-title"
aria-hidden=""
role="dialog">
<div class="dialog confirm">
<form class="edit-sectionrelease-dialog" action="#">
<div class="form-content">
<h2 class="title dialog-edit-sectionrelease-title">${_("Section Release Date")}</h2>
<p id="dialog-edit-sectionrelease-description" class="message">${_('On the date set below, this section - {name} - will be released to students. Any units marked private will only be visible to admins.').format(name='<strong class="section-name"></strong>')}</p>
<ul class="list-input picker datepair">
<li class="field field-start-date">
<label for="start_date">${_("Release Day")}</label>
<input class="start-date date" type="text" name="start_date" value="" placeholder="MM/DD/YYYY" class="date" size='15' autocomplete="off"/>
</div>
<div class="field field-start-time">
<label for="">${_("Release Time")} (<abbr title="${_("Coordinated Universal Time")}">UTC</abbr>)</label>
</li>
<li class="field field-start-time">
<label for="start_time">${_("Release Time")} (<abbr title="${_("Coordinated Universal Time")}">UTC</abbr>)</label>
<input class="start-time time" type="text" name="start_time" value="" placeholder="HH:MM" class="time" size='10' autocomplete="off"/>
</li>
</ul>
</div>
<div class="description">
<p>${_('On the date set above, this section - {name} - will be released to students. Any units marked private will only be visible to admins.').format(name='<strong class="section-name"></strong>')}</p>
</div>
<div class="actions">
<h3 class="sr">${_("Form Actions")}</h3>
<ul>
<li class="action-item">
<a href="#" class="button action-primary action-save">${_("Save")}</a>
</li>
<li class="action-item">
<a href="#" class="button action-secondary action-cancel">${_("Cancel")}</a>
</li>
</ul>
</div>
<a href="#" class="save-button">${_("Save")}</a><a href="#" class="cancel-button">${_("Cancel")}</a>
</form>
</div>
</div>
</%block>
......@@ -46,7 +46,7 @@ require(["domReady!", "jquery", "js/models/module_info", "coffee/src/views/unit"
</div>
<div class="main-column">
<article class="unit-body window">
<p class="unit-name-input"><label>${_("Display Name:")}</label><input type="text" value="${unit.display_name_with_default | h}" class="unit-display-name-input" /></p>
<p class="unit-name-input"><label for="unit-display-name-input">${_("Display Name:")}</label><input type="text" value="${unit.display_name_with_default | h}" id="unit-display-name-input" class="unit-display-name-input" /></p>
<ol class="components">
% for locator in components:
<li class="component" data-locator="${locator}"/>
......@@ -147,8 +147,8 @@ require(["domReady!", "jquery", "js/models/module_info", "coffee/src/views/unit"
<h4 class="header">${_("Unit Settings")}</h4>
<div class="window-contents">
<div class="row visibility">
<label class="inline-label">${_("Visibility:")}</label>
<select name="visibility-select" class='visibility-select'>
<label for="visibility-select" class="inline-label">${_("Visibility:")}</label>
<select name="visibility-select" id="visibility-select" class='visibility-select'>
<option value="public">${_("Public")}</option>
<option value="private">${_("Private")}</option>
</select>
......@@ -181,17 +181,19 @@ require(["domReady!", "jquery", "js/models/module_info", "coffee/src/views/unit"
<div class="window-contents">
<div class="row wrapper-unit-id">
<p class="unit-id">
<span class="label">${_("Unit Identifier:")}</span>
<input type="text" class="url value" value="${unit.location.name}" readonly />
<label for="unit-location-id-input">${_("Unit Identifier:")}</label>
<input type="text" class="url value" id="unit-location-id-input" value="${unit.location.name}" readonly />
</p>
</div>
<div class="unit-tree-location">
<ol>
<li>
<a href="${index_url}" class="section-item">${section.display_name_with_default}</a>
<li class="section">
<a href="${index_url}" class="section-item section-name">
<span class="section-name">${section.display_name_with_default}</span>
</a>
<ol>
<li>
<li class="subsection">
<a href="${subsection_url}" class="section-item">
<span class="folder-icon"></span>
<span class="subsection-name"><span class="subsection-name-value">${subsection.display_name_with_default}</span></span>
</a>
${units.enum_units(subsection, actions=False, selected=unit.location)}
......@@ -204,5 +206,6 @@ require(["domReady!", "jquery", "js/models/module_info", "coffee/src/views/unit"
</div>
</div>
</div>
</div>
</%block>
<%! 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)
%>
<li class="courseware-unit leaf unit is-draggable" data-locator="${unit_locator}"
<li class="courseware-unit unit is-draggable" data-locator="${unit_locator}"
data-parent="${subsection_locator}">
<%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
%>
<div class="section-item ${selected_class}">
<a href="${unit_locator.url_reverse('unit')}" class="${unit_state}-item">
<span class="${unit.scope_ids.block_type}-icon"></span>
<span class="unit-name">${unit.display_name_with_default}</span>
</a>
% if actions:
<div class="item-actions">
<a href="#" data-tooltip="Delete this unit" class="delete-button" data-locator="${unit_locator}">
<span class="delete-icon"></span></a>
<span data-tooltip="Drag to sort" class="drag-handle unit-drag-handle"></span>
<ul class="actions-list">
<li class="actions-item delete">
<a href="#" data-tooltip="${_("Delete this unit")}" class="delete-unit-button action" data-locator="${unit_locator}"><i class="icon-trash"></i><span class="sr">${_("Delete unit")}</span></a>
</li>
<li class="actions-item drag">
<span data-tooltip="${_("Drag to sort")}" class="drag-handle unit-drag-handle action"><span class="sr"> ${_("Drag to reorder unit")}</span></span>
</li>
</ul>
</div>
% endif
</div>
......@@ -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" />
</li>
% endfor
<li>
<li class="courseware-unit add-new-unit">
<%include file="_ui-dnd-indicator-initial.html" />
<a href="#" class="new-unit-item" data-category="${new_unit_category}" data-parent="${subsection_locator}">
<span class="new-unit-icon"></span>New Unit
<i class="icon-plus"></i> ${_("New Unit")}
</a>
</li>
</ol>
......
......@@ -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;
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment