diff --git a/cms/djangoapps/contentstore/tests/test_contentstore.py b/cms/djangoapps/contentstore/tests/test_contentstore.py index 7622ee7661..416fac4868 100644 --- a/cms/djangoapps/contentstore/tests/test_contentstore.py +++ b/cms/djangoapps/contentstore/tests/test_contentstore.py @@ -401,11 +401,11 @@ class ContentStoreTest(ModuleStoreTestCase): def test_capa_module(self): """Test that a problem treats markdown specially.""" - CourseFactory.create(org='MITx', course='999', display_name='Robot Super Course') + course = CourseFactory.create(org='MITx', course='999', display_name='Robot Super Course') problem_data = { 'parent_location': 'i4x://MITx/999/course/Robot_Super_Course', - 'template': 'i4x://edx/templates/problem/Empty' + 'template': 'i4x://edx/templates/problem/Blank_Common_Problem' } resp = self.client.post(reverse('clone_item'), problem_data) @@ -429,7 +429,7 @@ class TemplateTestCase(ModuleStoreTestCase): # insert a bogus template in the store bogus_template_location = Location('i4x', 'edx', 'templates', 'html', 'bogus') - source_template_location = Location('i4x', 'edx', 'templates', 'html', 'Empty') + source_template_location = Location('i4x', 'edx', 'templates', 'html', 'Blank_HTML_Page') ms.clone_item(source_template_location, bogus_template_location) diff --git a/cms/djangoapps/contentstore/views.py b/cms/djangoapps/contentstore/views.py index 87a2943773..1ae0757393 100644 --- a/cms/djangoapps/contentstore/views.py +++ b/cms/djangoapps/contentstore/views.py @@ -273,7 +273,7 @@ def edit_unit(request, location): template.display_name, template.location.url(), 'markdown' in template.metadata, - template.location.name == 'Empty' + 'empty' in template.metadata )) components = [ diff --git a/cms/static/img/html-icon.png b/cms/static/img/html-icon.png index e739f2fc11..8f576178b2 100644 Binary files a/cms/static/img/html-icon.png and b/cms/static/img/html-icon.png differ diff --git a/cms/static/img/large-discussion-icon.png b/cms/static/img/large-discussion-icon.png index 2f0bfea98f..cebf332769 100644 Binary files a/cms/static/img/large-discussion-icon.png and b/cms/static/img/large-discussion-icon.png differ diff --git a/cms/static/img/large-freeform-icon.png b/cms/static/img/large-freeform-icon.png index b1d195a7ca..0d5e454f58 100644 Binary files a/cms/static/img/large-freeform-icon.png and b/cms/static/img/large-freeform-icon.png differ diff --git a/cms/static/img/large-problem-icon.png b/cms/static/img/large-problem-icon.png index b962d42b14..a30ab8eac8 100644 Binary files a/cms/static/img/large-problem-icon.png and b/cms/static/img/large-problem-icon.png differ diff --git a/cms/static/img/large-video-icon.png b/cms/static/img/large-video-icon.png index 392851324c..f1ab048b4c 100644 Binary files a/cms/static/img/large-video-icon.png and b/cms/static/img/large-video-icon.png differ diff --git a/cms/static/sass/_reset.scss b/cms/static/sass/_reset.scss index 6b4b653e87..ee03a0fca3 100644 --- a/cms/static/sass/_reset.scss +++ b/cms/static/sass/_reset.scss @@ -54,4 +54,118 @@ del { table { border-collapse: collapse; border-spacing: 0; +} + +/* Reset styles to remove ui-lightness jquery ui theme +from the tabs component (used in the add component problem tab menu) +*/ + +.ui-tabs { + padding: 0; + white-space: normal; +} + +.ui-corner-all, .ui-corner-bottom, .ui-corner-left, ui-corner-top, .ui-corner-br, .ui-corner-right { + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; + border-top-right-radius: 0; + border-top-left-radius: 0; +} + + +.ui-widget-content { + border: 0; + background: none; +} +.ui-widget { + font-family: 'Open Sans', sans-serif; + font-size: 16px; +} + +.ui-widget-header { + border:none; + background: none; +} + +.ui-tabs .ui-tabs-nav { + padding: 0; +} + +.ui-tabs .ui-tabs-nav li { + margin: 0; + padding: 0; + border: none; + top: 0; + margin: 0; + float: none; + border-top-left-radius: 0; + border-top-right-radius: 0; +} + +.ui-tabs-nav { + + li { + top: 0; + margin: 0; + } + a { + float: none; + font-weight: normal; + } +} + +.ui-tabs .ui-tabs-panel { + padding: 0; +} + +/* reapplying the tab styles from unit.scss after +removing jquery ui ui-lightness styling +*/ + +.problem-type-tabs { + border:none; + list-style-type: none; + width: 100%; + @include linear-gradient(top, rgba(255, 255, 255, .4), rgba(255, 255, 255, 0)); + //background-color: $lightBluishGrey; + @include box-shadow(0 1px 0 rgba(255, 255, 255, 0.2) inset, 0 -1px 0 rgba(0, 0, 0, 0.2) inset); + + li:first-child { + margin-left: 20px; + } + li { + opacity: .8; + + &:ui-state-active { + background-color: rgba(255, 255, 255, .3); + opacity: 1; + font-weight: 400; + } + a:focus { + outline: none; + border: 0px; + } + } +/* + li { + float:left; + display:inline-block; + text-align:center; + width: auto; + //@include linear-gradient(top, rgba(255, 255, 255, .4), rgba(255, 255, 255, 0)); + //background-color: tint($lightBluishGrey, 20%); + //@include box-shadow(0 1px 0 rgba(255, 255, 255, 0.2) inset, 0 -1px 0 rgba(0, 0, 0, 0.2) inset); + opacity:.8; + + &:hover { + opacity:1; + } + + &.current { + border: 0px; + //@include active; + opacity:1; + } + } +*/ } \ No newline at end of file diff --git a/cms/static/sass/_unit.scss b/cms/static/sass/_unit.scss index bdc76c811c..443eddba9f 100644 --- a/cms/static/sass/_unit.scss +++ b/cms/static/sass/_unit.scss @@ -3,6 +3,12 @@ margin: 40px; } +//Problem Selector tab menu requirements +.js .tabs .tab { + display: none; +} +//end problem selector reqs + .main-column { clear: both; float: left; @@ -58,6 +64,7 @@ margin: 20px 40px; + .title { margin: 0 0 15px 0; color: $mediumGrey; @@ -67,22 +74,25 @@ } &.new-component-item { - padding: 20px; - border: none; - border-radius: 3px; - background: $lightGrey; + margin: 20px 0px; + border-top: 1px solid $mediumGrey; + box-shadow: 0 2px 1px rgba(182, 182, 182, 0.75) inset; + background-color: $lightGrey; + margin-bottom: 0px; + padding-bottom: 20px; .new-component-button { display: block; padding: 20px; text-align: center; - color: #6d788b; + color: #edf1f5; } h5 { - margin-bottom: 8px; + margin: 20px 0px; color: #fff; - font-weight: 700; + font-weight: 600; + font-size: 18px; } .rendered-component { @@ -92,18 +102,21 @@ } .new-component-type { + a, li { display: inline-block; } a { + border: 1px solid $mediumGrey; width: 100px; height: 100px; - margin-right: 10px; - margin-bottom: 10px; + color: #fff; + margin-right: 15px; + margin-bottom: 20px; border-radius: 8px; - font-size: 13px; + font-size: 15px; line-height: 14px; text-align: center; @include box-shadow(0 1px 1px rgba(0, 0, 0, .2), 0 1px 0 rgba(255, 255, 255, .4) inset); @@ -115,25 +128,40 @@ width: 100%; padding: 10px; @include box-sizing(border-box); + color: #fff; } } } .new-component-templates { display: none; - padding: 20px; + margin: 20px 40px 20px 40px; + border-radius: 3px; + border: 1px solid $mediumGrey; + background-color: #fff; + @include box-shadow(0 1px 1px rgba(0, 0, 0, .2), 0 1px 0 rgba(255, 255, 255, .4) inset); @include clearfix; .cancel-button { + margin: 20px 0px 10px 10px; @include white-button; } + .problem-type-tabs { + display: none; + } + // specific menu types &.new-component-problem { + padding-bottom:10px; .ss-icon, .editor-indicator { display: inline-block; } + + .problem-type-tabs { + display: inline-block; + } } } @@ -146,7 +174,6 @@ border: 1px solid $darkGreen; background: tint($green,20%); color: #fff; - @include transition(background-color .15s); &:hover { background: $brightGreen; @@ -154,19 +181,81 @@ } } - .new-component-template { - margin-bottom: 20px; + .problem-type-tabs { + list-style-type: none; + border-radius: 0; + width: 100%; + @include linear-gradient(top, rgba(255, 255, 255, .4), rgba(255, 255, 255, 0)); + background-color: $lightBluishGrey; + @include box-shadow(0 1px 0 rgba(255, 255, 255, 0.2) inset, 0 -1px 0 rgba(0, 0, 0, 0.2) inset); - li:last-child { + li:first-child { + margin-left: 20px; + } + + li { + float:left; + display:inline-block; + text-align:center; + width: auto; + @include linear-gradient(top, rgba(255, 255, 255, .4), rgba(255, 255, 255, 0)); + background-color: tint($lightBluishGrey, 10%); + @include box-shadow(0 1px 0 rgba(255, 255, 255, 0.2) inset, 0 -1px 0 rgba(0, 0, 0, 0.2) inset); + opacity:.8; + + &:hover { + opacity:1; + background-color: tint($lightBluishGrey, 20%); + } + + &.ui-state-active { + border: 0px; + @include active; + opacity:1; + } + } + + a{ + display: block; + padding: 15px 25px; + font-size: 15px; + line-height: 16px; + text-align: center; + color: #3c3c3c; + text-shadow: 0 1px 0 rgba(255, 255, 255, 0.3); + } + } + + .new-component-template { + + a { + background: #fff; + border: 0px; + color: #3c3c3c; + @include transition (none); + + &:hover { + background: tint($green,30%); + color: #fff; + @include transition(background-color .15s); + } + } + + li { + border:none; + border-bottom: 1px dashed $lightGrey; + color: #fff; + } + + li:first-child { a { - border-radius: 0 0 3px 3px; - border-bottom: 1px solid $darkGreen; + border-top: 0px; } } li:nth-child(2) { a { - border-radius: 3px 3px 0 0; + border-radius: 0px; } } @@ -175,18 +264,20 @@ display: block; padding: 7px 20px; border-bottom: none; - font-weight: 300; + font-weight: 500; .name { float: left; .ss-icon { @include transition(opacity .15s); - position: relative; + display: inline-block; top: 1px; - font-size: 13px; margin-right: 5px; opacity: 0.5; + width: 17; + height: 21px; + vertical-align: middle; } } @@ -204,6 +295,7 @@ } &:hover { + color: #fff; .ss-icon { opacity: 1.0; @@ -217,14 +309,18 @@ // specific editor types .empty { - @include box-shadow(0 1px 3px rgba(0,0,0,0.2)); - margin-bottom: 10px; a { - border-bottom: 1px solid $darkGreen; - border-radius: 3px; - font-weight: 500; - background: $green; + line-height: 1.4; + font-weight: 400; + background: #fff; + color: #3c3c3c; + + + &:hover { + background: tint($green,30%); + color: #fff; + } } } } @@ -233,7 +329,7 @@ text-align: center; h5 { - color: $green; + color: $darkGreen; } } @@ -507,6 +603,7 @@ .edit-state-draft { .visibility, + .edit-draft-message, .view-button { display: none; diff --git a/cms/templates/unit.html b/cms/templates/unit.html index f3a779604e..84785a362d 100644 --- a/cms/templates/unit.html +++ b/cms/templates/unit.html @@ -13,12 +13,20 @@ state: '${unit_state}' }) }); - + + $(document).ready(function() { + $('body').addClass('js'); + + // tabs + $('.tab-group').tabs(); + }); + $('.new-component-template').each(function(){ $emptyEditor = $(this).find('.empty'); $(this).prepend($emptyEditor); }); }); + @@ -56,38 +64,66 @@ % for type, templates in sorted(component_templates.items()):
-

