diff --git a/cms/envs/aws.py b/cms/envs/aws.py index 44b6ea2ffb..7fdd7496a4 100644 --- a/cms/envs/aws.py +++ b/cms/envs/aws.py @@ -339,3 +339,4 @@ if FEATURES['ENABLE_COURSEWARE_INDEX'] or FEATURES['ENABLE_LIBRARY_INDEX']: SEARCH_ENGINE = "search.elastic.ElasticSearchEngine" XBLOCK_SETTINGS = ENV_TOKENS.get('XBLOCK_SETTINGS', {}) +XBLOCK_SETTINGS.setdefault("VideoDescriptor", {})["licensing_enabled"] = FEATURES.get("LICENSING", False) diff --git a/cms/envs/common.py b/cms/envs/common.py index e826d7f460..d10c98bcc8 100644 --- a/cms/envs/common.py +++ b/cms/envs/common.py @@ -143,6 +143,9 @@ FEATURES = { # Toggle course entrance exams feature 'ENTRANCE_EXAMS': False, + # Toggle platform-wide course licensing + 'LICENSING': False, + # Enable the courseware search functionality 'ENABLE_COURSEWARE_INDEX': False, @@ -945,3 +948,9 @@ ELASTIC_FIELD_MAPPINGS = { "type": "date" } } + +XBLOCK_SETTINGS = { + "VideoDescriptor": { + "licensing_enabled": FEATURES.get("LICENSING", False) + } +} diff --git a/cms/envs/devstack.py b/cms/envs/devstack.py index 3aa7f47b00..1acaadd6a5 100644 --- a/cms/envs/devstack.py +++ b/cms/envs/devstack.py @@ -78,6 +78,9 @@ FEATURES['MILESTONES_APP'] = True ################################ ENTRANCE EXAMS ################################ FEATURES['ENTRANCE_EXAMS'] = True +################################ COURSE LICENSES ################################ +FEATURES['LICENSING'] = True + ################################ SEARCH INDEX ################################ FEATURES['ENABLE_COURSEWARE_INDEX'] = True FEATURES['ENABLE_LIBRARY_INDEX'] = True diff --git a/cms/static/js/spec/views/license_spec.js b/cms/static/js/spec/views/license_spec.js index 6123b5190c..510a33fba1 100644 --- a/cms/static/js/spec/views/license_spec.js +++ b/cms/static/js/spec/views/license_spec.js @@ -138,19 +138,19 @@ define(["js/views/license", "js/models/license", "js/common_helpers/template_hel it("has no preview by default", function () { this.view.render(); - expect(this.view.$("#license-preview").length).toEqual(0) + expect(this.view.$(".license-preview").length).toEqual(0) this.view.$("li[data-license=creative-commons] button").click(); - expect(this.view.$("#license-preview").length).toEqual(0) + expect(this.view.$(".license-preview").length).toEqual(0) }); it("displays a preview if showPreview is true", function() { this.view = new LicenseView({model: this.model, showPreview: true}); this.view.render() - expect(this.view.$("#license-preview").length).toEqual(1) - expect(this.view.$("#license-preview")).toHaveText(""); + expect(this.view.$(".license-preview").length).toEqual(1) + expect(this.view.$(".license-preview")).toHaveText(""); this.view.$("li[data-license=creative-commons] button").click(); - expect(this.view.$("#license-preview").length).toEqual(1) - expect(this.view.$("#license-preview")).toContainText("Some Rights Reserved"); + expect(this.view.$(".license-preview").length).toEqual(1) + expect(this.view.$(".license-preview")).toContainText("Some Rights Reserved"); }); }) diff --git a/cms/static/js/views/license.js b/cms/static/js/views/license.js index 1f1dcf5484..013b79e8b5 100644 --- a/cms/static/js/views/license.js +++ b/cms/static/js/views/license.js @@ -7,7 +7,7 @@ define(["js/views/baseview", "underscore"], function(BaseView, _) { "creative-commons": { "name": gettext("Creative Commons"), "tooltip": gettext("You waive some rights for your work, such that others can use it too"), - "url": "//creativecommons.org/about", + "url": "https://creativecommons.org/about", "options": { "ver": { "name": gettext("Version"), @@ -18,31 +18,27 @@ define(["js/views/baseview", "underscore"], function(BaseView, _) { "name": gettext("Attribution"), "type": "boolean", "default": true, - "help": gettext("Allow others to copy, distribute, display and perform " + - "your copyrighted work but only if they give credit the way you request."), + "help": gettext("Allow others to copy, distribute, display and perform your copyrighted work but only if they give credit the way you request. Currently, this option is required."), "disabled": true, }, "NC": { "name": gettext("Noncommercial"), "type": "boolean", "default": true, - "help": gettext("Allow others to copy, distribute, display and perform " + - "your work - and derivative works based upon it - but for noncommercial purposes only."), + "help": gettext("Allow others to copy, distribute, display and perform your work - and derivative works based upon it - but for noncommercial purposes only."), }, "ND": { "name": gettext("No Derivatives"), "type": "boolean", "default": true, - "help": gettext("Allow others to copy, distribute, display and perform " + - "only verbatim copies of your work, not derivative works based upon it."), + "help": gettext("Allow others to copy, distribute, display and perform only verbatim copies of your work, not derivative works based upon it. This option is incompatible with \"Share Alike\"."), "conflictsWith": ["SA"] }, "SA": { "name": gettext("Share Alike"), "type": "boolean", "default": false, - "help": gettext("Allow others to distribute derivative works only under " + - "a license identical to the license that governs your work."), + "help": gettext("Allow others to distribute derivative works only under a license identical to the license that governs your work. This option is incompatible with \"No Derivatives\"."), "conflictsWith": ["ND"] } }, @@ -132,6 +128,7 @@ define(["js/views/baseview", "underscore"], function(BaseView, _) { // fire the change event manually. this.model.trigger("change change:options") } + e.preventDefault(); } }); diff --git a/cms/static/js/views/settings/main.js b/cms/static/js/views/settings/main.js index ded47c14ca..c8bb8552ca 100644 --- a/cms/static/js/views/settings/main.js +++ b/cms/static/js/views/settings/main.js @@ -276,12 +276,13 @@ var DetailsView = ValidatingView.extend({ this.model.fetch({ success: function() { self.render(); - _.each(self.codeMirrors, - function(mirror) { - var ele = mirror.getTextArea(); - var field = self.selectorToField[ele.id]; - mirror.setValue(self.model.get(field)); - }); + _.each(self.codeMirrors, function(mirror) { + var ele = mirror.getTextArea(); + var field = self.selectorToField[ele.id]; + mirror.setValue(self.model.get(field)); + }); + self.licenseModel.setFromString(self.model.get("license"), {silent: true}); + self.licenseView.render() }, reset: true, silent: true}); diff --git a/cms/static/sass/elements/_forms.scss b/cms/static/sass/elements/_forms.scss index 5f0bea1afc..307bd31d98 100644 --- a/cms/static/sass/elements/_forms.scss +++ b/cms/static/sass/elements/_forms.scss @@ -172,107 +172,6 @@ form { } } -// +Forms - License selector UI -// ==================== -.license-img { - padding: 4px; -} - -ul.license-types { - text-align: middle; - vertical-align: middle; - display: inline-block; - - li { - display: inline-block; - } - - .action.license-button { - @include grey-button; - @extend %t-action2; - - display: inline-block; - - text-align: center; - - width: 220px; - height: 40px; - - cursor: pointer; - - &.is-selected { - @include blue-button; - } - } - - .tip { - @extend %t-copy-sub2; - } -} -.wrapper-license-options { - margin-bottom: 10px; - - .tip { - @extend %t-copy-sub2; - } - #list-license-options { - padding-bottom: 10px; - - li { - line-height: 1.5; - border-bottom: 1px solid #EEE; - padding: ($baseline / 2) 0 ($baseline * 0.4); - &.is-clickable { - cursor: pointer; - } - &.last { - border-bottom: none; - } - - .fa { - vertical-align: top; - } - .fa-square-o { - display: inline-block; - margin: ($baseline * 0.15) 15px 0px; - } - .fa-square-o.is-disabled { - color: $gray; - } - .fa-check-square-o { - color: $blue; - display: none; - margin: ($baseline * 0.15) 14px 0px 16px; - } - .fa-check-square-o.is-disabled { - color: $gray; - } - &.is-selected { - .fa-check-square-o { - display: inline-block; - } - .fa-square-o { - display: none; - } - } - .option-name { - @extend %t-action3; - @extend %t-strong; - display: inline-block; - width: 15%; - vertical-align: top; - } - .explanation { - @extend %t-action4; - display: inline-block; - width: 75%; - vertical-align: top; - color: $gray; - } - } - } -} - // +Form - Create New // ==================== // form styling for creating a new content item (course, user, textbook) diff --git a/cms/static/sass/elements/_xblocks.scss b/cms/static/sass/elements/_xblocks.scss index 5bd2955234..9d110c056d 100644 --- a/cms/static/sass/elements/_xblocks.scss +++ b/cms/static/sass/elements/_xblocks.scss @@ -1,9 +1,22 @@ // studio - elements - xblock rendering // ========================== -// styling for xblocks at various levels of nesting: page level, +// Table of Contents +// * +Layout - Xblocks +// * +Licensing - Xblocks +// * +Pagination - Xblocks +// * +Messaging - Xblocks +// * +Case: Page Level +// * +Case: Nesting Level +// * +Case: Element / Component Level +// * +Case: Experiment Groups - Edited +// * +Editing - Xblocks +// * +Case - Special Xblock Type Overrides -// extends - UI archetypes - xblock rendering + +// +Layout - Xblocks +// ==================== +// styling for xblocks at various levels of nesting: page level, .wrapper-xblock { margin: ($baseline/2); border: 1px solid $gray-l4; @@ -45,7 +58,7 @@ } } - // secondary header for meta-information and associated actions + // UI: secondary header for meta-information and associated actions .xblock-header-secondary { overflow: hidden; border-top: 1px solid $gray-l3; @@ -103,28 +116,48 @@ } } + // +Licensing - Xblocks + // ==================== .xblock-license, - .xmodule_display.xmodule_HtmlModule .xblock-license { - text-align: $bi-app-right; + .xmodule_display.xmodule_HtmlModule .xblock-license, + .xmodule_VideoModule .xblock-license { + @include text-align(right); + @extend %t-title7; + display: block; + width: auto; border-top: 1px solid $gray-l3; - margin: 0 15px; - padding: 5px; - font-size: 80%; - color: $gray-l3; + padding: ($baseline/4) 0; + color: $gray; + text-align: $bi-app-right; + + .license-label, + .license-value, + .license-actions { + display: inline-block; + vertical-align: middle; + margin-bottom: 0; + } a { - color: $gray-l3; + color: $gray; &:hover { color: $ui-link-color; } } - span { - color: inherit; - } + i { + font-style: normal; + } } + // CASE: xblocks video + .xmodule_VideoModule .xblock-license { + border: 0; + } + + + // +Pagination - Xblocks .container-paging-header { .meta-wrap { margin: $baseline ($baseline/2); @@ -154,12 +187,9 @@ } } - - - // ==================== - //UI: default internal xblock content styles - + // ==================== + // TO-DO: clean-up / remove this reset // internal headings for problems and video components h2 { @extend %t-title5; @@ -220,6 +250,8 @@ } } + // +Messaging - Xblocks + // ==================== // xblock message area, for general information as well as validation .wrapper-xblock-message { @@ -281,7 +313,8 @@ } } - // CASE: page level - outer most level + // +Case: Page Level + // ==================== &.level-page { margin: 0; box-shadow: none; @@ -325,7 +358,9 @@ } - // CASE: nesting level - element wrapper level + // +Case: Nesting Level + // ==================== + // element wrapper level &.level-nesting { @include transition(all $tmg-f2 linear 0s); border: 1px solid $gray-l3; @@ -359,7 +394,8 @@ } } - // CASE: element/component level + // +Case: Element / Component Level + // ==================== &.level-element { @include transition(all $tmg-f2 linear 0s); box-shadow: none; @@ -416,7 +452,9 @@ } } - // CASE: edited experiment groups: active and inactive + // +Case: Experiment Groups - Edited + // ==================== + // edited experiment groups: active and inactive .wrapper-groups { .title { @@ -456,8 +494,8 @@ } } +// +Editing - Xblocks // ==================== -// XBlock editing // xblock Editor tab wrapper .wrapper-comp-editor { @@ -807,7 +845,10 @@ } } -// CASE: special xblock type overrides + +// +Case - Special Xblock Type Overrides +// ==================== +// TO-DO - remove this reset styling from base _xblocks.scss file // Latex Compiler // make room for the launch compiler button diff --git a/cms/static/sass/views/_outline.scss b/cms/static/sass/views/_outline.scss index 4cfa1958b2..c30113f351 100644 --- a/cms/static/sass/views/_outline.scss +++ b/cms/static/sass/views/_outline.scss @@ -217,27 +217,7 @@ } } - // course content license - // -------------------- - .course-license { - @extend .content-primary; - @include text-align(right); - display: block; - float: $bi-app-right; - width: auto; - - .license-label, - .license-value, - .license-actions { - display: inline-block; - vertical-align: middle; - margin-bottom: 0; - } - - img { - display: inline; - } - } + // REMOVE BEFORE MERGE - removed outline styling here from cms .wrapper-dnd { clear: both; diff --git a/cms/static/sass/views/_settings.scss b/cms/static/sass/views/_settings.scss index 9f91c780f5..4ce75c5ba2 100644 --- a/cms/static/sass/views/_settings.scss +++ b/cms/static/sass/views/_settings.scss @@ -1,6 +1,11 @@ // studio - views - course settings // ==================== +// Table of Contents +// * +Settings - Base / All +// * +Settings - Licenses +// +Settings - Base / All +// ==================== .view-settings { @include text-align(left); @include direction(); @@ -104,10 +109,11 @@ margin-top: ($baseline/4); color: $gray-d1; } - .tip-inline{ - display: inline; - margin-left: 5px; - } + + .tip-inline { + display: inline; + @include margin-left($baseline/4); + } .message-error { @extend %t-copy-sub1; @@ -149,6 +155,7 @@ } } } + #heading-entrance-exam{ font-weight: 600; } @@ -156,6 +163,7 @@ label[for="entrance-exam-enabled"] { font-size: 14px; } + .field { margin: 0 0 ($baseline*2) 0; @@ -978,3 +986,100 @@ } } } + +// +Settings - Licenses +// ==================== +.view-settings { + + .license-img { + padding: ($baseline/5); + } + + .license-types { + text-align: center; + vertical-align: middle; + display: inline-block; + + .license-type { + display: inline-block; + } + + .action.license-button { + @include grey-button; + @extend %t-action2; + display: inline-block; + text-align: center; + width: 220px; + height: 40px; + cursor: pointer; + + &.is-selected { + @include blue-button; + } + } + + .tip { + @extend %t-copy-sub2; + } + } + .wrapper-license-options { + margin-bottom: ($baseline/2); + + .tip { + @extend %t-copy-sub2; + } + .license-options { + padding-bottom: ($baseline/2); + + .license-option { + line-height: 1.5; + border-bottom: 1px solid $gray-l4; + padding: ($baseline/2) 0 ($baseline*0.4); + + &.is-clickable { + cursor: pointer; + } + + &:last-child { + border-bottom: none; + } + + input[type=checkbox] { + vertical-align: top; + width: auto; + min-width: auto; + height: auto; + border: 0; + margin: ($baseline*0.15) 15px 0px; + } + + .option-name { + @extend %t-action3; + @extend %t-strong; + display: inline-block; + width: 15%; + vertical-align: top; + cursor: pointer; + } + .explanation { + @extend %t-action4; + display: inline-block; + width: 75%; + vertical-align: top; + color: $gray; + } + } + } + } + .license-preview a { + color: $gray; + + &:hover { + color: $ui-link-color; + } + } + .list-input.settings-list ul.license-options li { + // to make sure the padding is correctly overridden + padding: ($baseline / 2) 0 ($baseline * 0.4); + } +} \ No newline at end of file diff --git a/cms/templates/course_outline.html b/cms/templates/course_outline.html index f0a3cc1e98..f3246a9e9f 100644 --- a/cms/templates/course_outline.html +++ b/cms/templates/course_outline.html @@ -109,13 +109,6 @@ from contentstore.utils import reverse_usage_url - % if settings.FEATURES.get("LICENSING", False): -
<%include file="license.html" args="license=context_course.license" />
-
div {
+ display: table;
+ table-layout: fixed;
+ width: 100%;
+ border-radius: 3px;
+ border: 1px solid $outer-border-color;
+ background: $container-bg;
+ box-shadow: 0 1px 2px $shadow-l2;
+ }
+}
+
+
+// +Resets - Old, Body
+// ====================
+
body {
min-width: 980px;
min-height: 100%;
@@ -26,25 +60,8 @@ a {
}
}
-.content-wrapper {
- background: none;
- border: none;
-}
-
-.container {
- padding: 0;
-
- > div {
- display: table;
- table-layout: fixed;
- width: 100%;
- border-radius: 3px;
- border: 1px solid $outer-border-color;
- background: $container-bg;
- box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
- }
-}
-
+// +Resets - Old, Forms
+// ====================
form {
label {
display: block;
@@ -102,6 +119,8 @@ button,
}
+// +Resets - Old, Images
+// ====================
img {
max-width: 100%;
}
@@ -134,6 +153,9 @@ img {
}
}
+
+// +Resets - Old, Misc
+// ====================
.test-class {
border: 1px solid #f00;
}
diff --git a/lms/static/sass/course/courseware/_courseware.scss b/lms/static/sass/course/courseware/_courseware.scss
index f52cc86fb6..9882b39f04 100644
--- a/lms/static/sass/course/courseware/_courseware.scss
+++ b/lms/static/sass/course/courseware/_courseware.scss
@@ -41,61 +41,63 @@ html.video-fullscreen{
}
}
-div.course-wrapper {
- position: relative;
+.content-wrapper {
- .course-license {
- position: absolute;
- margin: 5px auto;
- bottom: 0;
- text-align: center;
- width: 100%;
- color: $gray-l3;
-
- a:link, a:visited {
- color: $gray-l3;
- }
- a:active, a:hover {
- color: $link-hover;
- }
- }
-
- .xblock-license {
+ .container-footer {
+ margin: 0 auto;
+ max-width: grid-width(12);
+ min-width: 760px;
+ width: flex-grid(12);
+ color: $gray;
text-align: $bi-app-right;
- border-top: 1px solid $gray-l3;
- margin: 0 15px;
- padding: 5px;
- font-size: 80%;
+ }
+}
+
+.content-wrapper {
+
+ .course-license, .xblock-license {
+ @include text-align(right);
+ @extend %t-title7;
+ display: block;
+ width: auto;
+ padding: ($baseline/4) 0;
span {
color: inherit;
}
- &, a {
- color: $gray-l3;
-
- &:hover {
- color: $link-hover;
- }
+ a:link, a:visited {
+ color: $gray;
}
- }
-
- .xmodule_display .xblock-license,
- .xmodule_display .xblock-license a {
- color: $gray-l3;
-
- &:hover {
+ a:active, a:hover {
color: $link-hover;
}
- }
- .xmodule_VideoModule .xblock-license {
- border: 0;
+ .license-label,
+ .license-value,
+ .license-actions {
+ display: inline-block;
+ vertical-align: middle;
+ margin-bottom: 0;
+ }
+
+ i {
+ font-style: normal;
+ }
+
+ img {
+ display: inline;
+ }
}
+}
+
+// TO-DO should this be content wrapper?
+div.course-wrapper {
+ position: relative;
section.course-content {
@extend .content;
- padding: 40px;
+ padding: ($baseline*2);
line-height: 1.6;
h1 {