Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
P
problem-builder
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
OpenEdx
problem-builder
Commits
bee4e702
Commit
bee4e702
authored
Jul 08, 2015
by
Jonathan Piacenti
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Allow students to download a copy of their answer table.
parent
6aaa3aba
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
143 additions
and
70 deletions
+143
-70
problem_builder/answer.py
+3
-1
problem_builder/dashboard.py
+40
-31
problem_builder/public/js/mentoring-table.js
+0
-9
problem_builder/public/js/review_blocks.js
+16
-2
problem_builder/table.py
+30
-5
problem_builder/templates/html/mentoring-table-report.html
+25
-0
problem_builder/templates/html/mentoring-table.html
+29
-22
No files found.
problem_builder/answer.py
View file @
bee4e702
...
...
@@ -272,6 +272,8 @@ class AnswerRecapBlock(AnswerMixin, StudioEditableXBlockMixin, XBlock):
)
editable_fields
=
(
'name'
,
'display_name'
,
'description'
)
css_path
=
'public/css/answer.css'
@property
def
student_input
(
self
):
if
self
.
name
:
...
...
@@ -287,7 +289,7 @@ class AnswerRecapBlock(AnswerMixin, StudioEditableXBlockMixin, XBlock):
html
=
loader
.
render_template
(
'templates/html/answer_read_only.html'
,
context
)
fragment
=
Fragment
(
html
)
fragment
.
add_css_url
(
self
.
runtime
.
local_resource_url
(
self
,
'public/css/answer.css'
))
fragment
.
add_css_url
(
self
.
runtime
.
local_resource_url
(
self
,
self
.
css_path
))
return
fragment
def
student_view
(
self
,
context
=
None
):
...
...
problem_builder/dashboard.py
View file @
bee4e702
...
...
@@ -58,6 +58,39 @@ def _(text):
# Classes ###########################################################
class
ExportMixin
(
object
):
"""
Used by blocks which need to provide a downloadable export.
"""
def
_get_user_full_name
(
self
):
"""
Get the full name of the current user, for the downloadable report.
"""
user_service
=
self
.
runtime
.
service
(
self
,
'user'
)
if
user_service
:
return
user_service
.
get_current_user
()
.
full_name
return
""
def
_get_course_name
(
self
):
"""
Get the name of the current course, for the downloadable report.
"""
try
:
course_key
=
self
.
scope_ids
.
usage_id
.
course_key
except
AttributeError
:
return
""
# We are not in an edX runtime
try
:
course_root_key
=
course_key
.
make_usage_key
(
'course'
,
'course'
)
return
self
.
runtime
.
get_block
(
course_root_key
)
.
display_name
except
Exception
:
# ItemNotFoundError most likely, but we can't import that exception in non-edX environments
# We may be on old mongo:
try
:
course_root_key
=
course_key
.
make_usage_key
(
'course'
,
course_key
.
run
)
return
self
.
runtime
.
get_block
(
course_root_key
)
.
display_name
except
Exception
:
return
""
class
ColorRule
(
object
):
"""
A rule used to conditionally set colors
...
...
@@ -155,7 +188,7 @@ class InvalidUrlName(ValueError):
@XBlock.needs
(
"i18n"
)
@XBlock.wants
(
"user"
)
class
DashboardBlock
(
StudioEditableXBlockMixin
,
XBlock
):
class
DashboardBlock
(
StudioEditableXBlockMixin
,
ExportMixin
,
XBlock
):
"""
A block to summarize self-assessment results.
"""
...
...
@@ -260,7 +293,7 @@ class DashboardBlock(StudioEditableXBlockMixin, XBlock):
'color_rules'
,
'visual_rules'
,
'visual_title'
,
'visual_desc'
,
'header_html'
,
'footer_html'
,
)
css_path
=
'public/css/dashboard.css'
js_path
=
'public/js/
dashboard
.js'
js_path
=
'public/js/
review_blocks
.js'
def
get_mentoring_blocks
(
self
,
mentoring_ids
,
ignore_errors
=
True
):
"""
...
...
@@ -343,34 +376,6 @@ class DashboardBlock(StudioEditableXBlockMixin, XBlock):
return
rule
.
color_str
return
None
def
_get_user_full_name
(
self
):
"""
Get the full name of the current user, for the downloadable report.
"""
user_service
=
self
.
runtime
.
service
(
self
,
'user'
)
if
user_service
:
return
user_service
.
get_current_user
()
.
full_name
return
""
def
_get_course_name
(
self
):
"""
Get the name of the current course, for the downloadable report.
"""
try
:
course_key
=
self
.
scope_ids
.
usage_id
.
course_key
except
AttributeError
:
return
""
# We are not in an edX runtime
try
:
course_root_key
=
course_key
.
make_usage_key
(
'course'
,
'course'
)
return
self
.
runtime
.
get_block
(
course_root_key
)
.
display_name
except
Exception
:
# ItemNotFoundError most likely, but we can't import that exception in non-edX environments
# We may be on old mongo:
try
:
course_root_key
=
course_key
.
make_usage_key
(
'course'
,
course_key
.
run
)
return
self
.
runtime
.
get_block
(
course_root_key
)
.
display_name
except
Exception
:
return
""
def
_get_problem_questions
(
self
,
mentoring_block
):
""" Generator returning only children of specified block that are MCQs """
for
child_id
in
mentoring_block
.
children
:
...
...
@@ -469,7 +474,11 @@ class DashboardBlock(StudioEditableXBlockMixin, XBlock):
fragment
=
Fragment
(
html
)
fragment
.
add_css_url
(
self
.
runtime
.
local_resource_url
(
self
,
self
.
css_path
))
fragment
.
add_javascript_url
(
self
.
runtime
.
local_resource_url
(
self
,
self
.
js_path
))
fragment
.
initialize_js
(
'PBDashboardBlock'
,
{
'reportTemplate'
:
report_template
})
fragment
.
initialize_js
(
'PBDashboardBlock'
,
{
'reportTemplate'
:
report_template
,
'reportContentSelector'
:
'.dashboard-report'
})
return
fragment
def
validate_field_data
(
self
,
validation
,
data
):
...
...
problem_builder/public/js/mentoring-table.js
deleted
100644 → 0
View file @
6aaa3aba
function
MentoringTableBlock
(
runtime
,
element
)
{
// Display an exceprt for long answers, with a "more" link to display the full text
$
(
'.answer-table'
,
element
).
shorten
({
moreText
:
'more'
,
lessText
:
'less'
,
showChars
:
'500'
});
return
{};
}
problem_builder/public/js/
dashboard
.js
→
problem_builder/public/js/
review_blocks
.js
View file @
bee4e702
// Client side code for the Problem Builder Dashboard XBlock
// So far, this code is only used to generate a downloadable report.
function
PBDashboardBlock
(
runtime
,
element
,
initData
)
{
function
ExportBase
(
runtime
,
element
,
initData
)
{
"use strict"
;
var
reportTemplate
=
initData
.
reportTemplate
;
...
...
@@ -32,7 +32,7 @@ function PBDashboardBlock(runtime, element, initData) {
// Download Report:
// Change the URL to a data: URI before continuing with the click event.
if
(
$
(
this
).
attr
(
'href'
).
charAt
(
0
)
==
'#'
)
{
var
$report
=
$
(
'.dashboard-report'
,
element
).
clone
();
var
$report
=
$
(
initData
.
reportContentSelector
,
element
).
clone
();
// Convert all images in $report to data URIs:
$report
.
find
(
'image'
).
each
(
function
()
{
var
origURL
=
$
(
this
).
attr
(
'xlink:href'
);
...
...
@@ -49,3 +49,17 @@ function PBDashboardBlock(runtime, element, initData) {
var
$downloadLink
=
$
(
'.report-download-link'
,
element
);
$downloadLink
.
on
(
'click'
,
downloadReport
);
}
function
PBDashboardBlock
(
runtime
,
element
,
initData
)
{
new
ExportBase
(
runtime
,
element
,
initData
);
}
function
MentoringTableBlock
(
runtime
,
element
,
initData
)
{
// Display an excerpt for long answers, with a "more" link to display the full text
$
(
'.answer-table'
,
element
).
shorten
({
moreText
:
'more'
,
lessText
:
'less'
,
showChars
:
'500'
});
new
ExportBase
(
runtime
,
element
,
initData
)
}
problem_builder/table.py
View file @
bee4e702
...
...
@@ -24,13 +24,15 @@ import errno
from
xblock.core
import
XBlock
from
xblock.fields
import
Scope
,
String
from
xblock.fields
import
Scope
,
String
,
Boolean
from
xblock.fragment
import
Fragment
from
xblockutils.resources
import
ResourceLoader
from
xblockutils.studio_editable
import
StudioEditableXBlockMixin
,
StudioContainerXBlockMixin
# Globals ###########################################################
from
problem_builder
import
AnswerRecapBlock
from
problem_builder.dashboard
import
ExportMixin
loader
=
ResourceLoader
(
__name__
)
...
...
@@ -42,7 +44,8 @@ def _(text):
# Classes ###########################################################
class
MentoringTableBlock
(
StudioEditableXBlockMixin
,
StudioContainerXBlockMixin
,
XBlock
):
@XBlock.wants
(
"user"
)
class
MentoringTableBlock
(
StudioEditableXBlockMixin
,
StudioContainerXBlockMixin
,
ExportMixin
,
XBlock
):
"""
Table-type display of information from mentoring blocks
...
...
@@ -66,9 +69,18 @@ class MentoringTableBlock(StudioEditableXBlockMixin, StudioContainerXBlockMixin,
{
"display_name"
:
"Immunity Map"
,
"value"
:
"immunity-map"
},
],
)
editable_fields
=
(
"type"
,
)
editable_fields
=
(
"type"
,
"allow_download"
)
allow_download
=
Boolean
(
display_name
=
_
(
"Allow Download"
),
help
=
_
(
"Allow students to download a copy of the table for themselves."
),
default
=
False
,
scope
=
Scope
.
content
)
has_children
=
True
css_path
=
'public/css/mentoring-table.css'
js_path
=
'public/js/review_blocks.js'
def
student_view
(
self
,
context
):
context
=
context
.
copy
()
if
context
else
{}
fragment
=
Fragment
()
...
...
@@ -83,6 +95,7 @@ class MentoringTableBlock(StudioEditableXBlockMixin, StudioContainerXBlockMixin,
fragment
.
add_frag_resources
(
child_frag
)
context
[
'header_values'
]
=
header_values
if
any
(
header_values
)
else
None
context
[
'content_values'
]
=
content_values
context
[
'allow_download'
]
=
self
.
allow_download
if
self
.
type
:
# Load an optional background image:
...
...
@@ -96,11 +109,23 @@ class MentoringTableBlock(StudioEditableXBlockMixin, StudioContainerXBlockMixin,
else
:
raise
report_template
=
loader
.
render_template
(
'templates/html/mentoring-table-report.html'
,
{
'title'
:
self
.
display_name
,
'css'
:
loader
.
load_unicode
(
AnswerRecapBlock
.
css_path
)
+
loader
.
load_unicode
(
self
.
css_path
),
'student_name'
:
self
.
_get_user_full_name
(),
'course_name'
:
self
.
_get_course_name
(),
})
fragment
.
add_content
(
loader
.
render_template
(
'templates/html/mentoring-table.html'
,
context
))
fragment
.
add_css_url
(
self
.
runtime
.
local_resource_url
(
self
,
'public/css/mentoring-table.css'
))
fragment
.
add_javascript_url
(
self
.
runtime
.
local_resource_url
(
self
,
'public/js/vendor/jquery-shorten.js'
))
fragment
.
add_javascript_url
(
self
.
runtime
.
local_resource_url
(
self
,
'public/js/mentoring-table.js'
))
fragment
.
initialize_js
(
'MentoringTableBlock'
)
fragment
.
add_javascript_url
(
self
.
runtime
.
local_resource_url
(
self
,
self
.
js_path
))
fragment
.
initialize_js
(
'MentoringTableBlock'
,
{
'reportContentSelector'
:
'.mentoring-table-container'
,
'reportTemplate'
:
report_template
,
}
)
return
fragment
...
...
problem_builder/templates/html/mentoring-table-report.html
0 → 100644
View file @
bee4e702
{% load i18n %}
<!DOCTYPE html>
<html
lang=
"en"
>
<head>
<meta
charset=
"utf-8"
>
<meta
name=
"viewport"
content=
"width=device-width, initial-scale=1"
>
<title>
{{ title }}
</title>
<style>
body
{
font-family
:
'Open Sans'
,
'Helvetica Neue'
,
Helvetica
,
Arial
,
sans-serif
;
}
{
{css|safe
}
}
</style>
</head>
<body>
<div
class=
"mentoring"
>
<div
class=
"identification"
>
{% if student_name %}{% trans "Student" %}: {{student_name}}
<br>
{% endif %}
{% if course_name %}{% trans "Course" %}: {{course_name}}
<br>
{% endif %}
{% trans "Date" %}: {% now "DATE_FORMAT" %}
<br>
</div>
REPORT_GOES_HERE
</div>
</body>
</html>
problem_builder/templates/html/mentoring-table.html
View file @
bee4e702
<div
class=
"mentoring-table {{ self.type }}"
style=
"background-image: url({{ bg_image_url }})"
>
<div
class=
"cont-text-sr"
>
{{ bg_image_description }}
</div>
<table>
{% if header_values %}
<thead>
{% for header in header_values %}
<th>
{{ header|safe }}
</th>
{% endfor %}
</thead>
{% endif %}
<tbody>
<tr>
{% for content in content_values %}
<td>
<div
class=
"mentoring-column"
>
{{content|safe}}
</div>
</td>
{% load i18n %}
<div
class=
"mentoring-table-container"
>
<div
class=
"mentoring-table {{ self.type }}"
style=
"background-image: url({{ bg_image_url }})"
>
<div
class=
"cont-text-sr"
>
{{ bg_image_description }}
</div>
<table>
{% if header_values %}
<thead>
{% for header in header_values %}
<th>
{{ header|safe }}
</th>
{% endfor %}
</tr>
</tbody>
</table>
</div>
</thead>
{% endif %}
<tbody>
<tr>
{% for content in content_values %}
<td>
<div
class=
"mentoring-column"
>
{{content|safe}}
</div>
</td>
{% endfor %}
</tr>
</tbody>
</table>
</div>
{% if allow_download %}
<p><a
class=
"report-download-link"
href=
"#report_download"
download=
"report.html"
>
{% trans "Download report" %}
</a></p>
{% endif %}
</div>
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment