Merge pull request #1550 from pateljannat/issues-112

fix: misc issues
This commit is contained in:
Jannat Patel
2025-05-31 12:49:16 +05:30
committed by GitHub
9 changed files with 42 additions and 38 deletions

View File

@@ -293,8 +293,8 @@ const tabsStructure = computed(() => {
type: 'checkbox', type: 'checkbox',
}, },
{ {
label: 'Certified Participants', label: 'Certified Members',
name: 'certified_participants', name: 'certified_members',
type: 'checkbox', type: 'checkbox',
}, },
{ {

View File

@@ -61,7 +61,7 @@
</button> </button>
</template> </template>
<script setup> <script setup>
import { Tooltip, Button } from 'frappe-ui' import { Tooltip } from 'frappe-ui'
import { computed } from 'vue' import { computed } from 'vue'
import { useRouter } from 'vue-router' import { useRouter } from 'vue-router'
import * as icons from 'lucide-vue-next' import * as icons from 'lucide-vue-next'

View File

@@ -12,10 +12,7 @@
</Button> </Button>
</router-link> </router-link>
</header> </header>
<div <div class="mx-auto w-full max-w-4xl pt-6 pb-10">
v-if="participants.data?.length"
class="mx-auto w-full max-w-4xl pt-6 pb-10"
>
<div class="flex flex-col md:flex-row justify-between mb-4 px-3"> <div class="flex flex-col md:flex-row justify-between mb-4 px-3">
<div class="text-xl font-semibold text-ink-gray-7 mb-4 md:mb-0"> <div class="text-xl font-semibold text-ink-gray-7 mb-4 md:mb-0">
{{ memberCount }} {{ __('certified members') }} {{ memberCount }} {{ __('certified members') }}
@@ -41,7 +38,7 @@
</div> </div>
</div> </div>
</div> </div>
<div class="divide-y"> <div v-if="participants.data?.length" class="divide-y">
<template v-for="participant in participants.data"> <template v-for="participant in participants.data">
<router-link <router-link
:to="{ :to="{
@@ -92,6 +89,7 @@
</router-link> </router-link>
</template> </template>
</div> </div>
<EmptyState v-else type="Certified Members" />
<div <div
v-if="!participants.list.loading && participants.hasNextPage" v-if="!participants.list.loading && participants.hasNextPage"
class="flex justify-center mt-5" class="flex justify-center mt-5"
@@ -101,7 +99,6 @@
</Button> </Button>
</div> </div>
</div> </div>
<EmptyState v-else type="Certified Members" />
</template> </template>
<script setup> <script setup>
import { import {
@@ -134,9 +131,8 @@ onMounted(() => {
const participants = createListResource({ const participants = createListResource({
doctype: 'LMS Certificate', doctype: 'LMS Certificate',
url: 'lms.lms.api.get_certified_participants', url: 'lms.lms.api.get_certified_participants',
cache: ['certified_participants'],
start: 0, start: 0,
pageLength: 30, pageLength: 100,
}) })
const getMemberCount = () => { const getMemberCount = () => {

View File

@@ -26,7 +26,6 @@
</header> </header>
<div> <div>
<div <div
v-if="jobCount"
class="flex flex-col lg:flex-row space-y-4 lg:space-y-0 lg:items-center justify-between w-full md:w-4/5 mx-auto p-5" class="flex flex-col lg:flex-row space-y-4 lg:space-y-0 lg:items-center justify-between w-full md:w-4/5 mx-auto p-5"
> >
<div class="text-xl font-semibold text-ink-gray-7 mb-4 md:mb-0"> <div class="text-xl font-semibold text-ink-gray-7 mb-4 md:mb-0">
@@ -34,7 +33,6 @@
</div> </div>
<div <div
v-if="jobs.data?.length || jobCount > 0"
class="grid grid-cols-1 gap-2" class="grid grid-cols-1 gap-2"
:class="user.data ? 'md:grid-cols-3' : 'md:grid-cols-2'" :class="user.data ? 'md:grid-cols-3' : 'md:grid-cols-2'"
> >
@@ -119,12 +117,14 @@ onMounted(() => {
jobType.value = queries.get('type') jobType.value = queries.get('type')
} }
updateJobs() updateJobs()
getJobCount()
}) })
const jobs = createResource({ const jobs = createResource({
url: 'lms.lms.api.get_job_opportunities', url: 'lms.lms.api.get_job_opportunities',
cache: ['jobs'], cache: ['jobs'],
onSuccess(data) {
jobCount.value = data.length
},
}) })
const updateJobs = () => { const updateJobs = () => {
@@ -165,18 +165,6 @@ const updateFilters = () => {
} }
} }
const getJobCount = () => {
call('lms.lms.api.get_count', {
doctype: 'Job Opportunity',
filters: {
status: 'Open',
disabled: 0,
},
}).then((data) => {
jobCount.value = data
})
}
watch(country, (val) => { watch(country, (val) => {
updateJobs() updateJobs()
}) })

View File

@@ -20,7 +20,6 @@ from frappe.utils import (
date_diff, date_diff,
) )
from frappe.query_builder import DocType from frappe.query_builder import DocType
from pypika.functions import DistinctOptionFunction
from lms.lms.utils import get_average_rating, get_lesson_count from lms.lms.utils import get_average_rating, get_lesson_count
from xml.dom.minidom import parseString from xml.dom.minidom import parseString
from lms.lms.doctype.course_lesson.course_lesson import save_progress from lms.lms.doctype.course_lesson.course_lesson import save_progress
@@ -413,7 +412,7 @@ def get_evaluator_details(evaluator):
@frappe.whitelist(allow_guest=True) @frappe.whitelist(allow_guest=True)
def get_certified_participants(filters=None, start=0, page_length=30): def get_certified_participants(filters=None, start=0, page_length=100):
or_filters = {} or_filters = {}
if not filters: if not filters:
filters = {} filters = {}
@@ -451,18 +450,14 @@ def get_certified_participants(filters=None, start=0, page_length=30):
return participants return participants
class CountDistinct(DistinctOptionFunction):
def __init__(self, field):
super().__init__("COUNT", field, distinct=True)
@frappe.whitelist(allow_guest=True) @frappe.whitelist(allow_guest=True)
def get_count_of_certified_members(filters=None): def get_count_of_certified_members(filters=None):
Certificate = DocType("LMS Certificate") Certificate = DocType("LMS Certificate")
query = ( query = (
frappe.qb.from_(Certificate) frappe.qb.from_(Certificate)
.select(CountDistinct(Certificate.member).as_("total")) .select(Certificate.member)
.distinct()
.where(Certificate.published == 1) .where(Certificate.published == 1)
) )
@@ -473,9 +468,11 @@ def get_count_of_certified_members(filters=None):
Certificate.course_title.like(f"%{value}%") Certificate.course_title.like(f"%{value}%")
| Certificate.batch_title.like(f"%{value}%") | Certificate.batch_title.like(f"%{value}%")
) )
elif field == "member_name":
query = query.where(Certificate.member_name.like(value[1]))
result = query.run(as_dict=True) result = query.run(as_dict=True)
return result[0]["total"] if result else 0 return len(result) or 0
@frappe.whitelist(allow_guest=True) @frappe.whitelist(allow_guest=True)
@@ -552,7 +549,7 @@ def get_sidebar_settings():
items = [ items = [
"courses", "courses",
"batches", "batches",
"certified_participants", "certified_members",
"jobs", "jobs",
"statistics", "statistics",
"notifications", "notifications",

View File

@@ -35,6 +35,7 @@
"courses", "courses",
"batches", "batches",
"certified_participants", "certified_participants",
"certified_members",
"column_break_exdz", "column_break_exdz",
"jobs", "jobs",
"statistics", "statistics",
@@ -277,6 +278,7 @@
"default": "1", "default": "1",
"fieldname": "certified_participants", "fieldname": "certified_participants",
"fieldtype": "Check", "fieldtype": "Check",
"hidden": 1,
"label": "Certified Participants" "label": "Certified Participants"
}, },
{ {
@@ -397,13 +399,19 @@
"fieldtype": "Check", "fieldtype": "Check",
"label": "Persona Captured", "label": "Persona Captured",
"read_only": 1 "read_only": 1
},
{
"default": "0",
"fieldname": "certified_members",
"fieldtype": "Check",
"label": "Certified Members"
} }
], ],
"grid_page_length": 50, "grid_page_length": 50,
"index_web_pages_for_search": 1, "index_web_pages_for_search": 1,
"issingle": 1, "issingle": 1,
"links": [], "links": [],
"modified": "2025-05-14 12:43:22.749850", "modified": "2025-05-30 19:02:51.381668",
"modified_by": "sayali@frappe.io", "modified_by": "sayali@frappe.io",
"module": "LMS", "module": "LMS",
"name": "LMS Settings", "name": "LMS Settings",

