Commit d780724a by Xavier Antoviaque

Add XML editor, with default sample content, to Studio editing view

parent f8cda89b
...@@ -2,6 +2,5 @@ ...@@ -2,6 +2,5 @@
*.pyc *.pyc
/xblock_mentoring.egg-info /xblock_mentoring.egg-info
/workbench.sqlite /workbench.sqlite
/mentoring/templates/xml
/dist /dist
/templates /templates
...@@ -73,6 +73,7 @@ class LightChildrenMixin(XBlockWithChildrenFragmentsMixin): ...@@ -73,6 +73,7 @@ class LightChildrenMixin(XBlockWithChildrenFragmentsMixin):
@classmethod @classmethod
def parse_xml(cls, node, runtime, keys, id_generator): def parse_xml(cls, node, runtime, keys, id_generator):
log.debug('parse_xml called')
block = runtime.construct_xblock_from_class(cls, keys) block = runtime.construct_xblock_from_class(cls, keys)
cls.init_block_from_node(block, node, node.items()) cls.init_block_from_node(block, node, node.items())
block.xml_content = getattr(block, 'xml_content', '') or etree.tostring(node) block.xml_content = getattr(block, 'xml_content', '') or etree.tostring(node)
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
# Imports ########################################################### # Imports ###########################################################
import logging import logging
import uuid
from xblock.core import XBlock from xblock.core import XBlock
from xblock.fields import Boolean, Scope, String from xblock.fields import Boolean, Scope, String
...@@ -59,9 +60,9 @@ class MentoringBlock(XBlockWithLightChildren): ...@@ -59,9 +60,9 @@ class MentoringBlock(XBlockWithLightChildren):
followed_by = String(help="url_name of the step after the current mentoring block in workflow", followed_by = String(help="url_name of the step after the current mentoring block in workflow",
default=None, scope=Scope.content) default=None, scope=Scope.content)
url_name = String(help="Name of the current step, used for URL building", url_name = String(help="Name of the current step, used for URL building",
default='mentoring', scope=Scope.content) default='mentoring-default', scope=Scope.content)
enforce_dependency = Boolean(help="Should the next step be the current block to complete?", enforce_dependency = Boolean(help="Should the next step be the current block to complete?",
default=True, scope=Scope.content) default=False, scope=Scope.content)
display_submit = Boolean(help="Allow to submit current block?", default=True, scope=Scope.content) display_submit = Boolean(help="Allow to submit current block?", default=True, scope=Scope.content)
xml_content = String(help="XML content", default='', scope=Scope.content) xml_content = String(help="XML content", default='', scope=Scope.content)
icon_class = 'problem' icon_class = 'problem'
...@@ -135,7 +136,6 @@ class MentoringBlock(XBlockWithLightChildren): ...@@ -135,7 +136,6 @@ class MentoringBlock(XBlockWithLightChildren):
elif completed and self.next_step == self.url_name: elif completed and self.next_step == self.url_name:
self.next_step = self.followed_by self.next_step = self.followed_by
log.warn(submit_results);
self.completed = bool(completed) self.completed = bool(completed)
return { return {
'submitResults': submit_results, 'submitResults': submit_results,
...@@ -163,8 +163,9 @@ class MentoringBlock(XBlockWithLightChildren): ...@@ -163,8 +163,9 @@ class MentoringBlock(XBlockWithLightChildren):
fragment = Fragment() fragment = Fragment()
fragment.add_content(render_template('templates/html/mentoring_edit.html', { fragment.add_content(render_template('templates/html/mentoring_edit.html', {
'self': self, 'self': self,
'xml_content': self.xml_content or self.default_xml_content,
})) }))
fragment.add_javascript_url(self.runtime.local_resource_url(self, 'public/js/mentoring_edit.js')) fragment.add_javascript(load_resource('public/js/mentoring_edit.js'))
fragment.initialize_js('MentoringEditBlock') fragment.initialize_js('MentoringEditBlock')
...@@ -172,7 +173,7 @@ class MentoringBlock(XBlockWithLightChildren): ...@@ -172,7 +173,7 @@ class MentoringBlock(XBlockWithLightChildren):
@XBlock.json_handler @XBlock.json_handler
def studio_submit(self, submissions, suffix=''): def studio_submit(self, submissions, suffix=''):
log.info(u'Received submissions: {}'.format(submissions)) log.info(u'Received studio submissions: {}'.format(submissions))
# TODO-MRQ: Add XML validation # TODO-MRQ: Add XML validation
self.xml_content = submissions['xml_content'] self.xml_content = submissions['xml_content']
...@@ -180,6 +181,27 @@ class MentoringBlock(XBlockWithLightChildren): ...@@ -180,6 +181,27 @@ class MentoringBlock(XBlockWithLightChildren):
'result': 'success', 'result': 'success',
} }
@property
def default_xml_content(self):
return render_template('templates/xml/mentoring_default.xml', {
'self': self,
'url_name': self.url_name_with_default,
})
@property
def url_name_with_default(self):
"""
Ensure the `url_name` is set to a unique, non-empty value.
This should ideally be handled by Studio, but we need to declare the attribute
to be able to use it from the workbench, and when this happen Studio doesn't set
a unique default value - this property gives either the set value, or if none is set
a randomized default value
"""
if self.url_name == 'mentoring-default':
return 'mentoring-{}'.format(uuid.uuid4())
else:
return self.url_name
@staticmethod @staticmethod
def workbench_scenarios(): def workbench_scenarios():
""" """
......
function MentoringEditBlock(runtime, element) { function MentoringEditBlock(runtime, element) {
var xml_editor_textarea = $('.block-xml-editor', element),
xml_editor = CodeMirror.fromTextArea(xml_editor_textarea[0], { mode: 'xml' });
$('.save-button').bind('click', function() { $('.save-button').bind('click', function() {
var data = { var data = {
'xml_content': $('#mentoring-xml-content').val(), 'xml_content': xml_editor.getValue(),
}; };
var handlerUrl = runtime.handlerUrl(element, 'studio_submit'); var handlerUrl = runtime.handlerUrl(element, 'studio_submit');
$.post(handlerUrl, JSON.stringify(data)).complete(function() { $.post(handlerUrl, JSON.stringify(data)).complete(function() {
// TODO-MRQ: Error handling // TODO-MRQ: Error handling
......
<!-- TODO: Replace by default edit view once available in Studio --> <!-- TODO: Replace by default edit view once available in Studio -->
<div class="wrapper-comp-settings is-active" id="settings-tab"> <div class="wrapper-comp-settings is-active" id="settings-tab">
<script id="metadata-editor-tpl" type="text/template">// JS crashes when empty //</script> <script id="metadata-editor-tpl" type="text/template">// JS crashes when empty //</script>
<ul class="list-input settings-list"> <textarea class="block-xml-editor">{{ xml_content }}</textarea>
<li class="field comp-setting-entry is-set">
<div class="wrapper-comp-setting">
<label class="label setting-label" for="mentoring-xml-content">XML content</label>
<input class="input setting-input" id="mentoring-xml-content" value="{{ self.xml_content }}" type="text">
</div>
<span class="tip setting-help">XML source of the mentoring block</span>
</li>
</ul>
</div> </div>
<div class="row module-actions"> <div class="row module-actions">
<a href="#" class="save-button action-primary action">Save</a> <a href="#" class="save-button action-primary action">Save</a>
......
<mentoring url_name="{{ url_name }}">
<html>
<p>What is your goal?</p>
</html>
<answer name="goal" />
<quizz name="quizz_1_1" type="choices">
<question>Do you like this quizz?</question>
<choice value="yes">Yes</choice>
<choice value="maybenot">Maybe not</choice>
<choice value="understand">I don't understand</choice>
<tip display="yes">Great!</tip>
<tip reject="maybenot">Ah, damn.</tip>
<tip reject="understand"><html><div id="test-custom-html">Really?</div></html></tip>
</quizz>
<quizz name="quizz_1_2" type="rating" low="Not good at all" high="Extremely good">
<question>How much do you rate this quizz?</question>
<choice value="notwant">I don't want to rate it</choice>
<tip display="4,5">I love good grades.</tip>
<tip reject="1,2,3">Will do better next time...</tip>
<tip reject="notwant">Your loss!</tip>
</quizz>
<message type="completed">
<html><p>Congratulations!</p></html>
</message>
</mentoring>
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