Added the ability to save sketches
Implemented by exposing an RPC method to save the sketch and calling from JS using `frappe.call`. Any logged-in user can create new sketches and the owner can edit his/her own sketches.
This commit is contained in:
@@ -3,8 +3,37 @@
|
|||||||
# For license information, please see license.txt
|
# For license information, please see license.txt
|
||||||
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
# import frappe
|
import frappe
|
||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
|
|
||||||
class LMSSketch(Document):
|
class LMSSketch(Document):
|
||||||
pass
|
def get_owner_name(self):
|
||||||
|
return self.owner.split("@")[0]
|
||||||
|
|
||||||
|
@frappe.whitelist()
|
||||||
|
def save_sketch(name, title, code):
|
||||||
|
if not name or name == "new":
|
||||||
|
doc = frappe.new_doc('LMS Sketch')
|
||||||
|
doc.title = title
|
||||||
|
doc.code = code
|
||||||
|
doc.runtime = 'python-canvas'
|
||||||
|
doc.insert()
|
||||||
|
status = "created"
|
||||||
|
else:
|
||||||
|
doc = frappe.get_doc("LMS Sketch", name)
|
||||||
|
|
||||||
|
if doc.owner != frappe.session.user:
|
||||||
|
return {
|
||||||
|
"ok": False,
|
||||||
|
"error": "Permission Denied"
|
||||||
|
}
|
||||||
|
doc.title = title
|
||||||
|
doc.code = code
|
||||||
|
doc.save()
|
||||||
|
status = "updated"
|
||||||
|
return {
|
||||||
|
"ok": True,
|
||||||
|
"status": status,
|
||||||
|
"name": doc.name,
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -25,6 +25,8 @@
|
|||||||
{% macro LiveCodeEditorJS(name, code) %}
|
{% macro LiveCodeEditorJS(name, code) %}
|
||||||
<script type="text/javascript" src="{{ livecode_url }}/static/livecode.js"></script>
|
<script type="text/javascript" src="{{ livecode_url }}/static/livecode.js"></script>
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
|
var livecodeEditors = [];
|
||||||
|
|
||||||
$(function() {
|
$(function() {
|
||||||
$(".canvas-editor").each((i, e) => {
|
$(".canvas-editor").each((i, e) => {
|
||||||
var editor = new LiveCodeEditor(e, {
|
var editor = new LiveCodeEditor(e, {
|
||||||
@@ -32,6 +34,7 @@
|
|||||||
base_url: "{{ livecode_url }}",
|
base_url: "{{ livecode_url }}",
|
||||||
codemirror: true
|
codemirror: true
|
||||||
})
|
})
|
||||||
|
livecodeEditors.push(editor);
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -29,22 +29,81 @@
|
|||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
<div class="sketch-header">
|
<div class="sketch-header">
|
||||||
<h1 class="sketch-title">{{ sketch.title }}</h1>
|
{% if editable %}
|
||||||
<div class="sketch-owner-wrapper">By <span class="sketch-owner">{{sketch.owner}}</span></div>
|
<input type="button" class="pull-right" id="sketch-save" value="Save"/>
|
||||||
|
<h1 class="sketch-title">
|
||||||
|
<input type="text" name="title" id="sketch-title" value="{{ sketch.title }}" />
|
||||||
|
</h1>
|
||||||
|
{% else %}
|
||||||
|
<h1 class="sketch-title">{{sketch.title}}</h1>
|
||||||
|
{% endif %}
|
||||||
|
<div class="sketch-owner-wrapper">By <span class="sketch-owner">{{sketch.get_owner_name()}}</span></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% if not sketch.name %}
|
{% if sketch.is_new() and not editable %}
|
||||||
<div class="alert alert-warning">
|
<div class="alert alert-warning">
|
||||||
Saving sketches is not yet implemented. Coming soon!
|
Please login to save this sketch.
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
<div class="sketch-editor">
|
||||||
{{LiveCodeEditor(sketch.name, sketch.code) }}
|
{{LiveCodeEditor(sketch.name, sketch.code) }}
|
||||||
|
</div>
|
||||||
</section>
|
</section>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{%- block script %}
|
{%- block script %}
|
||||||
{{ super() }}
|
{{ super() }}
|
||||||
{{ LiveCodeEditorJS() }}
|
{{ LiveCodeEditorJS() }}
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
var sketch_name = {{ sketch.name | tojson }};
|
||||||
|
|
||||||
|
function saveSketch() {
|
||||||
|
var title = $("#sketch-title").val()
|
||||||
|
var code = livecodeEditors[0].codemirror.doc.getValue()
|
||||||
|
frappe.call('community.lms.doctype.lms_sketch.lms_sketch.save_sketch', {
|
||||||
|
name: sketch_name,
|
||||||
|
title: title,
|
||||||
|
code: code
|
||||||
|
})
|
||||||
|
.then(r => {
|
||||||
|
var msg = r.message;
|
||||||
|
if (!msg.ok) {
|
||||||
|
var error = msg.error || "Save failed."
|
||||||
|
frappe.msgprint({
|
||||||
|
"title": "Error",
|
||||||
|
"indicator": "red",
|
||||||
|
"message": error
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else if (msg.status == "created") {
|
||||||
|
var path = "/sketches/sketch?sketch=" + msg.name;
|
||||||
|
var url = window.location.protocol + "//" + window.location.host + path
|
||||||
|
window.history.pushState({path: url}, '', url);
|
||||||
|
sketch_name = name;
|
||||||
|
|
||||||
|
frappe.msgprint({
|
||||||
|
"title": "Notification",
|
||||||
|
"indicator": "green",
|
||||||
|
"message": "New sketch has been saved!"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else if (msg.status == "updated") {
|
||||||
|
frappe.msgprint({
|
||||||
|
"title": "Notification",
|
||||||
|
"indicator": "green",
|
||||||
|
"message": "The sketch has been saved!"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
$(function() {
|
||||||
|
$("#sketch-save").click(function() {
|
||||||
|
saveSketch();
|
||||||
|
});
|
||||||
|
})
|
||||||
|
</script>
|
||||||
{%- endblock %}
|
{%- endblock %}
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,15 @@ def get_context(context):
|
|||||||
course_name = get_queryparam("sketch", '/sketches')
|
course_name = get_queryparam("sketch", '/sketches')
|
||||||
context.sketch = get_sketch(course_name)
|
context.sketch = get_sketch(course_name)
|
||||||
context.livecode_url = get_livecode_url()
|
context.livecode_url = get_livecode_url()
|
||||||
|
context.editable = is_editable(context.sketch, frappe.sesson.user)
|
||||||
|
|
||||||
|
def is_editable(sketch, user):
|
||||||
|
if sketch.name == "new":
|
||||||
|
# new sketches can be editable by any logged in user
|
||||||
|
return user != "Guest"
|
||||||
|
else:
|
||||||
|
# existing sketches are editable by the owner
|
||||||
|
return sketch.owner == user
|
||||||
|
|
||||||
def get_livecode_url():
|
def get_livecode_url():
|
||||||
doc = frappe.get_doc("LMS Settings")
|
doc = frappe.get_doc("LMS Settings")
|
||||||
@@ -20,15 +29,13 @@ def get_queryparam(name, redirect_when_not_found):
|
|||||||
def get_sketch(name):
|
def get_sketch(name):
|
||||||
if name == 'new':
|
if name == 'new':
|
||||||
sketch = frappe.new_doc('LMS Sketch')
|
sketch = frappe.new_doc('LMS Sketch')
|
||||||
|
sketch.name = "new"
|
||||||
sketch.title = "New Sketch"
|
sketch.title = "New Sketch"
|
||||||
sketch.code = "circle(100, 100, 50)"
|
sketch.code = "circle(100, 100, 50)"
|
||||||
sketch.owner = frappe.session.user.split("@")[0]
|
|
||||||
return sketch
|
return sketch
|
||||||
|
|
||||||
try:
|
try:
|
||||||
sketch = frappe.get_doc('LMS Sketch', name)
|
return frappe.get_doc('LMS Sketch', name)
|
||||||
except frappe.exceptions.DoesNotExistError:
|
except frappe.exceptions.DoesNotExistError:
|
||||||
raise frappe.NotFound
|
raise frappe.NotFound
|
||||||
|
|
||||||
sketch.owner = sketch.owner.split("@")[0]
|
|
||||||
return sketch
|
|
||||||
|
|||||||
Reference in New Issue
Block a user