Merge branch 'master' of github.com:edx/mitx into feature/cdodge/autoprovision-forums-master

This commit is contained in:
Chris Dodge
2013-05-10 10:01:53 -04:00
39 changed files with 443 additions and 275 deletions

View File

@@ -1,4 +1,5 @@
from xmodule.templates import update_templates
from xmodule.modulestore.django import modulestore
from django.core.management.base import BaseCommand
@@ -6,4 +7,4 @@ class Command(BaseCommand):
help = 'Imports and updates the Studio component templates from the code pack and put in the DB'
def handle(self, *args, **options):
update_templates()
update_templates(modulestore('direct'))

View File

@@ -947,7 +947,7 @@ class TemplateTestCase(ModuleStoreTestCase):
self.assertIsNotNone(verify_create)
# now run cleanup
update_templates()
update_templates(modulestore('direct'))
# now try to find dangling template, it should not be in DB any longer
asserted = False

View File

@@ -895,4 +895,4 @@ function saveSetSectionScheduleDate(e) {
hideModal();
});
}
}

View File

@@ -2,13 +2,13 @@
* Create a HesitateEvent and assign it as the event to execute:
* $(el).on('mouseEnter', CMS.HesitateEvent( expand, 'mouseLeave').trigger);
* It calls the executeOnTimeOut function with the event.currentTarget after the configurable timeout IFF the cancelSelector event
* did not occur on the event.currentTarget.
*
* More specifically, when trigger is called (triggered by the event you bound it to), it starts a timer
* did not occur on the event.currentTarget.
*
* More specifically, when trigger is called (triggered by the event you bound it to), it starts a timer
* which the cancelSelector event will cancel or if the timer finished, it executes the executeOnTimeOut function
* passing it the original event (whose currentTarget s/b the specific ele). It never accumulates events; however, it doesn't hurt for your
* code to minimize invocations of trigger by binding to mouseEnter v mouseOver and such.
*
*
* NOTE: if something outside of this wants to cancel the event, invoke cachedhesitation.untrigger(null | anything);
*/
@@ -25,7 +25,7 @@ CMS.HesitateEvent.DURATION = 800;
CMS.HesitateEvent.prototype.trigger = function(event) {
if (event.data.timeoutEventId == null) {
event.data.timeoutEventId = window.setTimeout(
function() { event.data.fireEvent(event); },
function() { event.data.fireEvent(event); },
CMS.HesitateEvent.DURATION);
event.data.originalEvent = event;
$(event.data.originalEvent.delegateTarget).on(event.data.cancelSelector, event.data, event.data.untrigger);
@@ -45,4 +45,4 @@ CMS.HesitateEvent.prototype.untrigger = function(event) {
$(event.data.originalEvent.delegateTarget).off(event.data.cancelSelector, event.data.untrigger);
}
event.data.timeoutEventId = null;
};
};

View File

@@ -80,6 +80,6 @@ $(document).ready(function(){
$('section.problem-edit').show();
return false;
});
});

View File

