Merge pull request #433 from pateljannat/activity-details
This commit is contained in:
@@ -81,10 +81,8 @@ def quiz_summary(quiz, results):
|
|||||||
for point in result["is_correct"]:
|
for point in result["is_correct"]:
|
||||||
correct = correct and point
|
correct = correct and point
|
||||||
|
|
||||||
result["result"] = "Right" if correct else "Wrong"
|
result["is_correct"] = correct
|
||||||
score += correct
|
score += correct
|
||||||
|
|
||||||
del result["is_correct"]
|
|
||||||
del result["question_index"]
|
del result["question_index"]
|
||||||
|
|
||||||
frappe.get_doc(
|
frappe.get_doc(
|
||||||
|
|||||||
@@ -7,33 +7,36 @@
|
|||||||
"field_order": [
|
"field_order": [
|
||||||
"question",
|
"question",
|
||||||
"answer",
|
"answer",
|
||||||
"result"
|
"is_correct"
|
||||||
],
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
"fieldname": "question",
|
"fieldname": "question",
|
||||||
"fieldtype": "Text",
|
"fieldtype": "Text",
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"label": "Question"
|
"label": "Question",
|
||||||
},
|
"read_only": 1
|
||||||
{
|
|
||||||
"fieldname": "result",
|
|
||||||
"fieldtype": "Select",
|
|
||||||
"in_list_view": 1,
|
|
||||||
"label": "Result",
|
|
||||||
"options": "Right\nWrong"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "answer",
|
"fieldname": "answer",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"label": "Users Response"
|
"label": "Users Response",
|
||||||
|
"read_only": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": "0",
|
||||||
|
"fieldname": "is_correct",
|
||||||
|
"fieldtype": "Check",
|
||||||
|
"in_list_view": 1,
|
||||||
|
"label": "Is Correct",
|
||||||
|
"read_only": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2021-10-12 10:32:45.139121",
|
"modified": "2022-11-24 11:15:45.931119",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "LMS",
|
"module": "LMS",
|
||||||
"name": "LMS Quiz Result",
|
"name": "LMS Quiz Result",
|
||||||
@@ -41,5 +44,6 @@
|
|||||||
"permissions": [],
|
"permissions": [],
|
||||||
"sort_field": "modified",
|
"sort_field": "modified",
|
||||||
"sort_order": "DESC",
|
"sort_order": "DESC",
|
||||||
|
"states": [],
|
||||||
"track_changes": 1
|
"track_changes": 1
|
||||||
}
|
}
|
||||||
@@ -38,3 +38,4 @@ lms.patches.v0_0.set_member_in_progress #09-11-2022
|
|||||||
lms.patches.v0_0.convert_progress_to_float
|
lms.patches.v0_0.convert_progress_to_float
|
||||||
lms.patches.v0_0.add_pages_to_nav #11-11-2022
|
lms.patches.v0_0.add_pages_to_nav #11-11-2022
|
||||||
lms.patches.v0_0.change_role_names
|
lms.patches.v0_0.change_role_names
|
||||||
|
lms.patches.v0_0.quiz_submission_result
|
||||||
|
|||||||
11
lms/patches/v0_0/quiz_submission_result.py
Normal file
11
lms/patches/v0_0/quiz_submission_result.py
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import frappe
|
||||||
|
|
||||||
|
|
||||||
|
def execute():
|
||||||
|
frappe.reload_doc("lms", "doctype", "lms_quiz_submission")
|
||||||
|
frappe.reload_doc("lms", "doctype", "lms_quiz_result")
|
||||||
|
results = frappe.get_all("LMS Quiz Result", fields=["name", "result"])
|
||||||
|
|
||||||
|
for result in results:
|
||||||
|
value = 1 if result.result == "Right" else 0
|
||||||
|
frappe.db.set_value("LMS Quiz Result", result.name, "is_correct", value)
|
||||||
@@ -1874,6 +1874,7 @@ select {
|
|||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
background-size: 0.75rem;
|
background-size: 0.75rem;
|
||||||
padding-right: 2.5rem;
|
padding-right: 2.5rem;
|
||||||
|
text-align: left;
|
||||||
-webkit-print-color-adjust: exact;
|
-webkit-print-color-adjust: exact;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,57 +7,72 @@
|
|||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="common-page-style">
|
<div class="common-page-style">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="common-card-style column-card">
|
<div class="common-card-style column-card medium">
|
||||||
<div class="course-home-headings"> {{ _("Assignment Grading") }} </div>
|
<div class="course-home-headings"> {{ _("Assignment Grading") }} </div>
|
||||||
<div class="medium w-50 mt-3">
|
{{ AssignmentForm(assignment) }}
|
||||||
<a class="btn btn-secondary btn-sm" href="{{ assignment.assignment }}" target="_blank">
|
</div>
|
||||||
{{ _("Open Attachment") }}
|
</div>
|
||||||
</a>
|
</div>
|
||||||
<select class="btn btn-secondary btn-sm ml-2 lms-menu" id="result" data-type="{{ assignment.status }}">
|
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
|
||||||
|
{% macro AssignmentForm(assignment) %}
|
||||||
|
{% set course_title = frappe.db.get_value("LMS Course", assignment.course, "title") %}
|
||||||
|
{% set lesson_title = frappe.db.get_value("Course Lesson", assignment.lesson, "title") %}
|
||||||
|
|
||||||
|
<form class="register-form">
|
||||||
|
|
||||||
|
<div class="form-padding">
|
||||||
|
<div class="form-row">
|
||||||
|
<div class="form-group col-md-6">
|
||||||
|
<label> {{ _("Member") }} </label>
|
||||||
|
<input type="text" class="form-control" value="{{ assignment.member_name }}" disabled readonly />
|
||||||
|
</div>
|
||||||
|
<div class="form-group col-md-6">
|
||||||
|
<label> {{ _("Course") }} </label>
|
||||||
|
<input type="text" class="form-control" value="{{ course_title }}" disabled readonly />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-row">
|
||||||
|
<div class="col-md-6">
|
||||||
|
<div class="form-group">
|
||||||
|
<label> {{ _("Lesson") }} </label>
|
||||||
|
<input type="text" class="form-control" value="{{ lesson_title }}" disabled readonly />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label> {{ _("Result") }} </label>
|
||||||
|
<div class="control-input flex align-center form-control">
|
||||||
|
<select class="input-with-feedback form-control pl-0" id="result" data-type="{{ assignment.status }}">
|
||||||
<option selected> {{ _("Not Graded") }} </option>
|
<option selected> {{ _("Not Graded") }} </option>
|
||||||
<option value="Pass"> {{ _("Pass") }} </option>
|
<option value="Pass"> {{ _("Pass") }} </option>
|
||||||
<option value="Fail"> {{ _("Fail") }} </option>
|
<option value="Fail"> {{ _("Fail") }} </option>
|
||||||
</select>
|
</select>
|
||||||
|
<div class="select-icon">
|
||||||
<div class="mt-3">
|
<svg class="icon icon-sm">
|
||||||
<span class="subheading">
|
<use class="" href="#icon-select"></use>
|
||||||
{{ _("Member") }}:
|
</svg>
|
||||||
</span>
|
|
||||||
<span>
|
|
||||||
{{ assignment.member_name }}
|
|
||||||
</span>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="mt-3">
|
|
||||||
{% set course_title = frappe.db.get_value("LMS Course", assignment.course, "title") %}
|
|
||||||
<span class="subheading">
|
|
||||||
{{ _("Course") }}:
|
|
||||||
</span>
|
|
||||||
<span>
|
|
||||||
{{ course_title }}
|
|
||||||
</span>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="mt-3">
|
|
||||||
{% set lesson_title = frappe.db.get_value("Course Lesson", assignment.lesson, "title") %}
|
|
||||||
<span class="subheading"> {{ _("Lesson") }}: </span>
|
|
||||||
<span>
|
|
||||||
{{ lesson_title }}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="subheading mt-3"> {{ _("Comments") }}: </div>
|
|
||||||
<div class="control-input-wrapper">
|
|
||||||
<div class="control-input">
|
|
||||||
<textarea type="text" class="input-with-feedback form-control" id="comments" spellcheck="false"
|
|
||||||
autocomplete="off" placeholder="Comments">{% if assignment.comments %}{{ assignment.comments }}{% endif %}
|
|
||||||
</textarea>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="btn btn-primary btn-sm mt-3" id="save-assignment" data-assignment="{{ assignment.name }}">
|
<div class="form-group col-md-6">
|
||||||
|
<label>{{ _("Comments") }}</label>
|
||||||
|
<textarea class="form-control" id="comments">{% if assignment.comments %}{{ assignment.comments }}{% endif %}</textarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="text-right form-padding">
|
||||||
|
<a class="btn btn-secondary btn-sm" href="{{ assignment.assignment }}" target="_blank">
|
||||||
|
{{ _("Open Attachment") }}
|
||||||
|
</a>
|
||||||
|
<button class="btn btn-primary btn-sm ml-2" id="save-assignment" data-assignment="{{ assignment.name }}">
|
||||||
{{ _("Save") }}
|
{{ _("Save") }}
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</form>
|
||||||
</div>
|
{% endmacro %}
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endblock %}
|
|
||||||
|
|||||||
@@ -29,11 +29,17 @@ const set_result = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const save_assignment = (e) => {
|
const save_assignment = (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
if (!["Pass", "Fail"].includes(this.result))
|
||||||
|
frappe.throw({
|
||||||
|
title: __("Not Graded"),
|
||||||
|
message: __("Please grade the assignment."),
|
||||||
|
});
|
||||||
frappe.call({
|
frappe.call({
|
||||||
method: "lms.lms.doctype.lesson_assignment.lesson_assignment.grade_assignment",
|
method: "lms.lms.doctype.lesson_assignment.lesson_assignment.grade_assignment",
|
||||||
args: {
|
args: {
|
||||||
name: $(e.currentTarget).data("assignment"),
|
name: $(e.currentTarget).data("assignment"),
|
||||||
result: self.result,
|
result: this.result,
|
||||||
comments: $("#comments").val(),
|
comments: $("#comments").val(),
|
||||||
},
|
},
|
||||||
callback: (data) => {
|
callback: (data) => {
|
||||||
@@ -41,6 +47,9 @@ const save_assignment = (e) => {
|
|||||||
message: __("Saved"),
|
message: __("Saved"),
|
||||||
indicator: "green",
|
indicator: "green",
|
||||||
});
|
});
|
||||||
|
setTimeout(() => {
|
||||||
|
window.history.go(-2);
|
||||||
|
}, 2000);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -234,6 +234,7 @@ const check_answer = (e = undefined) => {
|
|||||||
const parse_options = () => {
|
const parse_options = () => {
|
||||||
let answer = [];
|
let answer = [];
|
||||||
let is_correct = [];
|
let is_correct = [];
|
||||||
|
|
||||||
$(".active-question input").each((i, element) => {
|
$(".active-question input").each((i, element) => {
|
||||||
let correct = parseInt($(element).attr("data-correct"));
|
let correct = parseInt($(element).attr("data-correct"));
|
||||||
if ($(element).prop("checked")) {
|
if ($(element).prop("checked")) {
|
||||||
@@ -247,6 +248,7 @@ const parse_options = () => {
|
|||||||
: add_icon(element, "minus-circle");
|
: add_icon(element, "minus-circle");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return [answer, is_correct];
|
return [answer, is_correct];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ def get_context(context):
|
|||||||
["name", "title", "start_date", "end_date", "description"],
|
["name", "title", "start_date", "end_date", "description"],
|
||||||
as_dict=True,
|
as_dict=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
context.published_courses = frappe.get_all(
|
context.published_courses = frappe.get_all(
|
||||||
"LMS Course", {"published": 1}, ["name", "title"]
|
"LMS Course", {"published": 1}, ["name", "title"]
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -79,8 +79,8 @@
|
|||||||
{% set submission = frappe.db.get_value("LMS Quiz Submission", filters, ["score", "creation"], as_dict=True) %}
|
{% set submission = frappe.db.get_value("LMS Quiz Submission", filters, ["score", "creation"], as_dict=True) %}
|
||||||
{% set total_questions = frappe.db.count("LMS Quiz Question", {"parent": quiz.name}) %}
|
{% set total_questions = frappe.db.count("LMS Quiz Question", {"parent": quiz.name}) %}
|
||||||
|
|
||||||
<tr class="">
|
<tr>
|
||||||
<td class="subheading vertically-center">
|
<td class="vertically-center">
|
||||||
<svg class="icon icon-sm">
|
<svg class="icon icon-sm">
|
||||||
<use href="#icon-quiz"></use>
|
<use href="#icon-quiz"></use>
|
||||||
</svg>
|
</svg>
|
||||||
@@ -108,26 +108,28 @@
|
|||||||
{% set status = submission.status %}
|
{% set status = submission.status %}
|
||||||
{% set color = "green" if status == "Pass" else "red" if status == "Fail" else "orange" %}
|
{% set color = "green" if status == "Pass" else "red" if status == "Fail" else "orange" %}
|
||||||
|
|
||||||
<tr>
|
<tr {% if has_submitted %} class="clickable-row" data-href="/assignments/{{ has_submitted }}" {% endif %}>
|
||||||
<td class="subheading vertically-center">
|
<td class="{% if has_submitted %} subheading {% endif %} vertically-center">
|
||||||
<svg class="icon icon-md">
|
<svg class="icon icon-md">
|
||||||
<use href="#icon-file"></use>
|
<use href="#icon-file"></use>
|
||||||
</svg>
|
</svg>
|
||||||
{{ _("Assignment") }}</td>
|
{{ _("Assignment") }}
|
||||||
|
</td>
|
||||||
|
|
||||||
<td>{{ assignment.title }}</td>
|
<td>{{ assignment.title }}</td>
|
||||||
|
|
||||||
{% if has_submitted %}
|
{% if has_submitted %}
|
||||||
<td>
|
<td>
|
||||||
{% if status == "Not Graded" %}
|
|
||||||
<a class="btn btn-secondary btn-sm" href="/assignments/{{ has_submitted }}"> {{ _("Grade") }} </a>
|
|
||||||
{% else %}
|
|
||||||
<div class="indicator-pill {{ color }}">
|
<div class="indicator-pill {{ color }}">
|
||||||
{{ status }}
|
{{ status }}
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<td>{{ frappe.utils.format_date(submission.creation, "medium") }}</td>
|
<td>{{ frappe.utils.format_date(submission.creation, "medium") }}</td>
|
||||||
|
|
||||||
{% else %}
|
{% else %}
|
||||||
<td>-</td>
|
<td>-</td>
|
||||||
|
|
||||||
<td>
|
<td>
|
||||||
<div class="indicator-pill red">
|
<div class="indicator-pill red">
|
||||||
{{ _("Not Attempted") }}
|
{{ _("Not Attempted") }}
|
||||||
|
|||||||
33
lms/www/quiz_result/quiz_result.html
Normal file
33
lms/www/quiz_result/quiz_result.html
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
{% extends "templates/base.html" %}
|
||||||
|
{% block title %}
|
||||||
|
{{ _("Quiz Submission") }}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<div class="common-page-style">
|
||||||
|
<div class="container">
|
||||||
|
<div class="common-card-style column-card">
|
||||||
|
<div class="course-home-headings">
|
||||||
|
{{ _("Quiz Submission") }}
|
||||||
|
</div>
|
||||||
|
{% for question in questions %}
|
||||||
|
<div>
|
||||||
|
{{ question.question }}
|
||||||
|
</div>
|
||||||
|
{{ question.is_correct }}
|
||||||
|
{{ question.answer }}
|
||||||
|
{% for i in range(1,5) %}
|
||||||
|
{% set num = frappe.utils.cstr(i) %}
|
||||||
|
{% set option = question["option_" + num] %}
|
||||||
|
{% if question["option_" + num] %}
|
||||||
|
<div>
|
||||||
|
{{ question["option_" + num] }}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
26
lms/www/quiz_result/quiz_result.py
Normal file
26
lms/www/quiz_result/quiz_result.py
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
import frappe
|
||||||
|
|
||||||
|
|
||||||
|
def get_context(context):
|
||||||
|
context.no_cache = 1
|
||||||
|
name = frappe.form_dict["subname"]
|
||||||
|
|
||||||
|
context.submission = frappe.db.get_value(
|
||||||
|
"LMS Quiz Submission", name, ["name", "quiz"], as_dict=1
|
||||||
|
)
|
||||||
|
|
||||||
|
questions = frappe.get_all(
|
||||||
|
"LMS Quiz Result", {"parent": name}, ["question", "is_correct", "answer"]
|
||||||
|
)
|
||||||
|
|
||||||
|
for question in questions:
|
||||||
|
options = frappe.db.get_value(
|
||||||
|
"LMS Quiz Question",
|
||||||
|
{"question": question.question},
|
||||||
|
["option_1", "option_2", "option_3", "option_4"],
|
||||||
|
as_dict=1,
|
||||||
|
)
|
||||||
|
question.update(options)
|
||||||
|
question.answer = question.answer.split(",")
|
||||||
|
|
||||||
|
context.questions = questions
|
||||||
Reference in New Issue
Block a user