Compare commits
59 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0b7ff1dff3 | ||
|
|
9ac4efe9dc | ||
|
|
e278e1ed35 | ||
|
|
9db203d74f | ||
|
|
c6366835d2 | ||
|
|
5e8ad81ff3 | ||
|
|
ac24a353b0 | ||
|
|
8a3c681a6f | ||
|
|
2da946236d | ||
|
|
d4641c9135 | ||
|
|
cf710d7be5 | ||
|
|
e56b8928f7 | ||
|
|
66121e6cce | ||
|
|
cd824631bb | ||
|
|
115b72f2f0 | ||
|
|
8d17b35160 | ||
|
|
4c21ce2caa | ||
|
|
0057467acf | ||
|
|
7048b22df0 | ||
|
|
ddc3352b4b | ||
|
|
060a2808de | ||
|
|
d8f8a8e559 | ||
|
|
c471d39ba8 | ||
|
|
55ec813f82 | ||
|
|
727f7b032c | ||
|
|
d1b613c0bb | ||
|
|
c3af65e535 | ||
|
|
d688d5cdd9 | ||
|
|
97543a43eb | ||
|
|
0e6df83961 | ||
|
|
6329d9c917 | ||
|
|
015e228304 | ||
|
|
a9f40d16f0 | ||
|
|
b8da14a32e | ||
|
|
a64b0f734a | ||
|
|
34ba2fb361 | ||
|
|
98ccb15796 | ||
|
|
6c06f7d19b | ||
|
|
86b129a25f | ||
|
|
6e8d4cd8e8 | ||
|
|
1b4622bdb2 | ||
|
|
58d51579e3 | ||
|
|
06706ea41b | ||
|
|
d634a0f784 | ||
|
|
a92159b811 | ||
|
|
7e1e37393c | ||
|
|
d2f9a2cea4 | ||
|
|
5111d83eee | ||
|
|
0dc77343c4 | ||
|
|
cec5913632 | ||
|
|
75d43a1563 | ||
|
|
8e1db293db | ||
|
|
08261c804f | ||
|
|
af838121d9 | ||
|
|
93b3eda05c | ||
|
|
740584d883 | ||
|
|
822603128d | ||
|
|
9dbe8fbb1f | ||
|
|
26f1e228a9 |
@@ -18,6 +18,7 @@
|
||||
"@editorjs/nested-list": "^1.4.2",
|
||||
"@editorjs/paragraph": "^2.11.3",
|
||||
"@editorjs/simple-image": "^1.6.0",
|
||||
"@editorjs/table": "^2.4.2",
|
||||
"ace-builds": "^1.36.2",
|
||||
"chart.js": "^4.4.1",
|
||||
"codemirror-editor-vue3": "^2.8.0",
|
||||
|
||||
@@ -186,18 +186,27 @@ const addQuizzes = () => {
|
||||
}
|
||||
|
||||
const addPrograms = () => {
|
||||
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
|
||||
}
|
||||
let activeFor = ['Programs', 'ProgramForm']
|
||||
let index = 1
|
||||
let canAddProgram = false
|
||||
|
||||
if (
|
||||
!isInstructor.value &&
|
||||
!isModerator.value &&
|
||||
settingsStore.learningPaths.data
|
||||
) {
|
||||
sidebarLinks.value = sidebarLinks.value.filter(
|
||||
(link) => link.label !== 'Courses'
|
||||
)
|
||||
activeFor.push('CourseDetail')
|
||||
activeFor.push('Lesson')
|
||||
index = 0
|
||||
canAddProgram = true
|
||||
} else if (isInstructor.value || isModerator.value) {
|
||||
canAddProgram = true
|
||||
}
|
||||
|
||||
if (canAddProgram) {
|
||||
sidebarLinks.value.splice(index, 0, {
|
||||
label: 'Programs',
|
||||
icon: 'Route',
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
<AppSidebar />
|
||||
</div>
|
||||
<div class="w-full overflow-auto" id="scrollContainer">
|
||||
<OnboardingBanner />
|
||||
<slot />
|
||||
</div>
|
||||
</div>
|
||||
@@ -17,5 +16,4 @@
|
||||
</template>
|
||||
<script setup>
|
||||
import AppSidebar from './AppSidebar.vue'
|
||||
import OnboardingBanner from '@/components/OnboardingBanner.vue'
|
||||
</script>
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
@click="openHelpDialog('upload')"
|
||||
>
|
||||
<span class="leading-5">
|
||||
{{ __('How to upload content from your system?') }}
|
||||
{{ __(contentMap['upload']) }}
|
||||
</span>
|
||||
<Info class="w-3 h-3 text-gray-700" />
|
||||
</div>
|
||||
@@ -44,7 +44,7 @@
|
||||
@click="openHelpDialog('youtube')"
|
||||
>
|
||||
<span>
|
||||
{{ __('How to add a YouTube Video?') }}
|
||||
{{ __(contentMap['youtube']) }}
|
||||
</span>
|
||||
<Info class="w-3 h-3 text-gray-700" />
|
||||
</div>
|
||||
@@ -72,7 +72,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<ExplanationVideos v-model="showExplanation" :type="type" />
|
||||
<ExplanationVideos v-model="showExplanation" :title="title" :type="type" />
|
||||
</template>
|
||||
<script setup>
|
||||
import { Info } from 'lucide-vue-next'
|
||||
@@ -81,9 +81,16 @@ import ExplanationVideos from '@/components/Modals/ExplanationVideos.vue'
|
||||
|
||||
const showExplanation = ref(false)
|
||||
const type = ref(null)
|
||||
const title = ref(null)
|
||||
const contentMap = {
|
||||
quiz: 'How to add a Quiz?',
|
||||
upload: 'How to upload content from your system?',
|
||||
youtube: 'How to add a YouTube Video?',
|
||||
}
|
||||
|
||||
const openHelpDialog = (contentType) => {
|
||||
type.value = contentType
|
||||
title.value = contentMap[contentType]
|
||||
showExplanation.value = true
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -3,10 +3,11 @@
|
||||
v-model="show"
|
||||
:options="{
|
||||
size: '4xl',
|
||||
title: title,
|
||||
}"
|
||||
>
|
||||
<template #body>
|
||||
<div class="p-4">
|
||||
<template #body-content>
|
||||
<div>
|
||||
<VideoBlock :file="file" />
|
||||
</div>
|
||||
</template>
|
||||
@@ -24,6 +25,10 @@ const props = defineProps({
|
||||
type: [String, null],
|
||||
required: true,
|
||||
},
|
||||
title: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
})
|
||||
|
||||
const file = computed(() => {
|
||||
|
||||
@@ -56,12 +56,14 @@
|
||||
type="select"
|
||||
:options="['Choices', 'User Input', 'Open Ended']"
|
||||
class="pb-2"
|
||||
:required="true"
|
||||
/>
|
||||
<div v-if="question.type == 'Choices'" class="divide-y border-t">
|
||||
<div v-for="n in 4" class="space-y-4 py-2">
|
||||
<FormControl
|
||||
:label="__('Option') + ' ' + n"
|
||||
v-model="question[`option_${n}`]"
|
||||
:required="n <= 2 ? true : false"
|
||||
/>
|
||||
<FormControl
|
||||
:label="__('Explanation')"
|
||||
@@ -82,6 +84,7 @@
|
||||
<FormControl
|
||||
:label="__('Possibility') + ' ' + n"
|
||||
v-model="question[`possibility_${n}`]"
|
||||
:required="n == 1 ? true : false"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -11,11 +11,11 @@
|
||||
@click="redirectToCourseForm()"
|
||||
class="flex items-center space-x-2"
|
||||
:class="{
|
||||
'cursor-pointer': !onboardingDetails.data.course_created.length,
|
||||
'cursor-pointer': !onboardingDetails.data.course_created?.length,
|
||||
}"
|
||||
>
|
||||
<span
|
||||
v-if="onboardingDetails.data.course_created.length"
|
||||
v-if="onboardingDetails.data.course_created?.length"
|
||||
class="py-1 px-1 bg-white rounded-full"
|
||||
>
|
||||
<Check class="h-4 w-4 stroke-2 text-green-600" />
|
||||
@@ -32,13 +32,13 @@
|
||||
class="flex items-center space-x-2"
|
||||
:class="{
|
||||
'cursor-pointer':
|
||||
onboardingDetails.data.course_created.length &&
|
||||
!onboardingDetails.data.chapter_created.length,
|
||||
'text-gray-400': !onboardingDetails.data.course_created.length,
|
||||
onboardingDetails.data.course_created?.length &&
|
||||
!onboardingDetails.data.chapter_created?.length,
|
||||
'text-gray-400': !onboardingDetails.data.course_created?.length,
|
||||
}"
|
||||
>
|
||||
<span
|
||||
v-if="onboardingDetails.data.chapter_created.length"
|
||||
v-if="onboardingDetails.data.chapter_created?.length"
|
||||
class="py-1 px-1 bg-white rounded-full"
|
||||
>
|
||||
<Check class="h-4 w-4 stroke-2 text-green-600" />
|
||||
@@ -55,15 +55,15 @@
|
||||
class="flex items-center space-x-2"
|
||||
:class="{
|
||||
'cursor-pointer':
|
||||
onboardingDetails.data.course_created.length &&
|
||||
onboardingDetails.data.chapter_created.length,
|
||||
onboardingDetails.data.course_created?.length &&
|
||||
onboardingDetails.data.chapter_created?.length,
|
||||
'text-gray-400':
|
||||
!onboardingDetails.data.course_created.length ||
|
||||
!onboardingDetails.data.chapter_created.length,
|
||||
!onboardingDetails.data.course_created?.length ||
|
||||
!onboardingDetails.data.chapter_created?.length,
|
||||
}"
|
||||
>
|
||||
<span
|
||||
v-if="onboardingDetails.data.lesson_created.length"
|
||||
v-if="onboardingDetails.data.lesson_created?.length"
|
||||
class="py-1 px-1 bg-white rounded-full"
|
||||
>
|
||||
<Check class="h-4 w-4 stroke-2 text-green-600" />
|
||||
|
||||
@@ -19,8 +19,13 @@
|
||||
v-model="job.job_title"
|
||||
:label="__('Title')"
|
||||
class="mb-4"
|
||||
:required="true"
|
||||
/>
|
||||
<FormControl
|
||||
v-model="job.location"
|
||||
:label="__('Location')"
|
||||
:required="true"
|
||||
/>
|
||||
<FormControl v-model="job.location" :label="__('Location')" />
|
||||
</div>
|
||||
<div>
|
||||
<FormControl
|
||||
@@ -29,18 +34,21 @@
|
||||
type="select"
|
||||
:options="jobTypes"
|
||||
class="mb-4"
|
||||
:required="true"
|
||||
/>
|
||||
<FormControl
|
||||
v-model="job.status"
|
||||
:label="__('Status')"
|
||||
type="select"
|
||||
:options="jobStatuses"
|
||||
:required="true"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-4">
|
||||
<label class="block text-gray-600 text-xs mb-1">
|
||||
{{ __('Description') }}
|
||||
<span class="text-red-500">*</span>
|
||||
</label>
|
||||
<TextEditor
|
||||
:content="job.description"
|
||||
@@ -61,10 +69,12 @@
|
||||
v-model="job.company_name"
|
||||
:label="__('Company Name')"
|
||||
class="mb-4"
|
||||
:required="true"
|
||||
/>
|
||||
<FormControl
|
||||
v-model="job.company_website"
|
||||
:label="__('Company Website')"
|
||||
:required="true"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
@@ -72,9 +82,11 @@
|
||||
v-model="job.company_email_address"
|
||||
:label="__('Company Email Address')"
|
||||
class="mb-4"
|
||||
:required="true"
|
||||
/>
|
||||
<label class="block text-gray-600 text-xs mb-1 mt-4">
|
||||
{{ __('Company Logo') }}
|
||||
<span class="text-red-500">*</span>
|
||||
</label>
|
||||
<FileUploader
|
||||
v-if="!job.image"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
class="sticky top-0 z-10 flex flex-col md:flex-row md:items-center justify-between border-b bg-white px-3 py-2.5 sm:px-5"
|
||||
>
|
||||
<Breadcrumbs :items="breadbrumbs" />
|
||||
<Button variant="solid">
|
||||
<Button variant="solid" @click="saveProgram()">
|
||||
{{ __('Save') }}
|
||||
</Button>
|
||||
</header>
|
||||
@@ -50,6 +50,7 @@
|
||||
item-key="name"
|
||||
group="items"
|
||||
@end="updateOrder"
|
||||
class="cursor-move"
|
||||
>
|
||||
<template #item="{ element: row }">
|
||||
<ListRow :row="row" />
|
||||
@@ -191,11 +192,13 @@ import { Plus, Trash2 } from 'lucide-vue-next'
|
||||
import Link from '@/components/Controls/Link.vue'
|
||||
import { showToast } from '@/utils/'
|
||||
import Draggable from 'vuedraggable'
|
||||
import { useRouter } from 'vue-router'
|
||||
|
||||
const showDialog = ref(false)
|
||||
const currentForm = ref(null)
|
||||
const course = ref(null)
|
||||
const member = ref(null)
|
||||
const router = useRouter()
|
||||
|
||||
const props = defineProps({
|
||||
programName: {
|
||||
@@ -302,6 +305,16 @@ const updateOrder = (e) => {
|
||||
)
|
||||
}
|
||||
|
||||
const saveProgram = () => {
|
||||
call('frappe.model.rename_doc.update_document_title', {
|
||||
doctype: 'LMS Program',
|
||||
docname: program.doc.name,
|
||||
name: program.doc.title,
|
||||
}).then((data) => {
|
||||
router.push({ name: 'ProgramForm', params: { programName: data } })
|
||||
})
|
||||
}
|
||||
|
||||
const courseColumns = computed(() => {
|
||||
return [
|
||||
{
|
||||
@@ -332,10 +345,10 @@ const memberColumns = computed(() => {
|
||||
align: 'left',
|
||||
},
|
||||
{
|
||||
label: 'Progress',
|
||||
label: 'Progress (%)',
|
||||
key: 'progress',
|
||||
width: 3,
|
||||
align: 'left',
|
||||
align: 'right',
|
||||
},
|
||||
]
|
||||
})
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
</Button>
|
||||
</header>
|
||||
<div v-if="programs.data?.length" class="pt-5 px-5">
|
||||
<div v-for="program in programs.data" class="mb-20">
|
||||
<div v-for="program in programs.data" class="mb-10">
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="text-xl font-semibold">
|
||||
{{ program.name }}
|
||||
@@ -61,12 +61,23 @@
|
||||
v-if="program.courses?.length"
|
||||
class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-5 mt-5"
|
||||
>
|
||||
<CourseCard
|
||||
v-for="course in program.courses"
|
||||
:course="course"
|
||||
@click="enrollMember(program.name, course.name)"
|
||||
class="cursor-pointer"
|
||||
/>
|
||||
<div v-for="course in program.courses" class="relative group">
|
||||
<CourseCard
|
||||
:course="course"
|
||||
@click="enrollMember(program.name, course.name)"
|
||||
class="cursor-pointer"
|
||||
/>
|
||||
<div
|
||||
v-if="lockCourse(course)"
|
||||
class="absolute inset-0 bg-black-overlay-500 opacity-60 rounded-md"
|
||||
></div>
|
||||
<div
|
||||
v-if="lockCourse(course)"
|
||||
class="absolute inset-0 flex items-center justify-center"
|
||||
>
|
||||
<LockKeyhole class="size-10 text-white" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="text-sm italic text-gray-600 mt-4">
|
||||
{{ __('No courses in this program') }}
|
||||
@@ -118,16 +129,28 @@ import {
|
||||
Dialog,
|
||||
FormControl,
|
||||
} from 'frappe-ui'
|
||||
import { computed, inject, ref } from 'vue'
|
||||
import { BookOpen, Edit, Plus } from 'lucide-vue-next'
|
||||
import { computed, inject, onMounted, ref } from 'vue'
|
||||
import { BookOpen, Edit, Plus, LockKeyhole } from 'lucide-vue-next'
|
||||
import CourseCard from '@/components/CourseCard.vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { showToast, singularize } from '@/utils'
|
||||
import { useSettings } from '@/stores/settings'
|
||||
|
||||
const user = inject('$user')
|
||||
const showDialog = ref(false)
|
||||
const router = useRouter()
|
||||
const title = ref('')
|
||||
const settings = useSettings()
|
||||
|
||||
onMounted(() => {
|
||||
if (
|
||||
!settings.learningPaths.data &&
|
||||
!user.data?.is_moderator &&
|
||||
!user.data?.is_instructor
|
||||
) {
|
||||
router.push({ name: 'Courses' })
|
||||
}
|
||||
})
|
||||
|
||||
const programs = createResource({
|
||||
url: 'lms.lms.utils.get_programs',
|
||||
@@ -177,6 +200,13 @@ const enrollMember = (program, course) => {
|
||||
})
|
||||
}
|
||||
|
||||
const lockCourse = (course) => {
|
||||
if (user.data?.is_moderator || user.data?.is_instructor) return false
|
||||
if (course.membership) return false
|
||||
if (course.eligible) return false
|
||||
return true
|
||||
}
|
||||
|
||||
const breadbrumbs = computed(() => [
|
||||
{
|
||||
label: 'Programs',
|
||||
|
||||
@@ -48,6 +48,7 @@
|
||||
? __('Title')
|
||||
: __('Enter a title and save the quiz to proceed')
|
||||
"
|
||||
:required="true"
|
||||
/>
|
||||
<div v-if="quizDetails.data?.name">
|
||||
<div class="grid grid-cols-2 gap-5 mt-4 mb-8">
|
||||
@@ -205,7 +206,6 @@ import {
|
||||
inject,
|
||||
onBeforeUnmount,
|
||||
watch,
|
||||
isReactive,
|
||||
} from 'vue'
|
||||
import { Plus, Trash2 } from 'lucide-vue-next'
|
||||
import Question from '@/components/Modals/Question.vue'
|
||||
|
||||
@@ -15,38 +15,45 @@
|
||||
</Button>
|
||||
</div>
|
||||
</header>
|
||||
<div v-if="submisisonDetails.doc" class="w-1/2 mx-auto py-5 space-y-4">
|
||||
<div class="grid grid-cols-2 gap-5">
|
||||
<FormControl
|
||||
v-model="submisisonDetails.doc.quiz_title"
|
||||
:label="__('Quiz')"
|
||||
:disabled="true"
|
||||
/>
|
||||
<FormControl
|
||||
v-model="submisisonDetails.doc.member_name"
|
||||
:label="__('Member')"
|
||||
:disabled="true"
|
||||
/>
|
||||
<div v-if="submisisonDetails.doc" class="w-1/2 mx-auto py-5 space-y-5">
|
||||
<div class="text-xl font-semibold">
|
||||
{{ submisisonDetails.doc.member_name }}
|
||||
</div>
|
||||
<div class="space-y-4 border p-5 rounded-md">
|
||||
<div class="grid grid-cols-2 gap-5">
|
||||
<FormControl
|
||||
v-model="submisisonDetails.doc.quiz_title"
|
||||
:label="__('Quiz')"
|
||||
:disabled="true"
|
||||
/>
|
||||
<FormControl
|
||||
v-model="submisisonDetails.doc.member_name"
|
||||
:label="__('Member')"
|
||||
:disabled="true"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-2 gap-5">
|
||||
<FormControl
|
||||
v-model="submisisonDetails.doc.score"
|
||||
:label="__('Score')"
|
||||
:disabled="true"
|
||||
/>
|
||||
<FormControl
|
||||
v-model="submisisonDetails.doc.percentage"
|
||||
:label="__('Percentage')"
|
||||
:disabled="true"
|
||||
/>
|
||||
<div class="grid grid-cols-2 gap-5">
|
||||
<FormControl
|
||||
v-model="submisisonDetails.doc.score"
|
||||
:label="__('Score')"
|
||||
:disabled="true"
|
||||
/>
|
||||
<FormControl
|
||||
v-model="submisisonDetails.doc.percentage"
|
||||
:label="__('Percentage')"
|
||||
:disabled="true"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-for="row in submisisonDetails.doc.result"
|
||||
class="border p-5 rounded-md space-y-4"
|
||||
>
|
||||
<div class="font-semibold">{{ row.idx }}. {{ row.question }}</div>
|
||||
<div class="flex space-x-1 font-semibold">
|
||||
<span class="leading-5" v-html="row.question"> </span>
|
||||
</div>
|
||||
<div v-html="row.answer" class="leading-5"></div>
|
||||
<div class="grid grid-cols-2 gap-5">
|
||||
<FormControl v-model="row.marks" :label="__('Marks')" />
|
||||
@@ -67,7 +74,7 @@ import {
|
||||
Button,
|
||||
Badge,
|
||||
} from 'frappe-ui'
|
||||
import { computed, onMounted, inject } from 'vue'
|
||||
import { computed, onBeforeUnmount, onMounted, inject } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { showToast } from '@/utils'
|
||||
|
||||
@@ -77,8 +84,25 @@ const user = inject('$user')
|
||||
onMounted(() => {
|
||||
if (!user.data?.is_instructor && !user.data?.is_moderator)
|
||||
router.push({ name: 'Courses' })
|
||||
|
||||
window.addEventListener('keydown', keyboardShortcut)
|
||||
})
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
window.removeEventListener('keydown', keyboardShortcut)
|
||||
})
|
||||
|
||||
const keyboardShortcut = (e) => {
|
||||
if (
|
||||
e.key === 's' &&
|
||||
(e.ctrlKey || e.metaKey) &&
|
||||
!e.target.classList.contains('ProseMirror')
|
||||
) {
|
||||
saveSubmission()
|
||||
e.preventDefault()
|
||||
}
|
||||
}
|
||||
|
||||
const props = defineProps({
|
||||
submission: {
|
||||
type: String,
|
||||
|
||||
@@ -11,6 +11,7 @@ import { watch } from 'vue'
|
||||
import dayjs from '@/utils/dayjs'
|
||||
import Embed from '@editorjs/embed'
|
||||
import SimpleImage from '@editorjs/simple-image'
|
||||
import Table from '@editorjs/table'
|
||||
|
||||
export function createToast(options) {
|
||||
toast({
|
||||
@@ -150,6 +151,7 @@ export function getEditorTools() {
|
||||
quiz: Quiz,
|
||||
upload: Upload,
|
||||
image: SimpleImage,
|
||||
table: Table,
|
||||
paragraph: {
|
||||
class: Paragraph,
|
||||
inlineToolbar: true,
|
||||
|
||||
@@ -60,6 +60,9 @@ export class Quiz {
|
||||
}
|
||||
|
||||
renderQuizModal() {
|
||||
if (this.readOnly) {
|
||||
return
|
||||
}
|
||||
const app = createApp(QuizPlugin, {
|
||||
onQuizAddition: (quiz) => {
|
||||
this.data.quiz = quiz
|
||||
|
||||
@@ -120,6 +120,13 @@
|
||||
dependencies:
|
||||
"@codexteam/icons" "^0.0.6"
|
||||
|
||||
"@editorjs/table@^2.4.2":
|
||||
version "2.4.2"
|
||||
resolved "https://registry.yarnpkg.com/@editorjs/table/-/table-2.4.2.tgz#99a2b3f9ea8f39c9ca4df80b8e63bff6e21d0193"
|
||||
integrity sha512-zGmwLCarsaTgOfccxR3Lc6oC3QTX0JdoK0O3+8TE/VCR/xnW92VO7rAcu4cqTwtbFMQErYl8id9a5hM23vyFng==
|
||||
dependencies:
|
||||
"@codexteam/icons" "^0.0.6"
|
||||
|
||||
"@esbuild/aix-ppc64@0.21.5":
|
||||
version "0.21.5"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz#c7184a326533fcdf1b8ee0733e21c713b975575f"
|
||||
|
||||
@@ -1 +1 @@
|
||||
__version__ = "2.13.0"
|
||||
__version__ = "2.15.0"
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
],
|
||||
"index_web_pages_for_search": 1,
|
||||
"links": [],
|
||||
"modified": "2024-11-20 12:26:02.214628",
|
||||
"modified": "2024-11-28 22:06:16.742867",
|
||||
"modified_by": "Administrator",
|
||||
"module": "LMS",
|
||||
"name": "LMS Program",
|
||||
@@ -80,5 +80,6 @@
|
||||
],
|
||||
"sort_field": "creation",
|
||||
"sort_order": "DESC",
|
||||
"states": []
|
||||
"states": [],
|
||||
"track_changes": 1
|
||||
}
|
||||
@@ -134,7 +134,6 @@ def quiz_summary(quiz, results):
|
||||
result["marks"] = marks
|
||||
score += marks
|
||||
|
||||
del result["question_name"]
|
||||
else:
|
||||
result["is_correct"] = 0
|
||||
is_open_ended = True
|
||||
|
||||
@@ -5,6 +5,7 @@ import frappe
|
||||
from frappe.model.document import Document
|
||||
from frappe.utils import cint
|
||||
from frappe import _
|
||||
from frappe.desk.doctype.notification_log.notification_log import make_notification_logs
|
||||
|
||||
|
||||
class LMSQuizSubmission(Document):
|
||||
@@ -12,6 +13,9 @@ class LMSQuizSubmission(Document):
|
||||
self.validate_marks()
|
||||
self.set_percentage()
|
||||
|
||||
def on_update(self):
|
||||
self.notify_member()
|
||||
|
||||
def validate_marks(self):
|
||||
for row in self.result:
|
||||
if cint(row.marks) > cint(row.marks_out_of):
|
||||
@@ -26,3 +30,24 @@ class LMSQuizSubmission(Document):
|
||||
def set_percentage(self):
|
||||
if self.score and self.score_out_of:
|
||||
self.percentage = (self.score / self.score_out_of) * 100
|
||||
|
||||
def notify_member(self):
|
||||
if self.score != 0 and self.has_value_changed("score"):
|
||||
notification = frappe._dict(
|
||||
{
|
||||
"subject": _("You have got a score of {0} for the quiz {1}").format(
|
||||
self.score, self.quiz_title
|
||||
),
|
||||
"email_content": _(
|
||||
"There has been an update on your submission. You have got a score of {0} for the quiz {1}"
|
||||
).format(self.score, self.quiz_title),
|
||||
"document_type": self.doctype,
|
||||
"document_name": self.name,
|
||||
"for_user": self.member,
|
||||
"from_user": "Administrator",
|
||||
"type": "Alert",
|
||||
"link": "",
|
||||
}
|
||||
)
|
||||
|
||||
make_notification_logs(notification, [self.member])
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
"""Handy module to make access to all doctypes from a single place.
|
||||
"""
|
||||
from .doctype.lms_enrollment.lms_enrollment import (
|
||||
LMSBatchMembership as Membership,
|
||||
)
|
||||
from .doctype.lms_course.lms_course import LMSCourse as Course
|
||||
@@ -1,5 +1,4 @@
|
||||
import frappe
|
||||
from payments.utils import get_payment_gateway_controller
|
||||
|
||||
|
||||
def get_payment_gateway():
|
||||
@@ -7,7 +6,10 @@ def get_payment_gateway():
|
||||
|
||||
|
||||
def get_controller(payment_gateway):
|
||||
return get_payment_gateway_controller(payment_gateway)
|
||||
if "payments" in frappe.get_installed_apps():
|
||||
from payments.utils import get_payment_gateway_controller
|
||||
|
||||
return get_payment_gateway_controller(payment_gateway)
|
||||
|
||||
|
||||
def validate_currency(payment_gateway, currency):
|
||||
|
||||
@@ -6,11 +6,7 @@ import razorpay
|
||||
import requests
|
||||
from frappe import _
|
||||
from frappe.desk.doctype.dashboard_chart.dashboard_chart import get_result
|
||||
from frappe.desk.doctype.notification_log.notification_log import (
|
||||
make_notification_logs,
|
||||
enqueue_create_notification,
|
||||
get_title,
|
||||
)
|
||||
from frappe.desk.doctype.notification_log.notification_log import make_notification_logs
|
||||
from frappe.desk.search import get_user_groups
|
||||
from frappe.desk.notifications import extract_mentions
|
||||
from frappe.utils import (
|
||||
@@ -858,7 +854,8 @@ def get_telemetry_boot_info():
|
||||
@frappe.whitelist()
|
||||
def is_onboarding_complete():
|
||||
if not has_course_moderator_role():
|
||||
return {"is_onboarded": False}
|
||||
return {"is_onboarded": True}
|
||||
|
||||
course_created = frappe.db.a_row_exists("LMS Course")
|
||||
chapter_created = frappe.db.a_row_exists("Course Chapter")
|
||||
lesson_created = frappe.db.a_row_exists("Course Lesson")
|
||||
@@ -1774,8 +1771,18 @@ def get_programs():
|
||||
"LMS Program Course", {"parent": program.name}, ["course"], order_by="idx"
|
||||
)
|
||||
program.courses = []
|
||||
for course in program_courses:
|
||||
program.courses.append(get_course_details(course.course))
|
||||
previous_progress = 0
|
||||
for i, course in enumerate(program_courses):
|
||||
details = get_course_details(course.course)
|
||||
if i == 0:
|
||||
details.eligible = True
|
||||
elif previous_progress == 100:
|
||||
details.eligible = True
|
||||
else:
|
||||
details.eligible = False
|
||||
|
||||
previous_progress = details.membership.progress if details.membership else 0
|
||||
program.courses.append(details)
|
||||
|
||||
program.members = frappe.db.count("LMS Program Member", {"parent": program.name})
|
||||
|
||||
|
||||
458
lms/locale/ar.po
458
lms/locale/ar.po
File diff suppressed because it is too large
Load Diff
458
lms/locale/bs.po
458
lms/locale/bs.po
File diff suppressed because it is too large
Load Diff
458
lms/locale/de.po
458
lms/locale/de.po
File diff suppressed because it is too large
Load Diff
458
lms/locale/eo.po
458
lms/locale/eo.po
File diff suppressed because it is too large
Load Diff
458
lms/locale/es.po
458
lms/locale/es.po
File diff suppressed because it is too large
Load Diff
466
lms/locale/fa.po
466
lms/locale/fa.po
File diff suppressed because it is too large
Load Diff
458
lms/locale/fr.po
458
lms/locale/fr.po
File diff suppressed because it is too large
Load Diff
458
lms/locale/hu.po
458
lms/locale/hu.po
File diff suppressed because it is too large
Load Diff
@@ -7,8 +7,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Frappe LMS VERSION\n"
|
||||
"Report-Msgid-Bugs-To: jannat@frappe.io\n"
|
||||
"POT-Creation-Date: 2024-11-22 16:05+0000\n"
|
||||
"PO-Revision-Date: 2024-11-22 16:05+0000\n"
|
||||
"POT-Creation-Date: 2024-11-29 16:04+0000\n"
|
||||
"PO-Revision-Date: 2024-11-29 16:04+0000\n"
|
||||
"Last-Translator: jannat@frappe.io\n"
|
||||
"Language-Team: jannat@frappe.io\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
@@ -103,7 +103,7 @@ msgstr ""
|
||||
#: frontend/src/components/Categories.vue:26
|
||||
#: frontend/src/components/LiveClass.vue:11
|
||||
#: frontend/src/components/Members.vue:43 frontend/src/pages/ProgramForm.vue:30
|
||||
#: frontend/src/pages/ProgramForm.vue:91 frontend/src/pages/ProgramForm.vue:136
|
||||
#: frontend/src/pages/ProgramForm.vue:92 frontend/src/pages/ProgramForm.vue:137
|
||||
msgid "Add"
|
||||
msgstr ""
|
||||
|
||||
@@ -145,8 +145,8 @@ msgstr ""
|
||||
msgid "Add a lesson"
|
||||
msgstr ""
|
||||
|
||||
#: frontend/src/components/Modals/Question.vue:141
|
||||
#: frontend/src/pages/QuizForm.vue:182
|
||||
#: frontend/src/components/Modals/Question.vue:144
|
||||
#: frontend/src/pages/QuizForm.vue:183
|
||||
msgid "Add a new question"
|
||||
msgstr ""
|
||||
|
||||
@@ -920,25 +920,25 @@ msgstr ""
|
||||
|
||||
#. Label of the company_details_section (Section Break) field in DocType 'Job
|
||||
#. Opportunity'
|
||||
#: frontend/src/pages/JobCreation.vue:56
|
||||
#: frontend/src/pages/JobCreation.vue:64
|
||||
#: lms/job/doctype/job_opportunity/job_opportunity.json
|
||||
msgid "Company Details"
|
||||
msgstr ""
|
||||
|
||||
#. Label of the company_email_address (Data) field in DocType 'Job Opportunity'
|
||||
#: frontend/src/pages/JobCreation.vue:73
|
||||
#: frontend/src/pages/JobCreation.vue:83
|
||||
#: lms/job/doctype/job_opportunity/job_opportunity.json
|
||||
msgid "Company Email Address"
|
||||
msgstr ""
|
||||
|
||||
#. Label of the company_logo (Attach Image) field in DocType 'Job Opportunity'
|
||||
#: frontend/src/pages/JobCreation.vue:77
|
||||
#: frontend/src/pages/JobCreation.vue:88
|
||||
#: lms/job/doctype/job_opportunity/job_opportunity.json
|
||||
msgid "Company Logo"
|
||||
msgstr ""
|
||||
|
||||
#. Label of the company_name (Data) field in DocType 'Job Opportunity'
|
||||
#: frontend/src/pages/JobCreation.vue:62
|
||||
#: frontend/src/pages/JobCreation.vue:70
|
||||
#: lms/job/doctype/job_opportunity/job_opportunity.json
|
||||
msgid "Company Name"
|
||||
msgstr ""
|
||||
@@ -949,7 +949,7 @@ msgid "Company Type"
|
||||
msgstr ""
|
||||
|
||||
#. Label of the company_website (Data) field in DocType 'Job Opportunity'
|
||||
#: frontend/src/pages/JobCreation.vue:67
|
||||
#: frontend/src/pages/JobCreation.vue:76
|
||||
#: lms/job/doctype/job_opportunity/job_opportunity.json
|
||||
msgid "Company Website"
|
||||
msgstr ""
|
||||
@@ -1023,7 +1023,7 @@ msgstr ""
|
||||
msgid "Contract"
|
||||
msgstr ""
|
||||
|
||||
#: lms/lms/utils.py:442
|
||||
#: lms/lms/utils.py:438
|
||||
msgid "Cookie Policy"
|
||||
msgstr ""
|
||||
|
||||
@@ -1045,7 +1045,7 @@ msgstr ""
|
||||
msgid "Correct"
|
||||
msgstr ""
|
||||
|
||||
#: frontend/src/components/Modals/Question.vue:71
|
||||
#: frontend/src/components/Modals/Question.vue:73
|
||||
msgid "Correct Answer"
|
||||
msgstr ""
|
||||
|
||||
@@ -1216,7 +1216,7 @@ msgstr ""
|
||||
msgid "Course Title"
|
||||
msgstr ""
|
||||
|
||||
#: frontend/src/pages/ProgramForm.vue:226
|
||||
#: frontend/src/pages/ProgramForm.vue:229
|
||||
msgid "Course added to program"
|
||||
msgstr ""
|
||||
|
||||
@@ -1228,7 +1228,7 @@ msgstr ""
|
||||
msgid "Course deleted successfully"
|
||||
msgstr ""
|
||||
|
||||
#: frontend/src/pages/ProgramForm.vue:295
|
||||
#: frontend/src/pages/ProgramForm.vue:298
|
||||
msgid "Course moved successfully"
|
||||
msgstr ""
|
||||
|
||||
@@ -1268,7 +1268,7 @@ msgid "Cover Image"
|
||||
msgstr ""
|
||||
|
||||
#: frontend/src/components/Modals/ChapterModal.vue:9
|
||||
#: frontend/src/pages/Programs.vue:99
|
||||
#: frontend/src/pages/Programs.vue:110
|
||||
msgid "Create"
|
||||
msgstr ""
|
||||
|
||||
@@ -1444,7 +1444,7 @@ msgstr ""
|
||||
#. Label of the description (Text) field in DocType 'LMS Live Class'
|
||||
#. Label of the description (Small Text) field in DocType 'Work Experience'
|
||||
#: frontend/src/components/Modals/LiveClassModal.vue:78
|
||||
#: frontend/src/pages/BatchForm.vue:96 frontend/src/pages/JobCreation.vue:43
|
||||
#: frontend/src/pages/BatchForm.vue:96 frontend/src/pages/JobCreation.vue:50
|
||||
#: lms/job/doctype/job_opportunity/job_opportunity.json
|
||||
#: lms/lms/doctype/certification/certification.json
|
||||
#: lms/lms/doctype/cohort/cohort.json
|
||||
@@ -1525,7 +1525,7 @@ msgstr ""
|
||||
msgid "Duration"
|
||||
msgstr ""
|
||||
|
||||
#: frontend/src/pages/QuizForm.vue:62
|
||||
#: frontend/src/pages/QuizForm.vue:63
|
||||
msgid "Duration (in minutes)"
|
||||
msgstr ""
|
||||
|
||||
@@ -1560,7 +1560,7 @@ msgstr ""
|
||||
msgid "Edit Profile"
|
||||
msgstr ""
|
||||
|
||||
#: frontend/src/pages/QuizForm.vue:181
|
||||
#: frontend/src/pages/QuizForm.vue:182
|
||||
msgid "Edit the question"
|
||||
msgstr ""
|
||||
|
||||
@@ -1691,7 +1691,7 @@ msgstr ""
|
||||
msgid "Enrollment Count"
|
||||
msgstr ""
|
||||
|
||||
#: lms/lms/utils.py:1705
|
||||
#: lms/lms/utils.py:1702
|
||||
msgid "Enrollment Failed"
|
||||
msgstr ""
|
||||
|
||||
@@ -1723,12 +1723,12 @@ msgstr ""
|
||||
#: frontend/src/components/Modals/ChapterModal.vue:159
|
||||
#: frontend/src/components/Modals/ChapterModal.vue:166
|
||||
#: frontend/src/components/Modals/ChapterModal.vue:202
|
||||
#: frontend/src/components/Modals/Question.vue:246
|
||||
#: frontend/src/components/Modals/Question.vue:266
|
||||
#: frontend/src/components/Modals/Question.vue:323
|
||||
#: frontend/src/components/Modals/Question.vue:249
|
||||
#: frontend/src/components/Modals/Question.vue:269
|
||||
#: frontend/src/components/Modals/Question.vue:326
|
||||
#: frontend/src/pages/Billing.vue:264 frontend/src/pages/QuizForm.vue:350
|
||||
#: frontend/src/pages/QuizForm.vue:365
|
||||
#: frontend/src/pages/QuizSubmission.vue:117
|
||||
#: frontend/src/pages/QuizSubmission.vue:141
|
||||
msgid "Error"
|
||||
msgstr ""
|
||||
|
||||
@@ -1856,7 +1856,7 @@ msgstr ""
|
||||
#. Label of the explanation_1 (Small Text) field in DocType 'LMS Question'
|
||||
#. Label of the explanation_3 (Small Text) field in DocType 'LMS Question'
|
||||
#. Label of the explanation_4 (Small Text) field in DocType 'LMS Question'
|
||||
#: frontend/src/components/Modals/Question.vue:67
|
||||
#: frontend/src/components/Modals/Question.vue:69
|
||||
#: lms/lms/doctype/lms_question/lms_question.json
|
||||
msgid "Explanation"
|
||||
msgstr ""
|
||||
@@ -2114,14 +2114,6 @@ msgstr ""
|
||||
msgid "How to add a Quiz?"
|
||||
msgstr ""
|
||||
|
||||
#: frontend/src/components/LessonHelp.vue:47
|
||||
msgid "How to add a YouTube Video?"
|
||||
msgstr ""
|
||||
|
||||
#: frontend/src/components/LessonHelp.vue:28
|
||||
msgid "How to upload content from your system?"
|
||||
msgstr ""
|
||||
|
||||
#. Label of the current (Check) field in DocType 'Work Experience'
|
||||
#: lms/lms/doctype/work_experience/work_experience.json
|
||||
msgid "I am currently working here"
|
||||
@@ -2200,7 +2192,7 @@ msgstr ""
|
||||
msgid "Image search powered by"
|
||||
msgstr ""
|
||||
|
||||
#: lms/lms/doctype/lms_quiz/lms_quiz.py:222
|
||||
#: lms/lms/doctype/lms_quiz/lms_quiz.py:221
|
||||
msgid "Image: Corrupted Data Stream"
|
||||
msgstr ""
|
||||
|
||||
@@ -2386,7 +2378,7 @@ msgstr ""
|
||||
msgid "Items in Sidebar"
|
||||
msgstr ""
|
||||
|
||||
#: frontend/src/pages/ProgramForm.vue:269
|
||||
#: frontend/src/pages/ProgramForm.vue:272
|
||||
msgid "Items removed successfully"
|
||||
msgstr ""
|
||||
|
||||
@@ -2755,7 +2747,7 @@ msgid "Letter Grade (e.g. A, B-)"
|
||||
msgstr ""
|
||||
|
||||
#. Label of the limit_questions_to (Int) field in DocType 'LMS Quiz'
|
||||
#: frontend/src/pages/QuizForm.vue:107 lms/lms/doctype/lms_quiz/lms_quiz.json
|
||||
#: frontend/src/pages/QuizForm.vue:108 lms/lms/doctype/lms_quiz/lms_quiz.json
|
||||
msgid "Limit Questions To"
|
||||
msgstr ""
|
||||
|
||||
@@ -2815,7 +2807,7 @@ msgstr ""
|
||||
#. Label of the location (Data) field in DocType 'Job Opportunity'
|
||||
#. Label of the location (Data) field in DocType 'Education Detail'
|
||||
#. Label of the location (Data) field in DocType 'Work Experience'
|
||||
#: frontend/src/pages/JobCreation.vue:23 frontend/src/pages/JobDetail.vue:89
|
||||
#: frontend/src/pages/JobCreation.vue:26 frontend/src/pages/JobDetail.vue:89
|
||||
#: lms/job/doctype/job_opportunity/job_opportunity.json
|
||||
#: lms/lms/doctype/education_detail/education_detail.json
|
||||
#: lms/lms/doctype/work_experience/work_experience.json
|
||||
@@ -2885,21 +2877,21 @@ msgstr ""
|
||||
#. Label of the marks (Int) field in DocType 'LMS Quiz Question'
|
||||
#. Label of the marks (Int) field in DocType 'LMS Quiz Result'
|
||||
#: frontend/src/components/Modals/Question.vue:50
|
||||
#: frontend/src/components/Modals/Question.vue:96
|
||||
#: frontend/src/components/Modals/Question.vue:99
|
||||
#: frontend/src/components/Quiz.vue:94 frontend/src/pages/QuizForm.vue:394
|
||||
#: frontend/src/pages/QuizSubmission.vue:52
|
||||
#: frontend/src/pages/QuizSubmission.vue:59
|
||||
#: lms/lms/doctype/lms_quiz_question/lms_quiz_question.json
|
||||
#: lms/lms/doctype/lms_quiz_result/lms_quiz_result.json
|
||||
#: lms/templates/quiz/quiz.html:59
|
||||
msgid "Marks"
|
||||
msgstr ""
|
||||
|
||||
#: lms/lms/doctype/lms_quiz_submission/lms_quiz_submission.py:19
|
||||
#: lms/lms/doctype/lms_quiz_submission/lms_quiz_submission.py:23
|
||||
msgid "Marks for question number {0} cannot be greater than the marks allotted for that question."
|
||||
msgstr ""
|
||||
|
||||
#. Label of the marks_out_of (Int) field in DocType 'LMS Quiz Result'
|
||||
#: frontend/src/pages/QuizSubmission.vue:55
|
||||
#: frontend/src/pages/QuizSubmission.vue:62
|
||||
#: lms/lms/doctype/lms_quiz_result/lms_quiz_result.json
|
||||
msgid "Marks out of"
|
||||
msgstr ""
|
||||
@@ -2909,7 +2901,7 @@ msgstr ""
|
||||
msgid "Max Attempts"
|
||||
msgstr ""
|
||||
|
||||
#: frontend/src/pages/QuizForm.vue:57
|
||||
#: frontend/src/pages/QuizForm.vue:58
|
||||
msgid "Maximun Attempts"
|
||||
msgstr ""
|
||||
|
||||
@@ -2943,7 +2935,7 @@ msgstr ""
|
||||
#. Label of the member (Link) field in DocType 'LMS Payment'
|
||||
#. Label of the member (Link) field in DocType 'LMS Program Member'
|
||||
#. Label of the member (Link) field in DocType 'LMS Quiz Submission'
|
||||
#: frontend/src/pages/QuizSubmission.vue:27
|
||||
#: frontend/src/pages/QuizSubmission.vue:31
|
||||
#: frontend/src/pages/QuizSubmissionList.vue:77
|
||||
#: lms/lms/doctype/exercise_latest_submission/exercise_latest_submission.json
|
||||
#: lms/lms/doctype/exercise_submission/exercise_submission.json
|
||||
@@ -3006,7 +2998,7 @@ msgstr ""
|
||||
msgid "Member Type"
|
||||
msgstr ""
|
||||
|
||||
#: frontend/src/pages/ProgramForm.vue:248
|
||||
#: frontend/src/pages/ProgramForm.vue:251
|
||||
msgid "Member added to program"
|
||||
msgstr ""
|
||||
|
||||
@@ -3171,19 +3163,19 @@ msgstr ""
|
||||
msgid "New Job Applicant"
|
||||
msgstr ""
|
||||
|
||||
#: frontend/src/pages/Programs.vue:96
|
||||
#: frontend/src/pages/Programs.vue:107
|
||||
msgid "New Program"
|
||||
msgstr ""
|
||||
|
||||
#: frontend/src/pages/ProgramForm.vue:132
|
||||
#: frontend/src/pages/ProgramForm.vue:133
|
||||
msgid "New Program Course"
|
||||
msgstr ""
|
||||
|
||||
#: frontend/src/pages/ProgramForm.vue:133
|
||||
#: frontend/src/pages/ProgramForm.vue:134
|
||||
msgid "New Program Member"
|
||||
msgstr ""
|
||||
|
||||
#: frontend/src/pages/QuizForm.vue:122
|
||||
#: frontend/src/pages/QuizForm.vue:123
|
||||
msgid "New Question"
|
||||
msgstr ""
|
||||
|
||||
@@ -3196,11 +3188,11 @@ msgstr ""
|
||||
msgid "New Sign Up"
|
||||
msgstr ""
|
||||
|
||||
#: lms/lms/utils.py:627
|
||||
#: lms/lms/utils.py:623
|
||||
msgid "New comment in batch {0}"
|
||||
msgstr ""
|
||||
|
||||
#: lms/lms/utils.py:620
|
||||
#: lms/lms/utils.py:616
|
||||
msgid "New reply on the topic {0} in course {1}"
|
||||
msgstr ""
|
||||
|
||||
@@ -3254,7 +3246,7 @@ msgstr ""
|
||||
msgid "No courses found"
|
||||
msgstr ""
|
||||
|
||||
#: frontend/src/pages/Programs.vue:72
|
||||
#: frontend/src/pages/Programs.vue:83
|
||||
msgid "No courses in this program"
|
||||
msgstr ""
|
||||
|
||||
@@ -3274,7 +3266,7 @@ msgstr ""
|
||||
msgid "No live classes scheduled"
|
||||
msgstr ""
|
||||
|
||||
#: frontend/src/pages/Programs.vue:82
|
||||
#: frontend/src/pages/Programs.vue:93
|
||||
msgid "No programs found"
|
||||
msgstr ""
|
||||
|
||||
@@ -3386,7 +3378,7 @@ msgstr ""
|
||||
msgid "Online"
|
||||
msgstr ""
|
||||
|
||||
#: frontend/src/pages/ProgramForm.vue:156
|
||||
#: frontend/src/pages/ProgramForm.vue:157
|
||||
msgid "Only courses for which self learning is disabled can be added to program."
|
||||
msgstr ""
|
||||
|
||||
@@ -3394,7 +3386,7 @@ msgstr ""
|
||||
msgid "Only files of type {0} will be accepted."
|
||||
msgstr ""
|
||||
|
||||
#: frontend/src/pages/CourseForm.vue:497 frontend/src/utils/index.js:518
|
||||
#: frontend/src/pages/CourseForm.vue:497 frontend/src/utils/index.js:520
|
||||
msgid "Only image file is allowed."
|
||||
msgstr ""
|
||||
|
||||
@@ -3430,7 +3422,7 @@ msgid "Open Network"
|
||||
msgstr ""
|
||||
|
||||
#. Label of the option (Data) field in DocType 'LMS Option'
|
||||
#: frontend/src/components/Modals/Question.vue:63
|
||||
#: frontend/src/components/Modals/Question.vue:64
|
||||
#: lms/lms/doctype/lms_option/lms_option.json
|
||||
msgid "Option"
|
||||
msgstr ""
|
||||
@@ -3545,7 +3537,7 @@ msgstr ""
|
||||
|
||||
#. Label of the passing_percentage (Int) field in DocType 'LMS Quiz'
|
||||
#. Label of the passing_percentage (Int) field in DocType 'LMS Quiz Submission'
|
||||
#: frontend/src/pages/QuizForm.vue:71 frontend/src/pages/Quizzes.vue:125
|
||||
#: frontend/src/pages/QuizForm.vue:72 frontend/src/pages/Quizzes.vue:125
|
||||
#: lms/lms/doctype/lms_quiz/lms_quiz.json
|
||||
#: lms/lms/doctype/lms_quiz_submission/lms_quiz_submission.json
|
||||
msgid "Passing Percentage"
|
||||
@@ -3639,7 +3631,7 @@ msgid "Pending"
|
||||
msgstr ""
|
||||
|
||||
#. Label of the percentage (Int) field in DocType 'LMS Quiz Submission'
|
||||
#: frontend/src/pages/QuizSubmission.vue:40
|
||||
#: frontend/src/pages/QuizSubmission.vue:44
|
||||
#: frontend/src/pages/QuizSubmissionList.vue:93
|
||||
#: lms/lms/doctype/lms_quiz_submission/lms_quiz_submission.json
|
||||
msgid "Percentage"
|
||||
@@ -3674,7 +3666,7 @@ msgstr ""
|
||||
msgid "Please click on the following button to set your new password"
|
||||
msgstr ""
|
||||
|
||||
#: lms/lms/utils.py:1817 lms/lms/utils.py:1821
|
||||
#: lms/lms/utils.py:1824 lms/lms/utils.py:1828
|
||||
msgid "Please complete the previous courses in the program to enroll in this course."
|
||||
msgstr ""
|
||||
|
||||
@@ -3777,7 +3769,7 @@ msgstr ""
|
||||
msgid "Point of Score (e.g. 70)"
|
||||
msgstr ""
|
||||
|
||||
#: frontend/src/components/Modals/Question.vue:83
|
||||
#: frontend/src/components/Modals/Question.vue:85
|
||||
msgid "Possibility"
|
||||
msgstr ""
|
||||
|
||||
@@ -3873,7 +3865,7 @@ msgstr ""
|
||||
msgid "Primary Subgroup"
|
||||
msgstr ""
|
||||
|
||||
#: lms/lms/utils.py:441
|
||||
#: lms/lms/utils.py:437
|
||||
msgid "Privacy Policy"
|
||||
msgstr ""
|
||||
|
||||
@@ -3901,7 +3893,7 @@ msgstr ""
|
||||
msgid "Profile Image"
|
||||
msgstr ""
|
||||
|
||||
#: frontend/src/pages/ProgramForm.vue:154
|
||||
#: frontend/src/pages/ProgramForm.vue:155
|
||||
msgid "Program Course"
|
||||
msgstr ""
|
||||
|
||||
@@ -3911,12 +3903,12 @@ msgstr ""
|
||||
msgid "Program Courses"
|
||||
msgstr ""
|
||||
|
||||
#: frontend/src/pages/ProgramForm.vue:169
|
||||
#: frontend/src/pages/ProgramForm.vue:170
|
||||
msgid "Program Member"
|
||||
msgstr ""
|
||||
|
||||
#. Label of the program_members (Table) field in DocType 'LMS Program'
|
||||
#: frontend/src/pages/ProgramForm.vue:78
|
||||
#: frontend/src/pages/ProgramForm.vue:79
|
||||
#: lms/lms/doctype/lms_program/lms_program.json
|
||||
msgid "Program Members"
|
||||
msgstr ""
|
||||
@@ -3999,11 +3991,11 @@ msgstr ""
|
||||
msgid "Question Name"
|
||||
msgstr ""
|
||||
|
||||
#: frontend/src/components/Modals/Question.vue:261
|
||||
#: frontend/src/components/Modals/Question.vue:264
|
||||
msgid "Question added successfully"
|
||||
msgstr ""
|
||||
|
||||
#: frontend/src/components/Modals/Question.vue:313
|
||||
#: frontend/src/components/Modals/Question.vue:316
|
||||
msgid "Question updated successfully"
|
||||
msgstr ""
|
||||
|
||||
@@ -4016,7 +4008,7 @@ msgid "Question {0} of {1}"
|
||||
msgstr ""
|
||||
|
||||
#. Label of the questions (Table) field in DocType 'LMS Quiz'
|
||||
#: frontend/src/pages/QuizForm.vue:116 lms/lms/doctype/lms_quiz/lms_quiz.json
|
||||
#: frontend/src/pages/QuizForm.vue:117 lms/lms/doctype/lms_quiz/lms_quiz.json
|
||||
msgid "Questions"
|
||||
msgstr ""
|
||||
|
||||
@@ -4026,7 +4018,7 @@ msgstr ""
|
||||
|
||||
#. Label of the quiz (Link) field in DocType 'LMS Quiz Submission'
|
||||
#. Label of a Link in the LMS Workspace
|
||||
#: frontend/src/pages/QuizSubmission.vue:22
|
||||
#: frontend/src/pages/QuizSubmission.vue:26
|
||||
#: frontend/src/pages/QuizSubmissionList.vue:82 frontend/src/utils/quiz.js:24
|
||||
#: lms/lms/doctype/lms_quiz_submission/lms_quiz_submission.json
|
||||
#: lms/lms/workspace/lms/lms.json
|
||||
@@ -4044,7 +4036,7 @@ msgstr ""
|
||||
msgid "Quiz Submission"
|
||||
msgstr ""
|
||||
|
||||
#: frontend/src/pages/QuizSubmission.vue:98
|
||||
#: frontend/src/pages/QuizSubmission.vue:122
|
||||
#: frontend/src/pages/QuizSubmissionList.vue:102
|
||||
msgid "Quiz Submissions"
|
||||
msgstr ""
|
||||
@@ -4313,7 +4305,7 @@ msgid "Scope"
|
||||
msgstr ""
|
||||
|
||||
#. Label of the score (Int) field in DocType 'LMS Quiz Submission'
|
||||
#: frontend/src/pages/QuizSubmission.vue:35
|
||||
#: frontend/src/pages/QuizSubmission.vue:39
|
||||
#: frontend/src/pages/QuizSubmissionList.vue:87
|
||||
#: lms/lms/doctype/lms_quiz_submission/lms_quiz_submission.json
|
||||
#: lms/templates/quiz/quiz.html:148
|
||||
@@ -4350,7 +4342,7 @@ msgstr ""
|
||||
msgid "Seats Left"
|
||||
msgstr ""
|
||||
|
||||
#: frontend/src/components/Modals/Question.vue:91
|
||||
#: frontend/src/components/Modals/Question.vue:94
|
||||
msgid "Select a question"
|
||||
msgstr ""
|
||||
|
||||
@@ -4379,7 +4371,7 @@ msgstr ""
|
||||
|
||||
#: frontend/src/components/Modals/Settings.vue:7
|
||||
#: frontend/src/pages/BatchForm.vue:165 frontend/src/pages/CourseForm.vue:161
|
||||
#: frontend/src/pages/ProfileRoles.vue:4 frontend/src/pages/QuizForm.vue:78
|
||||
#: frontend/src/pages/ProfileRoles.vue:4 frontend/src/pages/QuizForm.vue:79
|
||||
msgid "Settings"
|
||||
msgstr ""
|
||||
|
||||
@@ -4403,12 +4395,12 @@ msgid "Show Answer"
|
||||
msgstr ""
|
||||
|
||||
#. Label of the show_answers (Check) field in DocType 'LMS Quiz'
|
||||
#: frontend/src/pages/QuizForm.vue:84 lms/lms/doctype/lms_quiz/lms_quiz.json
|
||||
#: frontend/src/pages/QuizForm.vue:85 lms/lms/doctype/lms_quiz/lms_quiz.json
|
||||
msgid "Show Answers"
|
||||
msgstr ""
|
||||
|
||||
#. Label of the show_submission_history (Check) field in DocType 'LMS Quiz'
|
||||
#: frontend/src/pages/QuizForm.vue:89 lms/lms/doctype/lms_quiz/lms_quiz.json
|
||||
#: frontend/src/pages/QuizForm.vue:90 lms/lms/doctype/lms_quiz/lms_quiz.json
|
||||
msgid "Show Submission History"
|
||||
msgstr ""
|
||||
|
||||
@@ -4433,11 +4425,11 @@ msgid "Show live class"
|
||||
msgstr ""
|
||||
|
||||
#. Label of the shuffle_questions (Check) field in DocType 'LMS Quiz'
|
||||
#: frontend/src/pages/QuizForm.vue:102 lms/lms/doctype/lms_quiz/lms_quiz.json
|
||||
#: frontend/src/pages/QuizForm.vue:103 lms/lms/doctype/lms_quiz/lms_quiz.json
|
||||
msgid "Shuffle Questions"
|
||||
msgstr ""
|
||||
|
||||
#: frontend/src/pages/QuizForm.vue:96
|
||||
#: frontend/src/pages/QuizForm.vue:97
|
||||
msgid "Shuffle Settings"
|
||||
msgstr ""
|
||||
|
||||
@@ -4633,7 +4625,7 @@ msgstr ""
|
||||
#. Label of the status (Select) field in DocType 'LMS Course Progress'
|
||||
#. Label of the status (Select) field in DocType 'LMS Mentor Request'
|
||||
#: frontend/src/components/Modals/Event.vue:91
|
||||
#: frontend/src/pages/JobCreation.vue:35
|
||||
#: frontend/src/pages/JobCreation.vue:41
|
||||
#: lms/job/doctype/job_opportunity/job_opportunity.json
|
||||
#: lms/lms/doctype/cohort/cohort.json
|
||||
#: lms/lms/doctype/cohort_join_request/cohort_join_request.json
|
||||
@@ -4725,7 +4717,7 @@ msgstr ""
|
||||
#: frontend/src/components/Modals/AssessmentModal.vue:9
|
||||
#: frontend/src/components/Modals/BatchCourseModal.vue:9
|
||||
#: frontend/src/components/Modals/EvaluationModal.vue:9
|
||||
#: frontend/src/components/Modals/Question.vue:335
|
||||
#: frontend/src/components/Modals/Question.vue:338
|
||||
#: frontend/src/components/Quiz.vue:214 lms/templates/assignment.html:9
|
||||
#: lms/templates/livecode/extension_footer.html:25
|
||||
#: lms/templates/quiz/quiz.html:128 lms/templates/reviews.html:163
|
||||
@@ -4752,12 +4744,12 @@ msgstr ""
|
||||
#: frontend/src/components/Modals/ChapterModal.vue:198
|
||||
#: frontend/src/components/Modals/Event.vue:255
|
||||
#: frontend/src/components/Modals/Event.vue:310
|
||||
#: frontend/src/components/Modals/Question.vue:261
|
||||
#: frontend/src/components/Modals/Question.vue:312
|
||||
#: frontend/src/pages/CourseForm.vue:460 frontend/src/pages/ProgramForm.vue:226
|
||||
#: frontend/src/pages/ProgramForm.vue:248
|
||||
#: frontend/src/pages/ProgramForm.vue:269
|
||||
#: frontend/src/pages/ProgramForm.vue:295 frontend/src/pages/QuizForm.vue:343
|
||||
#: frontend/src/components/Modals/Question.vue:264
|
||||
#: frontend/src/components/Modals/Question.vue:315
|
||||
#: frontend/src/pages/CourseForm.vue:460 frontend/src/pages/ProgramForm.vue:229
|
||||
#: frontend/src/pages/ProgramForm.vue:251
|
||||
#: frontend/src/pages/ProgramForm.vue:272
|
||||
#: frontend/src/pages/ProgramForm.vue:298 frontend/src/pages/QuizForm.vue:343
|
||||
#: frontend/src/pages/QuizForm.vue:362 frontend/src/pages/QuizForm.vue:431
|
||||
msgid "Success"
|
||||
msgstr ""
|
||||
@@ -4854,7 +4846,7 @@ msgstr ""
|
||||
msgid "Temporarily Disabled"
|
||||
msgstr ""
|
||||
|
||||
#: lms/lms/utils.py:440
|
||||
#: lms/lms/utils.py:436
|
||||
msgid "Terms of Use"
|
||||
msgstr ""
|
||||
|
||||
@@ -4918,7 +4910,7 @@ msgstr ""
|
||||
msgid "There are no courses available at the moment. Keep an eye out, fresh learning experiences are on the way soon!"
|
||||
msgstr ""
|
||||
|
||||
#: frontend/src/pages/Programs.vue:86
|
||||
#: frontend/src/pages/Programs.vue:97
|
||||
msgid "There are no programs available at the moment. Keep an eye out, fresh learning experiences are on the way soon!"
|
||||
msgstr ""
|
||||
|
||||
@@ -4934,6 +4926,10 @@ msgstr ""
|
||||
msgid "There are no {0} on this site."
|
||||
msgstr ""
|
||||
|
||||
#: lms/lms/doctype/lms_quiz_submission/lms_quiz_submission.py:41
|
||||
msgid "There has been an update on your submission. You have got a score of {0} for the quiz {1}"
|
||||
msgstr ""
|
||||
|
||||
#. Description of the 'section_break_ubxi' (Section Break) field in DocType
|
||||
#. 'LMS Batch'
|
||||
#: lms/lms/doctype/lms_batch/lms_batch.json
|
||||
@@ -4953,7 +4949,7 @@ msgstr ""
|
||||
msgid "This course has:"
|
||||
msgstr ""
|
||||
|
||||
#: lms/lms/utils.py:1585
|
||||
#: lms/lms/utils.py:1582
|
||||
msgid "This course is free."
|
||||
msgstr ""
|
||||
|
||||
@@ -5058,7 +5054,7 @@ msgstr ""
|
||||
#: frontend/src/components/Modals/LiveClassModal.vue:23
|
||||
#: frontend/src/pages/BatchForm.vue:20 frontend/src/pages/CourseForm.vue:32
|
||||
#: frontend/src/pages/JobCreation.vue:20 frontend/src/pages/ProgramForm.vue:11
|
||||
#: frontend/src/pages/Programs.vue:107 frontend/src/pages/QuizForm.vue:48
|
||||
#: frontend/src/pages/Programs.vue:118 frontend/src/pages/QuizForm.vue:48
|
||||
#: frontend/src/pages/Quizzes.vue:114 lms/lms/doctype/cohort/cohort.json
|
||||
#: lms/lms/doctype/cohort_subgroup/cohort_subgroup.json
|
||||
#: lms/lms/doctype/cohort_web_page/cohort_web_page.json
|
||||
@@ -5095,7 +5091,7 @@ msgstr ""
|
||||
msgid "To Date"
|
||||
msgstr ""
|
||||
|
||||
#: lms/lms/utils.py:1596
|
||||
#: lms/lms/utils.py:1593
|
||||
msgid "To join this batch, please contact the Administrator."
|
||||
msgstr ""
|
||||
|
||||
@@ -5112,7 +5108,7 @@ msgid "Total"
|
||||
msgstr ""
|
||||
|
||||
#. Label of the total_marks (Int) field in DocType 'LMS Quiz'
|
||||
#: frontend/src/pages/QuizForm.vue:66 frontend/src/pages/Quizzes.vue:119
|
||||
#: frontend/src/pages/QuizForm.vue:67 frontend/src/pages/Quizzes.vue:119
|
||||
#: lms/lms/doctype/lms_quiz/lms_quiz.json
|
||||
msgid "Total Marks"
|
||||
msgstr ""
|
||||
@@ -5149,7 +5145,7 @@ msgstr ""
|
||||
#. Label of the type (Select) field in DocType 'LMS Quiz Question'
|
||||
#: frontend/src/components/Modals/AssessmentModal.vue:22
|
||||
#: frontend/src/components/Modals/Question.vue:54
|
||||
#: frontend/src/pages/JobCreation.vue:28 frontend/src/pages/Jobs.vue:16
|
||||
#: frontend/src/pages/JobCreation.vue:33 frontend/src/pages/Jobs.vue:16
|
||||
#: lms/job/doctype/job_opportunity/job_opportunity.json
|
||||
#: lms/lms/doctype/lms_assignment/lms_assignment.json
|
||||
#: lms/lms/doctype/lms_assignment_submission/lms_assignment_submission.json
|
||||
@@ -5513,6 +5509,10 @@ msgstr ""
|
||||
msgid "You have been enrolled in this course"
|
||||
msgstr ""
|
||||
|
||||
#: lms/lms/doctype/lms_quiz_submission/lms_quiz_submission.py:38
|
||||
msgid "You have got a score of {0} for the quiz {1}"
|
||||
msgstr ""
|
||||
|
||||
#: frontend/src/pages/Quizzes.vue:60
|
||||
msgid "You have not created any quizzes yet. To create a new quiz, click on the \"New Quiz\" button above."
|
||||
msgstr ""
|
||||
@@ -5683,7 +5683,7 @@ msgstr ""
|
||||
msgid "{0} is your evaluator"
|
||||
msgstr ""
|
||||
|
||||
#: lms/lms/utils.py:704
|
||||
#: lms/lms/utils.py:700
|
||||
msgid "{0} mentioned you in a comment"
|
||||
msgstr ""
|
||||
|
||||
@@ -5691,11 +5691,11 @@ msgstr ""
|
||||
msgid "{0} mentioned you in a comment in your batch."
|
||||
msgstr ""
|
||||
|
||||
#: lms/lms/utils.py:657 lms/lms/utils.py:663
|
||||
#: lms/lms/utils.py:653 lms/lms/utils.py:659
|
||||
msgid "{0} mentioned you in a comment in {1}"
|
||||
msgstr ""
|
||||
|
||||
#: lms/lms/utils.py:480
|
||||
#: lms/lms/utils.py:476
|
||||
msgid "{0}k"
|
||||
msgstr ""
|
||||
|
||||
|
||||
458
lms/locale/pl.po
458
lms/locale/pl.po
File diff suppressed because it is too large
Load Diff
458
lms/locale/ru.po
458
lms/locale/ru.po
File diff suppressed because it is too large
Load Diff
622
lms/locale/sv.po
622
lms/locale/sv.po
File diff suppressed because it is too large
Load Diff
472
lms/locale/tr.po
472
lms/locale/tr.po
File diff suppressed because it is too large
Load Diff
2153
lms/locale/zh.po
2153
lms/locale/zh.po
File diff suppressed because it is too large
Load Diff
@@ -94,4 +94,5 @@ lms.patches.v2_0.delete_certificate_request_notification #18-09-2024
|
||||
lms.patches.v2_0.add_course_statistics #21-10-2024
|
||||
lms.patches.v2_0.give_discussions_permissions
|
||||
lms.patches.v2_0.delete_web_forms
|
||||
lms.patches.v2_0.update_desk_access_for_lms_roles
|
||||
lms.patches.v2_0.update_desk_access_for_lms_roles
|
||||
lms.patches.v2_0.update_quiz_submission_data
|
||||
@@ -2,4 +2,4 @@ import frappe
|
||||
|
||||
|
||||
def execute():
|
||||
frappe.db.delete("Web Form", {"module": "LMS"})
|
||||
frappe.db.delete("Web Form", {"module": "LMS", "is_standard": 1})
|
||||
|
||||
47
lms/patches/v2_0/update_quiz_submission_data.py
Normal file
47
lms/patches/v2_0/update_quiz_submission_data.py
Normal file
@@ -0,0 +1,47 @@
|
||||
import frappe
|
||||
|
||||
|
||||
def execute():
|
||||
set_question_data()
|
||||
set_submission_data()
|
||||
|
||||
|
||||
def set_question_data():
|
||||
questions = frappe.get_all("LMS Quiz Question", fields=["name", "question"])
|
||||
|
||||
for question in questions:
|
||||
question_doc = frappe.db.get_value(
|
||||
"LMS Question", question.question, ["question", "type"], as_dict=1
|
||||
)
|
||||
frappe.db.set_value(
|
||||
"LMS Quiz Question",
|
||||
question.name,
|
||||
{"question_detail": question_doc.question, "type": question_doc.type},
|
||||
)
|
||||
|
||||
|
||||
def set_submission_data():
|
||||
submissions = frappe.get_all("LMS Quiz Submission", fields=["name", "quiz"])
|
||||
|
||||
for submission in submissions:
|
||||
quiz_title = frappe.db.get_value("LMS Quiz", submission.quiz, "title")
|
||||
frappe.db.set_value("LMS Quiz Submission", submission.name, "quiz_title", quiz_title)
|
||||
|
||||
questions = frappe.get_all(
|
||||
"LMS Quiz Result", filters={"parent": submission.name}, fields=["question_name"]
|
||||
)
|
||||
|
||||
for question in questions:
|
||||
if question.question_name:
|
||||
marks_out_of = frappe.db.get_value(
|
||||
"LMS Quiz Question",
|
||||
{"parent": submission.quiz, "question": question.question_name},
|
||||
["marks"],
|
||||
)
|
||||
|
||||
frappe.db.set_value(
|
||||
"LMS Quiz Result",
|
||||
{"parent": submission.name, "question_name": question.question_name},
|
||||
"marks_out_of",
|
||||
marks_out_of,
|
||||
)
|
||||
@@ -1,74 +0,0 @@
|
||||
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
|
||||
|
||||
|
||||
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()
|
||||
|
||||
|
||||
def get_livecode_url():
|
||||
return frappe.db.get_single_value("LMS Settings", "livecode_url")
|
||||
|
||||
|
||||
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
|
||||
|
||||
|
||||
def get_current_lesson_details(lesson_number, context, is_edit=False):
|
||||
details_list = list(filter(lambda x: cstr(x.number) == lesson_number, context.lessons))
|
||||
|
||||
if not len(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
|
||||
|
||||
|
||||
def is_student(batch, member=None):
|
||||
if not member:
|
||||
member = frappe.session.user
|
||||
|
||||
return frappe.db.exists(
|
||||
"Batch Student",
|
||||
{
|
||||
"student": member,
|
||||
"parent": batch,
|
||||
},
|
||||
)
|
||||
Reference in New Issue
Block a user