@@ -1,17 +1,17 @@
// single per course holds the updates and handouts
// single per course holds the updates and handouts
CMS.Models.CourseInfo = Backbone.Model.extend({
// This model class is not suited for restful operations and is considered just a server side initialized container
url: '',
defaults: {
"courseId": "", // the location url
"updates" : null, // UpdateCollection
"handouts": null // HandoutCollection
},
idAttribute : "courseId"
});
// course update -- biggest kludge here is the lack of a real id to map updates to originals
CMS.Models.CourseUpdate = Backbone.Model.extend({
defaults: {
@@ -26,11 +26,11 @@ CMS.Models.CourseUpdate = Backbone.Model.extend({
*/
CMS.Models.CourseUpdateCollection = Backbone.Collection.extend({
url : function() {return this.urlbase + "course_info/updates/";},
model : CMS.Models.CourseUpdate
});

View File

@@ -16,7 +16,7 @@ CMS.Models.Location = Backbone.Model.extend({
},
_tagPattern : /[^:]+/g,
_fieldPattern : new RegExp('[^/]+','g'),
parse: function(payload) {
if (_.isArray(payload)) {
return {
@@ -25,7 +25,7 @@ CMS.Models.Location = Backbone.Model.extend({
course: payload[2],
category: payload[3],
name: payload[4]
}
};
}
else if (_.isString(payload)) {
this._tagPattern.lastIndex = 0; // odd regex behavior requires this to be reset sometimes
@@ -65,4 +65,4 @@ CMS.Models.CourseRelative = Backbone.Model.extend({
CMS.Models.CourseRelativeCollection = Backbone.Collection.extend({
model : CMS.Models.CourseRelative
});
});

View File

@@ -6,5 +6,5 @@ CMS.Models.ModuleInfo = Backbone.Model.extend({
"data": null,
"metadata" : null,
"children" : null
},
});
}
});

View File

@@ -11,7 +11,7 @@ CMS.Models.Settings.Advanced = Backbone.Model.extend({
validate: function (attrs) {
// Keys can no longer be edited. We are currently not validating values.
},
save : function (attrs, options) {
// wraps the save call w/ the deletion of the removed keys after we know the saved ones worked
options = options ? _.clone(options) : {};
@@ -23,7 +23,7 @@ CMS.Models.Settings.Advanced = Backbone.Model.extend({
};
Backbone.Model.prototype.save.call(this, attrs, options);
},
afterSave : function(self) {
// remove deleted attrs
if (!_.isEmpty(self.deleteKeys)) {

View File

@@ -66,7 +66,7 @@ CMS.Models.Settings.CourseDetails = Backbone.Model.extend({
save_videosource: function(newsource) {
// newsource either is <video youtube="speed:key, *"/> or just the "speed:key, *" string
// returns the videosource for the preview which iss the key whose speed is closest to 1
if (_.isEmpty(newsource) && !_.isEmpty(this.get('intro_video'))) this.save({'intro_video': null});
if (_.isEmpty(newsource) && !_.isEmpty(this.get('intro_video'))) this.save({'intro_video': null});
// TODO remove all whitespace w/in string
else {
if (this.get('intro_video') !== newsource) this.save('intro_video', newsource);

View File

@@ -1,9 +1,9 @@
if (!CMS.Models['Settings']) CMS.Models.Settings = new Object();
CMS.Models.Settings.CourseGradingPolicy = Backbone.Model.extend({
defaults : {
defaults : {
course_location : null,
graders : null, // CourseGraderCollection
graders : null, // CourseGraderCollection
grade_cutoffs : null, // CourseGradeCutoff model
grace_period : null // either null or { hours: n, minutes: m, ...}
},
@@ -54,7 +54,7 @@ CMS.Models.Settings.CourseGrader = Backbone.Model.extend({
"type" : "", // must be unique w/in collection (ie. w/in course)
"min_count" : 1,
"drop_count" : 0,
"short_label" : "", // what to use in place of type if space is an issue
"short_label" : "", // what to use in place of type if space is an issue
"weight" : 0 // int 0..100
},
parse : function(attrs) {
@@ -125,4 +125,4 @@ CMS.Models.Settings.CourseGraderCollection = Backbone.Collection.extend({
sumWeights : function() {
return this.reduce(function(subtotal, grader) { return subtotal + grader.get('weight'); }, 0);
}
});
});

View File

@@ -93,4 +93,4 @@ CMS.Views.Checklists = Backbone.View.extend({
error : CMS.ServerError
});
}
});
});

View File

@@ -32,7 +32,7 @@ CMS.Views.ClassInfoUpdateView = Backbone.View.extend({
"click .post-actions > .edit-button" : "onEdit",
"click .post-actions > .delete-button" : "onDelete"
},
initialize: function() {
var self = this;
// instantiates an editor template for each update in the collection
@@ -41,13 +41,13 @@ CMS.Views.ClassInfoUpdateView = Backbone.View.extend({
"/static/client_templates/course_info_update.html",
function (raw_template) {
self.template = _.template(raw_template);
self.render();
self.render();
}
);
// when the client refetches the updates as a whole, re-render them
this.listenTo(this.collection, 'reset', this.render);
},
render: function () {
// iterate over updates and create views for each using the template
var updateEle = this.$el.find("#course-update-list");
@@ -66,14 +66,14 @@ CMS.Views.ClassInfoUpdateView = Backbone.View.extend({
this.$el.find('.date').datepicker({ 'dateFormat': 'MM d, yy' });
return this;
},
onNew: function(event) {
event.preventDefault();
var self = this;
// create new obj, insert into collection, and render this one ele overriding the hidden attr
var newModel = new CMS.Models.CourseUpdate();
this.collection.add(newModel, {at : 0});
var $newForm = $(this.template({ updateModel : newModel }));
var updateEle = this.$el.find("#course-update-list");
@@ -87,7 +87,7 @@ CMS.Views.ClassInfoUpdateView = Backbone.View.extend({
lineWrapping: true,
});
}
$newForm.addClass('editing');
this.$currentPost = $newForm.closest('li');
@@ -99,21 +99,21 @@ CMS.Views.ClassInfoUpdateView = Backbone.View.extend({
$('.date').datepicker('destroy');
$('.date').datepicker({ 'dateFormat': 'MM d, yy' });
},
onSave: function(event) {
event.preventDefault();
var targetModel = this.eventModel(event);
targetModel.set({ date : this.dateEntry(event).val(), content : this.$codeMirror.getValue() });
// push change to display, hide the editor, submit the change
// push change to display, hide the editor, submit the change
targetModel.save({}, {error : CMS.ServerError});
this.closeEditor(this);
analytics.track('Saved Course Update', {
'course': course_location_analytics,
'date': this.dateEntry(event).val()
'date': this.dateEntry(event).val()
});
},
onCancel: function(event) {
event.preventDefault();
// change editor contents back to model values and hide the editor
@@ -121,13 +121,13 @@ CMS.Views.ClassInfoUpdateView = Backbone.View.extend({
var targetModel = this.eventModel(event);
this.closeEditor(this, !targetModel.id);
},
onEdit: function(event) {
event.preventDefault();
var self = this;
this.$currentPost = $(event.target).closest('li');
this.$currentPost.addClass('editing');
$(this.editor(event)).show();
var $textArea = this.$currentPost.find(".new-update-content").first();
if (this.$codeMirror == null ) {
@@ -154,13 +154,13 @@ CMS.Views.ClassInfoUpdateView = Backbone.View.extend({
analytics.track('Deleted Course Update', {
'course': course_location_analytics,
'date': this.dateEntry(event).val()
'date': this.dateEntry(event).val()
});
var targetModel = this.eventModel(event);
this.modelDom(event).remove();
var cacheThis = this;
targetModel.destroy({success : function (model, response) {
targetModel.destroy({success : function (model, response) {
cacheThis.collection.fetch({success : function() {cacheThis.render();},
error : CMS.ServerError});
},
@@ -192,17 +192,17 @@ CMS.Views.ClassInfoUpdateView = Backbone.View.extend({
this.$codeMirror = null;
self.$currentPost.find('.CodeMirror').remove();
},
// Dereferencing from events to screen elements
// Dereferencing from events to screen elements
eventModel: function(event) {
// not sure if it should be currentTarget or delegateTarget
return this.collection.get($(event.currentTarget).attr("name"));
},
modelDom: function(event) {
return $(event.currentTarget).closest("li");
},
editor: function(event) {
var li = $(event.currentTarget).closest("li");
if (li) return $(li).find("form").first();
@@ -216,7 +216,7 @@ CMS.Views.ClassInfoUpdateView = Backbone.View.extend({
contentEntry: function(event) {
return $(event.currentTarget).closest("li").find(".new-update-content").first();
},
dateDisplay: function(event) {
return $(event.currentTarget).closest("li").find("#date-display").first();
},
@@ -224,7 +224,7 @@ CMS.Views.ClassInfoUpdateView = Backbone.View.extend({
contentDisplay: function(event) {
return $(event.currentTarget).closest("li").find(".update-contents").first();
}
});
// the handouts view is dumb right now; it needs tied to a model and all that jazz
@@ -245,7 +245,7 @@ CMS.Views.ClassInfoHandoutsView = Backbone.View.extend({
"/static/client_templates/course_info_handouts.html",
function (raw_template) {
self.template = _.template(raw_template);
self.render();
self.render();
}
);
},
@@ -253,8 +253,8 @@ CMS.Views.ClassInfoHandoutsView = Backbone.View.extend({
}
);
},
render: function () {
render: function () {
var updateEle = this.$el;
var self = this;
this.$el.html(
@@ -313,4 +313,4 @@ CMS.Views.ClassInfoHandoutsView = Backbone.View.extend({
self.$form.find('.CodeMirror').remove();
this.$codeMirror = null;
}
});
});

View File

@@ -16,7 +16,7 @@ CMS.Models.AssignmentGrade = Backbone.Model.extend({
urlRoot : function() {
if (this.has('location')) {
var location = this.get('location');
return '/' + location.get('org') + "/" + location.get('course') + '/' + location.get('category') + '/'
return '/' + location.get('org') + "/" + location.get('course') + '/' + location.get('category') + '/'
+ location.get('name') + '/gradeas/';
}
else return "";
@@ -37,14 +37,14 @@ CMS.Views.OverviewAssignmentGrader = Backbone.View.extend({
'<a data-tooltip="Mark/unmark this subsection as graded" class="menu-toggle" href="#">' +
'<% if (!hideSymbol) {%><span class="ss-icon ss-standard">&#x2713;</span><%};%>' +
'</a>' +
'<ul class="menu">' +
'<ul class="menu">' +
'<% graders.each(function(option) { %>' +
'<li><a <% if (option.get("type") == assignmentType) {%>class="is-selected" <%}%> href="#"><%= option.get("type") %></a></li>' +
'<% }) %>' +
'<li><a class="gradable-status-notgraded" href="#">Not Graded</a></li>' +
'</ul>');
this.assignmentGrade = new CMS.Models.AssignmentGrade({
assignmentUrl : this.$el.closest('.id-holder').data('id'),
assignmentUrl : this.$el.closest('.id-holder').data('id'),
graderType : this.$el.data('initial-status')});
// TODO throw exception if graders is null
this.graders = this.options['graders'];
@@ -78,13 +78,13 @@ CMS.Views.OverviewAssignmentGrader = Backbone.View.extend({
},
selectGradeType : function(e) {
e.preventDefault();
this.removeMenu(e);
// TODO I'm not happy with this string fetch via the html for what should be an id. I'd rather use the id attr
// of the CourseGradingPolicy model or null for Not Graded (NOTE, change template's if check for is-selected accordingly)
this.assignmentGrade.save('graderType', $(e.target).text());
this.render();
}
})
})

View File

@@ -6,26 +6,26 @@ $(document).ready(function() {
$('.unit').draggable({
axis: 'y',
handle: '.drag-handle',
zIndex: 999,
zIndex: 999,
start: initiateHesitate,
// left 2nd arg in as inert selector b/c i was uncertain whether we'd try to get the shove up/down
// to work in the future
drag: generateCheckHoverState('.collapsed', ''),
drag: generateCheckHoverState('.collapsed', ''),
stop: removeHesitate,
revert: "invalid"
});
// Subsection reordering
$('.id-holder').draggable({
axis: 'y',
handle: '.section-item .drag-handle',
zIndex: 999,
zIndex: 999,
start: initiateHesitate,
drag: generateCheckHoverState('.courseware-section.collapsed', ''),
stop: removeHesitate,
revert: "invalid"
});
// Section reordering
$('.courseware-section').draggable({
axis: 'y',
@@ -33,8 +33,8 @@ $(document).ready(function() {
stack: '.courseware-section',
revert: "invalid"
});
$('.sortable-unit-list').droppable({
accept : '.unit',
greedy: true,
@@ -50,7 +50,7 @@ $(document).ready(function() {
drop: onSubsectionReordered,
greedy: true
});
// Section reordering
$('.courseware-overview').droppable({
accept : '.courseware-section',
@@ -58,7 +58,7 @@ $(document).ready(function() {
drop: onSectionReordered,
greedy: true
});
// stop clicks on drag bars from doing their thing w/o stopping drag
$('.drag-handle').click(function(e) {e.preventDefault(); });
@@ -87,7 +87,7 @@ function computeIntersection(droppable, uiHelper, y) {
$.extend(droppable, {offset : $(droppable).offset()});
var t = droppable.offset.top,
var t = droppable.offset.top,
b = t + droppable.proportions.height;
if (t === b) {
@@ -118,10 +118,10 @@ function generateCheckHoverState(selectorsToOpen, selectorsToShove) {
this[c === "isout" ? "isover" : "isout"] = false;
$(this).trigger(c === "isover" ? "dragEnter" : "dragLeave");
});
$(selectorsToShove).each(function() {
var intersectsBottom = computeIntersection(this, ui.helper, (draggable.positionAbs || draggable.position.absolute).top);
if ($(this).hasClass('ui-dragging-pushup')) {
if (!intersectsBottom) {
console.log('not up', $(this).data('id'));
@@ -132,10 +132,10 @@ function generateCheckHoverState(selectorsToOpen, selectorsToShove) {
console.log('up', $(this).data('id'));
$(this).addClass('ui-dragging-pushup');
}
var intersectsTop = computeIntersection(this, ui.helper,
var intersectsTop = computeIntersection(this, ui.helper,
(draggable.positionAbs || draggable.position.absolute).top + draggable.helperProportions.height);
if ($(this).hasClass('ui-dragging-pushdown')) {
if (!intersectsTop) {
console.log('not down', $(this).data('id'));
@@ -146,7 +146,7 @@ function generateCheckHoverState(selectorsToOpen, selectorsToShove) {
console.log('down', $(this).data('id'));
$(this).addClass('ui-dragging-pushdown');
}
});
}
}
@@ -159,20 +159,20 @@ function removeHesitate(event, ui) {
}
function expandSection(event) {
$(event.delegateTarget).removeClass('collapsed', 400);
$(event.delegateTarget).removeClass('collapsed', 400);
// don't descend to icon's on children (which aren't under first child) only to this element's icon
$(event.delegateTarget).children().first().find('.expand-collapse-icon').removeClass('expand', 400).addClass('collapse');
}
function onUnitReordered(event, ui) {
// a unit's been dropped on this subsection,
// figure out where it came from and where it slots in.
// figure out where it came from and where it slots in.
_handleReorder(event, ui, 'subsection-id', 'li:.leaf');
}
function onSubsectionReordered(event, ui) {
// a subsection has been dropped on this section,
// figure out where it came from and where it slots in.
// figure out where it came from and where it slots in.
_handleReorder(event, ui, 'section-id', 'li:.branch');
}
@@ -182,7 +182,7 @@ function onSectionReordered(event, ui) {
}
function _handleReorder(event, ui, parentIdField, childrenSelector) {
// figure out where it came from and where it slots in.
// figure out where it came from and where it slots in.
var subsection_id = $(event.target).data(parentIdField);
var _els = $(event.target).children(childrenSelector);
var children = _els.map(function(idx, el) { return $(el).data('id'); }).get();

View File

@@ -1,4 +1,4 @@
CMS.ServerError = function(model, error) {
// this handler is for the client:server communication not the validation errors which handleValidationError catches
window.alert("Server Error: " + error.responseText);
};
};

View File

@@ -1,6 +1,6 @@
CMS.Views.ValidatingView = Backbone.View.extend({
// Intended as an abstract class which catches validation errors on the model and
// decorates the fields. Needs wiring per class, but this initialization shows how
// Intended as an abstract class which catches validation errors on the model and
// decorates the fields. Needs wiring per class, but this initialization shows how
// either have your init call this one or copy the contents
initialize : function() {
this.listenTo(this.model, 'error', CMS.ServerError);
@@ -15,7 +15,7 @@ CMS.Views.ValidatingView = Backbone.View.extend({
"change textarea" : "clearValidationErrors"
},
fieldToSelectorMap : {
// Your subclass must populate this w/ all of the model keys and dom selectors
// Your subclass must populate this w/ all of the model keys and dom selectors
// which may be the subjects of validation errors
},
_cacheValidationErrors : [],

View File

@@ -6,7 +6,7 @@
@include box-sizing(border-box);
.copy {
@include font-size(13);
@extend .t-copy-sub2;
}
}
@@ -184,12 +184,12 @@
}
.action-primary {
@include font-size(13);
@extend .t-action3;
font-weight: 600;
}
.action-secondary {
@include font-size(13);
@extend .t-action3;
}
}
}
@@ -367,12 +367,12 @@
}
.copy {
@include font-size(13);
@extend .t-copy-sub2;
width: flex-grid(10, 12);
color: $gray-l2;
.title {
@include font-size(14);
@extend .t-title-4;
margin-bottom: 0;
color: $white;
}
@@ -409,13 +409,13 @@
.action-primary {
@include blue-button();
@include font-size(13);
@extend .t-action3;
border-color: $blue-d2;
font-weight: 600;
}
.action-secondary {
@include font-size(13);
@extend .t-action3;
}
}
@@ -504,7 +504,7 @@
// adopted alerts
.alert {
@include font-size(14);
@extend .t-copy-sub2;
@include box-sizing(border-box);
@include clearfix();
margin: 0 auto;
@@ -530,7 +530,7 @@
}
.copy {
@include font-size(13);
@extend .t-copy-sub2;
width: flex-grid(10, 12);
color: $gray-l2;
@@ -568,12 +568,12 @@
}
.action-primary {
@include font-size(13);
@extend .t-action3;
font-weight: 600;
}
.action-secondary {
@include font-size(13);
@extend .t-action3;
}
}
}
@@ -730,7 +730,7 @@ body.uxdesign.alerts {
border-radius: 3px;
background: #fbf6e1;
// background: #edbd3c;
font-size: 14px;
@extend .t-copy-sub1;
@include clearfix;
.alert-message {

View File

@@ -2,7 +2,7 @@
// ====================
// headings/titles
.t-title-1, .t-title-2, .t-title-3, .t-title-4, .t-title-5, .t-title-5 {
.t-title-1, .t-title-2, .t-title-3, .t-title-4, .t-title-5 {
color: $gray-d3;
}
@@ -21,7 +21,7 @@
}
.t-title-4 {
@include font-size(14);
}
.t-title-5 {
@@ -82,4 +82,4 @@
// misc
.t-icon {
line-height: 0;
}
}

View File

@@ -114,6 +114,7 @@
<li><a href="#alert-announcement2" class="show-alert">Show Announcement</a></li>
<li><a href="#alert-announcement1" class="show-alert">Show Announcement with Actions</a></li>
<li><a href="#alert-activation" class="show-alert">Show Activiation</a></li>
<li><a href="#alert-threeActions" class="show-alert">Alert with three actions</a></li>
</ul>
</section>
@@ -128,6 +129,10 @@
<h3 class="title-3">Different Static Examples of Notifications</h3>
<ul>
<li>
<a href="#notification-changesMade" class="show-notification">Show Changes Made (used in Advanced Settings)</a>
<a href="#notification-changesMade" class="hide-notification">Hide Changes Made (used in Advanced Settings)</a>
</li>
<li>
<a href="#notification-change" class="show-notification">Show Change Warning</a>
<a href="#notification-change" class="hide-notification">Hide Change Warning</a>
@@ -151,6 +156,10 @@
<a href="#notification-help" class="show-notification">Show Help</a>
<a href="#notification-help" class="hide-notification">Hide Help</a>
</li>
<li>
<a href="#notification-threeActions" class="show-notification">Show Notification with three actions</a>
<a href="#notification-threeActions" class="hide-notification">Hide Notification with three actions</a>
</li>
</ul>
</section>
@@ -182,6 +191,33 @@
</%block>
<%block name="view_alerts">
<!-- alert: 3 actions -->
<div class="wrapper wrapper-alert wrapper-alert-warning" id="alert-threeActions">
<div class="alert warning has-actions">
<i class="ss-icon ss-symbolicons-block icon icon-warning">&#x26A0;</i>
<div class="copy">
<h2 class="title title-3">You are editing a draft</h2>
<p class="message">Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa.</p>
</div>
<nav class="nav-actions">
<h3 class="sr">Alert Actions</h3>
<ul>
<li class="nav-item">
<a href="#" class="action action-save action-primary">Save Draft</a>
</li>
<li class="nav-item">
<a href="#" class="action action-cancel action-secondary">Disgard Draft</a>
</li>
<li class="nav-item">
<a href="#" class="action action-secondary">Do Something Elsee</a>
</li>
</ul>
</nav>
</div>
</div>
<!-- alert: you're editing a draft -->
<div class="wrapper wrapper-alert wrapper-alert-warning" id="alert-draft">
<div class="alert warning has-actions">
@@ -196,10 +232,10 @@
<h3 class="sr">Alert Actions</h3>
<ul>
<li class="nav-item">
<a href="#" class="button save-button action-primary">Save Draft</a>
<a href="#" class="action action-save action-primary">Save Draft</a>
</li>
<li class="nav-item">
<a href="#" class="button cancel-button action-secondary">Disgard Draft</a>
<a href="#" class="action action-cancel action-secondary">Disgard Draft</a>
</li>
</ul>
</nav>
@@ -220,10 +256,10 @@
<h3 class="sr">Alert Actions</h3>
<ul>
<li class="nav-item">
<a href="#" class="button save-button action-primary">Go to Newer Version</a>
<a href="#" class="action action-save action-primary">Go to Newer Version</a>
</li>
<li class="nav-item">
<a href="#" class="button cancel-button action-secondary">Continue Editing</a>
<a href="#" class="action action-cancel action-secondary">Continue Editing</a>
</li>
</ul>
</nav>
@@ -297,7 +333,7 @@
<h3 class="sr">Alert Actions</h3>
<ul>
<li class="nav-item">
<a href="#" class="button cancel-button action-primary">Cancel Your Submission</a>
<a href="#" class="action action-cancel action-primary">Cancel Your Submission</a>
</li>
</ul>
</nav>
@@ -367,13 +403,13 @@
<%block name="view_notifications">
<!-- notification: change has been made and a save is needed -->
<div class="wrapper wrapper-notification wrapper-notification-change" id="notification-change" role="status">
<div class="wrapper wrapper-notification wrapper-notification-change" aria-hidden="true" role="dialog" aria-labelledby="notification-change-title" aria-describedby="notification-change-description" id="notification-change">
<div class="notification change has-actions">
<i class="ss-icon ss-symbolicons-block icon icon-change">&#x1F4DD;</i>
<div class="copy">
<h2 class="title title-3">You've Made Some Changes</h2>
<p class="message">Your changes will not take effect until you <strong>save your progress</strong>.</p>
<h2 class="title title-3" id="notification-change-title">You've Made Some Changes</h2>
<p class="message" id="notification-change-description">Your changes will not take effect until you <strong>save your progress</strong>.</p>
</div>
<nav class="nav-actions">
@@ -390,6 +426,57 @@
</div>
</div>
<!-- notification: three actions example -->
<div class="wrapper wrapper-notification wrapper-notification-change" aria-hidden="true" role="dialog" aria-labelledby="notification-threeActions-title" aria-describedby="notification-threeActions-description" id="notification-threeActions">
<div class="notification change has-actions">
<i class="ss-icon ss-symbolicons-block icon icon-change">&#x1F4DD;</i>
<div class="copy">
<h2 class="title title-3" id="notification-threeActions-title">You've Made Some Changes</h2>
<p class="message" id="notification-threeActions-description">Your changes will not take effect until you <strong>save your progress</strong>.</p>
</div>
<nav class="nav-actions">
<h3 class="sr">Notification Actions</h3>
<ul>
<li class="nav-item">
<a href="#" class="action-primary">Save Changes</a>
</li>
<li class="nav-item">
<a href="#" class="action-secondary">Don't Save</a>
</li>
<li class="nav-item">
<a href="#" class="action-secondary">Do something else</a>
</li>
</ul>
</nav>
</div>
</div>
<!-- notification: change has been made and a save is needed -->
<div class="wrapper wrapper-notification wrapper-notification-warning" aria-hidden="true" role="dialog" aria-labelledby="notification-changesMade-title" aria-describedby="notification-changesMade-description" id="notification-changesMade">
<div class="notification warning has-actions">
<i class="ss-icon ss-symbolicons-block icon icon-warning">&#x26A0;</i>
<div class="copy">
<h2 class="title title-3" id="notification-changesMade-title">You've Made Some Changes</h2>
<p id="notification-changesMade-description">Your changes will not take effect until you <strong>save your progress</strong>. Take care with key and value formatting, as validation is <strong>not implemented</strong>.</p>
</div>
<nav class="nav-actions">
<h3 class="sr">Notification Actions</h3>
<ul>
<li class="nav-item">
<a href="" class="action action-save action-primary">Save Changes</a>
</li>
<li class="nav-item">
<a href="" class="action action-cancel action-secondary">Cancel</a>
</li>
</ul>
</nav>
</div>
</div>
<!-- notification: newer version exists -->
<div class="wrapper wrapper-notification wrapper-notification-warning" id="notification-version" aria-hidden="true" role="dialog" aria-labelledby="notification-warning-title" aria-describedby="notification-warning-description">
<div class="notification warning has-actions">
@@ -404,10 +491,10 @@
<h3 class="sr">Notification Actions</h3>
<ul>
<li class="nav-item">
<a href="#" class="button save-button action-primary">Go to Newer Version</a>
<a href="#" class="action action-save action-primary">Go to Newer Version</a>
</li>
<li class="nav-item">
<a href="#" class="button cancel-button action-secondary">Continue Editing</a>
<a href="#" class="action action-cancel action-secondary">Continue Editing</a>
</li>
</ul>
</nav>
@@ -428,10 +515,10 @@
<h3 class="sr">Notification Actions</h3>
<ul>
<li class="nav-item">
<a href="#" class="action-primary">Yes, I want to Edit X</a>
<a href="#" class="action action-proceed action-primary">Yes, I want to Edit X</a>
</li>
<li class="nav-item">
<a href="#" class="action-secondary">No, I do not</a>
<a href="#" class="action action-cancel action-secondary">No, I do not</a>
</li>
</ul>
</nav>

View File

@@ -8,7 +8,7 @@
% for field_name, field_value in editable_metadata_fields.items():
<li>
% if field_name == 'source_code':
% if field_value['is_default'] is False:
% if field_value['explicitly_set'] is True:
<a href="#hls-modal-${hlskey}" style="color:yellow;" id="hls-trig-${hlskey}" >Edit High Level Source</a>
% endif
% else:
@@ -26,8 +26,10 @@
% if False:
<label>Help: ${field_value['field'].help}</label>
<label>Type: ${type(field_value['field']).__name__}</label>
<label>Inherited: ${field_value['is_inherited']}</label>
<label>Default: ${field_value['is_default']}</label>
<label>Inheritable: ${field_value['inheritable']}</label>
<label>Showing inherited value: ${field_value['inheritable'] and not field_value['explicitly_set']}</label>
<label>Explicitly set: ${field_value['explicitly_set']}</label>
<label>Default value: ${field_value['default_value']}</label>
% if field_value['field'].values:
<label>Possible values:</label>
% for value in field_value['field'].values:
@@ -40,7 +42,7 @@
% endfor
</ul>
% if 'source_code' in editable_metadata_fields and not editable_metadata_fields['source_code']['is_default']:
% if 'source_code' in editable_metadata_fields and editable_metadata_fields['source_code']['explicitly_set']:
<%include file="source-edit.html" />
% endif