Merge branch 'develop' into develop

This commit is contained in:
Om vataliya
2026-01-13 16:55:36 +05:30
committed by GitHub
10 changed files with 5913 additions and 264 deletions

View File

@@ -36,7 +36,7 @@ jobs:
with: with:
python-version: '3.14' python-version: '3.14'
- name: setup node - name: setup node
uses: actions/setup-node@v4 uses: actions/setup-node@v6
with: with:
node-version: '24' node-version: '24'
check-latest: true check-latest: true

View File

@@ -26,6 +26,11 @@ jobs:
with: with:
python-version: "3.14" python-version: "3.14"
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: 24
- name: Run script to update POT file - name: Run script to update POT file
run: | run: |
bash ${GITHUB_WORKSPACE}/.github/helper/update_pot_file.sh bash ${GITHUB_WORKSPACE}/.github/helper/update_pot_file.sh

View File

@@ -16,9 +16,9 @@ jobs:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
with: with:
fetch-depth: 200 fetch-depth: 200
- uses: actions/setup-node@v4 - uses: actions/setup-node@v6
with: with:
node-version: 20 node-version: 24
check-latest: true check-latest: true
- name: Check commit titles - name: Check commit titles

View File

@@ -15,9 +15,9 @@ jobs:
fetch-depth: 0 fetch-depth: 0
persist-credentials: false persist-credentials: false
- name: Setup Node.js - name: Setup Node.js
uses: actions/setup-node@v4 uses: actions/setup-node@v6
with: with:
node-version: 20 node-version: 24
- name: Setup dependencies - name: Setup dependencies
run: | run: |
npm install @semantic-release/git @semantic-release/exec --no-save npm install @semantic-release/git @semantic-release/exec --no-save

View File

@@ -48,7 +48,7 @@ jobs:
exit 1 exit 1
fi fi
- uses: actions/setup-node@v4 - uses: actions/setup-node@v6
with: with:
node-version: 24 node-version: 24
check-latest: true check-latest: true

View File

