feat: program restrictions
This commit is contained in:
@@ -99,6 +99,7 @@ import { getSidebarLinks } from '../utils'
|
||||
import { usersStore } from '@/stores/user'
|
||||
import { sessionStore } from '@/stores/session'
|
||||
import { useSidebar } from '@/stores/sidebar'
|
||||
import { useSettings } from '@/stores/settings'
|
||||
import { ChevronRight, Plus } from 'lucide-vue-next'
|
||||
import { createResource, Button } from 'frappe-ui'
|
||||
import PageModal from '@/components/Modals/PageModal.vue'
|
||||
@@ -114,6 +115,7 @@ const isModerator = ref(false)
|
||||
const isInstructor = ref(false)
|
||||
const pageToEdit = ref(null)
|
||||
const showWebPages = ref(false)
|
||||
const settingsStore = useSettings()
|
||||
|
||||
onMounted(() => {
|
||||
socket.on('publish_lms_notifications', (data) => {
|
||||
@@ -184,12 +186,23 @@ const addQuizzes = () => {
|
||||
}
|
||||
|
||||
const addPrograms = () => {
|
||||
if (isInstructor.value || isModerator.value) {
|
||||
sidebarLinks.value.push({
|
||||
if (settingsStore.learningPaths.data) {
|
||||
let activeFor = ['Programs', 'ProgramForm']
|
||||
let index = 1
|
||||
if (!isInstructor.value && !isModerator.value) {
|
||||
sidebarLinks.value = sidebarLinks.value.filter(
|
||||
(link) => link.label !== 'Courses'
|
||||
)
|
||||
activeFor.push('CourseDetail')
|
||||
activeFor.push('Lesson')
|
||||
index = 0
|
||||
}
|
||||
|
||||
sidebarLinks.value.splice(index, 0, {
|
||||
label: 'Programs',
|
||||
icon: 'Route',
|
||||
to: 'Programs',
|
||||
activeFor: ['Programs', 'ProgramForm'],
|
||||
activeFor: activeFor,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -303,9 +303,9 @@ const trashChapter = (chapterName) => {
|
||||
}
|
||||
|
||||
const redirectToChapter = (chapter) => {
|
||||
if (!chapter.is_scorm_package) return
|
||||
event.preventDefault()
|
||||
if (props.allowEdit) return
|
||||
if (!chapter.is_scorm_package) return
|
||||
if (!user.data) {
|
||||
showToast(
|
||||
__('You are not enrolled'),
|
||||
|
||||
@@ -397,6 +397,9 @@ const attempts = createResource({
|
||||
watch(
|
||||
() => quiz.data,
|
||||
() => {
|
||||
if (quiz.data) {
|
||||
populateQuestions()
|
||||
}
|
||||
if (quiz.data && quiz.data.max_attempts) {
|
||||
attempts.reload()
|
||||
resetQuiz()
|
||||
|
||||
@@ -173,12 +173,14 @@ import { BookOpen, Plus, Search } from 'lucide-vue-next'
|
||||
import { ref, computed, inject, onMounted, watch } from 'vue'
|
||||
import { updateDocumentTitle } from '@/utils'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { useSettings } from '@/stores/settings'
|
||||
|
||||
const user = inject('$user')
|
||||
const searchQuery = ref('')
|
||||
const currentCategory = ref(null)
|
||||
const hasCourses = ref(false)
|
||||
const router = useRouter()
|
||||
const settings = useSettings()
|
||||
|
||||
onMounted(() => {
|
||||
checkLearningPath()
|
||||
@@ -189,14 +191,12 @@ onMounted(() => {
|
||||
})
|
||||
|
||||
const checkLearningPath = () => {
|
||||
call('frappe.client.get_single_value', {
|
||||
doctype: 'LMS Settings',
|
||||
field: 'enable_learning_paths',
|
||||
}).then((res) => {
|
||||
if (res && !user.data?.is_moderator && !user.data?.is_instructor) {
|
||||
router.push({ name: 'Programs' })
|
||||
}
|
||||
})
|
||||
if (
|
||||
settings.learningPaths.data &&
|
||||
(!user.data?.is_moderator || !user.data?.is_instructor)
|
||||
) {
|
||||
router.push({ name: 'Programs' })
|
||||
}
|
||||
}
|
||||
|
||||
const courses = createResource({
|
||||
|
||||
@@ -211,8 +211,6 @@ const program = createDocumentResource({
|
||||
cache: ['program', props.programName],
|
||||
})
|
||||
|
||||
console.log(program)
|
||||
|
||||
const addProgramCourse = () => {
|
||||
program.setValue.submit(
|
||||
{
|
||||
@@ -288,7 +286,6 @@ const updateOrder = (e) => {
|
||||
course.idx = index + 1
|
||||
})
|
||||
|
||||
console.log(courses)
|
||||
program.setValue.submit(
|
||||
{
|
||||
program_courses: courses,
|
||||
|
||||
@@ -15,15 +15,27 @@
|
||||
</Button>
|
||||
</header>
|
||||
<div v-if="programs.data?.length" class="pt-5 px-5">
|
||||
<div v-for="program in programs.data" class="mb-10">
|
||||
<div v-for="program in programs.data" class="mb-20">
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="text-xl font-semibold">
|
||||
{{ program.name }}
|
||||
</div>
|
||||
<div class="flex items-center space-x-2">
|
||||
<Badge v-if="program.members" variant="subtle" theme="green">
|
||||
{{ program.members }} {{ __('Members') }}
|
||||
<Badge
|
||||
v-if="program.members"
|
||||
variant="subtle"
|
||||
theme="green"
|
||||
size="lg"
|
||||
>
|
||||
{{ program.members }}
|
||||
{{
|
||||
program.members == 1 ? __(singularize('members')) : __('members')
|
||||
}}
|
||||
</Badge>
|
||||
<Badge variant="subtle" theme="blue" size="lg">
|
||||
{{ program.progress }}{{ __('% completed') }}
|
||||
</Badge>
|
||||
|
||||
<router-link
|
||||
v-if="user.data?.is_moderator || user.data?.is_instructor"
|
||||
:to="{
|
||||
@@ -44,35 +56,12 @@
|
||||
v-if="program.courses?.length"
|
||||
class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-5 mt-5"
|
||||
>
|
||||
<router-link
|
||||
<CourseCard
|
||||
v-for="course in program.courses"
|
||||
:to="
|
||||
course.membership && course.current_lesson
|
||||
? {
|
||||
name: 'Lesson',
|
||||
params: {
|
||||
courseName: course.name,
|
||||
chapterNumber: course.current_lesson.split('-')[0],
|
||||
lessonNumber: course.current_lesson.split('-')[1],
|
||||
},
|
||||
}
|
||||
: course.membership
|
||||
? {
|
||||
name: 'Lesson',
|
||||
params: {
|
||||
courseName: course.name,
|
||||
chapterNumber: 1,
|
||||
lessonNumber: 1,
|
||||
},
|
||||
}
|
||||
: {
|
||||
name: 'CourseDetail',
|
||||
params: { courseName: course.name },
|
||||
}
|
||||
"
|
||||
>
|
||||
<CourseCard :course="course" />
|
||||
</router-link>
|
||||
:course="course"
|
||||
@click="enrollMember(program.name, course.name)"
|
||||
class="cursor-pointer"
|
||||
/>
|
||||
</div>
|
||||
<div v-else class="text-sm italic text-gray-600 mt-4">
|
||||
{{ __('No courses in this program') }}
|
||||
@@ -128,6 +117,7 @@ import { computed, inject, ref } from 'vue'
|
||||
import { BookOpen, Edit, Plus } from 'lucide-vue-next'
|
||||
import CourseCard from '@/components/CourseCard.vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { showToast, singularize } from '@/utils'
|
||||
|
||||
const user = inject('$user')
|
||||
const showDialog = ref(false)
|
||||
@@ -140,8 +130,6 @@ const programs = createResource({
|
||||
cache: 'programs',
|
||||
})
|
||||
|
||||
console.log(programs)
|
||||
|
||||
const createProgram = (close) => {
|
||||
call('frappe.client.insert', {
|
||||
doc: {
|
||||
@@ -153,6 +141,37 @@ const createProgram = (close) => {
|
||||
})
|
||||
}
|
||||
|
||||
const enrollMember = (program, course) => {
|
||||
call('lms.lms.utils.enroll_in_program_course', {
|
||||
program: program,
|
||||
course: course,
|
||||
})
|
||||
.then((data) => {
|
||||
if (data.current_lesson) {
|
||||
router.push({
|
||||
name: 'Lesson',
|
||||
params: {
|
||||
courseName: course,
|
||||
chapterNumber: data.current_lesson.split('-')[0],
|
||||
lessonNumber: data.current_lesson.split('-')[1],
|
||||
},
|
||||
})
|
||||
} else if (data) {
|
||||
router.push({
|
||||
name: 'Lesson',
|
||||
params: {
|
||||
courseName: course,
|
||||
chapterNumber: 1,
|
||||
lessonNumber: 1,
|
||||
},
|
||||
})
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
showToast('Error', err.messages?.[0] || err, 'x')
|
||||
})
|
||||
}
|
||||
|
||||
const breadbrumbs = computed(() => [
|
||||
{
|
||||
label: 'Programs',
|
||||
|
||||
@@ -1,12 +1,25 @@
|
||||
import { defineStore } from 'pinia'
|
||||
import { ref } from 'vue'
|
||||
import { createResource } from 'frappe-ui'
|
||||
|
||||
export const useSettings = defineStore('settings', () => {
|
||||
const isSettingsOpen = ref(false)
|
||||
const activeTab = ref(null)
|
||||
const learningPaths = createResource({
|
||||
url: 'frappe.client.get_single_value',
|
||||
makeParams(values) {
|
||||
return {
|
||||
doctype: 'LMS Settings',
|
||||
field: 'enable_learning_paths',
|
||||
}
|
||||
},
|
||||
auto: true,
|
||||
cache: ['learningPaths'],
|
||||
})
|
||||
|
||||
return {
|
||||
isSettingsOpen,
|
||||
activeTab,
|
||||
learningPaths,
|
||||
}
|
||||
})
|
||||
|
||||
@@ -438,8 +438,6 @@ export function getSidebarLinks() {
|
||||
'Lesson',
|
||||
'CourseForm',
|
||||
'LessonForm',
|
||||
'Programs',
|
||||
'ProgramForm',
|
||||
],
|
||||
},
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user