Merge pull request #1509 from pateljannat/issues-108

fix: misc issues
This commit is contained in:
Jannat Patel
2025-05-16 11:55:31 +05:30
committed by GitHub
5 changed files with 108 additions and 82 deletions

View File

@@ -16,9 +16,9 @@ cd frappe-bench
# Use containers instead of localhost # Use containers instead of localhost
bench set-mariadb-host mariadb bench set-mariadb-host mariadb
bench set-redis-cache-host redis:6379 bench set-redis-cache-host redis://redis:6379
bench set-redis-queue-host redis:6379 bench set-redis-queue-host redis://redis:6379
bench set-redis-socketio-host redis:6379 bench set-redis-socketio-host redis://redis:6379
# Remove redis, watch from Procfile # Remove redis, watch from Procfile
sed -i '/redis/d' ./Procfile sed -i '/redis/d' ./Procfile

View File

@@ -148,7 +148,7 @@ function submitEvaluation(close) {
unavailabilityMessage = false unavailabilityMessage = false
} }
toast.warn(__('Evaluator is unavailable')) toast.warning(__('Evaluator is unavailable'))
}, },
}) })
} }

View File

@@ -494,7 +494,7 @@ const getAnswers = () => {
const checkAnswer = () => { const checkAnswer = () => {
let answers = getAnswers() let answers = getAnswers()
if (!answers.length) { if (!answers.length) {
toast.warn(__('Please select an option')) toast.warning(__('Please select an option'))
return return
} }

View File

@@ -2,10 +2,10 @@
<header <header
class="sticky top-0 z-10 flex items-center justify-between border-b bg-surface-white px-3 py-2.5 sm:px-5" class="sticky top-0 z-10 flex items-center justify-between border-b bg-surface-white px-3 py-2.5 sm:px-5"
> >
<Breadcrumbs v-if="submisisonDetails.doc" :items="breadcrumbs" /> <Breadcrumbs v-if="submissionDetails.doc" :items="breadcrumbs" />
<div class="space-x-2"> <div class="space-x-2">
<Badge <Badge
v-if="submisisonDetails.isDirty" v-if="submissionDetails.isDirty"
:label="__('Not Saved')" :label="__('Not Saved')"
variant="subtle" variant="subtle"
theme="orange" theme="orange"
@@ -15,19 +15,19 @@
</Button> </Button>
</div> </div>
</header> </header>
<div v-if="submisisonDetails.doc" class="w-1/2 mx-auto py-5 space-y-5"> <div v-if="submissionDetails.doc" class="w-2/3 border-x mx-auto py-5">
<div class="text-xl font-semibold text-ink-gray-9"> <div class="text-xl px-10 font-semibold text-ink-gray-9 mb-5">
{{ submisisonDetails.doc.member_name }} {{ submissionDetails.doc.member_name }}
</div> </div>
<div class="space-y-4 border p-5 rounded-md"> <div class="space-y-4 border-b pb-5 px-10">
<div class="grid grid-cols-2 gap-5"> <div class="grid grid-cols-2 gap-5">
<FormControl <FormControl
v-model="submisisonDetails.doc.quiz_title" v-model="submissionDetails.doc.quiz_title"
:label="__('Quiz')" :label="__('Quiz')"
:disabled="true" :disabled="true"
/> />
<FormControl <FormControl
v-model="submisisonDetails.doc.member_name" v-model="submissionDetails.doc.member_name"
:label="__('Member')" :label="__('Member')"
:disabled="true" :disabled="true"
/> />
@@ -35,39 +35,39 @@
<div class="grid grid-cols-2 gap-5"> <div class="grid grid-cols-2 gap-5">
<FormControl <FormControl
v-model="submisisonDetails.doc.score" v-model="submissionDetails.doc.score"
:label="__('Score')" :label="__('Score')"
:disabled="true" :disabled="true"
/> />
<FormControl <FormControl
v-model="submisisonDetails.doc.percentage" v-model="submissionDetails.doc.percentage"
:label="__('Percentage')" :label="__('Percentage')"
:disabled="true" :disabled="true"
/> />
</div> </div>
</div> </div>
<div <div class="divide-y">
v-for="(row, index) in submisisonDetails.doc.result" <div
class="border p-5 rounded-md space-y-4" v-for="(row, index) in submissionDetails.doc.result"
> class="py-5 px-10 space-y-4"
<div class="flex items-start space-x-1 font-semibold text-ink-gray-9"> >
<!-- <span> <div class="text-ink-gray-9">
{{ index + 1 }}. <span class="font-semibold"> {{ __('Question') }}: </span>
</span> --> <span class="leading-5" v-html="row.question"> </span>
<span class="leading-5" v-html="row.question"> </span> </div>
</div> <div class="">
<div class="leading-5 text-ink-gray-7 space-x-1"> <span class="font-semibold"> {{ __('Answer') }} </span>
<span> {{ __('Answer') }}: </span> <span class="leading-5" v-html="row.answer"></span>
<span v-html="row.answer"></span> </div>
</div> <div class="grid grid-cols-2 gap-5">
<div class="grid grid-cols-2 gap-5"> <FormControl v-model="row.marks" :label="__('Marks')" />
<FormControl v-model="row.marks" :label="__('Marks')" /> <FormControl
<FormControl v-model="row.marks_out_of"
v-model="row.marks_out_of" :label="__('Marks out of')"
:label="__('Marks out of')" :disabled="true"
:disabled="true" />
/> </div>
</div> </div>
</div> </div>
</div> </div>
@@ -119,7 +119,7 @@ const props = defineProps({
}, },
}) })
const submisisonDetails = createDocumentResource({ const submissionDetails = createDocumentResource({
doctype: 'LMS Quiz Submission', doctype: 'LMS Quiz Submission',
name: props.submission, name: props.submission,
auto: true, auto: true,
@@ -132,18 +132,18 @@ const breadcrumbs = computed(() => {
route: { route: {
name: 'QuizSubmissionList', name: 'QuizSubmissionList',
params: { params: {
quizID: submisisonDetails.doc.quiz, quizID: submissionDetails.doc.quiz,
}, },
}, },
}, },
{ {
label: submisisonDetails.doc.quiz_title, label: submissionDetails.doc.quiz_title,
}, },
] ]
}) })
const saveSubmission = () => { const saveSubmission = () => {
submisisonDetails.save.submit( submissionDetails.save.submit(
{}, {},
{ {
onError(err) { onError(err) {
@@ -155,7 +155,7 @@ const saveSubmission = () => {
usePageMeta(() => { usePageMeta(() => {
return { return {
title: `${submisisonDetails.doc.quiz_title}`, title: `${submissionDetails.doc?.quiz_title}`,
icon: brand.favicon, icon: brand.favicon,
} }
}) })

View File

@@ -96,9 +96,7 @@ def set_total_marks(questions):
@frappe.whitelist() @frappe.whitelist()
def quiz_summary(quiz, results): def quiz_summary(quiz, results):
score = 0
results = results and json.loads(results) results = results and json.loads(results)
is_open_ended = False
percentage = 0 percentage = 0
quiz_details = frappe.db.get_value( quiz_details = frappe.db.get_value(
@@ -108,7 +106,32 @@ def quiz_summary(quiz, results):
as_dict=1, as_dict=1,
) )
data = process_results(results, quiz)
results = data["results"]
score = data["score"]
is_open_ended = data["is_open_ended"]
score_out_of = quiz_details.total_marks score_out_of = quiz_details.total_marks
percentage = (score / score_out_of) * 100 if score_out_of else 0
submission = create_submission(
quiz, results, score_out_of, quiz_details.passing_percentage
)
save_progress_after_quiz(quiz_details, percentage)
return {
"score": score,
"score_out_of": score_out_of,
"submission": submission.name,
"pass": percentage == quiz_details.passing_percentage,
"percentage": percentage,
"is_open_ended": is_open_ended,
}
def process_results(results, quiz):
score = 0
is_open_ended = False
for result in results: for result in results:
question_details = frappe.db.get_value( question_details = frappe.db.get_value(
@@ -123,55 +146,28 @@ def quiz_summary(quiz, results):
result["marks_out_of"] = question_details.marks result["marks_out_of"] = question_details.marks
if question_details.type != "Open Ended": if question_details.type != "Open Ended":
correct = result["is_correct"][0] if len(result["is_correct"]) > 0:
for point in result["is_correct"]: correct = result["is_correct"][0]
correct = correct and point for point in result["is_correct"]:
result["is_correct"] = correct correct = correct and point
result["is_correct"] = correct
else:
result["is_correct"] = 0
marks = question_details.marks if correct else 0 marks = question_details.marks if correct else 0
result["marks"] = marks result["marks"] = marks
score += marks score += marks
else: else:
result["is_correct"] = 0
is_open_ended = True is_open_ended = True
result["is_correct"] = 0
percentage = (score / score_out_of) * 100 result["answer"] = re.sub(
result["answer"] = re.sub( r'<img[^>]*src\s*=\s*["\'](?=data:)(.*?)["\']', _save_file, result["answer"]
r'<img[^>]*src\s*=\s*["\'](?=data:)(.*?)["\']', _save_file, result["answer"] )
)
submission = frappe.new_doc("LMS Quiz Submission")
# Score and percentage are calculated by the controller function
submission.update(
{
"doctype": "LMS Quiz Submission",
"quiz": quiz,
"result": results,
"score": 0,
"score_out_of": score_out_of,
"member": frappe.session.user,
"percentage": 0,
"passing_percentage": quiz_details.passing_percentage,
}
)
submission.save(ignore_permissions=True)
if (
percentage >= quiz_details.passing_percentage
and quiz_details.lesson
and quiz_details.course
):
save_progress(quiz_details.lesson, quiz_details.course)
elif not quiz_details.passing_percentage:
save_progress(quiz_details.lesson, quiz_details.course)
return { return {
"results": results,
"score": score, "score": score,
"score_out_of": score_out_of,
"submission": submission.name,
"pass": percentage == quiz_details.passing_percentage,
"percentage": percentage,
"is_open_ended": is_open_ended, "is_open_ended": is_open_ended,
} }
@@ -219,6 +215,36 @@ def get_corrupted_image_msg():
return _("Image: Corrupted Data Stream") return _("Image: Corrupted Data Stream")
def create_submission(quiz, results, score_out_of, passing_percentage):
submission = frappe.new_doc("LMS Quiz Submission")
# Score and percentage are calculated by the controller function
submission.update(
{
"doctype": "LMS Quiz Submission",
"quiz": quiz,
"result": results,
"score": 0,
"score_out_of": score_out_of,
"member": frappe.session.user,
"percentage": 0,
"passing_percentage": passing_percentage,
}
)
submission.save(ignore_permissions=True)
return submission
def save_progress_after_quiz(quiz_details, percentage):
if (
percentage >= quiz_details.passing_percentage
and quiz_details.lesson
and quiz_details.course
):
save_progress(quiz_details.lesson, quiz_details.course)
elif not quiz_details.passing_percentage:
save_progress(quiz_details.lesson, quiz_details.course)
@frappe.whitelist() @frappe.whitelist()
def get_question_details(question): def get_question_details(question):
if frappe.db.exists("LMS Quiz Question", question): if frappe.db.exists("LMS Quiz Question", question):