Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Notifications UI 941 #978

Open
wants to merge 6 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,6 @@
"@vitejs/plugin-vue": "^5.0.3",
"autoprefixer": "^10.4.2",
"postcss": "^8.4.5",
"vite": "^5.0.11"
"vite": "^5.2.12"
}
}
10 changes: 6 additions & 4 deletions frontend/src/pages/Notifications.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
<Breadcrumbs :items="breadcrumbs" />
<div class="flex items-center space-x-2">
<Button
@click="markAllAsRead.submit"
:loading="markAllAsRead.loading"
@click="markAllAsRead"
:loading="markAllAsReadLoading"
v-if="activeTab === 'Unread' && unReadNotifications.data?.length > 0"
>
{{ __('Mark all as read') }}
Expand All @@ -32,7 +32,7 @@
<Link
v-if="log.link"
:to="log.link"
@click="markAsRead.submit({ name: log.name })"
@click="markAsRead(log.name)"
class="text-gray-600 font-medium text-sm hover:text-gray-700"
>
{{ __('View') }}
Expand All @@ -41,7 +41,7 @@
<Button
variant="ghost"
v-if="!log.read"
@click="markAsRead.submit({ name: log.name })"
@click="markAsRead(log.name)"
>
<template #icon>
<X class="h-4 w-4 text-gray-700 stroke-1.5" />
Expand Down Expand Up @@ -70,12 +70,14 @@ import UserAvatar from '@/components/UserAvatar.vue'
import { useRouter } from 'vue-router'
import { X } from 'lucide-vue-next'
import { updateDocumentTitle } from '@/utils'
import { useNotificationStore } from '@/stores/notificationStore'

const user = inject('$user')
const socket = inject('$socket')
const allUsers = inject('$allUsers')
const activeTab = ref('Unread')
const router = useRouter()
const notificationStore = useNotificationStore()

onMounted(() => {
if (!user.data) router.push({ name: 'Courses' })
Expand Down
20 changes: 20 additions & 0 deletions frontend/src/stores/notificationStore.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { defineStore } from 'pinia'

export const useNotificationStore = defineStore('notification', {
state: () => ({
unreadCount: 0
}),
actions: {
setUnreadCount(count) {
this.unreadCount = count
},
decrementUnreadCount() {
if (this.unreadCount > 0) {
this.unreadCount--
}
},
resetUnreadCount() {
this.unreadCount = 0
}
}
})
2 changes: 1 addition & 1 deletion frontend/src/telemetry.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useStorage } from "@vueuse/core";
import { call } from "frappe-ui";
import "../../../frappe/frappe/public/js/lib/posthog.js";
// import "../../../frappe/frappe/public/js/lib/posthog.js";

const APP = "lms";
const SITENAME = window.location.hostname;
Expand Down
4 changes: 2 additions & 2 deletions lms/public/css/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ input[type=checkbox] {
background-position: center;
border: 1px solid var(--gray-400);
box-sizing: border-box;
box-shadow: 0 1px 2px #0000001a;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
border-radius: 4px;
-webkit-appearance: none;
-webkit-print-color-adjust: exact;
Expand Down Expand Up @@ -2497,4 +2497,4 @@ select {

.toastui-calendar-weekday-event-block {
box-shadow: none !important;
}
}
157 changes: 100 additions & 57 deletions lms/www/utils.py
Original file line number Diff line number Diff line change
@@ -1,74 +1,117 @@
import frappe

from lms.lms.utils import get_lesson_url, get_lessons, get_membership
from frappe.utils import cstr
from lms.lms.utils import redirect_to_courses_list
from lms.lms.utils import get_lesson_url, get_lessons, get_membership, redirect_to_courses_list


def get_common_context(context):
context.no_cache = 1

try:
batch_name = frappe.form_dict["batch"]
except KeyError:
batch_name = None

course = frappe.db.get_value(
"LMS Course",
frappe.form_dict["course"],
["name", "title", "video_link", "enable_certification", "status"],
as_dict=True,
)
if not course:
redirect_to_courses_list()

context.course = course
context.lessons = get_lessons(course.name)
membership = get_membership(course.name, frappe.session.user, batch_name)
context.membership = membership
context.progress = frappe.utils.cint(membership.progress) if membership else 0
context.batch_old = (
membership.batch_old if membership and membership.batch_old else None
)
context.course.query_parameter = (
"?batch=" + membership.batch_old if membership and membership.batch_old else ""
)
context.livecode_url = get_livecode_url()
"""
Populate the common context for LMS pages.

Args:
context (dict): The context dictionary to be populated.

Returns:
None
"""
context.no_cache = 1

try:
batch_name = frappe.form_dict['batch']
except KeyError:
batch_name = None

course = frappe.db.get_value(
'LMS Course',
frappe.form_dict['course'],
['name', 'title', 'video_link', 'enable_certification', 'status'],
as_dict=True,
)
if not course:
redirect_to_courses_list()

context.course = course
context.lessons = get_lessons(course.name)
membership = get_membership(course.name, frappe.session.user, batch_name)
context.membership = membership
context.progress = frappe.utils.cint(membership.progress) if membership else 0
context.batch_old = (
membership.batch_old if membership and membership.batch_old else None
)
context.course.query_parameter = (
'?batch=' + membership.batch_old if membership and membership.batch_old else ''
)
context.livecode_url = get_livecode_url()


def get_livecode_url():
return frappe.db.get_single_value("LMS Settings", "livecode_url")
"""
Retrieve the livecode URL from LMS Settings.

Returns:
str: The livecode URL.
"""
return frappe.db.get_single_value('LMS Settings', 'livecode_url')


def redirect_to_lesson(course, index_='1.1'):
"""
Redirect to a specific lesson in the course.

def redirect_to_lesson(course, index_="1.1"):
frappe.local.flags.redirect_location = (
get_lesson_url(course.name, index_) + course.query_parameter
)
raise frappe.Redirect
Args:
course (dict): The course object.
index_ (str): The lesson index to redirect to.

Raises:
frappe.Redirect: To redirect to the specified lesson.
"""
frappe.local.flags.redirect_location = (
get_lesson_url(course.name, index_) + course.query_parameter
)
raise frappe.Redirect


def get_current_lesson_details(lesson_number, context, is_edit=False):
details_list = list(filter(lambda x: cstr(x.number) == lesson_number, context.lessons))
"""
Get details of the current lesson.

Args:
lesson_number (str): The lesson number to retrieve.
context (dict): The context containing lesson information.
is_edit (bool): Whether the function is called in edit mode.

Returns:
dict: The lesson details if found, None otherwise.
"""
details_list = [lesson for lesson in context.lessons if lesson.number == lesson_number]

if not len(details_list):
if is_edit:
return None
else:
redirect_to_lesson(context.course)
if not details_list:
if is_edit:
return None
else:
redirect_to_lesson(context.course)

lesson_info = details_list[0]
lesson_info.body = lesson_info.body.replace('"', "'")
return lesson_info
lesson_info = details_list[0]
lesson_info.body = lesson_info.body.replace("'", "\\'").replace('"', '\\"')
return lesson_info


def is_student(batch, member=None):
if not member:
member = frappe.session.user

return frappe.db.exists(
"Batch Student",
{
"student": member,
"parent": batch,
},
)
"""
Check if the given member is a student in the specified batch.

Args:
batch (str): The batch to check.
member (str, optional): The member to check. Defaults to the current user.

Returns:
bool: True if the member is a student in the batch, False otherwise.
"""
if not member:
member = frappe.session.user

return frappe.db.exists(
'Batch Student',
{
'student': member,
'parent': batch,
},
)