From fa774b0db23a38319cc3a19a3386c18d6ac16820 Mon Sep 17 00:00:00 2001 From: Jannat Patel Date: Fri, 19 Jul 2024 20:05:28 +0530 Subject: [PATCH 01/13] feat: quiz creation --- frontend/src/pages/QuizCreation.vue | 62 +++++++++++++ frontend/src/pages/Quizzes.vue | 117 +++++++++++++++++++++++++ frontend/src/router.js | 11 +++ frontend/src/translation.js | 1 + lms/lms/doctype/lms_quiz/lms_quiz.json | 6 +- 5 files changed, 196 insertions(+), 1 deletion(-) create mode 100644 frontend/src/pages/QuizCreation.vue create mode 100644 frontend/src/pages/Quizzes.vue diff --git a/frontend/src/pages/QuizCreation.vue b/frontend/src/pages/QuizCreation.vue new file mode 100644 index 00000000..99c7447e --- /dev/null +++ b/frontend/src/pages/QuizCreation.vue @@ -0,0 +1,62 @@ + + diff --git a/frontend/src/pages/Quizzes.vue b/frontend/src/pages/Quizzes.vue new file mode 100644 index 00000000..113fde84 --- /dev/null +++ b/frontend/src/pages/Quizzes.vue @@ -0,0 +1,117 @@ + + diff --git a/frontend/src/router.js b/frontend/src/router.js index 3b53ce19..d93d207a 100644 --- a/frontend/src/router.js +++ b/frontend/src/router.js @@ -141,6 +141,17 @@ const routes = [ component: () => import('@/pages/Badge.vue'), props: true, }, + { + path: '/quizzes', + name: 'Quizzes', + component: () => import('@/pages/Quizzes.vue'), + }, + { + path: '/quizzes/:quizID', + name: 'QuizCreation', + component: () => import('@/pages/QuizCreation.vue'), + props: true, + }, ] let router = createRouter({ diff --git a/frontend/src/translation.js b/frontend/src/translation.js index 0f9911dc..f6b9050b 100644 --- a/frontend/src/translation.js +++ b/frontend/src/translation.js @@ -2,6 +2,7 @@ import { createResource } from 'frappe-ui' export default function translationPlugin(app) { app.config.globalProperties.__ = translate + window.__ = translate if (!window.translatedMessages) fetchTranslations() } diff --git a/lms/lms/doctype/lms_quiz/lms_quiz.json b/lms/lms/doctype/lms_quiz/lms_quiz.json index 9c1b8e95..38d23b9a 100644 --- a/lms/lms/doctype/lms_quiz/lms_quiz.json +++ b/lms/lms/doctype/lms_quiz/lms_quiz.json @@ -74,6 +74,7 @@ "default": "1", "fieldname": "show_answers", "fieldtype": "Check", + "in_standard_filter": 1, "label": "Show Answers" }, { @@ -98,6 +99,8 @@ { "fieldname": "passing_percentage", "fieldtype": "Int", + "in_list_view": 1, + "in_standard_filter": 1, "label": "Passing Percentage", "non_negative": 1, "reqd": 1 @@ -110,6 +113,7 @@ "default": "0", "fieldname": "total_marks", "fieldtype": "Int", + "in_list_view": 1, "label": "Total Marks", "non_negative": 1, "read_only": 1, @@ -133,7 +137,7 @@ ], "index_web_pages_for_search": 1, "links": [], - "modified": "2024-06-27 22:03:48.576489", + "modified": "2024-07-19 18:21:26.681501", "modified_by": "Administrator", "module": "LMS", "name": "LMS Quiz", From a450c846a6996e1d340cb32885b7a8c45a72b345 Mon Sep 17 00:00:00 2001 From: Jannat Patel Date: Mon, 29 Jul 2024 19:44:04 +0530 Subject: [PATCH 02/13] feat: questions table --- .gitmodules | 3 + frappe-ui | 2 +- frontend/src/components/Modals/Question.vue | 30 ++++ frontend/src/pages/QuizCreation.vue | 132 +++++++++++++++--- frontend/src/pages/Quizzes.vue | 25 ++-- frontend/yarn.lock | 29 ++-- .../lms_quiz_question/lms_quiz_question.json | 23 ++- .../certificate_request_creation.html | 2 +- package.json | 2 +- 9 files changed, 199 insertions(+), 49 deletions(-) create mode 100644 .gitmodules create mode 100644 frontend/src/components/Modals/Question.vue diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000..e82154a1 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "frappe-ui"] + path = frappe-ui + url = https://github.com/pateljannat/frappe-ui diff --git a/frappe-ui b/frappe-ui index aa44431c..a349ab07 160000 --- a/frappe-ui +++ b/frappe-ui @@ -1 +1 @@ -Subproject commit aa44431c185b1e4563f2ebf6af380c7743d2cd4c +Subproject commit a349ab070a73a3d22ead6a33374c9fe44f6ecf57 diff --git a/frontend/src/components/Modals/Question.vue b/frontend/src/components/Modals/Question.vue new file mode 100644 index 00000000..bdecfc4c --- /dev/null +++ b/frontend/src/components/Modals/Question.vue @@ -0,0 +1,30 @@ + + \ No newline at end of file diff --git a/frontend/src/pages/QuizCreation.vue b/frontend/src/pages/QuizCreation.vue index 99c7447e..dd2b13a5 100644 --- a/frontend/src/pages/QuizCreation.vue +++ b/frontend/src/pages/QuizCreation.vue @@ -4,31 +4,97 @@ > -
- - - - - +
+ +
+
+ {{ __("Details") }} +
+
+
+ + + +
+
+ + +
+
+
+ + +
+
+ {{ __("Settings") }} +
+
+ + + +
+
+ + +
+
+
+ {{ __("Questions") }} +
+ +
+ + + + + + + +
+ {{ item }} +
+
+
+
+
+
+ \ No newline at end of file + diff --git a/frontend/src/pages/QuizCreation.vue b/frontend/src/pages/QuizCreation.vue index dd2b13a5..6a92150f 100644 --- a/frontend/src/pages/QuizCreation.vue +++ b/frontend/src/pages/QuizCreation.vue @@ -8,12 +8,15 @@
- {{ __("Details") }} + {{ __('Details') }}
- +
- +
- {{ __("Settings") }} + {{ __('Settings') }}
- - - + + +
@@ -45,28 +60,35 @@
- {{ __("Questions") }} + {{ __('Questions') }}
-
- + - +
{{ item }} @@ -77,15 +99,27 @@
- + + diff --git a/frontend/src/pages/QuizCreation.vue b/frontend/src/pages/QuizCreation.vue index b53b835e..90f6fdcb 100644 --- a/frontend/src/pages/QuizCreation.vue +++ b/frontend/src/pages/QuizCreation.vue @@ -3,6 +3,9 @@ class="sticky top-0 z-10 flex items-center justify-between border-b bg-white px-3 py-2.5 sm:px-5" > +
@@ -10,107 +13,128 @@
{{ __('Details') }}
-
-
- - - + +
+
+
+ + +
+
+ + +
-
- - -
-
-
- -
-
- {{ __('Settings') }} -
-
- - - -
-
- - -
-
-
- {{ __('Questions') }} + +
+
+ {{ __('Settings') }} +
+
+ + + +
- -
- - - - - - +
+
+
+ {{ __('Questions') }} +
+ +
+ - -
+ + + + - {{ item }} -
-
- {{ item }} -
-
- - -
+ +
+ {{ item }} +
+
+ {{ item }} +
+
+ + + +
+
- + diff --git a/frontend/src/pages/Quizzes.vue b/frontend/src/pages/Quizzes.vue index e7e75b30..3a678e91 100644 --- a/frontend/src/pages/Quizzes.vue +++ b/frontend/src/pages/Quizzes.vue @@ -3,12 +3,21 @@ class="sticky top-0 z-10 flex items-center justify-between border-b bg-white px-3 py-2.5 sm:px-5" > - + + +
{ + if (!user.data?.is_moderator && !user.data?.is_instructor) { + router.push({ name: 'Courses' }) + } +}) const quizFilter = computed(() => { if (user.data?.is_moderator) return {} @@ -68,6 +85,7 @@ const quizzes = createListResource({ fields: ['name', 'title', 'passing_percentage', 'total_marks'], auto: true, cache: ['quizzes', user.data?.name], + orderBy: 'modified desc', onSuccess(data) { data.forEach((row) => {}) }, diff --git a/lms/lms/doctype/lms_quiz/lms_quiz.py b/lms/lms/doctype/lms_quiz/lms_quiz.py index ef7f6243..33abac89 100644 --- a/lms/lms/doctype/lms_quiz/lms_quiz.py +++ b/lms/lms/doctype/lms_quiz/lms_quiz.py @@ -5,7 +5,7 @@ import json import frappe from frappe import _ from frappe.model.document import Document -from frappe.utils import cstr, comma_and +from frappe.utils import cstr, comma_and, cint from fuzzywuzzy import fuzz from lms.lms.doctype.course_lesson.course_lesson import save_progress from lms.lms.utils import ( @@ -30,12 +30,12 @@ class LMSQuiz(Document): ) def validate_limit(self): - if self.limit_questions_to and self.limit_questions_to >= len(self.questions): + if self.limit_questions_to and cint(self.limit_questions_to) >= len(self.questions): frappe.throw( _("Limit cannot be greater than or equal to the number of questions in the quiz.") ) - if self.limit_questions_to and self.limit_questions_to < len(self.questions): + if self.limit_questions_to and cint(self.limit_questions_to) < len(self.questions): marks = [question.marks for question in self.questions] if len(set(marks)) > 1: frappe.throw(_("All questions should have the same marks if the limit is set.")) @@ -43,10 +43,10 @@ class LMSQuiz(Document): def calculate_total_marks(self): if self.limit_questions_to: self.total_marks = sum( - question.marks for question in self.questions[: self.limit_questions_to] + question.marks for question in self.questions[: cint(self.limit_questions_to)] ) else: - self.total_marks = sum(question.marks for question in self.questions) + self.total_marks = sum(cint(question.marks) for question in self.questions) def autoname(self): if not self.name: From afe7df2989f50b439ea69b9d1bf498ce0a9f6b77 Mon Sep 17 00:00:00 2001 From: Jannat Patel Date: Mon, 5 Aug 2024 16:29:43 +0530 Subject: [PATCH 06/13] fix: fetch question --- frontend/src/components/Modals/Question.vue | 49 +++++++-------------- frontend/src/pages/QuizCreation.vue | 30 +++++++++++-- 2 files changed, 42 insertions(+), 37 deletions(-) diff --git a/frontend/src/components/Modals/Question.vue b/frontend/src/components/Modals/Question.vue index 74e14f13..2a7966c1 100644 --- a/frontend/src/components/Modals/Question.vue +++ b/frontend/src/components/Modals/Question.vue @@ -113,23 +113,12 @@ const existingQuestion = reactive({ question: '', marks: 0, }) - const question = reactive({ question: '', type: 'Choices', marks: 0, }) -const props = defineProps({ - title: { - type: String, - default: __('Add a new question'), - }, - questionName: { - type: String, - }, -}) - const populateFields = () => { let fields = ['option', 'is_correct', 'explanation', 'possibility'] let counter = 1 @@ -141,17 +130,22 @@ const populateFields = () => { }) } -const questionData = createResource({ - url: 'frappe.client.get', - makeParams(values) { - return { - doctype: 'LMS Question', - name: props.questionName, - } +populateFields() + +const props = defineProps({ + title: { + type: String, + default: __('Add a new question'), }, - auto: false, - cache: ['question', props.questionName], - onSuccess(data) { + questionData: { + type: [Object, null], + required: true, + }, +}) + +watch(show, () => { + let data = props.questionData + if (show.value && data) { let counter = 1 Object.keys(data).forEach((key) => { if (Object.hasOwn(question, key)) question[key] = data[key] @@ -161,7 +155,7 @@ const questionData = createResource({ ? true : false } - }, + } }) const questionRow = createResource({ @@ -247,17 +241,6 @@ const addQuestionRow = (question, close) => { ) } -watch( - () => props.questionName, - async (name) => { - console.log('name', name) - populateFields() - if (name != 'new') { - questionData.reload() - } - } -) - const dialogOptions = computed(() => { return { title: __(props.title), diff --git a/frontend/src/pages/QuizCreation.vue b/frontend/src/pages/QuizCreation.vue index 90f6fdcb..3c96bb5a 100644 --- a/frontend/src/pages/QuizCreation.vue +++ b/frontend/src/pages/QuizCreation.vue @@ -123,7 +123,7 @@