Select ${type} component type:

- - + % if type == "problem": +
+ + % endif +
+
    + % for name, location, has_markdown, is_empty in templates: + % if has_markdown or type != "problem": + % if is_empty: +
  • + + ${name} + +
  • + + % else: +
  • + + ${name} + +
  • + % endif + % endif + + %endfor +
+
+ % if type == "problem": +
+
    + % for name, location, has_markdown, is_empty in templates: + % if not has_markdown: + % if is_empty: +
  • + + ${name} + +
  • + + % else: +
  • + + ${name} + + +
  • + % endif + % endif + % endfor +
+
+
+ % endif Cancel
% endfor diff --git a/cms/templates/widgets/problem-edit.html b/cms/templates/widgets/problem-edit.html index 4ff9d299ab..8ca07a7928 100644 --- a/cms/templates/widgets/problem-edit.html +++ b/cms/templates/widgets/problem-edit.html @@ -1,20 +1,20 @@ <%include file="metadata-edit.html" />
- %if markdown != '' or data == '\n\n': + %if enable_markdown:
  • -
  • -
  • -
  • -
  • @@ -56,7 +56,7 @@
-
Check Multiple
+
Checkboxes
@@ -67,7 +67,7 @@
-
String Response
+
Text Input
@@ -76,7 +76,7 @@
-
Numerical Response
+
Numerical Input
@@ -85,7 +85,7 @@
-
Option Response
+
Dropdown
diff --git a/common/lib/xmodule/xmodule/capa_module.py b/common/lib/xmodule/xmodule/capa_module.py index d806ec7913..4635cc6871 100644 --- a/common/lib/xmodule/xmodule/capa_module.py +++ b/common/lib/xmodule/xmodule/capa_module.py @@ -703,15 +703,15 @@ class CapaDescriptor(RawDescriptor): def get_context(self): _context = RawDescriptor.get_context(self) - _context.update({'markdown': self.metadata.get('markdown', '')}) + _context.update({'markdown': self.metadata.get('markdown', ''), + 'enable_markdown' : 'markdown' in self.metadata}) return _context @property def editable_metadata_fields(self): - """Remove metadata from the editable fields since it has its own editor""" - subset = super(CapaDescriptor, self).editable_metadata_fields - if 'markdown' in subset: - subset.remove('markdown') + """Remove any metadata from the editable fields which have their own editor or shouldn't be edited by user.""" + subset = [field for field in super(CapaDescriptor,self).editable_metadata_fields + if field not in ['markdown', 'empty']] return subset diff --git a/common/lib/xmodule/xmodule/html_module.py b/common/lib/xmodule/xmodule/html_module.py index af1ce0ad80..456ea3cf10 100644 --- a/common/lib/xmodule/xmodule/html_module.py +++ b/common/lib/xmodule/xmodule/html_module.py @@ -172,6 +172,13 @@ class HtmlDescriptor(XmlDescriptor, EditingDescriptor): elt.set("filename", relname) return elt + @property + def editable_metadata_fields(self): + """Remove any metadata from the editable fields which have their own editor or shouldn't be edited by user.""" + subset = [field for field in super(HtmlDescriptor,self).editable_metadata_fields + if field not in ['empty']] + return subset + class AboutDescriptor(HtmlDescriptor): """ diff --git a/common/lib/xmodule/xmodule/templates/html/empty.yaml b/common/lib/xmodule/xmodule/templates/html/empty.yaml index 1262ed37cf..b6d867d7d6 100644 --- a/common/lib/xmodule/xmodule/templates/html/empty.yaml +++ b/common/lib/xmodule/xmodule/templates/html/empty.yaml @@ -1,6 +1,7 @@ --- metadata: - display_name: Empty + display_name: Blank HTML Page + empty: True data: | diff --git a/common/lib/xmodule/xmodule/templates/problem/circuitschematic.yaml b/common/lib/xmodule/xmodule/templates/problem/circuitschematic.yaml index f56b17b1b9..a94b824cfb 100644 --- a/common/lib/xmodule/xmodule/templates/problem/circuitschematic.yaml +++ b/common/lib/xmodule/xmodule/templates/problem/circuitschematic.yaml @@ -1,6 +1,7 @@ + --- metadata: - display_name: Circuit Schematic + display_name: Circuit Schematic Builder rerandomize: never showanswer: always weight: "" diff --git a/common/lib/xmodule/xmodule/templates/problem/customgrader.yaml b/common/lib/xmodule/xmodule/templates/problem/customgrader.yaml index 6ada6f97f3..aadbe4075a 100644 --- a/common/lib/xmodule/xmodule/templates/problem/customgrader.yaml +++ b/common/lib/xmodule/xmodule/templates/problem/customgrader.yaml @@ -1,6 +1,6 @@ --- metadata: - display_name: Custom Grader + display_name: Custom Python-Evaluated Input rerandomize: never showanswer: always weight: "" @@ -8,7 +8,7 @@ metadata: data: |

- A custom response problem accepts one or more lines of text input from the + A custom python-evaluated input problem accepts one or more lines of text input from the student, and evaluates the inputs for correctness based on evaluation using a python script embedded within the problem.

diff --git a/common/lib/xmodule/xmodule/templates/problem/empty.yaml b/common/lib/xmodule/xmodule/templates/problem/empty.yaml index 346f49609c..39c9e7671c 100644 --- a/common/lib/xmodule/xmodule/templates/problem/empty.yaml +++ b/common/lib/xmodule/xmodule/templates/problem/empty.yaml @@ -1,10 +1,11 @@ --- metadata: - display_name: Empty + display_name: Blank Common Problem rerandomize: never showanswer: always markdown: "" weight: "" + empty: True attempts: "" data: | diff --git a/common/lib/xmodule/xmodule/templates/problem/emptyadvanced.yaml b/common/lib/xmodule/xmodule/templates/problem/emptyadvanced.yaml new file mode 100644 index 0000000000..bba7b3a8ac --- /dev/null +++ b/common/lib/xmodule/xmodule/templates/problem/emptyadvanced.yaml @@ -0,0 +1,13 @@ +--- +metadata: + display_name: Blank Advanced Problem + rerandomize: never + showanswer: always + weight: "" + attempts: "" + empty: True +data: | + + + +children: [] diff --git a/common/lib/xmodule/xmodule/templates/problem/forumularesponse.yaml b/common/lib/xmodule/xmodule/templates/problem/forumularesponse.yaml index 5b30a0497d..b4c53a107b 100644 --- a/common/lib/xmodule/xmodule/templates/problem/forumularesponse.yaml +++ b/common/lib/xmodule/xmodule/templates/problem/forumularesponse.yaml @@ -1,6 +1,6 @@ --- metadata: - display_name: Formula Response + display_name: Math Expression Input rerandomize: never showanswer: always weight: "" @@ -8,7 +8,7 @@ metadata: data: |

- A formula response problem accepts a line of text representing a mathematical expression from the + A math expression input problem accepts a line of text representing a mathematical expression from the student, and evaluates the input for equivalence to a mathematical expression provided by the grader. Correctness is based on numerical sampling of the symbolic expressions.

diff --git a/common/lib/xmodule/xmodule/templates/problem/imageresponse.yaml b/common/lib/xmodule/xmodule/templates/problem/imageresponse.yaml index 069c157852..3ef619d54b 100644 --- a/common/lib/xmodule/xmodule/templates/problem/imageresponse.yaml +++ b/common/lib/xmodule/xmodule/templates/problem/imageresponse.yaml @@ -1,6 +1,6 @@ --- metadata: - display_name: Image Response + display_name: Image Mapped Input rerandomize: never showanswer: always weight: "" @@ -8,7 +8,7 @@ metadata: data: |

- An image response problem presents an image for the student. Input is + An image mapped input problem presents an image for the student. Input is given by the location of mouse clicks on the image. Correctness of input can be evaluated based on expected dimensions of a rectangle.

diff --git a/common/lib/xmodule/xmodule/templates/problem/multiplechoice.yaml b/common/lib/xmodule/xmodule/templates/problem/multiplechoice.yaml index 9e61324ae1..3a35a35199 100644 --- a/common/lib/xmodule/xmodule/templates/problem/multiplechoice.yaml +++ b/common/lib/xmodule/xmodule/templates/problem/multiplechoice.yaml @@ -26,10 +26,6 @@ metadata: ( ) The vegetable peeler - ( ) Android - - ( ) The Beatles - [explanation] The release of the iPod allowed consumers to carry their entire music library with them in a @@ -51,8 +47,6 @@ data: | Napster The iPod The vegetable peeler - Android - The Beatles diff --git a/common/lib/xmodule/xmodule/templates/problem/numericalresponse.yaml b/common/lib/xmodule/xmodule/templates/problem/numericalresponse.yaml index e0a5776222..1dc46f5f51 100644 --- a/common/lib/xmodule/xmodule/templates/problem/numericalresponse.yaml +++ b/common/lib/xmodule/xmodule/templates/problem/numericalresponse.yaml @@ -1,12 +1,12 @@ --- metadata: - display_name: Numerical Response + display_name: Numerical Input rerandomize: never showanswer: always weight: "" attempts: "" markdown: - "A numerical response problem accepts a line of text input from the + "A numerical input problem accepts a line of text input from the student, and evaluates the input for correctness based on its numerical value. @@ -45,7 +45,7 @@ metadata: data: |

- A numerical response problem accepts a line of text input from the + A numerical input problem accepts a line of text input from the student, and evaluates the input for correctness based on its numerical value.

diff --git a/common/lib/xmodule/xmodule/templates/problem/optionresponse.yaml b/common/lib/xmodule/xmodule/templates/problem/optionresponse.yaml index 1a42a5a009..f523c7fdc5 100644 --- a/common/lib/xmodule/xmodule/templates/problem/optionresponse.yaml +++ b/common/lib/xmodule/xmodule/templates/problem/optionresponse.yaml @@ -1,12 +1,12 @@ --- metadata: - display_name: Option Response + display_name: Dropdown rerandomize: never showanswer: always weight: "" attempts: "" markdown: - "OptionResponse gives a limited set of options for students to respond with, and presents those options + "Dropdown problems give a limited set of options for students to respond with, and present those options in a format that encourages them to search for a specific answer rather than being immediately presented with options from which to recognize the correct answer. @@ -14,30 +14,30 @@ metadata: The answer options and the identification of the correct answer is defined in the optioninput tag. - Translation between Option Response and __________ is extremely straightforward: + Translation between Dropdown and __________ is extremely straightforward: - [[(Multiple Choice), String Response, Numerical Response, External Response, Image Response]] + [[(Multiple Choice), Text Input, Numerical Input, External Response, Image Response]] [explanation] Multiple Choice also allows students to select from a variety of pre-written responses, although the - format makes it easier for students to read very long response options. Optionresponse also differs + format makes it easier for students to read very long response options. Dropdowns also differ slightly because students are more likely to think of an answer and then search for it rather than relying purely on recognition to answer the question. [explanation] " data: | -

OptionResponse gives a limited set of options for students to respond with, and presents those options +

Dropdown problems give a limited set of options for students to respond with, and present those options in a format that encourages them to search for a specific answer rather than being immediately presented with options from which to recognize the correct answer.

The answer options and the identification of the correct answer is defined in the optioninput tag.

-

Translation between Option Response and __________ is extremely straightforward: +

Translation between Dropdown and __________ is extremely straightforward: - +

diff --git a/common/lib/xmodule/xmodule/templates/problem/string_response.yaml b/common/lib/xmodule/xmodule/templates/problem/string_response.yaml index 1761ea8f67..c018d3f6cf 100644 --- a/common/lib/xmodule/xmodule/templates/problem/string_response.yaml +++ b/common/lib/xmodule/xmodule/templates/problem/string_response.yaml @@ -1,15 +1,15 @@ --- metadata: - display_name: String Response + display_name: Text Input rerandomize: never showanswer: always weight: "" attempts: "" # Note, the extra newlines are needed to make the yaml parser add blank lines instead of folding markdown: - "A string response problem accepts a line of text input from the + "A text input problem accepts a line of text from the student, and evaluates the input for correctness based on an expected - answer within each input box. + answer. The answer is correct if it matches every character of the expected answer. This can be a problem with @@ -30,9 +30,9 @@ data: |

- A string response problem accepts a line of text input from the + A text input problem accepts a line of text from the student, and evaluates the input for correctness based on an expected - answer within each input box. + answer. The answer is correct if it matches every character of the expected answer. This can be a problem with international spelling, dates, or anything where the format of the answer is not clear.