Commit 355a3b45 by Daniel Friedman

Merge pull request #5764 from edx/dan-f/highlight-active-unit-in-outline

Highlight active unit in studio container page's outline
parents 3d7ce0bb 3b3b3dcd
......@@ -88,6 +88,17 @@ define(["jquery", "js/common_helpers/ajax_helpers", "js/common_helpers/template_
expect(unitOutlineView.$('.list-units')).toExist();
});
it('highlights the current unit', function() {
createUnitOutlineView(this, createMockXBlockInfo('Mock Unit'));
$('.outline-unit').each(function(i) {
if ($(this).data('locator') === model.get('id')) {
expect($(this)).toHaveClass('is-current');
} else {
expect($(this)).not.toHaveClass('is-current');
}
});
});
it('can add a unit', function() {
var redirectSpy;
createUnitOutlineView(this, createMockXBlockInfo('Mock Unit'));
......
......@@ -35,15 +35,8 @@ define(["jquery", "underscore", "js/views/xblock_outline", "js/views/utils/view_
return !this.model.isVertical();
},
createChildView: function(xblockInfo, parentInfo, parentView) {
return new CourseOutlineView({
model: xblockInfo,
parentInfo: parentInfo,
initialState: this.initialState,
expandedLocators: this.expandedLocators,
template: this.template,
parentView: parentView || this
});
getChildViewClass: function() {
return CourseOutlineView;
},
/**
......@@ -112,7 +105,7 @@ define(["jquery", "underscore", "js/views/xblock_outline", "js/views/utils/view_
});
// Fetch the full xblock info for the section and then create a view for it
sectionInfo.fetch().done(function() {
sectionView = self.createChildView(sectionInfo, self.model, self);
sectionView = self.createChildView(sectionInfo, self.model, {parentView: self});
sectionView.initialState = initialState;
sectionView.expandedLocators = self.expandedLocators;
sectionView.render();
......
......@@ -3,9 +3,8 @@
* the ancestors of the unit along with its direct siblings. It also has a single "New Unit"
* button to allow a new sibling unit to be added.
*/
define(['js/views/xblock_outline'],
function(XBlockOutlineView) {
define(['underscore', 'js/views/xblock_outline', 'js/views/unit_outline_child'],
function(_, XBlockOutlineView, UnitOutlineChildView) {
var UnitOutlineView = XBlockOutlineView.extend({
// takes XBlockInfo as a model
......@@ -29,7 +28,11 @@ define(['js/views/xblock_outline'],
// i.e. subsection and then section.
for (i=ancestors.length - 1; i >= 0; i--) {
ancestor = ancestors[i];
ancestorView = this.createChildView(ancestor, previousAncestor, ancestorView);
ancestorView = this.createChildView(
ancestor,
previousAncestor,
{parentView: ancestorView, currentUnitId: this.model.get('id')}
);
ancestorView.render();
listElement.append(ancestorView.$el);
previousAncestor = ancestor;
......@@ -37,6 +40,17 @@ define(['js/views/xblock_outline'],
}
}
return ancestorView;
},
getChildViewClass: function() {
return UnitOutlineChildView;
},
getTemplateContext: function() {
return _.extend(
XBlockOutlineView.prototype.getTemplateContext.call(this),
{currentUnitId: this.model.get('id')}
);
}
});
......
/**
* The UnitOutlineChildView is used to render each Section,
* Subsection, and Unit within the Unit Outline component on the unit
* page.
*/
define(['underscore', 'js/views/xblock_outline'],
function(_, XBlockOutlineView) {
var UnitOutlineChildView = XBlockOutlineView.extend({
initialize: function() {
XBlockOutlineView.prototype.initialize.call(this);
this.currentUnitId = this.options.currentUnitId;
},
getTemplateContext: function() {
return _.extend(
XBlockOutlineView.prototype.getTemplateContext.call(this),
{currentUnitId: this.currentUnitId}
);
},
getChildViewClass: function() {
return UnitOutlineChildView;
},
createChildView: function(childInfo, parentInfo, options) {
options = _.isUndefined(options) ? {} : options;
return XBlockOutlineView.prototype.createChildView.call(
this, childInfo, parentInfo, _.extend(options, {currentUnitId: this.currentUnitId})
);
}
});
return UnitOutlineChildView;
}); // end define()
......@@ -54,6 +54,15 @@ define(["jquery", "underscore", "gettext", "js/views/baseview", "js/views/utils/
},
renderTemplate: function() {
var html = this.template(this.getTemplateContext());
if (this.parentInfo) {
this.setElement($(html));
} else {
this.$el.html(html);
}
},
getTemplateContext: function() {
var xblockInfo = this.model,
childInfo = xblockInfo.get('child_info'),
parentInfo = this.parentInfo,
......@@ -62,7 +71,6 @@ define(["jquery", "underscore", "gettext", "js/views/baseview", "js/views/utils/
parentType = parentInfo ? XBlockViewUtils.getXBlockType(parentInfo.get('category')) : null,
addChildName = null,
defaultNewChildName = null,
html,
isCollapsed = this.shouldRenderChildren() && !this.shouldExpandChildren();
if (childInfo) {
addChildName = interpolate(gettext('New %(component_type)s'), {
......@@ -70,7 +78,7 @@ define(["jquery", "underscore", "gettext", "js/views/baseview", "js/views/utils/
}, true);
defaultNewChildName = childInfo.display_name;
}
html = this.template({
return {
xblockInfo: xblockInfo,
visibilityClass: XBlockViewUtils.getXBlockVisibilityClass(xblockInfo.get('visibility_state')),
typeListClass: XBlockViewUtils.getXBlockListTypeClass(xblockType),
......@@ -86,20 +94,15 @@ define(["jquery", "underscore", "gettext", "js/views/baseview", "js/views/utils/
includesChildren: this.shouldRenderChildren(),
hasExplicitStaffLock: this.model.get('has_explicit_staff_lock'),
staffOnlyMessage: this.model.get('staff_only_message')
});
if (this.parentInfo) {
this.setElement($(html));
} else {
this.$el.html(html);
}
};
},
renderChildren: function() {
var self = this,
xblockInfo = this.model;
if (xblockInfo.get('child_info')) {
_.each(this.model.get('child_info').children, function(child) {
var childOutlineView = self.createChildView(child, xblockInfo);
parentInfo = this.model;
if (parentInfo.get('child_info')) {
_.each(this.model.get('child_info').children, function(childInfo) {
var childOutlineView = self.createChildView(childInfo, parentInfo);
childOutlineView.render();
self.addChildView(childOutlineView);
});
......@@ -182,15 +185,20 @@ define(["jquery", "underscore", "gettext", "js/views/baseview", "js/views/utils/
return true;
},
createChildView: function(xblockInfo, parentInfo, parentView) {
return new XBlockOutlineView({
model: xblockInfo,
getChildViewClass: function() {
return XBlockOutlineView;
},
createChildView: function(childInfo, parentInfo, options) {
var viewClass = this.getChildViewClass();
return new viewClass(_.extend({
model: childInfo,
parentInfo: parentInfo,
parentView: this,
initialState: this.initialState,
expandedLocators: this.expandedLocators,
template: this.template,
parentView: parentView || this
});
template: this.template
}, options));
},
onSync: function(event) {
......
......@@ -373,7 +373,7 @@ $outline-indent-width: $baseline;
}
.item-title a {
color: $color-heading-base;
color: $color-heading-base;
&:hover {
color: $blue;
......
......@@ -210,7 +210,7 @@
.widget-layout dl#brain_buster_captcha dd #captcha_answer {
display: block;
width: 97%%;
width: 97%;
}
.widget-layout .form-actions .btn-post_topic {
......
......@@ -262,6 +262,47 @@
.item-title {
@extend %cont-text-wrap;
a {
color: $blue;
&:hover {
color: $orange-d1;
}
}
}
// CASE: is current item being edited/viewed
.is-current {
background: $gray-l4;
.unit-title a {
@extend %ui-disabled;
@extend %t-strong;
color: $color-heading-base;
}
}
// typographical overrides (based off of outline-simple)
.section-header, .subsection-header {
line-height: 0;
margin-bottom: ($baseline/2);
}
.section-header {
border-bottom: 1px solid $gray-l4;
padding-bottom: ($baseline/2);
}
// subsections overrides (based off of outline-simple)
.outline-subsection {
border: none;
padding: 0;
}
// units overrides (based off of outline-simple)
.outline-unit {
padding: 3px 6px;
}
}
}
......
<% if (parentInfo) { %>
<li class="outline-item outline-<%= xblockType %> <%= visibilityClass %>"
<li class="outline-item outline-<%= xblockType %> <%= visibilityClass %> <%= xblockInfo.get('id') === currentUnitId ? 'is-current' : '' %>"
data-parent="<%= parentInfo.get('id') %>" data-locator="<%= xblockInfo.get('id') %>">
<div class="<%= xblockType %>-header">
<h3 class="<%= xblockType %>-header-details">
......
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