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
8633044e
Commit
8633044e
authored
Mar 23, 2015
by
Braden MacDonald
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Implementation of core features
parent
7a3423dc
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
123 additions
and
25 deletions
+123
-25
mentoring/dashboard.py
+77
-25
mentoring/public/css/dashboard.css
+26
-0
mentoring/templates/html/dashboard.html
+20
-0
No files found.
mentoring/dashboard.py
View file @
8633044e
...
...
@@ -21,19 +21,23 @@
# Imports ###########################################################
import
logging
from
lazy
import
lazy
from
.mcq
import
MCQBlock
from
.sub_api
import
sub_api
from
xblock.core
import
XBlock
from
xblock.fields
import
Scope
,
String
from
xblock.exceptions
import
XBlockNotFoundError
from
xblock.fields
import
Scope
,
Dict
,
List
,
String
from
xblock.fragment
import
Fragment
from
xblock.validation
import
ValidationMessage
from
xblockutils.helpers
import
child_isinstance
from
xblockutils.resources
import
ResourceLoader
from
xblockutils.studio_editable
import
StudioEditableXBlockMixin
# Globals ###########################################################
log
=
logging
.
getLogger
(
__name__
)
loader
=
ResourceLoader
(
__name__
)
# Make '_' a no-op so we can scrape strings
...
...
@@ -54,35 +58,82 @@ class DashboardBlock(StudioEditableXBlockMixin, XBlock):
scope
=
Scope
.
settings
,
default
=
_
(
'Self-Assessment Summary'
),
)
mcq_id
=
String
(
display_name
=
_
(
"MCQ ID"
),
help
=
_
(
"THe url_name of an MCQ to use as a proof of concept for using the submissions API"
),
mentoring_ids
=
List
(
display_name
=
_
(
"Mentoring Blocks"
),
help
=
_
(
"This should be an ordered list of the url_names of each mentoring block whose multiple choice question "
"values are to be shown on this dashboard. The list should be in JSON format. Example: {example_here}"
)
.
format
(
example_here
=
'["2754b8afc03a439693b9887b6f1d9e36", "215028f7df3d4c68b14fb5fea4da7053"]'
),
scope
=
Scope
.
content
,
default
=
""
)
color_codes
=
Dict
(
display_name
=
_
(
"Color Coding"
),
help
=
_
(
"You can optionally set a color for each expected value. Example: {example_here}"
)
.
format
(
example_here
=
'{ "1": "red", "2": "yellow", 3: "green", 4: "lightskyblue" }'
)
)
editable_fields
=
(
'display_name'
,
'mentoring_ids'
,
'color_codes'
)
def
get_mentoring_blocks
(
self
):
"""
Generator returning the specified mentoring blocks, in order.
returns a list. Will insert None for every invalid mentoring block ID.
"""
for
url_name
in
self
.
mentoring_ids
:
mentoring_id
=
self
.
scope_ids
.
usage_id
.
course_key
.
make_usage_key
(
'problem-builder'
,
url_name
)
try
:
yield
self
.
runtime
.
get_block
(
mentoring_id
)
except
XBlockNotFoundError
:
yield
None
def
generate_content
(
self
):
"""
Create the HTML for this block, by getting the data and inserting it into a template.
"""
blocks
=
[]
for
mentoring_block
in
self
.
get_mentoring_blocks
():
if
mentoring_block
is
None
:
continue
block
=
{
'display_name'
:
mentoring_block
.
display_name
,
'mcqs'
:
[]
}
for
child_id
in
mentoring_block
.
children
:
if
child_isinstance
(
mentoring_block
,
child_id
,
MCQBlock
):
# Get the student's submitted answer to this MCQ from the submissions API:
mcq_block
=
self
.
runtime
.
get_block
(
child_id
)
mcq_submission_key
=
dict
(
student_id
=
self
.
runtime
.
anonymous_student_id
,
course_id
=
unicode
(
child_id
.
course_key
),
item_id
=
unicode
(
child_id
),
item_type
=
child_id
.
block_type
,
)
try
:
value
=
sub_api
.
get_submissions
(
mcq_submission_key
,
limit
=
1
)[
0
][
"answer"
]
except
IndexError
:
# (sub_api.SubmissionNotFoundError, IndexError)
value
=
None
block
[
'mcqs'
]
.
append
({
"display_name"
:
mcq_block
.
question
,
"value"
:
value
,
"color"
:
self
.
color_codes
.
get
(
value
),
})
blocks
.
append
(
block
)
editable_fields
=
(
'display_name'
,
'mcq_id'
,
)
return
loader
.
render_template
(
'templates/html/dashboard.html'
,
{
'blocks'
:
blocks
,
'display_name'
:
self
.
display_name
,
})
def
fallback_view
(
self
,
view_name
,
context
=
None
):
context
=
context
or
{}
context
[
'self'
]
=
self
if
self
.
mcq_id
:
item_usage_key
=
self
.
scope_ids
.
usage_id
.
course_key
.
make_usage_key
(
'pb-mcq'
,
self
.
mcq_id
)
item_key
=
dict
(
student_id
=
self
.
runtime
.
anonymous_student_id
,
course_id
=
unicode
(
item_usage_key
.
course_key
),
item_id
=
unicode
(
item_usage_key
),
item_type
=
item_usage_key
.
block_type
,
)
try
:
submission
=
sub_api
.
get_submissions
(
item_key
,
limit
=
1
)[
0
]
except
(
sub_api
.
SubmissionNotFoundError
,
IndexError
):
message
=
"(No answer submitted yet)"
else
:
message
=
"Answer is: {}."
.
format
(
submission
[
"answer"
])
else
:
message
=
"(Not configured)"
fragment
=
Fragment
(
u"<h1>Dashboard</h1><p>{}</p>"
.
format
(
message
))
return
fragment
if
not
self
.
mentoring_ids
:
return
Fragment
(
u"<h1>{}</h1><p>{}</p>"
.
format
(
self
.
display_name
,
_
(
"Not configured."
)))
fragment
=
Fragment
(
self
.
generate_content
())
fragment
.
add_css_url
(
self
.
runtime
.
local_resource_url
(
self
,
'public/css/dashboard.css'
))
return
fragment
\ No newline at end of file
mentoring/public/css/dashboard.css
0 → 100644
View file @
8633044e
.pb-dashboard
table
{
max-width
:
800px
;
border-collapse
:
collapse
;
}
.pb-dashboard
table
td
{
border
:
1px
solid
black
;
padding
:
0.2em
;
}
.pb-dashboard
table
td
:last-child
{
min-width
:
3em
;
text-align
:
right
;
}
.pb-dashboard
table
td
:last-child
span
{
position
:
relative
;
background
:
transparent
;
color
:
black
;
/* Background color could be anything, so add a white outline to preserve readability */
text-shadow
:
-1px
-1px
1px
rgba
(
255
,
255
,
255
,
0.7
),
1px
-1px
1px
rgba
(
255
,
255
,
255
,
0.7
),
-1px
1px
1px
rgba
(
255
,
255
,
255
,
0.7
),
1px
1px
1px
rgba
(
255
,
255
,
255
,
0.7
);
}
mentoring/templates/html/dashboard.html
0 → 100644
View file @
8633044e
<div
class=
"pb-dashboard"
>
<h1>
{{display_name}}
</h1>
<table>
{% for block in blocks %}
<thead>
<th
colspan=
2
>
{{ block.display_name }}
</th>
</thead>
<tbody>
{% for mcq in block.mcqs %}
<tr>
<td>
{{ mcq.display_name }}
</td>
<td
{%
if
mcq
.
color
%}
style=
"background-color: {{mcq.color}};"
{%
endif
%}
>
<span>
{% if mcq.value %}{{ mcq.value }}{% endif %}
</span>
</td>
</tr>
{% endfor %}
</tbody>
{% endfor %}
</table>
</div>
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