@@ -15,7 +15,7 @@
<div class="mx-auto w-full max-w-4xl pt-6 pb-10"> <div class="mx-auto w-full max-w-4xl pt-6 pb-10">
<div class="flex flex-col md:flex-row justify-between mb-8 px-3"> <div class="flex flex-col md:flex-row justify-between mb-8 px-3">
<div class="text-xl font-semibold text-ink-gray-9 mb-4 md:mb-0"> <div class="text-xl font-semibold text-ink-gray-9 mb-4 md:mb-0">
{{ memberCount }} {{ __('certified members') }} {{ memberCount }} {{ __('Certified Members') }}
</div> </div>
<div <div
class="flex flex-col md:flex-row md:items-center space-y-4 md:space-y-0 md:space-x-4" class="flex flex-col md:flex-row md:items-center space-y-4 md:space-y-0 md:space-x-4"
@@ -65,42 +65,43 @@
username: participant.username, username: participant.username,
}, },
}" }"
class="flex rounded-md hover:bg-surface-gray-2 px-3"
> >
<div <div class="rounded-md hover:bg-surface-gray-2 px-3">
class="flex w-full space-x-3 py-2" <div
:class="{ class="flex items-center w-full space-x-3 py-2"
'border-b': index < participants.data.length - 1, :class="{
}" 'border-b': index < participants.data.length - 1,
> }"
<UserAvatar :user="participant" size="2xl" /> >
<UserAvatar :user="participant" size="2xl" />
<div class="flex flex-col md:flex-row w-full"> <div class="flex flex-col md:flex-row w-full">
<div class="flex-1"> <div class="flex-1">
<div class="text-base font-medium text-ink-gray-8"> <div class="text-base font-medium text-ink-gray-8">
{{ participant.full_name }} {{ participant.full_name }}
</div>
<div
v-if="participant.headline"
class="mt-1.5 text-base text-ink-gray-5"
>
{{ participant.headline }}
</div>
</div> </div>
<div <div
v-if="participant.headline" class="flex items-center space-x-3 md:space-x-24 text-sm md:text-base mt-1.5"
class="mt-1.5 text-base text-ink-gray-5"
> >
{{ participant.headline }} <div class="text-ink-gray-5">
</div> {{ participant.certificate_count }}
</div> {{
<div participant.certificate_count > 1
class="flex items-center space-x-3 md:space-x-24 text-sm md:text-base mt-1.5" ? __('certificates')
> : __('certificate')
<div class="text-ink-gray-5"> }}
{{ participant.certificate_count }} </div>
{{ <span class="text-ink-gray-4 md:hidden">·</span>
participant.certificate_count > 1 <div class="text-ink-gray-5">
? __('certificates') {{ dayjs(participant.issue_date).format('DD MMM YYYY') }}
: __('certificate') </div>
}}
</div>
<span class="text-ink-gray-4 md:hidden">·</span>
<div class="text-ink-gray-5">
{{ dayjs(participant.issue_date).format('DD MMM YYYY') }}
</div> </div>
</div> </div>
</div> </div>
@@ -190,7 +191,7 @@ const updateParticipants = () => {
const updateFilters = () => { const updateFilters = () => {
filters.value = { filters.value = {
...(currentCategory.value && { ...(currentCategory.value.trim('') && {
category: currentCategory.value, category: currentCategory.value,
}), }),
...(nameFilter.value && { ...(nameFilter.value && {

5629
frontend/yarn.lock Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -15,7 +15,6 @@ from frappe.integrations.frappe_providers.frappecloud_billing import (
current_site_info, current_site_info,
is_fc_site, is_fc_site,
) )
from frappe.query_builder import DocType
from frappe.translate import get_all_translations from frappe.translate import get_all_translations
from frappe.utils import ( from frappe.utils import (
add_days, add_days,
@@ -281,53 +280,17 @@ 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=100): def get_certified_participants(filters=None, start=0, page_length=100):
filters, or_filters, open_to_opportunities, hiring = update_certification_filters(filters) query = get_certification_query(filters)
query = query.orderby("issue_date", order=frappe.qb.desc).offset(start).limit(page_length)
participants = frappe.db.get_all( participants = query.run(as_dict=True)
"LMS Certificate",
filters=filters,
or_filters=or_filters,
fields=["member", "issue_date", "batch_name", "course", "name"],
group_by="member",
order_by="issue_date desc",
start=start,
page_length=page_length,
)
for participant in participants: for participant in participants:
details = get_certified_participant_details(participant.member) details = get_certified_participant_details(participant.member)
participant.update(details) participant.update(details)
participants = filter_by_open_to_criteria(participants, open_to_opportunities, hiring)
return participants return participants
def update_certification_filters(filters):
open_to_opportunities = False
hiring = False
or_filters = {}
if not filters:
filters = {}
filters.update({"published": 1})
category = filters.get("category")
if category:
del filters["category"]
or_filters["course_title"] = ["like", f"%{category}%"]
or_filters["batch_title"] = ["like", f"%{category}%"]
if filters.get("open_to_opportunities"):
del filters["open_to_opportunities"]
open_to_opportunities = True
if filters.get("hiring"):
del filters["hiring"]
hiring = True
return filters, or_filters, open_to_opportunities, hiring
def get_certified_participant_details(member): def get_certified_participant_details(member):
count = frappe.db.count("LMS Certificate", {"member": member}) count = frappe.db.count("LMS Certificate", {"member": member})
details = frappe.db.get_value( details = frappe.db.get_value(
@@ -340,25 +303,18 @@ def get_certified_participant_details(member):
return details return details
def filter_by_open_to_criteria(participants, open_to_opportunities, hiring): def get_certification_query(filters):
if not open_to_opportunities and not hiring: Certificate = frappe.qb.DocType("LMS Certificate")
return participants User = frappe.qb.DocType("User")
if open_to_opportunities:
participants = [participant for participant in participants if participant.open_to == "Opportunities"]
if hiring:
participants = [participant for participant in participants if participant.open_to == "Hiring"]
return participants
@frappe.whitelist(allow_guest=True)
def get_count_of_certified_members(filters=None):
Certificate = DocType("LMS Certificate")
query = ( query = (
frappe.qb.from_(Certificate).select(Certificate.member).distinct().where(Certificate.published == 1) frappe.qb.from_(Certificate)
.select(Certificate.member)
.distinct()
.join(User)
.on(Certificate.member == User.name)
.where(Certificate.published == 1)
.where(User.enabled == 1)
) )
if filters: if filters:
@@ -367,9 +323,18 @@ def get_count_of_certified_members(filters=None):
query = query.where( query = query.where(
Certificate.course_title.like(f"%{value}%") | Certificate.batch_title.like(f"%{value}%") Certificate.course_title.like(f"%{value}%") | Certificate.batch_title.like(f"%{value}%")
) )
elif field == "member_name": if field == "member_name":
query = query.where(Certificate.member_name.like(value[1])) query = query.where(Certificate.member_name.like(value[1]))
if field == "open_to_opportunities":
query = query.where(User.open_to == "Opportunities")
if field == "hiring":
query = query.where(User.open_to == "Hiring")
return query
@frappe.whitelist(allow_guest=True)
def get_count_of_certified_members(filters=None):
query = get_certification_query(filters)
result = query.run(as_dict=True) result = query.run(as_dict=True)
return len(result) or 0 return len(result) or 0

File diff suppressed because it is too large Load Diff

View File

@@ -64,3 +64,6 @@ ignore = [
quote-style = "double" quote-style = "double"
indent-style = "tab" indent-style = "tab"
docstring-code-format = true docstring-code-format = true
[tool.bench.frappe-dependencies]
frappe = ">=15.0.0,<17.0.0"