Make group config styles generic

This commit is contained in:
Frances Botsford
2015-01-09 23:30:33 -05:00
committed by Andy Armstrong
parent 39acbdcb2b
commit 6398af715a
20 changed files with 517 additions and 424 deletions

View File

@@ -24,7 +24,7 @@ define([
groupsAllocation: '.group-allocation',
errorMessage: '.group-configuration-edit-error',
inputGroupName: '.group-name',
inputName: '.group-configuration-name-input',
inputName: '.collection-name-input',
inputDescription: '.group-configuration-description-input',
usageCount: '.group-configuration-usage-count',
usage: '.group-configuration-usage',
@@ -635,15 +635,15 @@ define([
describe('Content groups list view', function() {
var newGroupCss = '.new-button',
addGroupCss = '.action-add',
inputCss = '.group-configuration-name-input',
inputCss = '.collection-name-input',
saveButtonCss = '.action-primary',
cancelButtonCss = '.action-cancel',
validationErrorCss = '.group-configuration-edit-error',
validationErrorCss = '.content-group-edit-error',
scopedGroupSelector, createGroups, renderView, saveOrCancel, editNewGroup, editExistingGroup,
verifyEditingGroup, respondToSave, expectGroupsVisible, correctValidationError;
scopedGroupSelector = function(groupIndex, additionalSelectors) {
var groupSelector = '.group-configurations-list-item-' + groupIndex;
var groupSelector = '.content-groups-list-item-' + groupIndex;
if (additionalSelectors) {
return groupSelector + ' ' + additionalSelectors;
} else {
@@ -704,11 +704,11 @@ define([
// editing a group.
index = index || 0;
if (expectEditing) {
expect(view.$(scopedGroupSelector(index, '.group-configuration-edit'))).toExist();
expect(view.$(scopedGroupSelector(index, '.content-group-edit'))).toExist();
expect(view.$(newGroupCss)).not.toExist();
expect(view.$(addGroupCss)).toHaveClass('is-hidden');
} else {
expect(view.$('.group-configuration-edit')).not.toExist();
expect(view.$('.content-group-edit')).not.toExist();
if (view.collection.length === 0) {
expect(view.$(newGroupCss)).toExist();
expect(view.$(addGroupCss)).not.toExist();
@@ -742,7 +742,7 @@ define([
expectGroupsVisible = function(view, groupNames) {
_.each(groupNames, function(groupName) {
expect(view.$('.group-configurations-list-item')).toContainText(groupName);
expect(view.$('.content-groups-list-item')).toContainText(groupName);
});
};
@@ -753,13 +753,13 @@ define([
});
it('shows a message when no groups are present', function() {
expect(renderView().$('.no-group-configurations-content'))
expect(renderView().$('.no-content'))
.toContainText('You have not created any content groups yet.');
});
it('can render groups', function() {
var groupNames = ['Group 1', 'Group 2', 'Group 3'];
renderView(groupNames).$('.group-configuration-details').each(function(index) {
renderView(groupNames).$('.content-group-details').each(function(index) {
expect($(this)).toContainText(groupNames[index]);
});
});

View File

@@ -52,7 +52,7 @@ define([
expect(view.$('.ui-loading')).toBeVisible();
view.render();
expect(view.$(groupConfigItemClassName)).toExist();
expect(view.$('.content-groups .no-group-configurations-content')).toExist();
expect(view.$('.content-groups .no-content')).toExist();
expect(view.$('.ui-loading')).toHaveClass('is-hidden');
});
});

View File

@@ -9,7 +9,7 @@ define([
var ContentGroupDetailsView = BaseView.extend({
tagName: 'div',
className: 'group-configuration-details',
className: 'content-group-details collection',
events: {
'click .edit': 'editGroup'

View File

@@ -10,7 +10,7 @@ function(ListItemEditorView, _) {
var ContentGroupEditorView = ListItemEditorView.extend({
tagName: 'div',
className: 'group-configuration-edit',
className: 'content-group-edit collection-edit',
events: {
'submit': 'setAndClose',
'click .action-cancel': 'cancel'

View File

@@ -12,6 +12,8 @@ define([
var ContentGroupItemView = ListItemView.extend({
tagName: 'section',
baseClassName: 'content-group',
createEditView: function() {
return new ContentGroupEditorView({model: this.model});
},

View File

@@ -15,6 +15,8 @@ define([
// Translators: This refers to a content group that can be linked to a student cohort.
itemCategoryDisplayName: gettext('content group'),
emptyMessage: gettext('You have not created any content groups yet.'),
createItemView: function(options) {
return new ContentGroupItemView(options);
}

View File

@@ -19,6 +19,7 @@ function(BaseView, _, gettext, str) {
var index = this.model.collection.indexOf(this.model);
return [
'collection',
'group-configuration-details',
'group-configuration-details-' + index
].join(' ');

View File

@@ -11,7 +11,7 @@ function(ListItemEditorView, _, $, gettext, ExperimentGroupEditView) {
var GroupConfigurationEditorView = ListItemEditorView.extend({
tagName: 'div',
events: {
'change .group-configuration-name-input': 'setName',
'change .collection-name-input': 'setName',
'change .group-configuration-description-input': 'setDescription',
'click .action-add-group': 'createGroup',
'focus .input-text': 'onFocus',
@@ -24,6 +24,7 @@ function(ListItemEditorView, _, $, gettext, ExperimentGroupEditView) {
var index = this.model.collection.indexOf(this.model);
return [
'collection-edit',
'group-configuration-edit',
'group-configuration-edit-' + index
].join(' ');
@@ -84,7 +85,7 @@ function(ListItemEditorView, _, $, gettext, ExperimentGroupEditView) {
setName: function(event) {
if (event && event.preventDefault) { event.preventDefault(); }
this.model.set(
'name', this.$('.group-configuration-name-input').val(),
'name', this.$('.collection-name-input').val(),
{ silent: true }
);
},

View File

@@ -18,6 +18,13 @@ define([
tagName: 'section',
baseClassName: 'group-configuration',
canDelete: true,
// Translators: this refers to a collection of groups.
itemDisplayName: gettext('group configuration'),
attributes: function () {
return {
'id': this.model.get('id'),
@@ -25,11 +32,6 @@ define([
};
},
// Translators: this refers to a collection of groups.
itemDisplayName: gettext('group configuration'),
canDelete: true,
createEditView: function() {
return new GroupConfigurationEditorView({model: this.model});
},

View File

@@ -17,6 +17,8 @@ define([
// Translators: this refers to a collection of groups.
itemCategoryDisplayName: gettext('group configuration'),
emptyMessage: gettext('You have not created any group configurations yet.'),
createItemView: function(options) {
return new GroupConfigurationItemView(options);
}

View File

@@ -10,6 +10,7 @@
* - itemCategoryDisplayName (string): Display name for the category
* of items this list contains. For example, 'Group Configuration'.
* Note that it must be translated.
* - emptyMessage (string): Text to render when the list is empty.
*/
define([
'js/views/baseview'
@@ -21,6 +22,8 @@ define([
'click .new-button': 'onAddItem'
},
listContainerCss: '.list-items',
initialize: function() {
this.listenTo(this.collection, 'add', this.addNewItemView);
this.listenTo(this.collection, 'remove', this.onRemoveItem);
@@ -35,12 +38,13 @@ define([
render: function(model) {
this.$el.html(this.template({
itemCategoryDisplayName: this.itemCategoryDisplayName,
emptyMessage: this.emptyMessage,
length: this.collection.length,
isEditing: model && model.get('editing')
}));
this.collection.each(function(model) {
this.$('.content-groups').append(this.createItemView({model: model}).render().el);
this.$(this.listContainerCss).append(this.createItemView({model: model}).render().el);
}, this);
return this;
@@ -71,7 +75,7 @@ define([
// If items already exist, just append one new.
// Otherwise re-render the empty list HTML.
if (this.collection.length > 1) {
this.$('.content-groups').append(view.render().el);
this.$(this.listContainerCss).append(view.render().el);
} else {
this.render();
}

View File

@@ -5,6 +5,7 @@
* Subclasses must implement:
* - itemDisplayName (string): Display name for the list item.
* Must be translated.
* - baseClassName (string): CSS class name representing the item.
* - createEditView (function): Render and append the edit view to the
* DOM.
* - createDetailsView (function): Render and append the details view
@@ -29,9 +30,11 @@ define([
var index = this.model.collection.indexOf(this.model);
return [
'group-configuration',
'group-configurations-list-item',
'group-configurations-list-item-' + index
'wrapper-collection',
'wrapper-collection-' + index,
this.baseClassName,
this.baseClassName + 's-list-item',
this.baseClassName + 's-list-item-' + index
].join(' ');
},

View File

@@ -19,7 +19,7 @@
text-align: center;
}
.no-group-configurations-content {
.no-content {
@extend %no-content;
}
@@ -35,193 +35,183 @@
.copy {
@extend %t-copy-sub1;
}
}
.group-configuration {
.wrapper-collection {
@extend %ui-window;
position: relative;
outline: none;
.group-configuration-details {
.wrapper-group-configuration {
padding: $baseline ($baseline*1.5);
&:hover .collection .actions {
opacity: 1.0;
}
.group-configuration-header {
margin-bottom: 0;
border-bottom: 0;
padding-bottom: 0;
}
.collection-details {
padding: $baseline ($baseline*1.5);
}
.group-configuration-title {
@extend %t-title5;
@extend %t-strong;
overflow: hidden;
text-overflow: ellipsis;
margin-right: ($baseline*14);
.collection-header {
margin-bottom: 0;
border-bottom: 0;
padding-bottom: 0;
.title {
@extend %cont-truncated;
@extend %t-title5;
@extend %t-strong;
margin-right: ($baseline*14);
color: $black;
.toggle {
display: inline-block;
padding-left: $baseline;
color: $black;
.group-toggle {
display: inline-block;
padding-left: $baseline;
color: $black;
&:hover, &:focus {
color: $blue;
}
}
}
.group-configuration-info {
@extend %t-copy-sub1;
color: $gray-l1;
margin-left: $baseline;
&.group-configuration-info-inline {
display: table;
width: 70%;
margin: ($baseline/4) 0 ($baseline/2) $baseline;
li {
@include box-sizing(border-box);
display: table-cell;
margin-right: 1%;
&.group-configuration-usage-count {
font-style: italic;
}
}
}
&.group-configuration-info-block {
li {
padding: ($baseline/4) 0;
}
}
.group-configuration-label {
text-transform: uppercase;
}
.group-configuration-description {
overflow: hidden;
text-overflow: ellipsis;
}
}
.ui-toggle-expansion {
@include transition(rotate .15s ease-in-out .25s);
@extend %t-action1;
display: inline-block;
width: ($baseline*0.75);
vertical-align: baseline;
margin-left: -$baseline;
}
&.is-selectable {
@extend %ui-fake-link;
&:hover {
&:hover, &:focus {
color: $blue;
.ui-toggle-expansion {
color: $blue;
}
}
}
.groups {
margin-left: $baseline;
margin-bottom: ($baseline*0.75);
.group {
@extend %t-copy-lead1;
padding: ($baseline/7) 0 ($baseline/4);
border-top: 1px solid $gray-l4;
white-space: nowrap;
&:first-child {
border-top: none;
}
.group-name {
overflow: hidden;
text-overflow: ellipsis;
display: inline-block;
vertical-align: middle;
width: 75%;
margin-right: 5%;
}
.group-allocation {
display: inline-block;
vertical-align: middle;
width: 20%;
color: $gray-l1;
text-align: right;
}
}
}
.actions {
@include transition(opacity .15s .25s ease-in-out);
opacity: 0.0;
position: absolute;
top: $baseline;
right: $baseline;
.action {
.ui-toggle-expansion {
@include transition(rotate .15s ease-in-out .25s);
@extend %t-action1;
display: inline-block;
vertical-align: middle;
margin-right: ($baseline/4);
.edit {
@extend %ui-btn-non-blue;
}
.delete {
@extend %ui-btn-non;
&.is-disabled {
background-color: $gray-l3;
color: $gray-l6;
}
}
width: ($baseline*0.75);
vertical-align: baseline;
margin-left: -$baseline;
}
}
}
.wrapper-group-configuration-usages {
@extend %t-copy-sub1;
box-shadow: 0 2px 2px 0 $shadow inset;
padding: $baseline ($baseline*1.5) $baseline ($baseline*2.5);
color: $gray-l1;
&.is-selectable {
@extend %ui-fake-link;
.group-configuration-usage {
margin-left: $baseline;
&:hover {
color: $blue;
.group-configuration-usage-unit {
padding: ($baseline/4) 0;
a {
font-weight: 600;
}
.fa-warning {
margin: ($baseline/4) ($baseline/2) 0 ($baseline*1.5);
color: $orange;
}
.fa-times-circle {
margin: ($baseline/4) ($baseline/2) 0 ($baseline*1.5);
color: $red-l2;
.ui-toggle-expansion {
color: $blue;
}
}
}
}
}
}
.wrapper-group-configuration-validation {
.collection-info {
@extend %t-copy-sub1;
color: $gray-l1;
margin-left: $baseline;
&.collection-info-inline {
display: table;
width: 70%;
margin: ($baseline/4) 0 ($baseline/2) $baseline;
li {
@include box-sizing(border-box);
display: table-cell;
margin-right: 1%;
padding: ($baseline/4) 0;
&.collection-usage-count {
font-style: italic;
}
}
}
.collection-label {
text-transform: uppercase;
}
.collection-description {
overflow: hidden;
text-overflow: ellipsis;
}
}
.collection-items {
margin-left: $baseline;
margin-bottom: ($baseline*0.75);
.item {
@extend %t-copy-lead1;
padding: ($baseline/7) 0 ($baseline/4);
border-top: 1px solid $gray-l4;
white-space: nowrap;
&:first-child {
border-top: none;
}
.name {
overflow: hidden;
text-overflow: ellipsis;
display: inline-block;
vertical-align: middle;
width: 75%;
margin-right: 5%;
}
}
}
.collection-details {
.actions {
@include transition(opacity .15s .25s ease-in-out);
position: absolute;
top: $baseline;
right: $baseline;
opacity: 0.0;
.action {
display: inline-block;
vertical-align: middle;
margin-right: ($baseline/4);
.edit {
@extend %ui-btn-non-blue;
}
.delete {
@extend %ui-btn-non;
&.is-disabled {
background-color: $gray-l3;
color: $gray-l6;
}
}
}
}
}
.collection-references {
@extend %t-copy-sub1;
box-shadow: 0 2px 2px 0 $shadow inset;
padding: $baseline ($baseline*1.5) $baseline ($baseline*2.5);
color: $gray-l1;
.usage {
margin-left: $baseline;
.usage-unit {
padding: ($baseline/4) 0;
a {
@extend %t-strong;
}
.fa-warning {
margin: ($baseline/4) ($baseline/2) 0 ($baseline*1.5);
color: $orange;
}
.fa-times-circle {
margin: ($baseline/4) ($baseline/2) 0 ($baseline*1.5);
color: $red-l2;
}
}
}
}
.usage-validation {
@extend %t-copy-sub1;
background-color: $gray-l6;
margin-top: $baseline;
@@ -233,17 +223,21 @@
float: left;
}
.group-configuration-validation-text {
.collection-validation-text {
overflow: auto;
}
}
.group-configuration-edit {
.collection-edit {
@include box-sizing(border-box);
border-radius: 2px;
width: 100%;
background: $white;
.message {
margin-bottom: 0;
}
.wrapper-form {
padding: $baseline ($baseline*1.5);
}
@@ -260,6 +254,113 @@
color: $gray;
}
.collection-fields {
@extend %cont-no-list;
margin-bottom: $baseline;
}
.field {
margin: 0 0 ($baseline*0.75) 0;
&:last-child {
@extend %wipe-last-child;
}
&.required {
label {
@extend %t-strong;
}
label:after {
margin-left: ($baseline/4);
content: "*";
}
}
label, input, textarea {
display: block;
}
textarea {
resize: vertical;
}
label {
@extend %t-copy-sub1;
@include transition(color, 0.15s, ease-in-out);
margin: 0 0 ($baseline/4) 0;
&.is-focused {
color: $blue;
}
}
//this section is borrowed from _account.scss - we should clean up and unify later
input, textarea {
@extend %t-copy-base;
height: 100%;
width: 100%;
padding: ($baseline/2);
&.long {
width: 100%;
}
&.short {
width: 25%;
}
::-webkit-input-placeholder {
color: $gray-l4;
}
:-moz-placeholder {
color: $gray-l3;
}
::-moz-placeholder {
color: $gray-l3;
}
:-ms-input-placeholder {
color: $gray-l3;
}
&:focus {
+ .tip {
color: $gray;
}
}
}
&.error {
label {
color: $red;
}
input {
border-color: $red;
}
}
}
label.required {
@extend %t-strong;
&:after {
margin-left: ($baseline/4);
content: "*";
}
}
.field.add-collection-name label {
@extend %t-title5;
display: inline-block;
vertical-align: bottom;
}
.actions {
box-shadow: inset 0 1px 2px $shadow;
border-top: 1px solid $gray-l1;
@@ -304,191 +405,9 @@
@extend %t-strong;
}
}
.groups-fields,
.group-configuration-fields {
@extend %cont-no-list;
.field {
margin: 0 0 ($baseline*0.75) 0;
&:last-child {
margin-bottom: 0;
}
&.required {
label {
@extend %t-strong;
}
label:after {
margin-left: ($baseline/4);
content: "*";
}
}
label, input, textarea {
display: block;
}
textarea {
resize: vertical;
}
label {
@extend %t-copy-sub1;
@include transition(color, 0.15s, ease-in-out);
margin: 0 0 ($baseline/4) 0;
&.is-focused {
color: $blue;
}
}
//this section is borrowed from _account.scss - we should clean up and unify later
input, textarea {
@extend %t-copy-base;
height: 100%;
width: 100%;
padding: ($baseline/2);
&.long {
width: 100%;
}
&.short {
width: 25%;
}
::-webkit-input-placeholder {
color: $gray-l4;
}
:-moz-placeholder {
color: $gray-l3;
}
::-moz-placeholder {
color: $gray-l3;
}
:-ms-input-placeholder {
color: $gray-l3;
}
&:focus {
+ .tip {
color: $gray;
}
}
}
&.error {
label {
color: $red;
}
input {
border-color: $red;
}
}
&.add-group-configuration-name label {
@extend %t-title5;
display: inline-block;
width: 50%;
padding-right: 5%;
overflow: hidden;
text-overflow: ellipsis;
vertical-align: bottom;
}
.group-configuration-id {
display: inline-block;
width: 45%;
text-align: right;
vertical-align: top;
color: $gray-l1;
.group-configuration-value {
@extend %t-strong;
white-space: nowrap;
margin-left: ($baseline*0.5);
}
}
&.group-allocation {
color: $gray-l1;
}
}
label.required {
@extend %t-strong;
&:after {
margin-left: ($baseline/4);
content: "*";
}
}
.field-group {
@include clearfix();
margin: 0 0 ($baseline/2) 0;
padding: ($baseline/4) 0 0 0;
.group-allocation,
.field {
display: inline-block;
vertical-align: middle;
margin: 0 3% 0 0;
}
.group-allocation {
max-width: 10%;
min-width: 5%;
color: $gray-l1;
}
.field {
position: relative;
&.long {
width: 80%;
}
&.short {
width: 10%;
}
}
.action-close {
@include transition(color $tmg-f2 ease-in-out);
@extend %t-action1;
display: inline-block;
border: 0;
padding: 0;
background: transparent;
color: $blue-l3;
vertical-align: middle;
&:hover {
color: $blue;
}
}
}
}
.group-configuration-fields {
margin-bottom: $baseline;
}
}
&:hover .wrapper-group-configuration .actions {
opacity: 1.0;
}
.action-add-group {
.action-add-item {
@extend %ui-btn-flat-outline;
@extend %t-action2;
@extend %t-strong;
@@ -499,7 +418,7 @@
}
}
// add/new items
// add/new collection
.action-add {
@extend %ui-btn-flat-outline;
display: block;
@@ -517,13 +436,167 @@
@include margin-right($baseline/2);
}
}
// specific group-type styles
.content-groups {
.collection-header{
.title {
margin-bottom: 0;
}
}
}
.experiment-groups {
.group-configuration-details {
.group-configuration-info {
@extend %t-copy-sub1;
color: $gray-l1;
margin-left: $baseline;
&.group-configuration-info-inline {
display: table;
width: 70%;
margin: ($baseline/4) 0 ($baseline/2) $baseline;
li {
@include box-sizing(border-box);
display: table-cell;
margin-right: 1%;
&.group-configuration-usage-count {
font-style: italic;
}
}
}
&.group-configuration-info-block {
li {
padding: ($baseline/4) 0;
}
}
.group-configuration-label {
text-transform: uppercase;
}
.group-configuration-description {
overflow: hidden;
text-overflow: ellipsis;
}
}
.groups {
margin-left: $baseline;
margin-bottom: ($baseline*0.75);
.group {
@extend %t-copy-lead1;
padding: ($baseline/7) 0 ($baseline/4);
border-top: 1px solid $gray-l4;
white-space: nowrap;
&:first-child {
border-top: none;
}
.group-name {
overflow: hidden;
text-overflow: ellipsis;
display: inline-block;
vertical-align: middle;
width: 75%;
margin-right: 5%;
}
.group-allocation {
display: inline-block;
vertical-align: middle;
width: 20%;
color: $gray-l1;
text-align: right;
}
}
}
}
.group-configuration-edit {
.add-collection-name label {
width: 50%;
padding-right: 5%;
overflow: hidden;
text-overflow: ellipsis;
vertical-align: bottom;
}
.group-configuration-id {
display: inline-block;
width: 45%;
text-align: right;
vertical-align: top;
color: $gray-l1;
.group-configuration-value {
@extend %t-strong;
white-space: nowrap;
margin-left: ($baseline*0.5);
}
}
.field-group {
@include clearfix();
margin: 0 0 ($baseline/2) 0;
padding: ($baseline/4) 0 0 0;
.group-allocation,
.field {
display: inline-block;
vertical-align: middle;
margin: 0 3% 0 0;
}
.group-allocation {
max-width: 10%;
min-width: 5%;
color: $gray-l1;
}
.field {
position: relative;
&.long {
width: 80%;
}
&.short {
width: 10%;
}
}
.action-close {
@include transition(color $tmg-f2 ease-in-out);
@extend %t-action1;
display: inline-block;
border: 0;
padding: 0;
background: transparent;
color: $blue-l3;
vertical-align: middle;
&:hover {
color: $blue;
}
}
}
}
}
}
.content-supplementary {
width: flex-grid(3, 12);
.content-groups-doc {
margin-bottom: $baseline;
}
}
}

View File

@@ -63,8 +63,8 @@
% endif
</article>
<aside class="content-supplementary" role="complementary">
<div class="content-groups-doc">
<div class="bit">
<div class="bit">
<div class="content-groups-doc">
<h3 class="title-3">${_("Content Groups")}</h3>
<p>${_("Use content groups to give groups of students access to a specific set of course content. In addition to course content that is intended for all students, each content group sees content that you specifically designate as visible to it. By associating a content group with one or more cohorts, you can customize the content that a particular cohort or cohorts sees in your course.")}</p>
<p>${_("Click {em_start}New content group{em_end} to add a new content group. To edit the name of a content group, hover over its box and click {em_start}Edit{em_end}. Content groups cannot be deleted.").format(em_start="<strong>", em_end="</strong>")}</p>
@@ -72,8 +72,8 @@
</div>
</div>
% if should_show_experiment_groups:
<div class="experiment-groups-doc">
<div class="bit">
<div class="bit">
<div class="experiment-groups-doc">
<h3 class="title-3">${_("Experiment Group Configurations")}</h3>
<p>${_("Use experiment group configurations to define how many groups of students are in a content experiment. When you create a content experiment for a course, you select the group configuration to use.")}</p>
<p>${_("Click {em_start}New Group Configuration{em_end} to add a new configuration. To edit a configuration, hover over its box and click {em_start}Edit{em_end}.").format(em_start="<strong>", em_end="</strong>")}</p>

View File

@@ -1,11 +1,11 @@
<div class="wrapper-group-configuration">
<header class="group-configuration-header">
<h3 class="group-configuration-title">
<div class="collection-details">
<header class="collection-header">
<h3 class="title">
<%- name %>
</h3>
</header>
<ul class="actions group-configuration-actions">
<ul class="actions">
<li class="action action-edit">
<button class="edit"><i class="icon fa fa-pencil"></i> <%= gettext("Edit") %></button>
</li>

View File

@@ -1,14 +1,14 @@
<form class="group-configuration-edit-form">
<div class="wrapper-form">
<form class="collection-edit-form">
<% if (error && error.message) { %>
<div class="group-configuration-edit-error message message-status message-status error is-shown" name="group-configuration-edit-error">
<div class="content-group-edit-error message message-status message-status error is-shown">
<%= gettext(error.message) %>
</div>
<% } %>
<fieldset class="groups-fields">
<div class="input-wrap field text required add-group-configuration-name <% if(error && error.attributes && error.attributes.name) { print('error'); } %>">
<div class="wrapper-form">
<fieldset class="collection-fields">
<div class="input-wrap field text required add-collection-name <% if(error && error.attributes && error.attributes.name) { print('error'); } %>">
<label for="group-cohort-name-<%= uniqueId %>"><%= gettext("Content Group Name") %></label>
<input name="group-cohort-name" id="group-cohort-name-<%= uniqueId %>" class="group-configuration-name-input input-text" value="<%- name %>" type="text" placeholder="<%= gettext("This is the name of the group") %>">
<input name="group-cohort-name" id="group-cohort-name-<%= uniqueId %>" class="collection-name-input input-text" value="<%- name %>" type="text" placeholder="<%= gettext("This is the name of the group") %>">
</div>
</fieldset>
</div>

View File

@@ -1,14 +1,14 @@
<div class="wrapper-group-configuration">
<header class="group-configuration-header">
<h3 class="group-configuration-title">
<a href="#" class="group-toggle <% if(showGroups){ print('hide'); } else { print('show'); } %>-groups">
<div class="collection-details wrapper-group-configuration">
<header class="collection-header group-configuration-header">
<h3 class="title group-configuration-title">
<a href="#" class="toggle group-toggle <% if(showGroups){ print('hide'); } else { print('show'); } %>-groups">
<i class="ui-toggle-expansion icon fa fa-caret-<% if(showGroups){ print('down'); } else { print('right'); } %>"></i>
<%= name %>
</a>
</h3>
</header>
<ol class="group-configuration-info group-configuration-info-<% if(showGroups){ print('block'); } else { print('inline'); } %>">
<ol class="collection-info group-configuration-info group-configuration-info-<% if(showGroups){ print('block'); } else { print('inline'); } %>">
<% if (!_.isUndefined(id)) { %>
<li class="group-configuration-id"
><span class="group-configuration-label"><%= gettext('ID') %>: </span
@@ -16,7 +16,7 @@
></li>
<% } %>
<% if (showGroups) { %>
<li class="group-configuration-description">
<li class="collection-description group-configuration-description">
<%= description %>
</li>
<% } else { %>
@@ -31,11 +31,11 @@
<% if(showGroups) { %>
<% allocation = Math.floor(100 / groups.length) %>
<ol class="groups groups-<%= index %>">
<ol class="collection-items groups groups-<%= index %>">
<% groups.each(function(group, groupIndex) { %>
<li class="group group-<%= groupIndex %>">
<span class="group-name"><%= group.get('name') %></span>
<span class="group-allocation"><%= allocation %>%</span>
<li class="item group group-<%= groupIndex %>">
<span class="name group-name"><%= group.get('name') %></span>
<span class="meta group-allocation"><%= allocation %>%</span>
</li>
<% }) %>
</ol>
@@ -56,12 +56,12 @@
</ul>
</div>
<% if(showGroups) { %>
<div class="wrapper-group-configuration-usages">
<div class="collection-references wrapper-group-configuration-usages">
<% if (!_.isEmpty(usage)) { %>
<h4 class="group-configuration-usage-text"><%= gettext('This Group Configuration is used in:') %></h4>
<ol class="group-configuration-usage">
<h4 class="intro group-configuration-usage-text"><%= gettext('This Group Configuration is used in:') %></h4>
<ol class="usage group-configuration-usage">
<% _.each(usage, function(unit) { %>
<li class="group-configuration-usage-unit">
<li class="usage-unit group-configuration-usage-unit">
<p><a href=<%= unit.url %> ><%= unit.label %></a></p>
<% if (unit.validation) { %>
<p>
@@ -70,7 +70,7 @@
<% } else if (unit.validation.type === 'error') { %>
<i class="icon fa fa-exclamation-circle"></i>
<% } %>
<span class="group-configuration-validation-message">
<span class="usage-validation-message group-configuration-validation-message">
<%= unit.validation.text %>
</span>
</p>

View File

@@ -1,13 +1,13 @@
<form class="group-configuration-edit-form">
<div class="wrapper-form">
<form class="collection-edit-form group-configuration-edit-form">
<% if (error && error.message) { %>
<div class="group-configuration-edit-error message message-status message-status error is-shown" name="group-configuration-edit-error">
<%= gettext(error.message) %>
</div>
<% } %>
<fieldset class="group-configuration-fields">
<div class="wrapper-form">
<fieldset class="collection-fields group-configuration-fields">
<legend class="sr"><%= gettext("Group Configuration information") %></legend>
<div class="input-wrap field text required add-group-configuration-name <% if(error && error.attributes && error.attributes.name) { print('error'); } %>">
<div class="input-wrap field text required add-collection-name add-group-configuration-name <% if(error && error.attributes && error.attributes.name) { print('error'); } %>">
<label for="group-configuration-name-<%= uniqueId %>"><%= gettext("Group Configuration Name") %></label><%
if (!_.isUndefined(id)) {
%><span class="group-configuration-id">
@@ -16,7 +16,7 @@
</span><%
}
%>
<input id="group-configuration-name-<%= uniqueId %>" class="group-configuration-name-input input-text" name="group-configuration-name" type="text" placeholder="<%= gettext("This is the Name of the Group Configuration") %>" value="<%= name %>">
<input id="group-configuration-name-<%= uniqueId %>" class="collection-name-input input-text" name="group-configuration-name" type="text" placeholder="<%= gettext("This is the Name of the Group Configuration") %>" value="<%= name %>">
<span class="tip tip-stacked"><%= gettext("Name or short description of the configuration") %></span>
</div>
<div class="input-wrap field text add-group-configuration-description">
@@ -30,10 +30,10 @@
<label class="groups-fields-label required"><%= gettext("Groups") %></label>
<span class="tip tip-stacked"><%= gettext("Name of the groups that students will be assigned to, for example, Control, Video, Problems. You must have two or more groups.") %></span>
<ol class="groups list-input enum"></ol>
<button class="action action-add-group"><i class="icon fa fa-plus"></i> <%= gettext("Add another group") %></button>
<button class="action action-add-group action-add-item"><i class="icon fa fa-plus"></i> <%= gettext("Add another group") %></button>
</fieldset>
<% if (!_.isEmpty(usage)) { %>
<div class="wrapper-group-configuration-validation">
<div class="wrapper-group-configuration-validation usage-validation">
<i class="icon fa fa-warning"></i>
<p class="group-configuration-validation-text">
<%= gettext('This configuration is currently used in content experiments. If you make changes to the groups, you may need to edit those experiments.') %>

View File

@@ -1,9 +1,12 @@
<% if (length === 0) { %>
<div class="no-group-configurations-content">
<p><%- interpolate(gettext("You have not created any %(item_type)ss yet."), {item_type: itemCategoryDisplayName}, true) %><a href="#" class="button new-button"><i class="icon fa fa-plus"></i> <%= gettext("Add your first content group") %></a></p>
<div class="no-content">
<p>
<%- emptyMessage %>
<a href="#" class="button new-button"><i class="icon fa fa-plus"></i> <%= interpolate(gettext("Add your first %(item_type)s"), {item_type: itemCategoryDisplayName}, true) %></a>
</p>
</div>
<% } else { %>
<div class="content-groups"></div>
<div class="list-items"></div>
<% if (!isEditing) { %>
<button class="action action-add">
<i class="icon fa fa-plus"></i><%- interpolate(gettext('New %(item_type)s'), {item_type: itemCategoryDisplayName}, true) %>

View File

@@ -49,7 +49,7 @@ class GroupConfigurationsPage(CoursePage):
"""
Return list of the group-configurations-list-item's of specified type for the course.
"""
css = prefix + ' .group-configurations-list-item'
css = prefix + ' .wrapper-collection'
return [GroupConfiguration(self, prefix, index) for index in xrange(len(self.q(css=css)))]
def create_experiment_group_configuration(self):
@@ -90,7 +90,7 @@ class GroupConfigurationsPage(CoursePage):
"""
Returns the message about "no content" for the specified type.
"""
return self.q(css='.wrapper-content ' + prefix + ' .no-group-configurations-content')
return self.q(css='.wrapper-content ' + prefix + ' .no-content')
@property
def experiment_group_sections_present(self):
@@ -107,7 +107,7 @@ class GroupConfiguration(object):
def __init__(self, page, prefix, index):
self.page = page
self.SELECTOR = prefix + ' .group-configurations-list-item-{}'.format(index)
self.SELECTOR = prefix + ' .wrapper-collection-{}'.format(index)
self.index = index
def get_selector(self, css=''):
@@ -195,9 +195,9 @@ class GroupConfiguration(object):
"""
Return group configuration mode.
"""
if self.find_css('.group-configuration-edit').present:
if self.find_css('.collection-edit').present:
return 'edit'
elif self.find_css('.group-configuration-details').present:
elif self.find_css('.collection').present:
return 'details'
@property
@@ -227,14 +227,14 @@ class GroupConfiguration(object):
"""
Return group configuration name.
"""
return self.get_text('.group-configuration-title')
return self.get_text('.title')
@name.setter
def name(self, value):
"""
Set group configuration name.
"""
self.find_css('.group-configuration-name-input').first.fill(value)
self.find_css('.collection-name-input').first.fill(value)
@property
def description(self):