View File

@@ -106,4 +106,5 @@ lms.patches.v2_0.update_job_city_and_country
lms.patches.v2_0.update_course_evaluator_data lms.patches.v2_0.update_course_evaluator_data
lms.patches.v2_0.move_zoom_settings #20-05-2025 lms.patches.v2_0.move_zoom_settings #20-05-2025
lms.patches.v2_0.link_zoom_account_to_live_class lms.patches.v2_0.link_zoom_account_to_live_class
lms.patches.v2_0.link_zoom_account_to_batch lms.patches.v2_0.link_zoom_account_to_batch
lms.patches.v2_0.sidebar_for_certified_members

View File

@@ -7,6 +7,10 @@ def execute():
def create_settings(): def create_settings():
current_settings = frappe.get_single("Zoom Settings") current_settings = frappe.get_single("Zoom Settings")
if not current_settings.enable:
return
member = current_settings.owner member = current_settings.owner
member_name = frappe.get_value("User", member, "full_name") member_name = frappe.get_value("User", member, "full_name")

View File

@@ -0,0 +1,10 @@
import frappe
def execute():
show_certified_members = frappe.db.get_single_value(
"LMS Settings", "certified_participants"
)
if show_certified_members:
frappe.db.set_single_value("LMS Settings", "certified_members", 1)