Commit 8d0e469c by Tim Babych Committed by cahrens

Remove code and template responsible for subsection edit page

parent 819c9468
......@@ -1289,11 +1289,6 @@ class ContentStoreTest(ContentStoreTestCase):
test_get_html('advanced_settings_handler')
test_get_html('textbooks_list_handler')
# go look at a subsection page
subsection_key = course_key.make_usage_key('sequential', 'test_sequence')
resp = self.client.get_html(get_url('subsection_handler', subsection_key))
self.assertEqual(resp.status_code, 200)
# go look at the Edit page
unit_key = course_key.make_usage_key('vertical', 'test_vertical')
resp = self.client.get_html(get_url('container_handler', unit_key))
......
......@@ -17,7 +17,6 @@ from xmodule.modulestore.django import modulestore
from xblock.core import XBlock
from xblock.django.request import webob_to_django_response, django_to_webob_request
from xblock.exceptions import NoSuchHandlerError
from xblock.fields import Scope
from xblock.plugin import PluginMissingError
from xblock.runtime import Mixologist
......@@ -25,7 +24,6 @@ from contentstore.utils import get_lms_link_for_item
from contentstore.views.helpers import get_parent_xblock, is_unit, xblock_type_display_name
from contentstore.views.item import create_xblock_info
from models.settings.course_grading import CourseGradingModel
from opaque_keys.edx.keys import UsageKey
from .access import has_course_access
......@@ -33,7 +31,6 @@ from django.utils.translation import ugettext as _
__all__ = ['OPEN_ENDED_COMPONENT_TYPES',
'ADVANCED_COMPONENT_POLICY_KEY',
'subsection_handler',
'container_handler',
'component_handler'
]
......
define ["js/views/overview", "js/views/feedback_notification", "js/spec_helpers/create_sinon", "js/base", "date", "jquery.timepicker"],
(Overview, Notification, create_sinon) ->
describe "Course Overview", ->
beforeEach ->
appendSetFixtures """
<div class="section-published-date">
<span class="published-status">
<strong>Release date:</strong> 06/12/2013 at 04:00 UTC
</span>
<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="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"/>
</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="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 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="#" data-tooltip="Delete this section" class="delete-section-button"><i class="icon-trash"></i> <span class="sr">Delete section</span></a>
</li>
</section>
"""
spyOn(Overview, 'saveSetSectionScheduleDate').andCallThrough()
# Have to do this here, as it normally gets bound in document.ready()
$('a.action-save').click(Overview.saveSetSectionScheduleDate)
$('a.delete-section-button').click(deleteSection)
$(".edit-subsection-publish-settings .start-date").datepicker()
@notificationSpy = spyOn(Notification.Mini.prototype, 'show').andCallThrough()
window.analytics = jasmine.createSpyObj('analytics', ['track'])
window.course_location_analytics = jasmine.createSpy()
afterEach ->
delete window.analytics
delete window.course_location_analytics
@notificationSpy.reset()
it "should save model when save is clicked", ->
$('a.edit-release-date').click()
$('a.action-save').click()
expect(Overview.saveSetSectionScheduleDate).toHaveBeenCalled()
it "should show a confirmation on save", ->
$('a.edit-release-date').click()
$('a.action-save').click()
expect(@notificationSpy).toHaveBeenCalled()
# Fails sporadically in Jenkins.
# it "should delete model when delete is clicked", ->
# $('a.delete-section-button').click()
# $('a.action-primary').click()
# expect(@requests[0].url).toEqual('/delete_item')
it "should not delete model when cancel is clicked", ->
requests = create_sinon["requests"](this)
$('a.delete-section-button').click()
$('a.action-secondary').click()
expect(requests.length).toEqual(0)
# Fails sporadically in Jenkins.
# it "should show a confirmation on delete", ->
# $('a.delete-section-button').click()
# $('a.action-primary').click()
# expect(@notificationSpy).toHaveBeenCalled()
require(["domReady", "jquery", "underscore", "gettext", "js/views/feedback_notification", "js/views/feedback_prompt",
"js/utils/date_utils", "js/utils/module", "js/utils/handle_iframe_binding", "js/utils/change_on_enter", "jquery.ui",
"jquery.leanModal", "jquery.form", "jquery.smoothScroll"],
function(domReady, $, _, gettext, NotificationView, PromptView, DateUtils, ModuleUtils, IframeUtils, TriggerChangeEventOnEnter)
"js/utils/date_utils", "js/utils/module", "js/utils/handle_iframe_binding",
"jquery.ui", "jquery.leanModal", "jquery.form", "jquery.smoothScroll"],
function(domReady, $, _, gettext, NotificationView, PromptView, DateUtils, ModuleUtils, IframeUtils)
{
var $body;
var $newComponentItem;
var $changedInput;
var $spinner;
var $newComponentTypePicker;
var $newComponentTemplatePickers;
var $newComponentButton;
domReady(function() {
$body = $('body');
$newComponentItem = $('.new-component-item');
$newComponentTypePicker = $('.new-component');
$newComponentTemplatePickers = $('.new-component-templates');
$newComponentButton = $('.new-component-button');
$spinner = $('<span class="spinner-in-field-icon"></span>');
$body.on('click', '.embeddable-xml-input', function() {
$(this).select();
});
$('body').addClass('js');
$('.unit .item-actions .delete-unit-button').bind('click', deleteUnit);
$('.new-unit-item').bind('click', createNewUnit);
$body.addClass('js');
// lean/simple modal
$('a[rel*=modal]').leanModal({
......@@ -69,7 +54,10 @@ domReady(function() {
});
// general link management - new window/tab
$('a[rel="external"]').attr('title', gettext('This link will open in a new browser window/tab')).bind('click', linkNewWindow);
$('a[rel="external"]').attr({
title: gettext('This link will open in a new browser window/tab'),
target: '_blank'
});
// general link management - lean modal window
$('a[rel="modal"]').attr('title', gettext('This link will open in a modal window')).leanModal({
......@@ -86,36 +74,6 @@ domReady(function() {
// tender feedback window scrolling
$('a.show-tender').bind('click', smoothScrollTop);
// autosave when leaving input field
$body.on('change', '.subsection-display-name-input', saveSubsection);
$('.subsection-display-name-input').each(function() {
this.val = $(this).val();
});
$("#start_date, #start_time, #due_date, #due_time").change(autosaveInput).keyup(TriggerChangeEventOnEnter)
$('.sync-date, .remove-date').bind('click', autosaveInput);
// expand/collapse methods for optional date setters
$('.set-date').bind('click', showDateSetter);
$('.remove-date').bind('click', removeDateSetter);
$('.delete-section-button').bind('click', deleteSection);
$('.delete-subsection-button').bind('click', deleteSubsection);
$('.sync-date').bind('click', syncReleaseDate);
// section date setting
$('.set-publish-date').bind('click', setSectionScheduleDate);
$('.edit-section-start-cancel').bind('click', cancelSetSectionScheduleDate);
$body.on('change', '.edit-subsection-publish-settings .start-date', function() {
if ($('.edit-subsection-publish-settings').find('.start-time').val() == '') {
$('.edit-subsection-publish-settings').find('.start-time').val('12:00am');
}
});
$('.edit-subsection-publish-settings').on('change', '.start-date, .start-time', function() {
$('.edit-subsection-publish-settings').find('.save-button').show();
});
IframeUtils.iframeBinding();
});
......@@ -143,183 +101,6 @@ function smoothScrollTop(e) {
});
}
function linkNewWindow(e) {
window.open($(e.target).attr('href'));
e.preventDefault();
}
function syncReleaseDate(e) {
e.preventDefault();
$(this).closest('.notice').hide();
$("#start_date").val("");
$("#start_time").val("");
}
function autosaveInput(e) {
var self = this;
if (this.saveTimer) {
clearTimeout(this.saveTimer);
}
this.saveTimer = setTimeout(function() {
$changedInput = $(e.target);
saveSubsection();
self.saveTimer = null;
}, 500);
}
function saveSubsection() {
// Spinner is no longer used by subsection name, but is still used by date and time pickers on the right.
if ($changedInput && !$changedInput.hasClass('no-spinner')) {
$spinner.css({
'position': 'absolute',
'top': Math.floor($changedInput.position().top + ($changedInput.outerHeight() / 2) + 3),
'left': $changedInput.position().left + $changedInput.outerWidth() - 24,
'margin-top': '-10px'
});
$changedInput.after($spinner);
$spinner.show();
}
var locator = $('.subsection-body').data('locator');
// pull all 'normalized' metadata editable fields on page
var metadata_fields = $('input[data-metadata-name]');
var metadata = {};
for (var i = 0; i < metadata_fields.length; i++) {
var el = metadata_fields[i];
metadata[$(el).data("metadata-name")] = el.value;
}
// get datetimes for start and due, stick into metadata
_(["start", "due"]).each(function(name) {
var datetime = DateUtils.getDate(
document.getElementById(name+"_date"),
document.getElementById(name+"_time")
);
// if datetime is null, we want to set that in metadata anyway;
// its an indication to the server to clear the datetime in the DB
metadata[name] = datetime;
});
$.ajax({
url: ModuleUtils.getUpdateUrl(locator),
type: "PUT",
dataType: "json",
contentType: "application/json",
data: JSON.stringify({
'metadata': metadata
}),
success: function() {
$spinner.delay(500).fadeOut(150);
$changedInput = null;
}
});
}
function createNewUnit(e) {
e.preventDefault();
var parent = $(this).data('parent');
var category = $(this).data('category');
analytics.track('Created a Unit', {
'course': course_location_analytics,
'parent_locator': parent
});
$.postJSON(ModuleUtils.getUpdateUrl(), {
'parent_locator': parent,
'category': category,
'display_name': 'New Unit'
},
function(data) {
// redirect to the edit page
window.location = "/container/" + data['locator'];
});
}
function deleteUnit(e) {
e.preventDefault();
_deleteItem($(this).parents('li.courseware-unit'), 'Unit');
}
function deleteSubsection(e) {
e.preventDefault();
_deleteItem($(this).parents('li.courseware-subsection'), 'Subsection');
}
function deleteSection(e) {
e.preventDefault();
_deleteItem($(this).parents('section.courseware-section'), 'Section');
}
function _deleteItem($el, type) {
var confirm = new PromptView.Warning({
title: gettext('Delete this ' + type + '?'),
message: gettext('Deleting this ' + type + ' is permanent and cannot be undone.'),
actions: {
primary: {
text: gettext('Yes, delete this ' + type),
click: function(view) {
view.hide();
var locator = $el.data('locator');
analytics.track('Deleted an Item', {
'course': course_location_analytics,
'id': locator
});
var deleting = new NotificationView.Mini({
title: gettext('Deleting&hellip;')
});
deleting.show();
$.ajax({
type: 'DELETE',
url: ModuleUtils.getUpdateUrl(locator),
success: function () {
$el.remove();
deleting.hide();
}
});
}
},
secondary: {
text: gettext('Cancel'),
click: function(view) {
view.hide();
}
}
}
});
confirm.show();
}
function showDateSetter(e) {
e.preventDefault();
var $block = $(this).closest('.due-date-input');
$(this).hide();
$block.find('.date-setter').show();
}
function removeDateSetter(e) {
e.preventDefault();
var $block = $(this).closest('.due-date-input');
$block.find('.date-setter').hide();
$block.find('.set-date').show();
// clear out the values
$block.find('.date').val('');
$block.find('.time').val('');
}
function hideNotification(e) {
(e).preventDefault();
$(this).closest('.wrapper-notification').removeClass('is-shown').addClass('is-hiding').attr('aria-hidden', 'true');
......@@ -330,18 +111,4 @@ function hideAlert(e) {
$(this).closest('.wrapper-alert').removeClass('is-shown');
}
function setSectionScheduleDate(e) {
e.preventDefault();
$(this).closest("h4").hide();
$(this).parent().siblings(".datepair").show();
}
function cancelSetSectionScheduleDate(e) {
e.preventDefault();
$(this).closest(".datepair").hide();
$(this).parent().siblings("h4").show();
}
window.deleteSection = deleteSection;
}); // end require()
......@@ -42,7 +42,6 @@
@import 'views/outline';
@import 'views/settings';
@import 'views/static-pages';
@import 'views/subsection';
@import 'views/unit';
@import 'views/container';
@import 'views/users';
......
// studio - views - course subsection
// ====================
.view-subsection {
.main-wrapper {
margin-top: ($baseline*2);
}
.unit-settings {
.window-contents {
padding: 10px 20px;
}
.datepair {
.field {
display: inline-block;
margin-right: ($baseline/4);
width: 45%;
&:last-child {
margin-right: 0;
}
label, input {
display: block;
text-align: left;
}
input {
width: 100%;
}
label {
@extend %t-title8;
margin-bottom: ($baseline/4);
}
}
}
.unit-actions {
border-bottom: none;
padding-bottom: 0;
}
.published-alert {
display: none;
padding: 10px;
border: 1px solid #edbd3c;
border-radius: 3px;
background: #fbf6e1;
font-size: 14px;
line-height: 1.4;
div {
margin-top: 15px;
}
}
input[type="radio"] {
margin-right: 7px;
}
.status {
font-size: 12px;
strong {
font-weight: 700;
}
}
.preview-button, .view-button {
@include white-button;
margin-bottom: 10px;
}
.publish-button {
@include orange-button;
}
.delete-button {
@include blue-button;
}
.delete-draft {
display: inline-block;
}
.delete-button,
.preview-button,
.publish-button,
.view-button {
font-size: 11px;
margin-top: 10px;
padding: 6px 15px 8px;
}
}
.unit-history {
&.collapsed {
h4 {
border-bottom: none;
border-radius: 3px;
}
.window-contents {
display: none;
}
}
ol {
border: 1px solid #ced2db;
li {
display: block;
padding: 6px 8px 8px 10px;
background: #edf1f5;
font-size: 12px;
&:hover {
background: #fffcf1;
.item-actions {
display: block;
}
}
&.checked {
background: #d1dae3;
}
.item-actions {
display: none;
}
input[type="radio"] {
margin-right: 7px;
}
}
}
}
.unit-location {
.url {
width: 100%;
margin-bottom: 10px;
box-shadow: none;
}
.draft-tag,
.hidden-tag,
.private-tag,
.has-new-draft-tag {
font-size: 8px;
}
.window-contents > ol {
@include tree-view;
.section-item {
display: inline-block;
width: 100%;
font-size: 11px;
padding: 2px 8px 4px;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
@include box-sizing(border-box);
}
ol {
.section-item {
padding-left: 20px;
}
.new-unit-item {
margin-left: 20px;
}
}
ol ol {
.section-item {
padding-left: 34px;
}
.new-unit-item {
margin: 0 0 10px 41px;
}
}
}
}
.subsection-body {
padding: 32px 40px;
@include clearfix;
> div {
margin-bottom: 40px;
}
input {
font-size: 14px;
}
}
.subsection-name-input {
label {
display: block;
}
input {
width: 100%;
font-size: 20px;
}
}
.scheduled-date-input,
.due-date-input {
@include clearfix;
.date-input,
.time-input {
display: inline-block;
width: 100px;
}
.inherits-check {
label {
font-size: 13px;
}
}
.notice {
@extend %t-copy-sub2;
margin-top: 6px;
color: #999;
}
}
.due-date-input {
label {
display: inline-block !important;
margin-right: 10px;
}
a {
font-size: 11px;
font-weight: bold;
text-transform: uppercase;
}
.date-setter {
@include clearfix;
display: none;
}
.remove-date {
display: block;
margin-top: ($baseline/4);
}
}
.row.visibility {
label {
display: inline-block !important;
margin-right: 10px;
line-height: 21px;
}
a {
display: inline-block;
height: 31px;
margin-right: 8px;
vertical-align: middle;
font-size: 11px;
font-weight: 700;
line-height: 31px;
text-transform: uppercase;
}
.large-toggle {
width: 41px;
background: url(../img/large-toggles.png) no-repeat;
background-position: 0 -50px;
.hidden {
background-position: 0 -5px;
}
}
}
.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;
}
.gradable-status {
position: relative;
top: -4px;
display: inline-block;
margin-left: 10px;
width: 65%;
.status-label {
margin: 0;
padding: 0;
background: transparent;
color: $blue;
border: none;
font-size: 11px;
font-weight: bold;
text-transform: uppercase;
}
.menu-toggle {
z-index: 100;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 20px;
background: transparent;
&:hover, &.is-active {
color: $blue;
}
}
.menu {
@include transition(opacity $tmg-f2 linear 0s);
z-index: 1;
position: absolute;
top: -12px;
left: -7px;
display: none;
width: 100%;
margin: 0;
padding: 8px 12px;
opacity: 0.0;
background: $white;
border: 1px solid $mediumGrey;
font-size: 12px;
border-radius: 4px;
box-shadow: 0 1px 2px rgba(0, 0, 0, .2);
li {
margin-bottom: 3px;
padding-bottom: 3px;
border-bottom: 1px solid $lightGrey;
&:last-child {
margin-bottom: 0;
padding-bottom: 0;
border: none;
}
}
a {
&.is-selected {
font-weight: bold;
}
}
}
// dropdown state
&.is-active {
.menu {
z-index: 10000;
display: block;
opacity: 1.0;
}
.menu-toggle {
z-index: 1000;
}
}
// set state
&.is-set {
.menu-toggle {
color: $blue;
}
.status-label {
display: block;
color: $blue;
}
}
}
}
// UI: DnD - specific elems/cases - units
.courseware-unit {
.draggable-drop-indicator-before {
top: 0;
}
.draggable-drop-indicator-after {
bottom: 0;
}
}
// UI: DnD - specific elems/cases - empty parents initial drop indicator
.draggable-drop-indicator-initial {
display: none;
}
}
......@@ -17,7 +17,6 @@ from django.utils.translation import ugettext as _
<%block name="bodyclass">is-signedin course container view-container</%block>
<%namespace name='static' file='static_content.html'/>
<%namespace name="units" file="widgets/units.html" />
<%!
templates = ["basic-modal", "modal-button", "edit-xblock-modal",
......
<%inherit file="base.html" />
<%def name="online_help_token()"><% return "subsection" %></%def>
<%!
import logging
from util.date_utils import get_default_time_display, almost_same_datetime
from django.utils.translation import ugettext as _
from django.core.urlresolvers import reverse
%>
<%block name="title">${_("CMS Subsection")}</%block>
<%block name="bodyclass">is-signedin course view-subsection</%block>
<%namespace name="units" file="widgets/units.html" />
<%namespace name='static' file='static_content.html'/>
<%block name="content">
<div class="main-wrapper">
<div class="inner-wrapper">
<div class="main-column">
<article class="subsection-body window" data-locator="${locator}" data-course-key="${locator.course_key}">
<div class="subsection-name-input">
<label>${_("Display Name:")}</label>
<input type="text" value="${subsection.display_name_with_default | h}" class="subsection-display-name-input" data-metadata-name="display_name"/>
</div>
<div class="wrapper-dnd">
<div class="sortable-unit-list">
<label>${_("Units:")}</label>
${units.enum_units(subsection, subsection_units=subsection_units)}
</div>
</div>
</article>
</div>
<div class="sidebar">
<div class="unit-settings window id-holder" data-locator="${locator}" data-course-key="${locator.course_key}">
<h4 class="header">${_("Subsection Settings")}</h4>
<div class="window-contents">
<div class="scheduled-date-input row">
<div class="datepair" data-language="javascript">
<div class="field field-start-date">
<label for="start_date">${_("Release Day")}</label>
<input type="text" id="start_date" name="start_date"
value="${subsection.start.strftime('%m/%d/%Y') if subsection.start else ''}"
placeholder="MM/DD/YYYY" class="date" size='15' autocomplete="off"/>
</div>
<div class="field field-start-time">
<label for="start_time">${_("Release Time")} (<abbr title="${_("Coordinated Universal Time")}">${_("UTC")}</abbr>)</label>
<input type="text" id="start_time" name="start_time"
value="${subsection.start.strftime('%H:%M') if subsection.start else ''}"
placeholder="HH:MM" class="time" size='10' autocomplete="off"/>
</div>
</div>
% if subsection.start and not almost_same_datetime(subsection.start, parent_item.start):
% if parent_item.start is None:
<p class="notice">${_("The date above differs from the release date of {name}, which is unset.").format(name=parent_item.display_name_with_default)}
% else:
<p class="notice">${_("The date above differs from the release date of {name} - {start_time}").format(name=parent_item.display_name_with_default, start_time=get_default_time_display(parent_item.start))}.
% endif
<a href="#" class="sync-date no-spinner">${_("Sync to {name}.").format(name=parent_item.display_name_with_default)}</a></p>
% endif
</div>
<div class="row gradable">
<label>${_("Graded as:")}</label>
<div class="gradable-status" data-initial-status="${subsection.format if subsection.format is not None else 'notgraded'}">
</div>
<div class="due-date-input row">
<a href="#" class="set-date">${_("Set a due date")}</a>
<div class="datepair date-setter">
<div class="field field-start-date">
<label for="due_date">${_("Due Day")}</label>
<input type="text" id="due_date" name="due_date"
value="${subsection.due.strftime('%m/%d/%Y') if subsection.due else ''}"
placeholder="MM/DD/YYYY" class="date" size='15' autocomplete="off"/>
</div>
<div class="field field-start-time">
<label for="due_time">${_("Due Time")} (<abbr title="${_('Coordinated Universal Time')}">UTC</abbr>)</label>
<input type="text" id="due_time" name="due_time"
value="${subsection.due.strftime('%H:%M') if subsection.due else ''}"
placeholder="HH:MM" class="time" size='10' autocomplete="off"/>
</div>
<a href="#" class="remove-date">${_("Remove due date")}</a>
</div>
</div>
<div class="row unit-actions">
<a href="${preview_link}" target="_blank" class="preview-button">${_("Preview Drafts")}</a>
%if can_view_live:
<a href="${lms_link}" target="_blank" class="preview-button">${_("View Live")}</a>
%endif
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</%block>
<%block name="jsextra">
<link rel="stylesheet" type="text/css" href="${static.url('js/vendor/timepicker/jquery.timepicker.css')}" />
<script type="text/javascript">
require(["domReady!", "jquery", "js/models/location", "js/views/overview_assignment_grader",
"js/collections/course_grader", "js/views/overview"],
function(doc, $, Location, OverviewAssignmentGrader, CourseGraderCollection) {
// expand the due-date area if the values are set
if ($('#due_date').val() != '') {
var $block = $('.set-date').closest('.due-date-input');
$('.set-date').hide();
$block.find('.date-setter').show();
}
// TODO figure out whether these should be in window or someplace else or whether they're only needed as local vars
// I believe that current (New Section/New Subsection) cause full page reloads which means these aren't needed globally
// but we really should change that behavior.
if (!window.graderTypes) {
window.graderTypes = new CourseGraderCollection(${course_graders|n}, {parse:true});
}
$(".gradable-status").each(function(index, ele) {
var gradeView = new OverviewAssignmentGrader({
el : ele,
graders : window.graderTypes,
hideSymbol : true
});
});
});
</script>
</%block>
......@@ -11,7 +11,6 @@
<%block name="bodyclass">is-signedin course uploads view-container</%block>
<%namespace name='static' file='../../static_content.html'/>
<%namespace name="units" file="../../widgets/units.html" />
<%block name="content">
<div id="content">
......
<%! from django.utils.translation import ugettext as _ %>
<%! from contentstore.views.helpers import xblock_studio_url %>
<!--
This def will enumerate through a passed in subsection and list all of the units
-->
<%def name="enum_units(subsection, actions=True, selected=None, sortable=True, subsection_units=None)">
<ol ${'class="sortable-unit-list"' if sortable else ''}>
<%
if subsection_units is None:
subsection_units = subsection.get_children()
%>
% for unit in subsection_units:
<li class="courseware-unit unit is-draggable" data-locator="${unit.location}"
data-parent="${subsection.location}" data-course-key="${unit.location.course_key}">
<%include file="_ui-dnd-indicator-before.html" />
<%
unit_state = 'draft' # Note: this is a hack since this HTML file is being removed in bulk-publishing
if unit.location == selected:
selected_class = 'editing'
else:
selected_class = ''
%>
<div class="section-item ${selected_class}">
<a href="${xblock_studio_url(unit)}" class="${unit_state}-item">
<span class="unit-name">${unit.display_name_with_default}</span>
</a>
% if actions:
<div class="item-actions">
<ul class="actions-list">
<li class="actions-item delete">
<a href="#" data-tooltip="${_("Delete this unit")}" class="delete-unit-button action" data-locator="${unit.location}"><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"><span class="sr"> ${_("Drag to reorder unit")}</span></span>
</li>
</ul>
</div>
% endif
</div>
<%include file="_ui-dnd-indicator-after.html" />
</li>
% endfor
<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.location}">
<i class="icon-plus"></i> ${_("New Unit")}
</a>
</li>
</ol>
</%def>
......@@ -74,7 +74,6 @@ urlpatterns += patterns(
),
url(r'^course/{}?$'.format(settings.COURSE_KEY_PATTERN), 'course_handler', name='course_handler'),
url(r'^course_notifications/{}/(?P<action_state_id>\d+)?$'.format(settings.COURSE_KEY_PATTERN), 'course_notifications_handler'),
url(r'^subsection/{}$'.format(settings.USAGE_KEY_PATTERN), 'subsection_handler'),
url(r'^container/{}$'.format(settings.USAGE_KEY_PATTERN), 'container_handler'),
url(r'^checklists/{}/(?P<checklist_index>\d+)?$'.format(settings.COURSE_KEY_PATTERN), 'checklists_handler'),
url(r'^orphan/{}$'.format(settings.COURSE_KEY_PATTERN), 'orphan_handler'),
......
......@@ -46,7 +46,7 @@ REQUIREJS_WAIT = {
# Note that calling your org, course number, or display name, 'course' will mess this up
re.compile('^Course Outline \|'): [
"js/base", "js/models/course", "js/models/location", "js/models/section",
"js/views/overview", "js/views/section_edit"],
"js/views/section_edit"],
# Dashboard
re.compile('^My Courses \|'): [
......
......@@ -258,11 +258,6 @@ function objectTagForFlashCamera(name) {
}
}
function linkNewWindow(e) {
window.open($(e.target).attr('href'));
e.preventDefault();
}
function waitForFlashLoad(func, flash_object) {
if(!flash_object.hasOwnProperty('percentLoaded') || flash_object.percentLoaded() < 100){
setTimeout(function() {
......@@ -334,6 +329,9 @@ $(document).ready(function() {
analytics.pageview("Capture Face Photo");
initSnapshotHandler(["photo_id", "face"], hasHtml5CameraSupport);
$('a[rel="external"]').attr('title', gettext('This link will open in a new browser window/tab')).bind('click', linkNewWindow);
$('a[rel="external"]').attr({
title: gettext('This link will open in a new browser window/tab'),
target: '_blank'
});
});
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