Commit 45bb18a6 by Tim Krones

Turn "Root block ID" field into user-friendly dropdown.

parent 3fc57163
......@@ -34,6 +34,7 @@ loader = ResourceLoader(__name__)
PAGE_SIZE = 15
# Make '_' a no-op so we can scrape strings
def _(text):
return text
......@@ -128,9 +129,53 @@ class InstructorToolBlock(XBlock):
_('Rating Question'): 'RatingBlock',
_('Long Answer'): 'AnswerBlock',
}
block_types = ('pb-mcq', 'pb-rating', 'pb-answer')
flat_block_tree = []
def build_tree(block, ancestors):
"""
Build up a tree of information about the XBlocks descending from root_block
"""
block_id = block.scope_ids.usage_id.block_id
block_name = getattr(block, "display_name", None)
block_type = block.runtime.id_reader.get_block_type(block.scope_ids.def_id)
if not block_name and block_type in block_types:
block_name = block.question
eligible = block_type in block_types
if eligible:
# If this block is a question whose answers we can export,
# we mark all of its ancestors as exportable too
if ancestors and not ancestors[-1]["eligible"]:
for ancestor in ancestors:
ancestor["eligible"] = True
new_entry = {
"depth": len(ancestors),
"id": block_id,
"name": block_name,
"eligible": eligible,
}
flat_block_tree.append(new_entry)
if block.has_children and not block_type == 'pb-mcq' and not \
getattr(block, "has_dynamic_children", lambda: False)():
for child_id in block.children:
build_tree(block.runtime.get_block(child_id), ancestors=(ancestors + [new_entry]))
root_block = self
while root_block.parent:
root_block = root_block.get_parent()
root_entry = {
"depth": 0,
"id": root_block.scope_ids.usage_id.block_id,
"name": "All",
}
flat_block_tree.append(root_entry)
for child_id in root_block.children:
child_block = root_block.runtime.get_block(child_id)
build_tree(child_block, [root_entry])
html = loader.render_template(
'templates/html/instructor_tool.html',
{'block_choices': block_choices}
{'block_choices': block_choices, 'block_tree': flat_block_tree}
)
fragment = Fragment(html)
fragment.add_css_url(self.runtime.local_resource_url(self, 'public/css/instructor_tool.css'))
......@@ -212,9 +257,6 @@ class InstructorToolBlock(XBlock):
root_block_id = self.scope_ids.usage_id
# Block ID not in workbench runtime.
root_block_id = unicode(getattr(root_block_id, 'block_id', root_block_id))
get_root = True
else:
get_root = False
# Launch task
from .tasks import export_data as export_data_task # Import here since this is edX LMS specific
......@@ -228,7 +270,6 @@ class InstructorToolBlock(XBlock):
block_types,
user_id,
match_string,
get_root=get_root
)
if async_result.ready():
# In development mode, the task may have executed synchronously.
......
......@@ -25,6 +25,12 @@
display: table-cell;
padding-left: 1em;
}
.data-export-field-container {
min-width: 45%;
}
.data-export-options .data-export-actions {
max-width: 10%;
}
.data-export-field {
margin-top: .5em;
margin-bottom: .5em;
......@@ -34,7 +40,7 @@
vertical-align: middle;
}
.data-export-field input, .data-export-field select {
max-width: 60%;
max-width: 55%;
float: right;
}
.data-export-results, .data-export-download, .data-export-cancel, .data-export-delete {
......
......@@ -170,7 +170,7 @@ function InstructorToolBlock(runtime, element) {
var $downloadButton = $element.find('.data-export-download');
var $deleteButton = $element.find('.data-export-delete');
var $blockTypes = $element.find("select[name='block_types']");
var $rootBlockId = $element.find("input[name='root_block_id']");
var $rootBlockId = $element.find("select[name='root_block_id']");
var $username = $element.find("input[name='username']");
var $matchString = $element.find("input[name='match_string']");
var $resultTable = $element.find('.data-export-results');
......
......@@ -20,7 +20,7 @@ logger = get_task_logger(__name__)
@task()
def export_data(course_id, source_block_id_str, block_types, user_id, match_string, get_root=True):
def export_data(course_id, source_block_id_str, block_types, user_id, match_string):
"""
Exports student answers to all MCQ questions to a CSV file.
"""
......@@ -34,12 +34,6 @@ def export_data(course_id, source_block_id_str, block_types, user_id, match_stri
raise ValueError("Could not find the specified Block ID.")
course_key_str = unicode(course_key)
root = src_block
if get_root:
# Get the root block for the course.
while root.parent:
root = root.get_parent()
type_map = {cls.__name__: cls for cls in [MCQBlock, RatingBlock, AnswerBlock]}
if not block_types:
......@@ -62,7 +56,7 @@ def export_data(course_id, source_block_id_str, block_types, user_id, match_stri
# Blocks may refer to missing children. Don't break in this case.
pass
scan_for_blocks(root)
scan_for_blocks(src_block)
# Define the header row of our CSV:
rows = []
......
......@@ -27,8 +27,16 @@
<div class="data-export-field-container">
<div class="data-export-field">
<label>
<span>{% trans "Root block ID:" %}</span>
<input type="text" name="root_block_id" />
<span>{% trans "Section/Question:" %}</span>
<select name="root_block_id">
{% for block in block_tree %}
<option value="{{ block.id }}"
{% if not block.eligible %} disabled="disabled" {% endif %}>
{% for _ in ""|ljust:block.depth %}&nbsp;&nbsp;{% endfor %}
{{ block.name }}
</option>
{% endfor %}
</select>
</label>
</div>
</div>
......
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