feat: assignment as text
This commit is contained in:
@@ -9,10 +9,12 @@
|
|||||||
"engine": "InnoDB",
|
"engine": "InnoDB",
|
||||||
"field_order": [
|
"field_order": [
|
||||||
"title",
|
"title",
|
||||||
|
"grade_assignment",
|
||||||
|
"question",
|
||||||
"column_break_hmwv",
|
"column_break_hmwv",
|
||||||
"type",
|
"type",
|
||||||
"section_break_lwvt",
|
"show_answer",
|
||||||
"question"
|
"answer"
|
||||||
],
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
@@ -26,7 +28,7 @@
|
|||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"in_standard_filter": 1,
|
"in_standard_filter": 1,
|
||||||
"label": "Type",
|
"label": "Type",
|
||||||
"options": "Document\nPDF\nURL\nImage"
|
"options": "Document\nPDF\nURL\nImage\nText"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "title",
|
"fieldname": "title",
|
||||||
@@ -40,13 +42,29 @@
|
|||||||
"fieldtype": "Column Break"
|
"fieldtype": "Column Break"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "section_break_lwvt",
|
"default": "0",
|
||||||
"fieldtype": "Section Break"
|
"depends_on": "eval:doc.type == \"Text\"",
|
||||||
|
"fieldname": "show_answer",
|
||||||
|
"fieldtype": "Check",
|
||||||
|
"label": "Show Answer"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"depends_on": "show_answer",
|
||||||
|
"fieldname": "answer",
|
||||||
|
"fieldtype": "Text Editor",
|
||||||
|
"label": "Answer"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": "1",
|
||||||
|
"depends_on": "eval:doc.type == \"Text\"",
|
||||||
|
"fieldname": "grade_assignment",
|
||||||
|
"fieldtype": "Check",
|
||||||
|
"label": "Grade Assignment"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2023-06-26 18:09:29.809564",
|
"modified": "2023-10-06 12:08:46.898950",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "LMS",
|
"module": "LMS",
|
||||||
"name": "LMS Assignment",
|
"name": "LMS Assignment",
|
||||||
|
|||||||
@@ -9,29 +9,29 @@
|
|||||||
"field_order": [
|
"field_order": [
|
||||||
"assignment",
|
"assignment",
|
||||||
"assignment_title",
|
"assignment_title",
|
||||||
"question",
|
"type",
|
||||||
"column_break_3",
|
"column_break_3",
|
||||||
"member",
|
"member",
|
||||||
"member_name",
|
"member_name",
|
||||||
"type",
|
"section_break_dlzh",
|
||||||
|
"question",
|
||||||
|
"column_break_zvis",
|
||||||
"assignment_attachment",
|
"assignment_attachment",
|
||||||
"answer",
|
"answer",
|
||||||
"section_break_rqal",
|
"section_break_rqal",
|
||||||
"status",
|
"status",
|
||||||
|
"evaluator",
|
||||||
"column_break_esgd",
|
"column_break_esgd",
|
||||||
"comments",
|
"comments",
|
||||||
"section_break_cwaw",
|
"section_break_cwaw",
|
||||||
"lesson",
|
"lesson",
|
||||||
"course",
|
"course",
|
||||||
"column_break_ygdu",
|
"column_break_ygdu"
|
||||||
"evaluator"
|
|
||||||
],
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
"fieldname": "lesson",
|
"fieldname": "lesson",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"in_list_view": 1,
|
|
||||||
"in_standard_filter": 1,
|
|
||||||
"label": "Lesson",
|
"label": "Lesson",
|
||||||
"options": "Course Lesson"
|
"options": "Course Lesson"
|
||||||
},
|
},
|
||||||
@@ -78,7 +78,7 @@
|
|||||||
"fieldname": "status",
|
"fieldname": "status",
|
||||||
"fieldtype": "Select",
|
"fieldtype": "Select",
|
||||||
"label": "Status",
|
"label": "Status",
|
||||||
"options": "Pass\nFail\nNot Graded"
|
"options": "Pass\nFail\nNot Graded\nNot Applicable"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "comments",
|
"fieldname": "comments",
|
||||||
@@ -94,7 +94,7 @@
|
|||||||
"read_only": 1
|
"read_only": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"depends_on": "eval:doc.type != \"URL\";",
|
"depends_on": "eval:!([\"URL\", \"Text\"]).includes(doc.type);",
|
||||||
"fieldname": "assignment_attachment",
|
"fieldname": "assignment_attachment",
|
||||||
"fieldtype": "Attach",
|
"fieldtype": "Attach",
|
||||||
"label": "Assignment Attachment",
|
"label": "Assignment Attachment",
|
||||||
@@ -104,8 +104,9 @@
|
|||||||
"fetch_from": "assignment.type",
|
"fetch_from": "assignment.type",
|
||||||
"fieldname": "type",
|
"fieldname": "type",
|
||||||
"fieldtype": "Select",
|
"fieldtype": "Select",
|
||||||
|
"in_list_view": 1,
|
||||||
"label": "Type",
|
"label": "Type",
|
||||||
"options": "Document\nPDF\nURL\nImage"
|
"options": "Document\nPDF\nURL\nImage\nText"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fetch_from": "assignment.question",
|
"fetch_from": "assignment.question",
|
||||||
@@ -137,17 +138,25 @@
|
|||||||
"fieldtype": "Column Break"
|
"fieldtype": "Column Break"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"depends_on": "eval:doc.type == \"URL\";",
|
"depends_on": "eval:([\"URL\", \"Text\"]).includes(doc.type);",
|
||||||
"fieldname": "answer",
|
"fieldname": "answer",
|
||||||
"fieldtype": "Long Text",
|
"fieldtype": "Text Editor",
|
||||||
"label": "Answer",
|
"label": "Answer",
|
||||||
"mandatory_depends_on": "eval:doc.type == \"URL\";"
|
"mandatory_depends_on": "eval:doc.type == \"URL\";"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "section_break_dlzh",
|
||||||
|
"fieldtype": "Section Break"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "column_break_zvis",
|
||||||
|
"fieldtype": "Column Break"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"make_attachments_public": 1,
|
"make_attachments_public": 1,
|
||||||
"modified": "2023-08-30 12:09:03.332820",
|
"modified": "2023-10-06 15:14:55.984714",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "LMS",
|
"module": "LMS",
|
||||||
"name": "LMS Assignment Submission",
|
"name": "LMS Assignment Submission",
|
||||||
@@ -181,6 +190,10 @@
|
|||||||
{
|
{
|
||||||
"color": "Red",
|
"color": "Red",
|
||||||
"title": "Fail"
|
"title": "Fail"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"color": "Blue",
|
||||||
|
"title": "Not Applicable"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"title_field": "assignment_title"
|
"title_field": "assignment_title"
|
||||||
|
|||||||
@@ -37,9 +37,12 @@ def upload_assignment(
|
|||||||
if frappe.session.user == "Guest":
|
if frappe.session.user == "Guest":
|
||||||
return
|
return
|
||||||
|
|
||||||
assignment_type = frappe.db.get_value("LMS Assignment", assignment, "type")
|
assignment_details = frappe.db.get_value(
|
||||||
|
"LMS Assignment", assignment, ["type", "grade_assignment"], as_dict=1
|
||||||
|
)
|
||||||
|
assignment_type = assignment_details.type
|
||||||
|
|
||||||
if assignment_type == "URL" and not answer:
|
if assignment_type in ["URL", "Text"] and not answer:
|
||||||
frappe.throw(_("Please enter the URL for assignment submission."))
|
frappe.throw(_("Please enter the URL for assignment submission."))
|
||||||
|
|
||||||
if assignment_type == "File" and not assignment_attachment:
|
if assignment_type == "File" and not assignment_attachment:
|
||||||
@@ -64,7 +67,9 @@ def upload_assignment(
|
|||||||
doc.update(
|
doc.update(
|
||||||
{
|
{
|
||||||
"assignment_attachment": assignment_attachment,
|
"assignment_attachment": assignment_attachment,
|
||||||
"status": status,
|
"status": "Not Applicable"
|
||||||
|
if assignment_type == "Text" and not assignment_details.grade_assignment
|
||||||
|
else status,
|
||||||
"comments": comments,
|
"comments": comments,
|
||||||
"answer": answer,
|
"answer": answer,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -71,4 +71,4 @@ lms.patches.v1_0.publish_batches
|
|||||||
lms.patches.v1_0.publish_certificates
|
lms.patches.v1_0.publish_certificates
|
||||||
lms.patches.v1_0.change_naming_for_batch_course #14-09-2023
|
lms.patches.v1_0.change_naming_for_batch_course #14-09-2023
|
||||||
execute:frappe.permissions.reset_perms("LMS Enrollment")
|
execute:frappe.permissions.reset_perms("LMS Enrollment")
|
||||||
lms.patches.v1_0.create_student_role
|
lms.patches.v1_0.create_student_role
|
||||||
@@ -350,7 +350,7 @@ const open_batch_dialog = () => {
|
|||||||
fieldtype: "Attach Image",
|
fieldtype: "Attach Image",
|
||||||
label: __("Meta Image"),
|
label: __("Meta Image"),
|
||||||
fieldname: "meta_image",
|
fieldname: "meta_image",
|
||||||
default: batch_info && batch_info.image,
|
default: batch_info && batch_info.meta_image,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
fieldtype: "Section Break",
|
fieldtype: "Section Break",
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
<div class="page-title">
|
<div class="page-title">
|
||||||
{{ assignment.title }}
|
{{ assignment.title }}
|
||||||
</div>
|
</div>
|
||||||
{% if submission.status %}
|
{% if assignment.grade_assignment and submission.status %}
|
||||||
{% set color = "green" if submission.status == "Pass" else "red" if submission.status == "Fail" else "orange" %}
|
{% set color = "green" if submission.status == "Pass" else "red" if submission.status == "Fail" else "orange" %}
|
||||||
<div class="indicator-pill {{ color }} ml-2">
|
<div class="indicator-pill {{ color }} ml-2">
|
||||||
{{ submission.status }}
|
{{ submission.status }}
|
||||||
@@ -37,7 +37,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{% if not assignment.show_answer or (assignment.show_answer and not submission) %}
|
||||||
<div class="align-self-center">
|
<div class="align-self-center">
|
||||||
<button class="btn btn-primary btn-sm btn-save-assignment"
|
<button class="btn btn-primary btn-sm btn-save-assignment"
|
||||||
data-assignment="{{ assignment.name }}" data-type="{{ assignment.type }}"
|
data-assignment="{{ assignment.name }}" data-type="{{ assignment.type }}"
|
||||||
@@ -45,6 +45,7 @@
|
|||||||
{{ _("Save") }}
|
{{ _("Save") }}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
@@ -52,7 +53,7 @@
|
|||||||
|
|
||||||
{% macro SubmissionForm(assignment) %}
|
{% macro SubmissionForm(assignment) %}
|
||||||
<article class="field-parent">
|
<article class="field-parent">
|
||||||
{% if submission.name %}
|
{% if assignment.grade_assignment and submission.name %}
|
||||||
<div class="alert alert-info">
|
<div class="alert alert-info">
|
||||||
{{ _("You've successfully submitted the assignment. Once the moderator grades your submission, you'll find the details here. Feel free to make edits to your submission if needed.") }}
|
{{ _("You've successfully submitted the assignment. Once the moderator grades your submission, you'll find the details here. Feel free to make edits to your submission if needed.") }}
|
||||||
</div>
|
</div>
|
||||||
@@ -73,7 +74,7 @@
|
|||||||
{{ assignment.question }}
|
{{ assignment.question }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% if assignment.type != "URL" %}
|
{% if assignment.type not in ["URL", "Text"] %}
|
||||||
<div class="field-group">
|
<div class="field-group">
|
||||||
<div class="bold-heading">
|
<div class="bold-heading">
|
||||||
{{ _("Submit")}}
|
{{ _("Submit")}}
|
||||||
@@ -100,17 +101,41 @@
|
|||||||
|
|
||||||
<div class="field-group">
|
<div class="field-group">
|
||||||
<div class="bold-heading">
|
<div class="bold-heading">
|
||||||
{{ _("Submit")}}
|
{{ _("Submission")}}
|
||||||
</div>
|
</div>
|
||||||
<div class="field-description">
|
<div class="field-description">
|
||||||
{{ _("Enter a URL") }}
|
{% if assignment.type == "URL" %}
|
||||||
|
{{ _("Enter a {0}").format(assignment.type) }}
|
||||||
|
{% else %}
|
||||||
|
{{ _("Enter your response") }}
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
<input id="assignment-url" type="text" class="field-input" placeholder="https://"
|
{% if assignment.type == "URL" %}
|
||||||
{% if submission.answer %} value="{{ submission.answer }}" {% endif %}>
|
<input type="text" class="field-input assignment-answer" placeholder="https://"
|
||||||
|
{% if submission.answer %} value="{{ submission.answer }}" {% endif %}>
|
||||||
|
{% else %}
|
||||||
|
<div class="assignment-text"></div>
|
||||||
|
{% if submission.answer %}
|
||||||
|
<div class="assignment-text-data hide">
|
||||||
|
{{ submission.answer }}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if is_moderator %}
|
{% if assignment.show_answer and submission %}
|
||||||
|
<div class="field-group">
|
||||||
|
<div class="bold-heading">
|
||||||
|
{{ _("Response by Instructor:") }}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
{{ assignment.answer }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if assignment.grade_assignment and is_moderator %}
|
||||||
<div class="field-group">
|
<div class="field-group">
|
||||||
<div class="field-label">
|
<div class="field-label">
|
||||||
{{ _("Status") }}
|
{{ _("Status") }}
|
||||||
|
|||||||
@@ -1,4 +1,10 @@
|
|||||||
frappe.ready(() => {
|
frappe.ready(() => {
|
||||||
|
if ($(".assignment-text").length) {
|
||||||
|
frappe.require("controls.bundle.js", () => {
|
||||||
|
make_text_editor();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
$(".btn-upload").click((e) => {
|
$(".btn-upload").click((e) => {
|
||||||
upload_file(e);
|
upload_file(e);
|
||||||
});
|
});
|
||||||
@@ -52,11 +58,19 @@ const save_assignment = (e) => {
|
|||||||
file = "";
|
file = "";
|
||||||
|
|
||||||
if (data == "URL") {
|
if (data == "URL") {
|
||||||
answer = $("#assignment-url").val();
|
answer = $(".assignment-answer").val();
|
||||||
if (!answer) {
|
if (!answer) {
|
||||||
frappe.throw({
|
frappe.throw({
|
||||||
title: __("No URL"),
|
title: __("No Submission"),
|
||||||
message: __("Please enter a URL."),
|
message: __("Please enter a response."),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else if (data == "Text") {
|
||||||
|
answer = this.text_editor.get_value("assignment_text");
|
||||||
|
if (!answer) {
|
||||||
|
frappe.throw({
|
||||||
|
title: __("No Submission"),
|
||||||
|
message: __("Please enter a response."),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -99,3 +113,20 @@ const clear_preview = (e) => {
|
|||||||
$("#assignment-preview a").attr("href", "");
|
$("#assignment-preview a").attr("href", "");
|
||||||
$("#assignment-preview .btn-close").addClass("hide");
|
$("#assignment-preview .btn-close").addClass("hide");
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const make_text_editor = () => {
|
||||||
|
this.text_editor = new frappe.ui.FieldGroup({
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
fieldname: "assignment_text",
|
||||||
|
fieldtype: "Text Editor",
|
||||||
|
default: $(".assignment-text-data").html(),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
body: $(".assignment-text").get(0),
|
||||||
|
});
|
||||||
|
this.text_editor.make();
|
||||||
|
$(".assignment-text .form-section:last").removeClass("empty-section");
|
||||||
|
$(".assignment-text .frappe-control").removeClass("hide-control");
|
||||||
|
$(".assignment-text .form-column").addClass("p-0");
|
||||||
|
};
|
||||||
|
|||||||
@@ -14,7 +14,10 @@ def get_context(context):
|
|||||||
assignment = frappe.form_dict["assignment"]
|
assignment = frappe.form_dict["assignment"]
|
||||||
|
|
||||||
context.assignment = frappe.db.get_value(
|
context.assignment = frappe.db.get_value(
|
||||||
"LMS Assignment", assignment, ["title", "name", "type", "question"], as_dict=1
|
"LMS Assignment",
|
||||||
|
assignment,
|
||||||
|
["title", "name", "type", "question", "show_answer", "answer", "grade_assignment"],
|
||||||
|
as_dict=1,
|
||||||
)
|
)
|
||||||
|
|
||||||
if submission == "new-submission":
|
if submission == "new-submission":
|
||||||
@@ -34,6 +37,10 @@ def get_context(context):
|
|||||||
],
|
],
|
||||||
as_dict=True,
|
as_dict=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if not context.submission:
|
||||||
|
raise frappe.PermissionError(_("Invalid Submission URL"))
|
||||||
|
|
||||||
if not context.is_moderator and frappe.session.user != context.submission.member:
|
if not context.is_moderator and frappe.session.user != context.submission.member:
|
||||||
raise frappe.PermissionError(_("You don't have permission to access this page."))
|
raise frappe.PermissionError(_("You don't have permission to access this page."))
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<main class="common-page-style">
|
<main class="common-page-style">
|
||||||
<div class="container form-width">
|
<div class="container">
|
||||||
{{ Header() }}
|
{{ Header() }}
|
||||||
{% if assignments | length %}
|
{% if assignments | length %}
|
||||||
{{ AssignmentList(assignments) }}
|
{{ AssignmentList(assignments) }}
|
||||||
@@ -32,7 +32,33 @@
|
|||||||
|
|
||||||
{% macro AssignmentList(assignments) %}
|
{% macro AssignmentList(assignments) %}
|
||||||
<div class="mt-5">
|
<div class="mt-5">
|
||||||
<ul class="list-unstyled">
|
<div class="form-grid">
|
||||||
|
<div class="grid-heading-row">
|
||||||
|
<div class="grid-row">
|
||||||
|
<div class="data-row row">
|
||||||
|
<div class="col grid-static-col">
|
||||||
|
{{ _("Title") }}
|
||||||
|
</div>
|
||||||
|
<div class="col grid-static-col col-xs-3">
|
||||||
|
{{ _("Type") }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% for assignment in assignments %}
|
||||||
|
<div class="grid-row">
|
||||||
|
<div class="data-row row">
|
||||||
|
<a class="col grid-static-col button-links clickable" href="/assignments/{{ assignment.name }}">
|
||||||
|
{{ assignment.title }}
|
||||||
|
</a>
|
||||||
|
<div class="col grid-static-col col-xs-3">
|
||||||
|
{{ assignment.type }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
<!-- <ul class="list-unstyled">
|
||||||
{% for assignment in assignments %}
|
{% for assignment in assignments %}
|
||||||
<li class="list-row">
|
<li class="list-row">
|
||||||
<a class="clickable" href="/assignments/{{ assignment.name }}">
|
<a class="clickable" href="/assignments/{{ assignment.name }}">
|
||||||
@@ -45,7 +71,7 @@
|
|||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul> -->
|
||||||
</div>
|
</div>
|
||||||
{% endmacro %}
|
{% endmacro %}
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,17 @@
|
|||||||
import frappe
|
import frappe
|
||||||
|
from lms.lms.utils import has_course_moderator_role
|
||||||
|
|
||||||
|
|
||||||
def get_context(context):
|
def get_context(context):
|
||||||
context.no_cache = 1
|
context.no_cache = 1
|
||||||
|
|
||||||
|
filters = {"owner": frappe.session.user}
|
||||||
|
|
||||||
|
if has_course_moderator_role():
|
||||||
|
filters = {}
|
||||||
|
|
||||||
context.assignments = frappe.get_all(
|
context.assignments = frappe.get_all(
|
||||||
"LMS Assignment",
|
"LMS Assignment",
|
||||||
{"owner": frappe.session.user},
|
filters,
|
||||||
["title", "name", "type", "question"],
|
["title", "name", "type", "question"],
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user