Merge pull request #639 from pateljannat/summary
feat: assignment as text
This commit is contained in:
@@ -9,10 +9,12 @@
|
||||
"engine": "InnoDB",
|
||||
"field_order": [
|
||||
"title",
|
||||
"grade_assignment",
|
||||
"question",
|
||||
"column_break_hmwv",
|
||||
"type",
|
||||
"section_break_lwvt",
|
||||
"question"
|
||||
"show_answer",
|
||||
"answer"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
@@ -26,7 +28,7 @@
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 1,
|
||||
"label": "Type",
|
||||
"options": "Document\nPDF\nURL\nImage"
|
||||
"options": "Document\nPDF\nURL\nImage\nText"
|
||||
},
|
||||
{
|
||||
"fieldname": "title",
|
||||
@@ -40,13 +42,29 @@
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "section_break_lwvt",
|
||||
"fieldtype": "Section Break"
|
||||
"default": "0",
|
||||
"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,
|
||||
"links": [],
|
||||
"modified": "2023-06-26 18:09:29.809564",
|
||||
"modified": "2023-10-06 12:08:46.898950",
|
||||
"modified_by": "Administrator",
|
||||
"module": "LMS",
|
||||
"name": "LMS Assignment",
|
||||
|
||||
@@ -9,29 +9,29 @@
|
||||
"field_order": [
|
||||
"assignment",
|
||||
"assignment_title",
|
||||
"question",
|
||||
"type",
|
||||
"column_break_3",
|
||||
"member",
|
||||
"member_name",
|
||||
"type",
|
||||
"section_break_dlzh",
|
||||
"question",
|
||||
"column_break_zvis",
|
||||
"assignment_attachment",
|
||||
"answer",
|
||||
"section_break_rqal",
|
||||
"status",
|
||||
"evaluator",
|
||||
"column_break_esgd",
|
||||
"comments",
|
||||
"section_break_cwaw",
|
||||
"lesson",
|
||||
"course",
|
||||
"column_break_ygdu",
|
||||
"evaluator"
|
||||
"column_break_ygdu"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
"fieldname": "lesson",
|
||||
"fieldtype": "Link",
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 1,
|
||||
"label": "Lesson",
|
||||
"options": "Course Lesson"
|
||||
},
|
||||
@@ -78,7 +78,7 @@
|
||||
"fieldname": "status",
|
||||
"fieldtype": "Select",
|
||||
"label": "Status",
|
||||
"options": "Pass\nFail\nNot Graded"
|
||||
"options": "Pass\nFail\nNot Graded\nNot Applicable"
|
||||
},
|
||||
{
|
||||
"fieldname": "comments",
|
||||
@@ -94,7 +94,7 @@
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.type != \"URL\";",
|
||||
"depends_on": "eval:!([\"URL\", \"Text\"]).includes(doc.type);",
|
||||
"fieldname": "assignment_attachment",
|
||||
"fieldtype": "Attach",
|
||||
"label": "Assignment Attachment",
|
||||
@@ -104,8 +104,9 @@
|
||||
"fetch_from": "assignment.type",
|
||||
"fieldname": "type",
|
||||
"fieldtype": "Select",
|
||||
"in_list_view": 1,
|
||||
"label": "Type",
|
||||
"options": "Document\nPDF\nURL\nImage"
|
||||
"options": "Document\nPDF\nURL\nImage\nText"
|
||||
},
|
||||
{
|
||||
"fetch_from": "assignment.question",
|
||||
@@ -137,17 +138,25 @@
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.type == \"URL\";",
|
||||
"depends_on": "eval:([\"URL\", \"Text\"]).includes(doc.type);",
|
||||
"fieldname": "answer",
|
||||
"fieldtype": "Long Text",
|
||||
"fieldtype": "Text Editor",
|
||||
"label": "Answer",
|
||||
"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,
|
||||
"links": [],
|
||||
"make_attachments_public": 1,
|
||||
"modified": "2023-08-30 12:09:03.332820",
|
||||
"modified": "2023-10-06 15:14:55.984714",
|
||||
"modified_by": "Administrator",
|
||||
"module": "LMS",
|
||||
"name": "LMS Assignment Submission",
|
||||
@@ -181,6 +190,10 @@
|
||||
{
|
||||
"color": "Red",
|
||||
"title": "Fail"
|
||||
},
|
||||
{
|
||||
"color": "Blue",
|
||||
"title": "Not Applicable"
|
||||
}
|
||||
],
|
||||
"title_field": "assignment_title"
|
||||
|
||||
@@ -37,9 +37,12 @@ def upload_assignment(
|
||||
if frappe.session.user == "Guest":
|
||||
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."))
|
||||
|
||||
if assignment_type == "File" and not assignment_attachment:
|
||||
@@ -64,7 +67,9 @@ def upload_assignment(
|
||||
doc.update(
|
||||
{
|
||||
"assignment_attachment": assignment_attachment,
|
||||
"status": status,
|
||||
"status": "Not Applicable"
|
||||
if assignment_type == "Text" and not assignment_details.grade_assignment
|
||||
else status,
|
||||
"comments": comments,
|
||||
"answer": answer,
|
||||
}
|
||||
|
||||
@@ -71,4 +71,4 @@ lms.patches.v1_0.publish_batches
|
||||
lms.patches.v1_0.publish_certificates
|
||||
lms.patches.v1_0.change_naming_for_batch_course #14-09-2023
|
||||
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",
|
||||
label: __("Meta Image"),
|
||||
fieldname: "meta_image",
|
||||
default: batch_info && batch_info.image,
|
||||
default: batch_info && batch_info.meta_image,
|
||||
},
|
||||
{
|
||||
fieldtype: "Section Break",
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<div class="page-title">
|
||||
{{ assignment.title }}
|
||||
</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" %}
|
||||
<div class="indicator-pill {{ color }} ml-2">
|
||||
{{ submission.status }}
|
||||
@@ -37,7 +37,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
{% if not assignment.show_answer or (assignment.show_answer and not submission) %}
|
||||
<div class="align-self-center">
|
||||
<button class="btn btn-primary btn-sm btn-save-assignment"
|
||||
data-assignment="{{ assignment.name }}" data-type="{{ assignment.type }}"
|
||||
@@ -45,6 +45,7 @@
|
||||
{{ _("Save") }}
|
||||
</button>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
@@ -52,7 +53,7 @@
|
||||
|
||||
{% macro SubmissionForm(assignment) %}
|
||||
<article class="field-parent">
|
||||
{% if submission.name %}
|
||||
{% if assignment.grade_assignment and submission.name %}
|
||||
<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.") }}
|
||||
</div>
|
||||
@@ -73,7 +74,7 @@
|
||||
{{ assignment.question }}
|
||||
</div>
|
||||
|
||||
{% if assignment.type != "URL" %}
|
||||
{% if assignment.type not in ["URL", "Text"] %}
|
||||
<div class="field-group">
|
||||
<div class="bold-heading">
|
||||
{{ _("Submit")}}
|
||||
@@ -100,17 +101,41 @@
|
||||
|
||||
<div class="field-group">
|
||||
<div class="bold-heading">
|
||||
{{ _("Submit")}}
|
||||
{{ _("Submission")}}
|
||||
</div>
|
||||
<div class="field-description">
|
||||
{{ _("Enter a URL") }}
|
||||
{% if assignment.type == "URL" %}
|
||||
{{ _("Enter a {0}").format(assignment.type) }}
|
||||
{% else %}
|
||||
{{ _("Enter your response") }}
|
||||
{% endif %}
|
||||
</div>
|
||||
<input id="assignment-url" type="text" class="field-input" placeholder="https://"
|
||||
{% if submission.answer %} value="{{ submission.answer }}" {% endif %}>
|
||||
{% if assignment.type == "URL" %}
|
||||
<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>
|
||||
{% 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-label">
|
||||
{{ _("Status") }}
|
||||
|
||||
@@ -1,4 +1,10 @@
|
||||
frappe.ready(() => {
|
||||
if ($(".assignment-text").length) {
|
||||
frappe.require("controls.bundle.js", () => {
|
||||
make_text_editor();
|
||||
});
|
||||
}
|
||||
|
||||
$(".btn-upload").click((e) => {
|
||||
upload_file(e);
|
||||
});
|
||||
@@ -52,11 +58,19 @@ const save_assignment = (e) => {
|
||||
file = "";
|
||||
|
||||
if (data == "URL") {
|
||||
answer = $("#assignment-url").val();
|
||||
answer = $(".assignment-answer").val();
|
||||
if (!answer) {
|
||||
frappe.throw({
|
||||
title: __("No URL"),
|
||||
message: __("Please enter a URL."),
|
||||
title: __("No Submission"),
|
||||
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 {
|
||||
@@ -99,3 +113,20 @@ const clear_preview = (e) => {
|
||||
$("#assignment-preview a").attr("href", "");
|
||||
$("#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"]
|
||||
|
||||
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":
|
||||
@@ -34,6 +37,10 @@ def get_context(context):
|
||||
],
|
||||
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:
|
||||
raise frappe.PermissionError(_("You don't have permission to access this page."))
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
{% block content %}
|
||||
<main class="common-page-style">
|
||||
<div class="container form-width">
|
||||
<div class="container">
|
||||
{{ Header() }}
|
||||
{% if assignments | length %}
|
||||
{{ AssignmentList(assignments) }}
|
||||
@@ -32,7 +32,33 @@
|
||||
|
||||
{% macro AssignmentList(assignments) %}
|
||||
<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 %}
|
||||
<li class="list-row">
|
||||
<a class="clickable" href="/assignments/{{ assignment.name }}">
|
||||
@@ -45,7 +71,7 @@
|
||||
</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</ul> -->
|
||||
</div>
|
||||
{% endmacro %}
|
||||
|
||||
|
||||
@@ -1,10 +1,17 @@
|
||||
import frappe
|
||||
from lms.lms.utils import has_course_moderator_role
|
||||
|
||||
|
||||
def get_context(context):
|
||||
context.no_cache = 1
|
||||
|
||||
filters = {"owner": frappe.session.user}
|
||||
|
||||
if has_course_moderator_role():
|
||||
filters = {}
|
||||
|
||||
context.assignments = frappe.get_all(
|
||||
"LMS Assignment",
|
||||
{"owner": frappe.session.user},
|
||||
filters,
|
||||
["title", "name", "type", "question"],
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user