@@ -101,6 +103,7 @@
:rows="field.rows"
:options="field.options"
:description="field.description"
+ :class="columns.length > 1 ? 'w-full' : 'w-1/2'"
/>
diff --git a/frontend/src/components/Settings/Settings.vue b/frontend/src/components/Settings/Settings.vue
index e60975f1..c6d27822 100644
--- a/frontend/src/components/Settings/Settings.vue
+++ b/frontend/src/components/Settings/Settings.vue
@@ -335,6 +335,9 @@ const tabsStructure = computed(() => {
description:
'New users will have to be manually registered by Admins.',
},
+ {
+ type: 'Column Break',
+ },
{
label: 'Signup Consent HTML',
name: 'custom_signup_content',
@@ -364,10 +367,14 @@ const tabsStructure = computed(() => {
description:
'Keywords for search engines to find your website. Separated by commas.',
},
+ {
+ type: 'Column Break',
+ },
{
label: 'Meta Image',
name: 'meta_image',
type: 'Upload',
+ size: 'lg',
},
],
},
diff --git a/frontend/src/components/Settings/ZoomSettings.vue b/frontend/src/components/Settings/ZoomSettings.vue
index d02a9c3d..6906be66 100644
--- a/frontend/src/components/Settings/ZoomSettings.vue
+++ b/frontend/src/components/Settings/ZoomSettings.vue
@@ -179,7 +179,7 @@ const columns = computed(() => {
key: 'member_name',
},
{
- label: __('Enabled'),
+ label: __('Status'),
key: 'enabled',
align: 'center',
},
diff --git a/frontend/src/pages/CertifiedParticipants.vue b/frontend/src/pages/CertifiedParticipants.vue
index b7d0de83..3fca3407 100644
--- a/frontend/src/pages/CertifiedParticipants.vue
+++ b/frontend/src/pages/CertifiedParticipants.vue
@@ -127,6 +127,7 @@ const memberCount = ref(0)
const dayjs = inject('$dayjs')
onMounted(() => {
+ getMemberCount()
updateParticipants()
})
@@ -138,11 +139,13 @@ const participants = createListResource({
pageLength: 30,
})
-const count = call('lms.lms.api.get_count_of_certified_members').then(
- (data) => {
+const getMemberCount = () => {
+ call('lms.lms.api.get_count_of_certified_members', {
+ filters: filters.value,
+ }).then((data) => {
memberCount.value = data
- }
-)
+ })
+}
const categories = createListResource({
doctype: 'LMS Certificate',
@@ -157,6 +160,7 @@ const categories = createListResource({
const updateParticipants = () => {
updateFilters()
+ getMemberCount()
participants.update({
filters: filters.value,
})
diff --git a/frontend/src/pages/CourseForm.vue b/frontend/src/pages/CourseForm.vue
index 3e9f090d..18878f1f 100644
--- a/frontend/src/pages/CourseForm.vue
+++ b/frontend/src/pages/CourseForm.vue
@@ -284,7 +284,7 @@ import {
} from 'vue'
import { Image, Trash2, X } from 'lucide-vue-next'
import { useRouter } from 'vue-router'
-import { capture } from '@/telemetry'
+import { capture, startRecording, stopRecording } from '@/telemetry'
import { useOnboarding } from 'frappe-ui/frappe'
import { sessionStore } from '../stores/session'
import { openSettings } from '@/utils'
@@ -337,6 +337,7 @@ onMounted(() => {
courseResource.reload()
} else {
capture('course_form_opened')
+ startRecording()
}
window.addEventListener('keydown', keyboardShortcut)
})
@@ -354,6 +355,7 @@ const keyboardShortcut = (e) => {
onBeforeUnmount(() => {
window.removeEventListener('keydown', keyboardShortcut)
+ stopRecording()
})
const courseCreationResource = createResource({
diff --git a/frontend/src/pages/Courses.vue b/frontend/src/pages/Courses.vue
index d585dd7d..3d5099c0 100644
--- a/frontend/src/pages/Courses.vue
+++ b/frontend/src/pages/Courses.vue
@@ -240,7 +240,6 @@ const updateTabFilter = () => {
filters.value['live'] = 1
} else if (currentTab.value == 'Upcoming') {
filters.value['upcoming'] = 1
- filters.value['published'] = 1
} else if (currentTab.value == 'New') {
filters.value['published'] = 1
filters.value['published_on'] = [
@@ -249,6 +248,8 @@ const updateTabFilter = () => {
]
} else if (currentTab.value == 'Created') {
filters.value['created'] = 1
+ } else if (currentTab.value == 'Unpublished') {
+ filters.value['published'] = 0
}
}
}
@@ -318,6 +319,7 @@ const courseTabs = computed(() => {
user.data?.is_evaluator
) {
tabs.push({ label: __('Created') })
+ tabs.push({ label: __('Unpublished') })
} else if (user.data) {
tabs.push({ label: __('Enrolled') })
}
diff --git a/frontend/src/pages/LessonForm.vue b/frontend/src/pages/LessonForm.vue
index 2d61e009..c7bab62b 100644
--- a/frontend/src/pages/LessonForm.vue
+++ b/frontend/src/pages/LessonForm.vue
@@ -99,7 +99,7 @@ import EditorJS from '@editorjs/editorjs'
import LessonHelp from '@/components/LessonHelp.vue'
import { ChevronRight } from 'lucide-vue-next'
import { getEditorTools, enablePlyr } from '@/utils'
-import { capture } from '@/telemetry'
+import { capture, startRecording, stopRecording } from '@/telemetry'
import { useOnboarding } from 'frappe-ui/frappe'
const { brand } = sessionStore()
@@ -131,6 +131,7 @@ onMounted(() => {
window.location.href = '/login'
}
capture('lesson_form_opened')
+ startRecording()
editor.value = renderEditor('content')
instructorEditor.value = renderEditor('instructor-notes')
window.addEventListener('keydown', keyboardShortcut)
@@ -226,6 +227,7 @@ const keyboardShortcut = (e) => {
onBeforeUnmount(() => {
clearInterval(autoSaveInterval)
window.removeEventListener('keydown', keyboardShortcut)
+ stopRecording()
})
const newLessonResource = createResource({
diff --git a/lms/lms/api.py b/lms/lms/api.py
index 7e540a4d..12c122cb 100644
--- a/lms/lms/api.py
+++ b/lms/lms/api.py
@@ -457,7 +457,7 @@ class CountDistinct(DistinctOptionFunction):
@frappe.whitelist(allow_guest=True)
-def get_count_of_certified_members():
+def get_count_of_certified_members(filters=None):
Certificate = DocType("LMS Certificate")
query = (
@@ -466,6 +466,14 @@ def get_count_of_certified_members():
.where(Certificate.published == 1)
)
+ if filters:
+ for field, value in filters.items():
+ if field == "category":
+ query = query.where(
+ Certificate.course_title.like(f"%{value}%")
+ | Certificate.batch_title.like(f"%{value}%")
+ )
+
result = query.run(as_dict=True)
return result[0]["total"] if result else 0
@@ -691,13 +699,13 @@ def get_categories(doctype, filters):
@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.
+ Args: start (int): Start index for the query.
<<<<<<< HEAD
- search (str): Search term to filter the results.
+ search (str): Search term to filter the results.
=======
- search (str): Search term to filter the results.
+ search (str): Search term to filter the results.
>>>>>>> 4869bba7bbb2fb38477d6fc29fb3b5838e075577
- Returns: List of members.
+ Returns: List of members.
"""
filters = {"enabled": 1, "name": ["not in", ["Administrator", "Guest"]]}
diff --git a/lms/lms/doctype/course_chapter/course_chapter.json b/lms/lms/doctype/course_chapter/course_chapter.json
index d4e58072..aa1953d0 100644
--- a/lms/lms/doctype/course_chapter/course_chapter.json
+++ b/lms/lms/doctype/course_chapter/course_chapter.json
@@ -103,6 +103,7 @@
"read_only": 1
}
],
+ "grid_page_length": 50,
"index_web_pages_for_search": 1,
"links": [
{
@@ -111,7 +112,7 @@
"link_fieldname": "chapter"
}
],
- "modified": "2025-02-03 15:23:17.125617",
+ "modified": "2025-05-29 12:38:26.266673",
"modified_by": "Administrator",
"module": "LMS",
"name": "Course Chapter",
@@ -151,8 +152,21 @@
"role": "Course Creator",
"share": 1,
"write": 1
+ },
+ {
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "export": 1,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "Moderator",
+ "share": 1,
+ "write": 1
}
],
+ "row_format": "Dynamic",
"search_fields": "title",
"show_title_field_in_link": 1,
"sort_field": "modified",
@@ -160,4 +174,4 @@
"states": [],
"title_field": "title",
"track_changes": 1
-}
\ No newline at end of file
+}
diff --git a/lms/lms/doctype/lms_course/lms_course.json b/lms/lms/doctype/lms_course/lms_course.json
index 6cf01f8e..db303c92 100644
--- a/lms/lms/doctype/lms_course/lms_course.json
+++ b/lms/lms/doctype/lms_course/lms_course.json
@@ -290,7 +290,7 @@
}
],
"make_attachments_public": 1,
- "modified": "2025-03-13 16:01:19.105212",
+ "modified": "2025-05-29 12:38:01.002898",
"modified_by": "Administrator",
"module": "LMS",
"name": "LMS Course",
@@ -319,12 +319,25 @@
"role": "Course Creator",
"share": 1,
"write": 1
+ },
+ {
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "export": 1,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "Moderator",
+ "share": 1,
+ "write": 1
}
],
+ "row_format": "Dynamic",
"show_title_field_in_link": 1,
"sort_field": "creation",
"sort_order": "DESC",
"states": [],
"title_field": "title",
"track_changes": 1
-}
\ No newline at end of file
+}