+
import { FormControl, Button } from 'frappe-ui'
-import { computed, ref } from 'vue'
+import { computed } from 'vue'
import Link from '@/components/Controls/Link.vue'
-let width = ref('w-full')
-
const props = defineProps({
fields: {
type: Array,
@@ -45,6 +51,13 @@ const props = defineProps({
type: Object,
required: true,
},
+ label: {
+ type: String,
+ required: true,
+ },
+ description: {
+ type: String,
+ },
})
const columns = computed(() => {
@@ -71,12 +84,6 @@ const columns = computed(() => {
cols.push(currentColumn)
}
- if (cols.length == 3) {
- width.value = 'w-64'
- } else {
- width.value = 'w-96'
- }
-
return cols
})
diff --git a/lms/__init__.py b/lms/__init__.py
index 9aa3f903..8a124bf6 100644
--- a/lms/__init__.py
+++ b/lms/__init__.py
@@ -1 +1 @@
-__version__ = "2.1.0"
+__version__ = "2.2.0"
diff --git a/lms/lms/api.py b/lms/lms/api.py
index d04ec783..df2272cd 100644
--- a/lms/lms/api.py
+++ b/lms/lms/api.py
@@ -562,3 +562,38 @@ def get_categories(doctype, filters):
categoryOptions.append({"label": category, "value": category})
return categoryOptions
+
+
+@frappe.whitelist()
+def get_members(start=0, search=""):
+ """Get members for the given search term and start index.
+ Args: start (int): Start index for the query.
+ search (str): Search term to filter the results.
+ Returns: List of members.
+ """
+
+ filters = {"enabled": 1, "name": ["not in", ["Administrator", "Guest"]]}
+
+ if search:
+ filters["full_name"] = ["like", f"%{search}%"]
+
+ members = frappe.get_all(
+ "User",
+ filters=filters,
+ fields=["name", "full_name", "user_image", "username"],
+ page_length=20,
+ start=start,
+ )
+
+ for member in members:
+ roles = frappe.get_roles(member.name)
+ if "Moderator" in roles:
+ member.role = "Moderator"
+ elif "Course Creator" in roles:
+ member.role = "Course Creator"
+ elif "Batch Evaluator" in roles:
+ member.role = "Batch Evaluator"
+ elif "LMS Student" in roles:
+ member.role = "LMS Student"
+
+ return members
diff --git a/lms/lms/doctype/invite_request/test_invite_request.py b/lms/lms/doctype/invite_request/test_invite_request.py
index b9cac5d3..0cc82050 100644
--- a/lms/lms/doctype/invite_request/test_invite_request.py
+++ b/lms/lms/doctype/invite_request/test_invite_request.py
@@ -11,74 +11,4 @@ from lms.lms.doctype.invite_request.invite_request import (
class TestInviteRequest(unittest.TestCase):
- @classmethod
- def setUpClass(self):
- create_invite_request("test_invite@example.com")
-
- def test_create_invite_request(self):
- if frappe.db.exists("Invite Request", {"invite_email": "test_invite@example.com"}):
- invite = frappe.db.get_value(
- "Invite Request",
- filters={"invite_email": "test_invite@example.com"},
- fieldname=["invite_email", "status", "signup_email"],
- as_dict=True,
- )
- self.assertEqual(invite.status, "Approved")
- self.assertEqual(invite.signup_email, None)
-
- def test_create_invite_request_update(self):
- if frappe.db.exists("Invite Request", {"invite_email": "test_invite@example.com"}):
-
- data = {
- "signup_email": "test_invite@example.com",
- "username": "test_invite",
- "full_name": "Test Invite",
- "password": "Test@invite",
- "invite_code": frappe.db.get_value(
- "Invite Request", {"invite_email": "test_invite@example.com"}, "name"
- ),
- }
-
- update_invite(data)
- invite = frappe.db.get_value(
- "Invite Request",
- filters={"invite_email": "test_invite@example.com"},
- fieldname=[
- "invite_email",
- "status",
- "signup_email",
- "full_name",
- "username",
- "invite_code",
- "name",
- ],
- as_dict=True,
- )
- self.assertEqual(invite.signup_email, "test_invite@example.com")
- self.assertEqual(invite.full_name, "Test Invite")
- self.assertEqual(invite.username, "test_invite")
- self.assertEqual(invite.invite_code, invite.name)
- self.assertEqual(invite.status, "Registered")
-
- user = frappe.db.get_value(
- "User",
- "test_invite@example.com",
- fieldname=["first_name", "username", "send_welcome_email", "user_type"],
- as_dict=True,
- )
- self.assertTrue(user)
- self.assertEqual(user.first_name, invite.full_name.split(" ")[0])
- self.assertEqual(user.username, invite.username)
- self.assertEqual(user.send_welcome_email, 0)
- self.assertEqual(user.user_type, "Website User")
-
- @classmethod
- def tearDownClass(self):
- if frappe.db.exists("User", "test_invite@example.com"):
- frappe.delete_doc("User", "test_invite@example.com")
-
- invite_request = frappe.db.exists(
- "Invite Request", {"invite_email": "test_invite@example.com"}
- )
- if invite_request:
- frappe.delete_doc("Invite Request", invite_request)
+ pass
diff --git a/lms/locale/main.pot b/lms/locale/main.pot
index fae436ae..960fed00 100644
--- a/lms/locale/main.pot
+++ b/lms/locale/main.pot
@@ -7,8 +7,8 @@ msgid ""
msgstr ""
"Project-Id-Version: Frappe LMS VERSION\n"
"Report-Msgid-Bugs-To: school@frappe.io\n"
-"POT-Creation-Date: 2024-08-09 16:04+0000\n"
-"PO-Revision-Date: 2024-08-09 16:04+0000\n"
+"POT-Creation-Date: 2024-08-16 16:04+0000\n"
+"PO-Revision-Date: 2024-08-16 16:04+0000\n"
"Last-Translator: school@frappe.io\n"
"Language-Team: school@frappe.io\n"
"MIME-Version: 1.0\n"
@@ -48,7 +48,7 @@ msgstr ""
msgid "Add a Lesson"
msgstr ""
-#: lms/doctype/lms_question/lms_question.py:59
+#: lms/doctype/lms_question/lms_question.py:60
msgid "Add at least one possible answer for this question: {0}"
msgstr ""
@@ -98,11 +98,6 @@ msgstr ""
msgid "Allow accessing future dates"
msgstr ""
-#. Label of the allow_student_progress (Check) field in DocType 'LMS Settings'
-#: lms/doctype/lms_settings/lms_settings.json
-msgid "Allow students to see each others progress in class"
-msgstr ""
-
#: overrides/user.py:195
msgid "Already Registered"
msgstr ""
@@ -136,12 +131,6 @@ msgstr ""
msgid "Answer"
msgstr ""
-#. Option for the 'Course Creation Access Through Website To' (Select) field in
-#. DocType 'LMS Settings'
-#: lms/doctype/lms_settings/lms_settings.json
-msgid "Anyone"
-msgstr ""
-
#. Label of the apply_gst (Check) field in DocType 'LMS Settings'
#: lms/doctype/lms_settings/lms_settings.json
msgid "Apply GST for India"
@@ -233,7 +222,7 @@ msgstr ""
msgid "Assignment will appear at the bottom of the lesson."
msgstr ""
-#: lms/doctype/lms_question/lms_question.py:41
+#: lms/doctype/lms_question/lms_question.py:42
msgid "At least one option must be correct for this question."
msgstr ""
@@ -850,11 +839,6 @@ msgstr ""
msgid "Course Content"
msgstr ""
-#. Label of the portal_course_creation (Select) field in DocType 'LMS Settings'
-#: lms/doctype/lms_settings/lms_settings.json
-msgid "Course Creation Access Through Website To"
-msgstr ""
-
#. Name of a role
#: lms/doctype/lms_course/lms_course.json
#: lms/doctype/lms_question/lms_question.json
@@ -862,12 +846,6 @@ msgstr ""
msgid "Course Creator"
msgstr ""
-#. Option for the 'Course Creation Access Through Website To' (Select) field in
-#. DocType 'LMS Settings'
-#: lms/doctype/lms_settings/lms_settings.json
-msgid "Course Creator Role"
-msgstr ""
-
#. Label of a Card Break in the LMS Workspace
#: lms/workspace/lms/lms.json
msgid "Course Data"
@@ -892,11 +870,6 @@ msgstr ""
msgid "Course List"
msgstr ""
-#. Label of the search_placeholder (Data) field in DocType 'LMS Settings'
-#: lms/doctype/lms_settings/lms_settings.json
-msgid "Course List Search Bar Placeholder"
-msgstr ""
-
#: lms/report/course_progress_summary/course_progress_summary.py:58
msgid "Course Name"
msgstr ""
@@ -912,10 +885,7 @@ msgid "Course Progress Summary"
msgstr ""
#. Label of the section_break_7 (Section Break) field in DocType 'LMS Course'
-#. Label of the course_settings_section (Section Break) field in DocType 'LMS
-#. Settings'
#: lms/doctype/lms_course/lms_course.json
-#: lms/doctype/lms_settings/lms_settings.json
msgid "Course Settings"
msgstr ""
@@ -1116,7 +1086,7 @@ msgstr ""
msgid "Dream Companies"
msgstr ""
-#: lms/doctype/lms_question/lms_question.py:31
+#: lms/doctype/lms_question/lms_question.py:32
msgid "Duplicate options found for this question."
msgstr ""
@@ -1254,7 +1224,7 @@ msgstr ""
msgid "Enter the correct answer"
msgstr ""
-#: lms/utils.py:1088
+#: lms/utils.py:1081
msgid "Error during payment: {0} Please contact the Administrator. Amount {1} Currency {2} Formatted {3}"
msgstr ""
@@ -1539,6 +1509,7 @@ msgid "Here are a few courses we recommend for you to get started with {0}"
msgstr ""
#: lms/notification/certificate_request_creation/certificate_request_creation.html:6
+#: templates/emails/certificate_request_notification.html:1
msgid "Hey {0}"
msgstr ""
@@ -1738,7 +1709,7 @@ msgstr ""
msgid "Invalid Start or End Time."
msgstr ""
-#: lms/utils.py:932
+#: lms/utils.py:925
msgid "Invalid document provided."
msgstr ""
@@ -2328,7 +2299,6 @@ msgstr ""
#. Label of the mentor_request_section (Section Break) field in DocType 'LMS
#. Settings'
-#. Label of the mentor_request_tab (Tab Break) field in DocType 'LMS Settings'
#: lms/doctype/lms_settings/lms_settings.json
msgid "Mentor Request"
msgstr ""
@@ -2385,11 +2355,11 @@ msgstr ""
msgid "Modified By"
msgstr ""
-#: lms/api.py:188
+#: lms/api.py:189
msgid "Module Name is incorrect or does not exist."
msgstr ""
-#: lms/api.py:184
+#: lms/api.py:185
msgid "Module is incorrect."
msgstr ""
@@ -2430,11 +2400,11 @@ msgstr ""
msgid "New Sign Up"
msgstr ""
-#: lms/utils.py:619
+#: lms/utils.py:612
msgid "New comment in batch {0}"
msgstr ""
-#: lms/utils.py:612
+#: lms/utils.py:605
msgid "New reply on the topic {0} in course {1}"
msgstr ""
@@ -2471,11 +2441,6 @@ msgstr ""
msgid "No courses under review"
msgstr ""
-#: templates/search_course/search_course.html:61
-#: templates/search_course/search_course.js:47
-msgid "No result found"
-msgstr ""
-
#: templates/course_list.html:13
msgid "No {0}"
msgstr ""
@@ -2719,7 +2684,7 @@ msgstr ""
msgid "Payment for Document Type"
msgstr ""
-#: lms/utils.py:949
+#: lms/utils.py:942
msgid "Payment for {0} course"
msgstr ""
@@ -2778,12 +2743,13 @@ msgstr ""
msgid "Please enter your answer"
msgstr ""
-#: lms/api.py:180
+#: lms/api.py:181
msgid "Please login to continue with payment."
msgstr ""
#: lms/notification/certificate_request_creation/certificate_request_creation.html:9
#: lms/notification/certificate_request_reminder/certificate_request_reminder.html:8
+#: templates/emails/certificate_request_notification.html:4
msgid "Please prepare well and be on time for the evaluations."
msgstr ""
@@ -2952,6 +2918,11 @@ msgstr ""
msgid "Question "
msgstr ""
+#. Label of the question_detail (Text) field in DocType 'LMS Quiz Question'
+#: lms/doctype/lms_quiz_question/lms_quiz_question.json
+msgid "Question Detail"
+msgstr ""
+
#. Label of the question_name (Link) field in DocType 'LMS Quiz Result'
#: lms/doctype/lms_quiz_result/lms_quiz_result.json
msgid "Question Name"
@@ -3214,11 +3185,6 @@ msgstr ""
msgid "Set your Password"
msgstr ""
-#. Label of the section_break_hsiv (Section Break) field in DocType 'LMS Quiz'
-#: lms/doctype/lms_quiz/lms_quiz.json
-msgid "Settings"
-msgstr ""
-
#. Label of the short_introduction (Small Text) field in DocType 'LMS Course'
#: lms/doctype/lms_course/lms_course.json
msgid "Short Introduction"
@@ -3670,7 +3636,7 @@ msgstr ""
msgid "The course {0} is now available on {1}."
msgstr ""
-#: lms/doctype/lms_certificate_request/lms_certificate_request.py:44
+#: lms/doctype/lms_certificate_request/lms_certificate_request.py:47
msgid "The evaluator of this course is unavailable from {0} to {1}. Please select a date after {1}"
msgstr ""
@@ -3678,7 +3644,7 @@ msgstr ""
msgid "The quiz has a time limit. For each question you will be given {0} seconds."
msgstr ""
-#: lms/doctype/lms_certificate_request/lms_certificate_request.py:62
+#: lms/doctype/lms_certificate_request/lms_certificate_request.py:65
msgid "The slot is already booked by another participant."
msgstr ""
@@ -3694,7 +3660,7 @@ msgstr ""
msgid "There are no {0} on this site."
msgstr ""
-#: lms/utils.py:1070
+#: lms/utils.py:1063
msgid "There is a problem with the payment gateway. Please contact the Administrator to proceed."
msgstr ""
@@ -3709,7 +3675,7 @@ msgstr ""
msgid "This certificate does no expire"
msgstr ""
-#: lms/utils.py:1028 lms/utils.py:1769
+#: lms/utils.py:1021 lms/utils.py:1762
msgid "This course is free."
msgstr ""
@@ -3823,7 +3789,7 @@ msgstr ""
msgid "To Date is mandatory in Work Experience."
msgstr ""
-#: lms/utils.py:1037 lms/utils.py:1780
+#: lms/utils.py:1030 lms/utils.py:1773
msgid "To join this batch, please contact the Administrator."
msgstr ""
@@ -4077,15 +4043,15 @@ msgstr ""
msgid "Write a review"
msgstr ""
-#: lms/doctype/lms_certificate_request/lms_certificate_request.py:86
+#: lms/doctype/lms_certificate_request/lms_certificate_request.py:89
msgid "You already have an evaluation on {0} at {1} for the course {2}."
msgstr ""
-#: lms/api.py:204
+#: lms/api.py:205
msgid "You are already enrolled for this batch."
msgstr ""
-#: lms/api.py:196
+#: lms/api.py:197
msgid "You are already enrolled for this course."
msgstr ""
@@ -4110,11 +4076,11 @@ msgstr ""
msgid "You can find their resume attached to this email."
msgstr ""
-#: lms/doctype/lms_certificate_request/lms_certificate_request.py:106
+#: lms/doctype/lms_certificate_request/lms_certificate_request.py:109
msgid "You cannot schedule evaluations after {0}."
msgstr ""
-#: lms/doctype/lms_certificate_request/lms_certificate_request.py:95
+#: lms/doctype/lms_certificate_request/lms_certificate_request.py:98
msgid "You cannot schedule evaluations for past slots."
msgstr ""
@@ -4122,7 +4088,7 @@ msgstr ""
msgid "You don't have any notifications."
msgstr ""
-#: templates/quiz/quiz.js:136
+#: templates/quiz/quiz.js:137
msgid "You got"
msgstr ""
@@ -4176,11 +4142,17 @@ msgstr ""
#: lms/notification/certificate_request_creation/certificate_request_creation.html:7
#: lms/notification/certificate_request_reminder/certificate_request_reminder.html:6
+#: templates/emails/certificate_request_notification.html:2
msgid "Your evaluation for the course {0} has been scheduled on {1} at {2} {3}."
msgstr ""
+#: lms/doctype/lms_certificate_request/lms_certificate_request.py:119
+msgid "Your evaluation slot has been booked"
+msgstr ""
+
#: lms/notification/certificate_request_creation/certificate_request_creation.html:8
#: lms/notification/certificate_request_reminder/certificate_request_reminder.html:7
+#: templates/emails/certificate_request_notification.html:3
msgid "Your evaluator is {0}"
msgstr ""
@@ -4188,7 +4160,7 @@ msgstr ""
msgid "Your request to join us as a mentor for the course"
msgstr ""
-#: templates/quiz/quiz.js:136
+#: templates/quiz/quiz.js:140
msgid "Your score is"
msgstr ""
@@ -4201,7 +4173,7 @@ msgstr ""
msgid "cancel your application"
msgstr ""
-#: templates/quiz/quiz.js:136
+#: templates/quiz/quiz.js:137
msgid "correct answers"
msgstr ""
@@ -4217,7 +4189,7 @@ msgstr ""
msgid "of"
msgstr ""
-#: templates/quiz/quiz.js:136
+#: templates/quiz/quiz.js:141
msgid "out of"
msgstr ""
@@ -4261,7 +4233,7 @@ msgstr ""
msgid "{0} is already certified for the course {1}"
msgstr ""
-#: lms/utils.py:696
+#: lms/utils.py:689
msgid "{0} mentioned you in a comment"
msgstr ""
@@ -4269,7 +4241,7 @@ msgstr ""
msgid "{0} mentioned you in a comment in your batch."
msgstr ""
-#: lms/utils.py:649 lms/utils.py:655
+#: lms/utils.py:642 lms/utils.py:648
msgid "{0} mentioned you in a comment in {1}"
msgstr ""
diff --git a/lms/overrides/user.py b/lms/overrides/user.py
index b7659493..da1d416b 100644
--- a/lms/overrides/user.py
+++ b/lms/overrides/user.py
@@ -16,6 +16,9 @@ class CustomUser(User):
super().validate()
self.validate_username_duplicates()
+ def after_insert(self):
+ self.add_roles("LMS Student")
+
def validate_username_duplicates(self):
while not self.username or self.username_exists():
self.username = append_number_if_name_exists(