fix: lesson auto save
This commit is contained in:
@@ -100,7 +100,7 @@ import { ChevronRight, Plus } from 'lucide-vue-next'
|
||||
import { createResource, Button } from 'frappe-ui'
|
||||
import PageModal from '@/components/Modals/PageModal.vue'
|
||||
|
||||
const { user } = sessionStore()
|
||||
const { user, sidebarSettings } = sessionStore()
|
||||
const { userResource } = usersStore()
|
||||
const socket = inject('$socket')
|
||||
const unreadCount = ref(0)
|
||||
@@ -115,6 +115,20 @@ onMounted(() => {
|
||||
unreadNotifications.reload()
|
||||
})
|
||||
addNotifications()
|
||||
sidebarSettings.reload(
|
||||
{},
|
||||
{
|
||||
onSuccess(data) {
|
||||
Object.keys(data).forEach((key) => {
|
||||
if (!parseInt(data[key])) {
|
||||
sidebarLinks.value = sidebarLinks.value.filter(
|
||||
(link) => link.label.toLowerCase().split(' ').join('_') !== key
|
||||
)
|
||||
}
|
||||
})
|
||||
},
|
||||
}
|
||||
)
|
||||
})
|
||||
|
||||
const unreadNotifications = createResource({
|
||||
@@ -153,21 +167,6 @@ const addNotifications = () => {
|
||||
}
|
||||
}
|
||||
|
||||
const sidebarSettings = createResource({
|
||||
url: 'lms.lms.api.get_sidebar_settings',
|
||||
cache: 'Sidebar Settings',
|
||||
auto: true,
|
||||
onSuccess(data) {
|
||||
Object.keys(data).forEach((key) => {
|
||||
if (!parseInt(data[key])) {
|
||||
sidebarLinks.value = sidebarLinks.value.filter(
|
||||
(link) => link.label.toLowerCase().split(' ').join('_') !== key
|
||||
)
|
||||
}
|
||||
})
|
||||
},
|
||||
})
|
||||
|
||||
const openPageModal = (link) => {
|
||||
showPageModal.value = true
|
||||
pageToEdit.value = link
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
<div class="outline-lesson pl-8 py-2 pr-4">
|
||||
<router-link
|
||||
:to="{
|
||||
name: allowEdit ? 'CreateLesson' : 'Lesson',
|
||||
name: allowEdit ? 'LessonForm' : 'Lesson',
|
||||
params: {
|
||||
courseName: courseName,
|
||||
chapterNumber: lesson.number.split('.')[0],
|
||||
@@ -89,7 +89,7 @@
|
||||
<div v-if="allowEdit" class="flex mt-2 mb-4 pl-8">
|
||||
<router-link
|
||||
:to="{
|
||||
name: 'CreateLesson',
|
||||
name: 'LessonForm',
|
||||
params: {
|
||||
courseName: courseName,
|
||||
chapterNumber: chapter.idx,
|
||||
|
||||
@@ -4,14 +4,14 @@
|
||||
<slot />
|
||||
</div>
|
||||
<div
|
||||
v-if="tabs"
|
||||
v-if="sidebarSettings.data"
|
||||
class="fixed flex justify-around border-t border-gray-300 bottom-0 z-10 w-full bg-white standalone:pb-4"
|
||||
:style="{
|
||||
gridTemplateColumns: `repeat(${tabs.length}, minmax(0, 1fr))`,
|
||||
gridTemplateColumns: `repeat(${sidebarLinks.length}, minmax(0, 1fr))`,
|
||||
}"
|
||||
>
|
||||
<button
|
||||
v-for="tab in tabs"
|
||||
v-for="tab in sidebarLinks"
|
||||
:key="tab.label"
|
||||
:class="isVisible(tab) ? 'block' : 'hidden'"
|
||||
class="flex flex-col items-center justify-center py-3 transition active:scale-95"
|
||||
@@ -29,21 +29,38 @@
|
||||
<script setup>
|
||||
import { getSidebarLinks } from '../utils'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { computed } from 'vue'
|
||||
import { computed, ref, onMounted } from 'vue'
|
||||
import { sessionStore } from '@/stores/session'
|
||||
import { usersStore } from '@/stores/user'
|
||||
import * as icons from 'lucide-vue-next'
|
||||
|
||||
const { logout, user } = sessionStore()
|
||||
const { logout, user, sidebarSettings } = sessionStore()
|
||||
let { isLoggedIn } = sessionStore()
|
||||
const router = useRouter()
|
||||
let { userResource } = usersStore()
|
||||
const sidebarLinks = ref(getSidebarLinks())
|
||||
|
||||
const tabs = computed(() => {
|
||||
let links = getSidebarLinks()
|
||||
onMounted(() => {
|
||||
sidebarSettings.reload(
|
||||
{},
|
||||
{
|
||||
onSuccess(data) {
|
||||
Object.keys(data).forEach((key) => {
|
||||
if (!parseInt(data[key])) {
|
||||
sidebarLinks.value = sidebarLinks.value.filter(
|
||||
(link) => link.label.toLowerCase().split(' ').join('_') !== key
|
||||
)
|
||||
}
|
||||
})
|
||||
addAccessLinks()
|
||||
},
|
||||
}
|
||||
)
|
||||
})
|
||||
|
||||
const addAccessLinks = () => {
|
||||
if (user) {
|
||||
links.push({
|
||||
sidebarLinks.value.push({
|
||||
label: 'Profile',
|
||||
icon: 'UserRound',
|
||||
activeFor: [
|
||||
@@ -54,18 +71,17 @@ const tabs = computed(() => {
|
||||
'ProfileRoles',
|
||||
],
|
||||
})
|
||||
links.push({
|
||||
sidebarLinks.value.push({
|
||||
label: 'Log out',
|
||||
icon: 'LogOut',
|
||||
})
|
||||
} else {
|
||||
links.push({
|
||||
sidebarLinks.value.push({
|
||||
label: 'Log in',
|
||||
icon: 'LogIn',
|
||||
})
|
||||
}
|
||||
return links
|
||||
})
|
||||
}
|
||||
|
||||
let isActive = (tab) => {
|
||||
return tab.activeFor?.includes(router.currentRoute.value.name)
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
>
|
||||
<Breadcrumbs
|
||||
class="h-7"
|
||||
:items="[{ label: __('All Batches'), route: { name: 'Batches' } }]"
|
||||
:items="[{ label: __('Batches'), route: { name: 'Batches' } }]"
|
||||
/>
|
||||
<div class="flex space-x-2">
|
||||
<div class="w-40">
|
||||
@@ -25,7 +25,7 @@
|
||||
>
|
||||
<Button variant="solid">
|
||||
<template #prefix>
|
||||
<Plus class="h-4 w-4" />
|
||||
<Plus class="h-4 w-4 stroke-1.5" />
|
||||
</template>
|
||||
{{ __('New Batch') }}
|
||||
</Button>
|
||||
|
||||
@@ -6,9 +6,10 @@
|
||||
<div>
|
||||
<FormControl
|
||||
type="text"
|
||||
placeholder="Search Participants"
|
||||
placeholder="Search"
|
||||
v-model="searchQuery"
|
||||
@input="participants.reload()"
|
||||
class="w-40"
|
||||
>
|
||||
<template #prefix>
|
||||
<Search class="w-4 stroke-1.5 text-gray-600" name="search" />
|
||||
|
||||
@@ -5,19 +5,21 @@
|
||||
>
|
||||
<Breadcrumbs
|
||||
class="h-7"
|
||||
:items="[{ label: __('All Courses'), route: { name: 'Courses' } }]"
|
||||
:items="[{ label: __('Courses'), route: { name: 'Courses' } }]"
|
||||
/>
|
||||
<div class="flex space-x-2">
|
||||
<FormControl
|
||||
type="text"
|
||||
placeholder="Search Course"
|
||||
v-model="searchQuery"
|
||||
@input="courses.reload()"
|
||||
>
|
||||
<template #prefix>
|
||||
<Search class="w-4 stroke-1.5 text-gray-600" name="search" />
|
||||
</template>
|
||||
</FormControl>
|
||||
<div class="flex space-x-2 justify-end">
|
||||
<div class="w-36">
|
||||
<FormControl
|
||||
type="text"
|
||||
placeholder="Search"
|
||||
v-model="searchQuery"
|
||||
@input="courses.reload()"
|
||||
>
|
||||
<template #prefix>
|
||||
<Search class="w-4 h-4 stroke-1.5" name="search" />
|
||||
</template>
|
||||
</FormControl>
|
||||
</div>
|
||||
<router-link
|
||||
:to="{
|
||||
name: 'CreateCourse',
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
<router-link
|
||||
v-if="allowEdit()"
|
||||
:to="{
|
||||
name: 'CreateLesson',
|
||||
name: 'LessonForm',
|
||||
params: {
|
||||
courseName: courseName,
|
||||
chapterNumber: props.chapterNumber,
|
||||
|
||||
@@ -80,6 +80,7 @@ const editor = ref(null)
|
||||
const instructorEditor = ref(null)
|
||||
const user = inject('$user')
|
||||
const openInstructorEditor = ref(false)
|
||||
let autoSaveInterval
|
||||
|
||||
const props = defineProps({
|
||||
courseName: {
|
||||
@@ -134,32 +135,45 @@ const lessonDetails = createResource({
|
||||
lesson[key] = data.lesson[key]
|
||||
})
|
||||
lesson.include_in_preview = data.include_in_preview ? true : false
|
||||
editor.value.isReady.then(() => {
|
||||
if (data.lesson.content) {
|
||||
editor.value.render(JSON.parse(data.lesson.content))
|
||||
} else if (data.lesson.body) {
|
||||
let blocks = convertToJSON(data.lesson)
|
||||
editor.value.render({
|
||||
blocks: blocks,
|
||||
})
|
||||
}
|
||||
})
|
||||
instructorEditor.value.isReady.then(() => {
|
||||
if (data.lesson.instructor_content) {
|
||||
instructorEditor.value.render(
|
||||
JSON.parse(data.lesson.instructor_content)
|
||||
)
|
||||
} else if (data.lesson.instructor_notes) {
|
||||
let blocks = convertToJSON(data.lesson)
|
||||
instructorEditor.value.render({
|
||||
blocks: blocks,
|
||||
})
|
||||
}
|
||||
})
|
||||
addLessonContent(data)
|
||||
addInstructorNotes(data)
|
||||
enableAutoSave()
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
const addLessonContent = (data) => {
|
||||
editor.value.isReady.then(() => {
|
||||
if (data.lesson.content) {
|
||||
editor.value.render(JSON.parse(data.lesson.content))
|
||||
} else if (data.lesson.body) {
|
||||
let blocks = convertToJSON(data.lesson)
|
||||
editor.value.render({
|
||||
blocks: blocks,
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const addInstructorNotes = (data) => {
|
||||
instructorEditor.value.isReady.then(() => {
|
||||
if (data.lesson.instructor_content) {
|
||||
instructorEditor.value.render(JSON.parse(data.lesson.instructor_content))
|
||||
} else if (data.lesson.instructor_notes) {
|
||||
let blocks = convertToJSON(data.lesson)
|
||||
instructorEditor.value.render({
|
||||
blocks: blocks,
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const enableAutoSave = () => {
|
||||
autoSaveInterval = setInterval(() => {
|
||||
saveLesson()
|
||||
}, 10000)
|
||||
}
|
||||
|
||||
const newLessonResource = createResource({
|
||||
url: 'frappe.client.insert',
|
||||
makeParams(values) {
|
||||
@@ -357,9 +371,6 @@ const editCurrentLesson = () => {
|
||||
validate() {
|
||||
return validateLesson()
|
||||
},
|
||||
onSuccess() {
|
||||
showToast('Success', 'Lesson updated successfully', 'check')
|
||||
},
|
||||
onError(err) {
|
||||
showToast('Error', err.message, 'x')
|
||||
},
|
||||
@@ -418,7 +429,7 @@ const breadcrumbs = computed(() => {
|
||||
crumbs.push({
|
||||
label: lessonDetails?.data?.lesson ? 'Edit Lesson' : 'Create Lesson',
|
||||
route: {
|
||||
name: 'CreateLesson',
|
||||
name: 'LessonForm',
|
||||
params: {
|
||||
courseName: props.courseName,
|
||||
chapterNumber: props.chapterNumber,
|
||||
@@ -16,7 +16,7 @@
|
||||
<h2 class="mb-3 text-lg font-semibold text-gray-900">
|
||||
{{ __('Achievements') }}
|
||||
</h2>
|
||||
<div class="grid grid-cols-5 gap-4">
|
||||
<div class="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-5 gap-4">
|
||||
<div v-for="badge in badges.data">
|
||||
<Popover trigger="hover" :leaveDelay="Number(0.01)">
|
||||
<template #target>
|
||||
|
||||
@@ -103,8 +103,8 @@ const routes = [
|
||||
},
|
||||
{
|
||||
path: '/courses/:courseName/learn/:chapterNumber-:lessonNumber/edit',
|
||||
name: 'CreateLesson',
|
||||
component: () => import('@/pages/CreateLesson.vue'),
|
||||
name: 'LessonForm',
|
||||
component: () => import('@/pages/LessonForm.vue'),
|
||||
props: true,
|
||||
},
|
||||
{
|
||||
|
||||
@@ -53,11 +53,18 @@ export const sessionStore = defineStore('lms-session', () => {
|
||||
},
|
||||
})
|
||||
|
||||
const sidebarSettings = createResource({
|
||||
url: 'lms.lms.api.get_sidebar_settings',
|
||||
cache: 'Sidebar Settings',
|
||||
auto: false,
|
||||
})
|
||||
|
||||
return {
|
||||
user,
|
||||
isLoggedIn,
|
||||
login,
|
||||
logout,
|
||||
branding,
|
||||
sidebarSettings,
|
||||
}
|
||||
})
|
||||
|
||||
@@ -425,7 +425,7 @@ export function getSidebarLinks() {
|
||||
'CourseDetail',
|
||||
'Lesson',
|
||||
'CreateCourse',
|
||||
'CreateLesson',
|
||||
'LessonForm',
|
||||
],
|
||||
},
|
||||
{
|
||||
|
||||
@@ -184,6 +184,7 @@ jinja = {
|
||||
"lms.lms.utils.get_lesson_index",
|
||||
"lms.lms.utils.get_lesson_url",
|
||||
"lms.page_renderers.get_profile_url",
|
||||
"lms.overrides.user.get_palette",
|
||||
],
|
||||
"filters": [],
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user